summaryrefslogtreecommitdiff
path: root/libs/taglib/taglib/mpeg/id3v2
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-09-17 08:44:51 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-09-17 08:44:51 +0000
commit1c299d5a5c493986ca4a19bd55a69281dabada86 (patch)
treedae18913a2261a157ba32308ef804050e1232542 /libs/taglib/taglib/mpeg/id3v2
parent8e9a83dfdc233898e7c470667c7c9b797c83fe8b (diff)
merge Sakari's (sbergen) branch back into 3.0, removing libsndfile and adding taglib
git-svn-id: svn://localhost/ardour2/branches/3.0@3736 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/taglib/taglib/mpeg/id3v2')
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/CMakeLists.txt4
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/Makefile.am26
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/Makefile.in766
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/CMakeLists.txt11
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/Makefile.am31
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/Makefile.in656
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp170
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.h220
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/commentsframe.cpp178
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/commentsframe.h168
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp176
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h174
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/relativevolumeframe.cpp236
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/relativevolumeframe.h274
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/textidentificationframe.cpp271
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/textidentificationframe.h258
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.cpp118
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.h113
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/unknownframe.cpp84
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/unknownframe.h79
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp162
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.h157
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/urllinkframe.cpp192
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/frames/urllinkframe.h172
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2.2.0.txt1660
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2.3.0.txt2022
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2.4.0-frames.txt1734
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2.4.0-structure.txt733
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2extendedheader.cpp71
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2extendedheader.h93
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2footer.cpp60
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2footer.h82
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2frame.cpp549
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2frame.h414
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2framefactory.cpp407
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2framefactory.h167
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2header.cpp243
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2header.h175
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2synchdata.cpp63
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2synchdata.h70
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2tag.cpp474
-rw-r--r--libs/taglib/taglib/mpeg/id3v2/id3v2tag.h300
42 files changed, 14013 insertions, 0 deletions
diff --git a/libs/taglib/taglib/mpeg/id3v2/CMakeLists.txt b/libs/taglib/taglib/mpeg/id3v2/CMakeLists.txt
new file mode 100644
index 0000000000..f6e1ef1309
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/CMakeLists.txt
@@ -0,0 +1,4 @@
+ADD_SUBDIRECTORY( frames )
+
+INSTALL(FILES id3v2extendedheader.h id3v2frame.h id3v2header.h id3v2synchdata.h id3v2footer.h id3v2framefactory.h id3v2tag.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib)
+
diff --git a/libs/taglib/taglib/mpeg/id3v2/Makefile.am b/libs/taglib/taglib/mpeg/id3v2/Makefile.am
new file mode 100644
index 0000000000..1a45ae5059
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/Makefile.am
@@ -0,0 +1,26 @@
+SUBDIRS = frames
+INCLUDES = \
+ -I$(top_srcdir)/taglib \
+ -I$(top_srcdir)/taglib/toolkit \
+ -I$(top_srcdir)/taglib/mpeg \
+ -I$(top_srcdir)/taglib/mpeg/id3v1 \
+ $(all_includes)
+
+noinst_LTLIBRARIES = libid3v2.la
+
+libid3v2_la_SOURCES = \
+ id3v2framefactory.cpp id3v2synchdata.cpp id3v2tag.cpp \
+ id3v2header.cpp id3v2frame.cpp id3v2footer.cpp \
+ id3v2extendedheader.cpp
+
+taglib_include_HEADERS = \
+ id3v2extendedheader.h id3v2frame.h id3v2header.h \
+ id3v2synchdata.h id3v2footer.h id3v2framefactory.h id3v2tag.h
+
+taglib_includedir = $(includedir)/taglib
+
+if link_zlib
+zlib = -lz
+endif
+
+libid3v2_la_LIBADD = ./frames/libframes.la $(zlib)
diff --git a/libs/taglib/taglib/mpeg/id3v2/Makefile.in b/libs/taglib/taglib/mpeg/id3v2/Makefile.in
new file mode 100644
index 0000000000..df65ec4546
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/Makefile.in
@@ -0,0 +1,766 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 483858 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = taglib/mpeg/id3v2
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(taglib_include_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libid3v2_la_DEPENDENCIES = ./frames/libframes.la $(am__DEPENDENCIES_1)
+am_libid3v2_la_OBJECTS = id3v2framefactory.lo id3v2synchdata.lo \
+ id3v2tag.lo id3v2header.lo id3v2frame.lo id3v2footer.lo \
+ id3v2extendedheader.lo
+#>- libid3v2_la_OBJECTS = $(am_libid3v2_la_OBJECTS)
+#>+ 6
+libid3v2_la_final_OBJECTS = libid3v2_la.all_cpp.lo
+libid3v2_la_nofinal_OBJECTS = id3v2framefactory.lo id3v2synchdata.lo \
+ id3v2tag.lo id3v2header.lo id3v2frame.lo id3v2footer.lo \
+ id3v2extendedheader.lo
+@KDE_USE_FINAL_FALSE@libid3v2_la_OBJECTS = $(libid3v2_la_nofinal_OBJECTS)
+@KDE_USE_FINAL_TRUE@libid3v2_la_OBJECTS = $(libid3v2_la_final_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
+am__depfiles_maybe = depfiles
+#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 2
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+#>- LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 3
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+CXXLD = $(CXX)
+#>- CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+#>- $(LDFLAGS) -o $@
+#>+ 3
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libid3v2_la_SOURCES)
+DIST_SOURCES = $(libid3v2_la_SOURCES)
+#>- RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+#>- html-recursive info-recursive install-data-recursive \
+#>- install-dvi-recursive install-exec-recursive \
+#>- install-html-recursive install-info-recursive \
+#>- install-pdf-recursive install-ps-recursive install-recursive \
+#>- installcheck-recursive installdirs-recursive pdf-recursive \
+#>- ps-recursive uninstall-recursive
+#>+ 7
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive nmcheck-recursive bcheck-recursive
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(taglib_includedir)"
+taglib_includeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(taglib_include_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = frames
+INCLUDES = \
+ -I$(top_srcdir)/taglib \
+ -I$(top_srcdir)/taglib/toolkit \
+ -I$(top_srcdir)/taglib/mpeg \
+ -I$(top_srcdir)/taglib/mpeg/id3v1 \
+ $(all_includes)
+
+noinst_LTLIBRARIES = libid3v2.la
+libid3v2_la_SOURCES = \
+ id3v2framefactory.cpp id3v2synchdata.cpp id3v2tag.cpp \
+ id3v2header.cpp id3v2frame.cpp id3v2footer.cpp \
+ id3v2extendedheader.cpp
+
+taglib_include_HEADERS = \
+ id3v2extendedheader.h id3v2frame.h id3v2header.h \
+ id3v2synchdata.h id3v2footer.h id3v2framefactory.h id3v2tag.h
+
+taglib_includedir = $(includedir)/taglib
+@link_zlib_TRUE@zlib = -lz
+libid3v2_la_LIBADD = ./frames/libframes.la $(zlib)
+#>- all: all-recursive
+#>+ 1
+all: docs-am all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu taglib/mpeg/id3v2/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu taglib/mpeg/id3v2/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu taglib/mpeg/id3v2/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu taglib/mpeg/id3v2/Makefile
+ cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/id3v2/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libid3v2.la: $(libid3v2_la_OBJECTS) $(libid3v2_la_DEPENDENCIES)
+ $(CXXLINK) $(libid3v2_la_OBJECTS) $(libid3v2_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2extendedheader.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2footer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2frame.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2framefactory.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2header.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2synchdata.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2tag.Plo@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-taglib_includeHEADERS: $(taglib_include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(taglib_includedir)" || $(MKDIR_P) "$(DESTDIR)$(taglib_includedir)"
+ @list='$(taglib_include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(taglib_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(taglib_includedir)/$$f'"; \
+ $(taglib_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(taglib_includedir)/$$f"; \
+ done
+
+uninstall-taglib_includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(taglib_include_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(taglib_includedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(taglib_includedir)/$$f"; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(taglib_includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-recursive
+#>+ 1
+clean: kde-rpo-clean clean-recursive
+
+#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+#>- mostlyclean-am
+#>+ 2
+clean-am: clean-bcheck clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-taglib_includeHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-info: install-info-recursive
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-ps: install-ps-recursive
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-taglib_includeHEADERS
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
+ install-strip
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ clean-noinstLTLIBRARIES ctags ctags-recursive distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-taglib_includeHEADERS installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am \
+ uninstall-taglib_includeHEADERS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+#>+ 2
+KDE_DIST=Makefile.in id3v2.3.0.txt id3v2.4.0-structure.txt id3v2.2.0.txt id3v2.4.0-frames.txt CMakeLists.txt Makefile.am
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu taglib/mpeg/id3v2/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu taglib/mpeg/id3v2/Makefile
+ cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/id3v2/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-recursive
+
+bcheck-am:
+ @for i in $(taglib_include_HEADERS); do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXXCOMPILE) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 11
+libid3v2_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/id3v2framefactory.cpp $(srcdir)/id3v2synchdata.cpp $(srcdir)/id3v2tag.cpp $(srcdir)/id3v2header.cpp $(srcdir)/id3v2frame.cpp $(srcdir)/id3v2footer.cpp $(srcdir)/id3v2extendedheader.cpp
+ @echo 'creating libid3v2_la.all_cpp.cpp ...'; \
+ rm -f libid3v2_la.all_cpp.files libid3v2_la.all_cpp.final; \
+ echo "#define KDE_USE_FINAL 1" >> libid3v2_la.all_cpp.final; \
+ for file in id3v2framefactory.cpp id3v2synchdata.cpp id3v2tag.cpp id3v2header.cpp id3v2frame.cpp id3v2footer.cpp id3v2extendedheader.cpp ; do \
+ echo "#include \"$$file\"" >> libid3v2_la.all_cpp.files; \
+ test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libid3v2_la.all_cpp.final; \
+ done; \
+ cat libid3v2_la.all_cpp.final libid3v2_la.all_cpp.files > libid3v2_la.all_cpp.cpp; \
+ rm -f libid3v2_la.all_cpp.final libid3v2_la.all_cpp.files
+
+#>+ 3
+clean-final:
+ -rm -f libid3v2_la.all_cpp.cpp
+
+#>+ 3
+final:
+ $(MAKE) libid3v2_la_OBJECTS="$(libid3v2_la_final_OBJECTS)" all-am
+
+#>+ 3
+final-install:
+ $(MAKE) libid3v2_la_OBJECTS="$(libid3v2_la_final_OBJECTS)" install-am
+
+#>+ 3
+no-final:
+ $(MAKE) libid3v2_la_OBJECTS="$(libid3v2_la_nofinal_OBJECTS)" all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) libid3v2_la_OBJECTS="$(libid3v2_la_nofinal_OBJECTS)" install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/CMakeLists.txt b/libs/taglib/taglib/mpeg/id3v2/frames/CMakeLists.txt
new file mode 100644
index 0000000000..1fb1e20868
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/CMakeLists.txt
@@ -0,0 +1,11 @@
+INSTALL(FILES
+ attachedpictureframe.h
+ commentsframe.h
+ generalencapsulatedobjectframe.h
+ relativevolumeframe.h
+ textidentificationframe.h
+ uniquefileidentifierframe.h
+ unknownframe.h
+ unsynchronizedlyricsframe.h
+ urllinkframe.h
+ DESTINATION ${INCLUDE_INSTALL_DIR}/taglib)
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/Makefile.am b/libs/taglib/taglib/mpeg/id3v2/frames/Makefile.am
new file mode 100644
index 0000000000..517cd75386
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/Makefile.am
@@ -0,0 +1,31 @@
+INCLUDES = \
+ -I$(top_srcdir)/taglib \
+ -I$(top_srcdir)/taglib/toolkit \
+ -I$(top_srcdir)/taglib/mpeg/id3v2 \
+ $(all_includes)
+
+noinst_LTLIBRARIES = libframes.la
+
+libframes_la_SOURCES = \
+ attachedpictureframe.cpp \
+ commentsframe.cpp \
+ generalencapsulatedobjectframe.cpp \
+ relativevolumeframe.cpp \
+ textidentificationframe.cpp \
+ uniquefileidentifierframe.cpp \
+ unknownframe.cpp \
+ unsynchronizedlyricsframe.cpp \
+ urllinkframe.cpp
+
+taglib_include_HEADERS = \
+ attachedpictureframe.h \
+ commentsframe.h \
+ generalencapsulatedobjectframe.h \
+ relativevolumeframe.h \
+ textidentificationframe.h \
+ uniquefileidentifierframe.h \
+ unknownframe.h \
+ unsynchronizedlyricsframe.h \
+ urllinkframe.h
+
+taglib_includedir = $(includedir)/taglib
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/Makefile.in b/libs/taglib/taglib/mpeg/id3v2/frames/Makefile.in
new file mode 100644
index 0000000000..9268ff5e8d
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/Makefile.in
@@ -0,0 +1,656 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# KDE tags expanded automatically by am_edit - $Revision: 483858 $
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = taglib/mpeg/id3v2/frames
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(taglib_include_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libframes_la_LIBADD =
+am_libframes_la_OBJECTS = attachedpictureframe.lo commentsframe.lo \
+ generalencapsulatedobjectframe.lo relativevolumeframe.lo \
+ textidentificationframe.lo uniquefileidentifierframe.lo \
+ unknownframe.lo unsynchronizedlyricsframe.lo urllinkframe.lo
+#>- libframes_la_OBJECTS = $(am_libframes_la_OBJECTS)
+#>+ 7
+libframes_la_final_OBJECTS = libframes_la.all_cpp.lo
+libframes_la_nofinal_OBJECTS = attachedpictureframe.lo commentsframe.lo \
+ generalencapsulatedobjectframe.lo relativevolumeframe.lo \
+ textidentificationframe.lo uniquefileidentifierframe.lo \
+ unknownframe.lo unsynchronizedlyricsframe.lo urllinkframe.lo
+@KDE_USE_FINAL_FALSE@libframes_la_OBJECTS = $(libframes_la_nofinal_OBJECTS)
+@KDE_USE_FINAL_TRUE@libframes_la_OBJECTS = $(libframes_la_final_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
+am__depfiles_maybe = depfiles
+#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 2
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+#>- LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+#>+ 3
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
+CXXLD = $(CXX)
+#>- CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+#>- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+#>- $(LDFLAGS) -o $@
+#>+ 3
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libframes_la_SOURCES)
+DIST_SOURCES = $(libframes_la_SOURCES)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(taglib_includedir)"
+taglib_includeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(taglib_include_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+#>+ 1
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTODIRS = @AUTODIRS@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONF_FILES = @CONF_FILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@
+KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@
+KDE_PLUGIN = @KDE_PLUGIN@
+KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
+KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
+KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
+KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
+KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@
+KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@
+LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NOOPT_CFLAGS = @NOOPT_CFLAGS@
+NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TOPSUBDIRS = @TOPSUBDIRS@
+USE_EXCEPTIONS = @USE_EXCEPTIONS@
+USE_RTTI = @USE_RTTI@
+VERSION = @VERSION@
+WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+all_includes = @all_includes@
+all_libraries = @all_libraries@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_srcdir)/taglib \
+ -I$(top_srcdir)/taglib/toolkit \
+ -I$(top_srcdir)/taglib/mpeg/id3v2 \
+ $(all_includes)
+
+noinst_LTLIBRARIES = libframes.la
+libframes_la_SOURCES = \
+ attachedpictureframe.cpp \
+ commentsframe.cpp \
+ generalencapsulatedobjectframe.cpp \
+ relativevolumeframe.cpp \
+ textidentificationframe.cpp \
+ uniquefileidentifierframe.cpp \
+ unknownframe.cpp \
+ unsynchronizedlyricsframe.cpp \
+ urllinkframe.cpp
+
+taglib_include_HEADERS = \
+ attachedpictureframe.h \
+ commentsframe.h \
+ generalencapsulatedobjectframe.h \
+ relativevolumeframe.h \
+ textidentificationframe.h \
+ uniquefileidentifierframe.h \
+ unknownframe.h \
+ unsynchronizedlyricsframe.h \
+ urllinkframe.h
+
+taglib_includedir = $(includedir)/taglib
+#>- all: all-am
+#>+ 1
+all: docs-am all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+#>- @for dep in $?; do \
+#>- case '$(am__configure_deps)' in \
+#>- *$$dep*) \
+#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+#>- && exit 0; \
+#>- exit 1;; \
+#>- esac; \
+#>- done; \
+#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu taglib/mpeg/id3v2/frames/Makefile'; \
+#>- cd $(top_srcdir) && \
+#>- $(AUTOMAKE) --gnu taglib/mpeg/id3v2/frames/Makefile
+#>+ 12
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu taglib/mpeg/id3v2/frames/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu taglib/mpeg/id3v2/frames/Makefile
+ cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/id3v2/frames/Makefile.in
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libframes.la: $(libframes_la_OBJECTS) $(libframes_la_DEPENDENCIES)
+ $(CXXLINK) $(libframes_la_OBJECTS) $(libframes_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attachedpictureframe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commentsframe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generalencapsulatedobjectframe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/relativevolumeframe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/textidentificationframe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uniquefileidentifierframe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unknownframe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unsynchronizedlyricsframe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/urllinkframe.Plo@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-taglib_includeHEADERS: $(taglib_include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(taglib_includedir)" || $(MKDIR_P) "$(DESTDIR)$(taglib_includedir)"
+ @list='$(taglib_include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(taglib_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(taglib_includedir)/$$f'"; \
+ $(taglib_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(taglib_includedir)/$$f"; \
+ done
+
+uninstall-taglib_includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(taglib_include_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(taglib_includedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(taglib_includedir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(taglib_includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+#>- clean: clean-am
+#>+ 1
+clean: kde-rpo-clean clean-am
+
+#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+#>- mostlyclean-am
+#>+ 2
+clean-am: clean-bcheck clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-taglib_includeHEADERS
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-taglib_includeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-taglib_includeHEADERS installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-taglib_includeHEADERS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+#>+ 2
+KDE_DIST=Makefile.in CMakeLists.txt Makefile.am
+
+#>+ 2
+docs-am:
+
+#>+ 15
+force-reedit:
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu taglib/mpeg/id3v2/frames/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu taglib/mpeg/id3v2/frames/Makefile
+ cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/id3v2/frames/Makefile.in
+
+
+#>+ 21
+clean-bcheck:
+ rm -f *.bchecktest.cc *.bchecktest.cc.class a.out
+
+bcheck: bcheck-am
+
+bcheck-am:
+ @for i in $(taglib_include_HEADERS); do \
+ if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \
+ echo "int main() {return 0;}" > $$i.bchecktest.cc ; \
+ echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \
+ echo "$$i"; \
+ if ! $(CXXCOMPILE) --dump-class-hierarchy -c $$i.bchecktest.cc; then \
+ rm -f $$i.bchecktest.cc; exit 1; \
+ fi ; \
+ echo "" >> $$i.bchecktest.cc.class; \
+ perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \
+ rm -f a.out; \
+ fi ; \
+ done
+
+
+#>+ 11
+libframes_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/attachedpictureframe.cpp $(srcdir)/commentsframe.cpp $(srcdir)/generalencapsulatedobjectframe.cpp $(srcdir)/relativevolumeframe.cpp $(srcdir)/textidentificationframe.cpp $(srcdir)/uniquefileidentifierframe.cpp $(srcdir)/unknownframe.cpp $(srcdir)/unsynchronizedlyricsframe.cpp $(srcdir)/urllinkframe.cpp
+ @echo 'creating libframes_la.all_cpp.cpp ...'; \
+ rm -f libframes_la.all_cpp.files libframes_la.all_cpp.final; \
+ echo "#define KDE_USE_FINAL 1" >> libframes_la.all_cpp.final; \
+ for file in attachedpictureframe.cpp commentsframe.cpp generalencapsulatedobjectframe.cpp relativevolumeframe.cpp textidentificationframe.cpp uniquefileidentifierframe.cpp unknownframe.cpp unsynchronizedlyricsframe.cpp urllinkframe.cpp ; do \
+ echo "#include \"$$file\"" >> libframes_la.all_cpp.files; \
+ test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libframes_la.all_cpp.final; \
+ done; \
+ cat libframes_la.all_cpp.final libframes_la.all_cpp.files > libframes_la.all_cpp.cpp; \
+ rm -f libframes_la.all_cpp.final libframes_la.all_cpp.files
+
+#>+ 3
+clean-final:
+ -rm -f libframes_la.all_cpp.cpp
+
+#>+ 3
+final:
+ $(MAKE) libframes_la_OBJECTS="$(libframes_la_final_OBJECTS)" all-am
+
+#>+ 3
+final-install:
+ $(MAKE) libframes_la_OBJECTS="$(libframes_la_final_OBJECTS)" install-am
+
+#>+ 3
+no-final:
+ $(MAKE) libframes_la_OBJECTS="$(libframes_la_nofinal_OBJECTS)" all-am
+
+#>+ 3
+no-final-install:
+ $(MAKE) libframes_la_OBJECTS="$(libframes_la_nofinal_OBJECTS)" install-am
+
+#>+ 3
+kde-rpo-clean:
+ -rm -f *.rpo
+
+#>+ 3
+nmcheck:
+nmcheck-am: nmcheck
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp b/libs/taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp
new file mode 100644
index 0000000000..8a88253f5c
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp
@@ -0,0 +1,170 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include "attachedpictureframe.h"
+
+#include <tstringlist.h>
+#include <tdebug.h>
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class AttachedPictureFrame::AttachedPictureFramePrivate
+{
+public:
+ AttachedPictureFramePrivate() : textEncoding(String::Latin1),
+ type(AttachedPictureFrame::Other) {}
+
+ String::Type textEncoding;
+ String mimeType;
+ AttachedPictureFrame::Type type;
+ String description;
+ ByteVector data;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+AttachedPictureFrame::AttachedPictureFrame() : Frame("APIC")
+{
+ d = new AttachedPictureFramePrivate;
+}
+
+AttachedPictureFrame::AttachedPictureFrame(const ByteVector &data) : Frame(data)
+{
+ d = new AttachedPictureFramePrivate;
+ setData(data);
+}
+
+AttachedPictureFrame::~AttachedPictureFrame()
+{
+ delete d;
+}
+
+String AttachedPictureFrame::toString() const
+{
+ String s = "[" + d->mimeType + "]";
+ return d->description.isEmpty() ? s : d->description + " " + s;
+}
+
+String::Type AttachedPictureFrame::textEncoding() const
+{
+ return d->textEncoding;
+}
+
+void AttachedPictureFrame::setTextEncoding(String::Type t)
+{
+ d->textEncoding = t;
+}
+
+String AttachedPictureFrame::mimeType() const
+{
+ return d->mimeType;
+}
+
+void AttachedPictureFrame::setMimeType(const String &m)
+{
+ d->mimeType = m;
+}
+
+AttachedPictureFrame::Type AttachedPictureFrame::type() const
+{
+ return d->type;
+}
+
+void AttachedPictureFrame::setType(Type t)
+{
+ d->type = t;
+}
+
+String AttachedPictureFrame::description() const
+{
+ return d->description;
+}
+
+void AttachedPictureFrame::setDescription(const String &desc)
+{
+ d->description = desc;
+}
+
+ByteVector AttachedPictureFrame::picture() const
+{
+ return d->data;
+}
+
+void AttachedPictureFrame::setPicture(const ByteVector &p)
+{
+ d->data = p;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void AttachedPictureFrame::parseFields(const ByteVector &data)
+{
+ if(data.size() < 5) {
+ debug("A picture frame must contain at least 5 bytes.");
+ return;
+ }
+
+ d->textEncoding = String::Type(data[0]);
+
+ int pos = 1;
+
+ d->mimeType = readStringField(data, String::Latin1, &pos);
+ d->type = (TagLib::ID3v2::AttachedPictureFrame::Type)data[pos++];
+ d->description = readStringField(data, d->textEncoding, &pos);
+
+ d->data = data.mid(pos);
+}
+
+ByteVector AttachedPictureFrame::renderFields() const
+{
+ ByteVector data;
+
+ String::Type encoding = checkEncoding(d->description, d->textEncoding);
+
+ data.append(char(encoding));
+ data.append(d->mimeType.data(String::Latin1));
+ data.append(textDelimiter(String::Latin1));
+ data.append(char(d->type));
+ data.append(d->description.data(encoding));
+ data.append(textDelimiter(encoding));
+ data.append(d->data);
+
+ return data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+AttachedPictureFrame::AttachedPictureFrame(const ByteVector &data, Header *h) : Frame(h)
+{
+ d = new AttachedPictureFramePrivate;
+ parseFields(fieldData(data));
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.h b/libs/taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.h
new file mode 100644
index 0000000000..bd95ed22d2
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/attachedpictureframe.h
@@ -0,0 +1,220 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ATTACHEDPICTUREFRAME_H
+#define TAGLIB_ATTACHEDPICTUREFRAME_H
+
+#include <id3v2frame.h>
+#include <id3v2header.h>
+#include "taglib_export.h"
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ //! An ID3v2 attached picture frame implementation
+
+ /*!
+ * This is an implementation of ID3v2 attached pictures. Pictures may be
+ * included in tags, one per APIC frame (but there may be multiple APIC
+ * frames in a single tag). These pictures are usually in either JPEG or
+ * PNG format.
+ */
+
+ class TAGLIB_EXPORT AttachedPictureFrame : public Frame
+ {
+ friend class FrameFactory;
+
+ public:
+
+ /*!
+ * This describes the function or content of the picture.
+ */
+ enum Type {
+ //! A type not enumerated below
+ Other = 0x00,
+ //! 32x32 PNG image that should be used as the file icon
+ FileIcon = 0x01,
+ //! File icon of a different size or format
+ OtherFileIcon = 0x02,
+ //! Front cover image of the album
+ FrontCover = 0x03,
+ //! Back cover image of the album
+ BackCover = 0x04,
+ //! Inside leaflet page of the album
+ LeafletPage = 0x05,
+ //! Image from the album itself
+ Media = 0x06,
+ //! Picture of the lead artist or soloist
+ LeadArtist = 0x07,
+ //! Picture of the artist or performer
+ Artist = 0x08,
+ //! Picture of the conductor
+ Conductor = 0x09,
+ //! Picture of the band or orchestra
+ Band = 0x0A,
+ //! Picture of the composer
+ Composer = 0x0B,
+ //! Picture of the lyricist or text writer
+ Lyricist = 0x0C,
+ //! Picture of the recording location or studio
+ RecordingLocation = 0x0D,
+ //! Picture of the artists during recording
+ DuringRecording = 0x0E,
+ //! Picture of the artists during performance
+ DuringPerformance = 0x0F,
+ //! Picture from a movie or video related to the track
+ MovieScreenCapture = 0x10,
+ //! Picture of a large, coloured fish
+ ColouredFish = 0x11,
+ //! Illustration related to the track
+ Illustration = 0x12,
+ //! Logo of the band or performer
+ BandLogo = 0x13,
+ //! Logo of the publisher (record company)
+ PublisherLogo = 0x14
+ };
+
+ /*!
+ * Constructs an empty picture frame. The description, content and text
+ * encoding should be set manually.
+ */
+ AttachedPictureFrame();
+
+ /*!
+ * Constructs an AttachedPicture frame based on \a data.
+ */
+ explicit AttachedPictureFrame(const ByteVector &data);
+
+ /*!
+ * Destroys the AttahcedPictureFrame instance.
+ */
+ virtual ~AttachedPictureFrame();
+
+ /*!
+ * Returns a string containing the description and mime-type
+ */
+ virtual String toString() const;
+
+ /*!
+ * Returns the text encoding used for the description.
+ *
+ * \see setTextEncoding()
+ * \see description()
+ */
+ String::Type textEncoding() const;
+
+ /*!
+ * Set the text encoding used for the description.
+ *
+ * \see description()
+ */
+ void setTextEncoding(String::Type t);
+
+ /*!
+ * Returns the mime type of the image. This should in most cases be
+ * "image/png" or "image/jpeg".
+ */
+ String mimeType() const;
+
+ /*!
+ * Sets the mime type of the image. This should in most cases be
+ * "image/png" or "image/jpeg".
+ */
+ void setMimeType(const String &m);
+
+ /*!
+ * Returns the type of the image.
+ *
+ * \see Type
+ * \see setType()
+ */
+ Type type() const;
+
+ /*!
+ * Sets the type for the image.
+ *
+ * \see Type
+ * \see type()
+ */
+ void setType(Type t);
+
+ /*!
+ * Returns a text description of the image.
+ *
+ * \see setDescription()
+ * \see textEncoding()
+ * \see setTextEncoding()
+ */
+
+ String description() const;
+
+ /*!
+ * Sets a textual description of the image to \a desc.
+ *
+ * \see description()
+ * \see textEncoding()
+ * \see setTextEncoding()
+ */
+
+ void setDescription(const String &desc);
+
+ /*!
+ * Returns the image data as a ByteVector.
+ *
+ * \note ByteVector has a data() method that returns a const char * which
+ * should make it easy to export this data to external programs.
+ *
+ * \see setPicture()
+ * \see mimeType()
+ */
+ ByteVector picture() const;
+
+ /*!
+ * Sets the image data to \a p. \a p should be of the type specified in
+ * this frame's mime-type specification.
+ *
+ * \see picture()
+ * \see mimeType()
+ * \see setMimeType()
+ */
+ void setPicture(const ByteVector &p);
+
+ protected:
+ virtual void parseFields(const ByteVector &data);
+ virtual ByteVector renderFields() const;
+
+ private:
+ AttachedPictureFrame(const ByteVector &data, Header *h);
+ AttachedPictureFrame(const AttachedPictureFrame &);
+ AttachedPictureFrame &operator=(const AttachedPictureFrame &);
+
+ class AttachedPictureFramePrivate;
+ AttachedPictureFramePrivate *d;
+ };
+ }
+}
+
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/commentsframe.cpp b/libs/taglib/taglib/mpeg/id3v2/frames/commentsframe.cpp
new file mode 100644
index 0000000000..2df176bde0
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/commentsframe.cpp
@@ -0,0 +1,178 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include <tbytevectorlist.h>
+#include <id3v2tag.h>
+#include <tdebug.h>
+#include <tstringlist.h>
+
+#include "commentsframe.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class CommentsFrame::CommentsFramePrivate
+{
+public:
+ CommentsFramePrivate() : textEncoding(String::Latin1) {}
+ String::Type textEncoding;
+ ByteVector language;
+ String description;
+ String text;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+CommentsFrame::CommentsFrame(String::Type encoding) : Frame("COMM")
+{
+ d = new CommentsFramePrivate;
+ d->textEncoding = encoding;
+}
+
+CommentsFrame::CommentsFrame(const ByteVector &data) : Frame(data)
+{
+ d = new CommentsFramePrivate;
+ setData(data);
+}
+
+CommentsFrame::~CommentsFrame()
+{
+ delete d;
+}
+
+String CommentsFrame::toString() const
+{
+ return d->text;
+}
+
+ByteVector CommentsFrame::language() const
+{
+ return d->language;
+}
+
+String CommentsFrame::description() const
+{
+ return d->description;
+}
+
+String CommentsFrame::text() const
+{
+ return d->text;
+}
+
+void CommentsFrame::setLanguage(const ByteVector &languageEncoding)
+{
+ d->language = languageEncoding.mid(0, 3);
+}
+
+void CommentsFrame::setDescription(const String &s)
+{
+ d->description = s;
+}
+
+void CommentsFrame::setText(const String &s)
+{
+ d->text = s;
+}
+
+String::Type CommentsFrame::textEncoding() const
+{
+ return d->textEncoding;
+}
+
+void CommentsFrame::setTextEncoding(String::Type encoding)
+{
+ d->textEncoding = encoding;
+}
+
+CommentsFrame *CommentsFrame::findByDescription(const ID3v2::Tag *tag, const String &d) // static
+{
+ ID3v2::FrameList comments = tag->frameList("COMM");
+
+ for(ID3v2::FrameList::ConstIterator it = comments.begin();
+ it != comments.end();
+ ++it)
+ {
+ CommentsFrame *frame = dynamic_cast<CommentsFrame *>(*it);
+ if(frame && frame->description() == d)
+ return frame;
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void CommentsFrame::parseFields(const ByteVector &data)
+{
+ if(data.size() < 5) {
+ debug("A comment frame must contain at least 5 bytes.");
+ return;
+ }
+
+ d->textEncoding = String::Type(data[0]);
+ d->language = data.mid(1, 3);
+
+ int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
+
+ ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
+
+ if(l.size() == 2) {
+ d->description = String(l.front(), d->textEncoding);
+ d->text = String(l.back(), d->textEncoding);
+ }
+}
+
+ByteVector CommentsFrame::renderFields() const
+{
+ ByteVector v;
+
+ String::Type encoding = d->textEncoding;
+
+ encoding = checkEncoding(d->description, encoding);
+ encoding = checkEncoding(d->text, encoding);
+
+ v.append(char(encoding));
+ v.append(d->language.size() == 3 ? d->language : "XXX");
+ v.append(d->description.data(encoding));
+ v.append(textDelimiter(encoding));
+ v.append(d->text.data(encoding));
+
+ return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+CommentsFrame::CommentsFrame(const ByteVector &data, Header *h) : Frame(h)
+{
+ d = new CommentsFramePrivate();
+ parseFields(fieldData(data));
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/commentsframe.h b/libs/taglib/taglib/mpeg/id3v2/frames/commentsframe.h
new file mode 100644
index 0000000000..9123c739be
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/commentsframe.h
@@ -0,0 +1,168 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_COMMENTSFRAME_H
+#define TAGLIB_COMMENTSFRAME_H
+
+#include <id3v2frame.h>
+#include "taglib_export.h"
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ //! An implementation of ID3v2 comments
+
+ /*!
+ * This implements the ID3v2 comment format. An ID3v2 comment concists of
+ * a language encoding, a description and a single text field.
+ */
+
+ class TAGLIB_EXPORT CommentsFrame : public Frame
+ {
+ friend class FrameFactory;
+
+ public:
+ /*!
+ * Construct an empty comment frame that will use the text encoding
+ * \a encoding.
+ */
+ explicit CommentsFrame(String::Type encoding = String::Latin1);
+
+ /*!
+ * Construct a comment based on the data in \a data.
+ */
+ explicit CommentsFrame(const ByteVector &data);
+
+ /*!
+ * Destroys this CommentFrame instance.
+ */
+ virtual ~CommentsFrame();
+
+ /*!
+ * Returns the text of this comment.
+ *
+ * \see text()
+ */
+ virtual String toString() const;
+
+ /*!
+ * Returns the language encoding as a 3 byte encoding as specified by
+ * <a href="http://en.wikipedia.org/wiki/ISO_639">ISO-639-2</a>.
+ *
+ * \note Most taggers simply ignore this value.
+ *
+ * \see setLanguage()
+ */
+ ByteVector language() const;
+
+ /*!
+ * Returns the description of this comment.
+ *
+ * \note Most taggers simply ignore this value.
+ *
+ * \see setDescription()
+ */
+ String description() const;
+
+ /*!
+ * Returns the text of this comment.
+ *
+ * \see setText()
+ */
+ String text() const;
+
+ /*!
+ * Set the language using the 3 byte language code from
+ * <a href="http://en.wikipedia.org/wiki/ISO_639">ISO-639-2</a> to
+ * \a languageCode.
+ *
+ * \see language()
+ */
+ void setLanguage(const ByteVector &languageCode);
+
+ /*!
+ * Sets the description of the comment to \a s.
+ *
+ * \see decription()
+ */
+ void setDescription(const String &s);
+
+ /*!
+ * Sets the text portion of the comment to \a s.
+ *
+ * \see text()
+ */
+ virtual void setText(const String &s);
+
+ /*!
+ * Returns the text encoding that will be used in rendering this frame.
+ * This defaults to the type that was either specified in the constructor
+ * or read from the frame when parsed.
+ *
+ * \see setTextEncoding()
+ * \see render()
+ */
+ String::Type textEncoding() const;
+
+ /*!
+ * Sets the text encoding to be used when rendering this frame to
+ * \a encoding.
+ *
+ * \see textEncoding()
+ * \see render()
+ */
+ void setTextEncoding(String::Type encoding);
+
+ /*!
+ * Comments each have a unique description. This searches for a comment
+ * frame with the decription \a d and returns a pointer to it. If no
+ * frame is found that matches the given description null is returned.
+ *
+ * \see description()
+ */
+ static CommentsFrame *findByDescription(const Tag *tag, const String &d);
+
+ protected:
+ // Reimplementations.
+
+ virtual void parseFields(const ByteVector &data);
+ virtual ByteVector renderFields() const;
+
+ private:
+ /*!
+ * The constructor used by the FrameFactory.
+ */
+ CommentsFrame(const ByteVector &data, Header *h);
+ CommentsFrame(const CommentsFrame &);
+ CommentsFrame &operator=(const CommentsFrame &);
+
+ class CommentsFramePrivate;
+ CommentsFramePrivate *d;
+ };
+
+ }
+}
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp b/libs/taglib/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp
new file mode 100644
index 0000000000..58b7b63f68
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp
@@ -0,0 +1,176 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ copyright : (C) 2006 by Aaron VonderHaar
+ email : avh4@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include <tdebug.h>
+
+#include "generalencapsulatedobjectframe.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class GeneralEncapsulatedObjectFrame::GeneralEncapsulatedObjectFramePrivate
+{
+public:
+ GeneralEncapsulatedObjectFramePrivate() : textEncoding(String::Latin1) {}
+
+ String::Type textEncoding;
+ String mimeType;
+ String fileName;
+ String description;
+ ByteVector data;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+GeneralEncapsulatedObjectFrame::GeneralEncapsulatedObjectFrame() : Frame("GEOB")
+{
+ d = new GeneralEncapsulatedObjectFramePrivate;
+}
+
+GeneralEncapsulatedObjectFrame::GeneralEncapsulatedObjectFrame(const ByteVector &data) : Frame(data)
+{
+ d = new GeneralEncapsulatedObjectFramePrivate;
+ setData(data);
+}
+
+GeneralEncapsulatedObjectFrame::~GeneralEncapsulatedObjectFrame()
+{
+ delete d;
+}
+
+String GeneralEncapsulatedObjectFrame::toString() const
+{
+ String text = "[" + d->mimeType + "]";
+
+ if(!d->fileName.isEmpty())
+ text += " " + d->fileName;
+
+ if(!d->description.isEmpty())
+ text += " \"" + d->description + "\"";
+
+ return text;
+}
+
+String::Type GeneralEncapsulatedObjectFrame::textEncoding() const
+{
+ return d->textEncoding;
+}
+
+void GeneralEncapsulatedObjectFrame::setTextEncoding(String::Type encoding)
+{
+ d->textEncoding = encoding;
+}
+
+String GeneralEncapsulatedObjectFrame::mimeType() const
+{
+ return d->mimeType;
+}
+
+void GeneralEncapsulatedObjectFrame::setMimeType(const String &type)
+{
+ d->mimeType = type;
+}
+
+String GeneralEncapsulatedObjectFrame::fileName() const
+{
+ return d->fileName;
+}
+
+void GeneralEncapsulatedObjectFrame::setFileName(const String &name)
+{
+ d->fileName = name;
+}
+
+String GeneralEncapsulatedObjectFrame::description() const
+{
+ return d->description;
+}
+
+void GeneralEncapsulatedObjectFrame::setDescription(const String &desc)
+{
+ d->description = desc;
+}
+
+ByteVector GeneralEncapsulatedObjectFrame::object() const
+{
+ return d->data;
+}
+
+void GeneralEncapsulatedObjectFrame::setObject(const ByteVector &data)
+{
+ d->data = data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void GeneralEncapsulatedObjectFrame::parseFields(const ByteVector &data)
+{
+ if(data.size() < 4) {
+ debug("An object frame must contain at least 4 bytes.");
+ return;
+ }
+
+ d->textEncoding = String::Type(data[0]);
+
+ int pos = 1;
+
+ d->mimeType = readStringField(data, String::Latin1, &pos);
+ d->fileName = readStringField(data, d->textEncoding, &pos);
+ d->description = readStringField(data, d->textEncoding, &pos);
+
+ d->data = data.mid(pos);
+}
+
+ByteVector GeneralEncapsulatedObjectFrame::renderFields() const
+{
+ ByteVector data;
+
+ data.append(char(d->textEncoding));
+ data.append(d->mimeType.data(String::Latin1));
+ data.append(textDelimiter(String::Latin1));
+ data.append(d->fileName.data(d->textEncoding));
+ data.append(textDelimiter(d->textEncoding));
+ data.append(d->description.data(d->textEncoding));
+ data.append(textDelimiter(d->textEncoding));
+ data.append(d->data);
+
+ return data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+GeneralEncapsulatedObjectFrame::GeneralEncapsulatedObjectFrame(const ByteVector &data, Header *h) : Frame(h)
+{
+ d = new GeneralEncapsulatedObjectFramePrivate;
+ parseFields(fieldData(data));
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h b/libs/taglib/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h
new file mode 100644
index 0000000000..9b4edf5456
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.h
@@ -0,0 +1,174 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ copyright : (C) 2006 by Aaron VonderHaar
+ email : avh4@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_GENERALENCAPSULATEDOBJECT_H
+#define TAGLIB_GENERALENCAPSULATEDOBJECT_H
+
+#include <id3v2frame.h>
+#include <id3v2header.h>
+#include "taglib_export.h"
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ //! An ID3v2 general encapsulated object frame implementation
+
+ /*!
+ * This is an implementation of ID3v2 general encapsulated objects.
+ * Arbitrary binary data may be included in tags, stored in GEOB frames.
+ * There may be multiple GEOB frames in a single tag. Each GEOB it
+ * labelled with a content description (which may be blank), a required
+ * mime-type, and a file name (may be blank). The content description
+ * uniquely identifies the GEOB frame in the tag.
+ */
+
+ class TAGLIB_EXPORT GeneralEncapsulatedObjectFrame : public Frame
+ {
+ friend class FrameFactory;
+
+ public:
+
+ /*!
+ * Constructs an empty object frame. The description, file name and text
+ * encoding should be set manually.
+ */
+ GeneralEncapsulatedObjectFrame();
+
+ /*!
+ * Constructs a GeneralEncapsulatedObjectFrame frame based on \a data.
+ */
+ explicit GeneralEncapsulatedObjectFrame(const ByteVector &data);
+
+ /*!
+ * Destroys the GeneralEncapsulatedObjectFrame instance.
+ */
+ virtual ~GeneralEncapsulatedObjectFrame();
+
+ /*!
+ * Returns a string containing the description, file name and mime-type
+ */
+ virtual String toString() const;
+
+ /*!
+ * Returns the text encoding used for the description and file name.
+ *
+ * \see setTextEncoding()
+ * \see description()
+ * \see fileName()
+ */
+ String::Type textEncoding() const;
+
+ /*!
+ * Set the text encoding used for the description and file name.
+ *
+ * \see description()
+ * \see fileName()
+ */
+ void setTextEncoding(String::Type encoding);
+
+ /*!
+ * Returns the mime type of the object.
+ */
+ String mimeType() const;
+
+ /*!
+ * Sets the mime type of the object.
+ */
+ void setMimeType(const String &type);
+
+ /*!
+ * Returns the file name of the object.
+ *
+ * \see setFileName()
+ */
+ String fileName() const;
+
+ /*!
+ * Sets the file name for the object.
+ *
+ * \see fileName()
+ */
+ void setFileName(const String &name);
+
+ /*!
+ * Returns the content description of the object.
+ *
+ * \see setDescription()
+ * \see textEncoding()
+ * \see setTextEncoding()
+ */
+
+ String description() const;
+
+ /*!
+ * Sets the content description of the object to \a desc.
+ *
+ * \see description()
+ * \see textEncoding()
+ * \see setTextEncoding()
+ */
+
+ void setDescription(const String &desc);
+
+ /*!
+ * Returns the object data as a ByteVector.
+ *
+ * \note ByteVector has a data() method that returns a const char * which
+ * should make it easy to export this data to external programs.
+ *
+ * \see setObject()
+ * \see mimeType()
+ */
+ ByteVector object() const;
+
+ /*!
+ * Sets the object data to \a data. \a data should be of the type specified in
+ * this frame's mime-type specification.
+ *
+ * \see object()
+ * \see mimeType()
+ * \see setMimeType()
+ */
+ void setObject(const ByteVector &object);
+
+ protected:
+ virtual void parseFields(const ByteVector &data);
+ virtual ByteVector renderFields() const;
+
+ private:
+ GeneralEncapsulatedObjectFrame(const ByteVector &data, Header *h);
+ GeneralEncapsulatedObjectFrame(const GeneralEncapsulatedObjectFrame &);
+ GeneralEncapsulatedObjectFrame &operator=(const GeneralEncapsulatedObjectFrame &);
+
+ class GeneralEncapsulatedObjectFramePrivate;
+ GeneralEncapsulatedObjectFramePrivate *d;
+ };
+ }
+}
+
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/relativevolumeframe.cpp b/libs/taglib/taglib/mpeg/id3v2/frames/relativevolumeframe.cpp
new file mode 100644
index 0000000000..8495197a60
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/relativevolumeframe.cpp
@@ -0,0 +1,236 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include <tdebug.h>
+#include <tmap.h>
+
+#include "relativevolumeframe.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+static inline int bitsToBytes(int i)
+{
+ return i % 8 == 0 ? i / 8 : (i - i % 8) / 8 + 1;
+}
+
+struct ChannelData
+{
+ ChannelData() : channelType(RelativeVolumeFrame::Other), volumeAdjustment(0) {}
+
+ RelativeVolumeFrame::ChannelType channelType;
+ short volumeAdjustment;
+ RelativeVolumeFrame::PeakVolume peakVolume;
+};
+
+class RelativeVolumeFrame::RelativeVolumeFramePrivate
+{
+public:
+ String identification;
+ Map<ChannelType, ChannelData> channels;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+RelativeVolumeFrame::RelativeVolumeFrame() : Frame("RVA2")
+{
+ d = new RelativeVolumeFramePrivate;
+}
+
+RelativeVolumeFrame::RelativeVolumeFrame(const ByteVector &data) : Frame(data)
+{
+ d = new RelativeVolumeFramePrivate;
+ setData(data);
+}
+
+RelativeVolumeFrame::~RelativeVolumeFrame()
+{
+ delete d;
+}
+
+String RelativeVolumeFrame::toString() const
+{
+ return d->identification;
+}
+
+List<RelativeVolumeFrame::ChannelType> RelativeVolumeFrame::channels() const
+{
+ List<ChannelType> l;
+
+ Map<ChannelType, ChannelData>::ConstIterator it = d->channels.begin();
+ for(; it != d->channels.end(); ++it)
+ l.append((*it).first);
+
+ return l;
+}
+
+// deprecated
+
+RelativeVolumeFrame::ChannelType RelativeVolumeFrame::channelType() const
+{
+ return MasterVolume;
+}
+
+// deprecated
+
+void RelativeVolumeFrame::setChannelType(ChannelType)
+{
+
+}
+
+short RelativeVolumeFrame::volumeAdjustmentIndex(ChannelType type) const
+{
+ return d->channels.contains(type) ? d->channels[type].volumeAdjustment : 0;
+}
+
+short RelativeVolumeFrame::volumeAdjustmentIndex() const
+{
+ return volumeAdjustmentIndex(MasterVolume);
+}
+
+void RelativeVolumeFrame::setVolumeAdjustmentIndex(short index, ChannelType type)
+{
+ d->channels[type].volumeAdjustment = index;
+}
+
+void RelativeVolumeFrame::setVolumeAdjustmentIndex(short index)
+{
+ setVolumeAdjustmentIndex(index, MasterVolume);
+}
+
+float RelativeVolumeFrame::volumeAdjustment(ChannelType type) const
+{
+ return d->channels.contains(type) ? float(d->channels[type].volumeAdjustment) / float(512) : 0;
+}
+
+float RelativeVolumeFrame::volumeAdjustment() const
+{
+ return volumeAdjustment(MasterVolume);
+}
+
+void RelativeVolumeFrame::setVolumeAdjustment(float adjustment, ChannelType type)
+{
+ d->channels[type].volumeAdjustment = short(adjustment * float(512));
+}
+
+void RelativeVolumeFrame::setVolumeAdjustment(float adjustment)
+{
+ setVolumeAdjustment(adjustment, MasterVolume);
+}
+
+RelativeVolumeFrame::PeakVolume RelativeVolumeFrame::peakVolume(ChannelType type) const
+{
+ return d->channels.contains(type) ? d->channels[type].peakVolume : PeakVolume();
+}
+
+RelativeVolumeFrame::PeakVolume RelativeVolumeFrame::peakVolume() const
+{
+ return peakVolume(MasterVolume);
+}
+
+void RelativeVolumeFrame::setPeakVolume(const PeakVolume &peak, ChannelType type)
+{
+ d->channels[type].peakVolume = peak;
+}
+
+void RelativeVolumeFrame::setPeakVolume(const PeakVolume &peak)
+{
+ setPeakVolume(peak, MasterVolume);
+}
+
+String RelativeVolumeFrame::identification() const
+{
+ return d->identification;
+}
+
+void RelativeVolumeFrame::setIdentification(const String &s)
+{
+ d->identification = s;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void RelativeVolumeFrame::parseFields(const ByteVector &data)
+{
+ int pos = 0;
+ d->identification = readStringField(data, String::Latin1, &pos);
+
+ // Each channel is at least 4 bytes.
+
+ while(pos <= (int)data.size() - 4) {
+
+
+ ChannelType type = ChannelType(data[pos]);
+ pos += 1;
+
+ ChannelData &channel = d->channels[type];
+
+ channel.volumeAdjustment = data.mid(pos, 2).toShort();
+ pos += 2;
+
+ channel.peakVolume.bitsRepresentingPeak = data[pos];
+ pos += 1;
+
+ int bytes = bitsToBytes(channel.peakVolume.bitsRepresentingPeak);
+ channel.peakVolume.peakVolume = data.mid(pos, bytes);
+ pos += bytes;
+ }
+}
+
+ByteVector RelativeVolumeFrame::renderFields() const
+{
+ ByteVector data;
+
+ data.append(d->identification.data(String::Latin1));
+ data.append(textDelimiter(String::Latin1));
+
+ Map<ChannelType, ChannelData>::ConstIterator it = d->channels.begin();
+
+ for(; it != d->channels.end(); ++it) {
+ ChannelType type = (*it).first;
+ const ChannelData &channel = (*it).second;
+
+ data.append(char(type));
+ data.append(ByteVector::fromShort(channel.volumeAdjustment));
+ data.append(char(channel.peakVolume.bitsRepresentingPeak));
+ data.append(channel.peakVolume.peakVolume);
+ }
+
+ return data;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+RelativeVolumeFrame::RelativeVolumeFrame(const ByteVector &data, Header *h) : Frame(h)
+{
+ d = new RelativeVolumeFramePrivate;
+ parseFields(fieldData(data));
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/relativevolumeframe.h b/libs/taglib/taglib/mpeg/id3v2/frames/relativevolumeframe.h
new file mode 100644
index 0000000000..f8521986bf
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/relativevolumeframe.h
@@ -0,0 +1,274 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_RELATIVEVOLUMEFRAME_H
+#define TAGLIB_RELATIVEVOLUMEFRAME_H
+
+#include <tlist.h>
+#include <id3v2frame.h>
+#include "taglib_export.h"
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ //! An ID3v2 relative volume adjustment frame implementation
+
+ /*!
+ * This is an implementation of ID3v2 relative volume adjustment. The
+ * presence of this frame makes it possible to specify an increase in volume
+ * for an audio file or specific audio tracks in that file.
+ *
+ * Multiple relative volume adjustment frames may be present in the tag
+ * each with a unique identification and describing volume adjustment for
+ * different channel types.
+ */
+
+ class TAGLIB_EXPORT RelativeVolumeFrame : public Frame
+ {
+ friend class FrameFactory;
+
+ public:
+
+ /*!
+ * This indicates the type of volume adjustment that should be applied.
+ */
+ enum ChannelType {
+ //! A type not enumerated below
+ Other = 0x00,
+ //! The master volume for the track
+ MasterVolume = 0x01,
+ //! The front right audio channel
+ FrontRight = 0x02,
+ //! The front left audio channel
+ FrontLeft = 0x03,
+ //! The back right audio channel
+ BackRight = 0x04,
+ //! The back left audio channel
+ BackLeft = 0x05,
+ //! The front center audio channel
+ FrontCentre = 0x06,
+ //! The back center audio channel
+ BackCentre = 0x07,
+ //! The subwoofer audio channel
+ Subwoofer = 0x08
+ };
+
+ //! Struct that stores the relevant values for ID3v2 peak volume
+
+ /*!
+ * The peak volume is described as a series of bits that is padded to fill
+ * a block of bytes. These two values should always be updated in tandem.
+ */
+ struct PeakVolume
+ {
+ /*!
+ * Constructs an empty peak volume description.
+ */
+ PeakVolume() : bitsRepresentingPeak(0) {}
+ /*!
+ * The number of bits (in the range of 0 to 255) used to describe the
+ * peak volume.
+ */
+ unsigned char bitsRepresentingPeak;
+ /*!
+ * The array of bits (represented as a series of bytes) used to describe
+ * the peak volume.
+ */
+ ByteVector peakVolume;
+ };
+
+ /*!
+ * Constructs a RelativeVolumeFrame. The relevant data should be set
+ * manually.
+ */
+ RelativeVolumeFrame();
+
+ /*!
+ * Constructs a RelativeVolumeFrame based on the contents of \a data.
+ */
+ RelativeVolumeFrame(const ByteVector &data);
+
+ /*!
+ * Destroys the RelativeVolumeFrame instance.
+ */
+ virtual ~RelativeVolumeFrame();
+
+ /*!
+ * Returns the frame's identification.
+ *
+ * \see identification()
+ */
+ virtual String toString() const;
+
+ /*!
+ * Returns a list of channels with information currently in the frame.
+ */
+ List<ChannelType> channels() const;
+
+ /*!
+ * \deprecated Always returns master volume.
+ */
+ ChannelType channelType() const;
+
+ /*!
+ * \deprecated This method no longer has any effect.
+ */
+ void setChannelType(ChannelType t);
+
+ /*
+ * There was a terrible API goof here, and while this can't be changed to
+ * the way it appears below for binary compaibility reasons, let's at
+ * least pretend that it looks clean.
+ */
+
+#ifdef DOXYGEN
+
+ /*!
+ * Returns the relative volume adjustment "index". As indicated by the
+ * ID3v2 standard this is a 16-bit signed integer that reflects the
+ * decibils of adjustment when divided by 512.
+ *
+ * This defaults to returning the value for the master volume channel if
+ * available and returns 0 if the specified channel does not exist.
+ *
+ * \see setVolumeAdjustmentIndex()
+ * \see volumeAjustment()
+ */
+ short volumeAdjustmentIndex(ChannelType type = MasterVolume) const;
+
+ /*!
+ * Set the volume adjustment to \a index. As indicated by the ID3v2
+ * standard this is a 16-bit signed integer that reflects the decibils of
+ * adjustment when divided by 512.
+ *
+ * By default this sets the value for the master volume.
+ *
+ * \see volumeAdjustmentIndex()
+ * \see setVolumeAjustment()
+ */
+ void setVolumeAdjustmentIndex(short index, ChannelType type = MasterVolume);
+
+ /*!
+ * Returns the relative volume adjustment in decibels.
+ *
+ * \note Because this is actually stored internally as an "index" to this
+ * value the value returned by this method may not be identical to the
+ * value set using setVolumeAdjustment().
+ *
+ * This defaults to returning the value for the master volume channel if
+ * available and returns 0 if the specified channel does not exist.
+ *
+ * \see setVolumeAdjustment()
+ * \see volumeAdjustmentIndex()
+ */
+ float volumeAdjustment(ChannelType type = MasterVolume) const;
+
+ /*!
+ * Set the relative volume adjustment in decibels to \a adjustment.
+ *
+ * By default this sets the value for the master volume.
+ *
+ * \note Because this is actually stored internally as an "index" to this
+ * value the value set by this method may not be identical to the one
+ * returned by volumeAdjustment().
+ *
+ * \see setVolumeAdjustment()
+ * \see volumeAdjustmentIndex()
+ */
+ void setVolumeAdjustment(float adjustment, ChannelType type = MasterVolume);
+
+ /*!
+ * Returns the peak volume (represented as a length and a string of bits).
+ *
+ * This defaults to returning the value for the master volume channel if
+ * available and returns 0 if the specified channel does not exist.
+ *
+ * \see setPeakVolume()
+ */
+ PeakVolume peakVolume(ChannelType type = MasterVolume) const;
+
+ /*!
+ * Sets the peak volume to \a peak.
+ *
+ * By default this sets the value for the master volume.
+ *
+ * \see peakVolume()
+ */
+ void setPeakVolume(const PeakVolume &peak, ChannelType type = MasterVolume);
+
+#else
+
+ // BIC: Combine each of the following pairs of functions (or maybe just
+ // rework this junk altogether).
+
+ short volumeAdjustmentIndex(ChannelType type) const;
+ short volumeAdjustmentIndex() const;
+
+ void setVolumeAdjustmentIndex(short index, ChannelType type);
+ void setVolumeAdjustmentIndex(short index);
+
+ float volumeAdjustment(ChannelType type) const;
+ float volumeAdjustment() const;
+
+ void setVolumeAdjustment(float adjustment, ChannelType type);
+ void setVolumeAdjustment(float adjustment);
+
+ PeakVolume peakVolume(ChannelType type) const;
+ PeakVolume peakVolume() const;
+
+ void setPeakVolume(const PeakVolume &peak, ChannelType type);
+ void setPeakVolume(const PeakVolume &peak);
+
+#endif
+
+ /*!
+ * Returns the identification for this frame.
+ */
+ String identification() const;
+
+ /*!
+ * Sets the identification of the frame to \a s. The string
+ * is used to identify the situation and/or device where this
+ * adjustment should apply.
+ */
+ void setIdentification(const String &s);
+
+ protected:
+ virtual void parseFields(const ByteVector &data);
+ virtual ByteVector renderFields() const;
+
+ private:
+ RelativeVolumeFrame(const ByteVector &data, Header *h);
+ RelativeVolumeFrame(const RelativeVolumeFrame &);
+ RelativeVolumeFrame &operator=(const RelativeVolumeFrame &);
+
+ class RelativeVolumeFramePrivate;
+ RelativeVolumeFramePrivate *d;
+ };
+
+ }
+}
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/textidentificationframe.cpp b/libs/taglib/taglib/mpeg/id3v2/frames/textidentificationframe.cpp
new file mode 100644
index 0000000000..7d3b4ff291
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/textidentificationframe.cpp
@@ -0,0 +1,271 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include <tbytevectorlist.h>
+#include <id3v2tag.h>
+
+#include "textidentificationframe.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class TextIdentificationFrame::TextIdentificationFramePrivate
+{
+public:
+ TextIdentificationFramePrivate() : textEncoding(String::Latin1) {}
+ String::Type textEncoding;
+ StringList fieldList;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// TextIdentificationFrame public members
+////////////////////////////////////////////////////////////////////////////////
+
+TextIdentificationFrame::TextIdentificationFrame(const ByteVector &type, String::Type encoding) :
+ Frame(type)
+{
+ d = new TextIdentificationFramePrivate;
+ d->textEncoding = encoding;
+}
+
+TextIdentificationFrame::TextIdentificationFrame(const ByteVector &data) :
+ Frame(data)
+{
+ d = new TextIdentificationFramePrivate;
+ setData(data);
+}
+
+TextIdentificationFrame::~TextIdentificationFrame()
+{
+ delete d;
+}
+
+void TextIdentificationFrame::setText(const StringList &l)
+{
+ d->fieldList = l;
+}
+
+void TextIdentificationFrame::setText(const String &s)
+{
+ d->fieldList = s;
+}
+
+String TextIdentificationFrame::toString() const
+{
+ return d->fieldList.toString();
+}
+
+StringList TextIdentificationFrame::fieldList() const
+{
+ return d->fieldList;
+}
+
+String::Type TextIdentificationFrame::textEncoding() const
+{
+ return d->textEncoding;
+}
+
+void TextIdentificationFrame::setTextEncoding(String::Type encoding)
+{
+ d->textEncoding = encoding;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TextIdentificationFrame protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void TextIdentificationFrame::parseFields(const ByteVector &data)
+{
+ // Don't try to parse invalid frames
+
+ if(data.size() < 2)
+ return;
+
+ // read the string data type (the first byte of the field data)
+
+ d->textEncoding = String::Type(data[0]);
+
+ // split the byte array into chunks based on the string type (two byte delimiter
+ // for unicode encodings)
+
+ int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
+
+ // build a small counter to strip nulls off the end of the field
+
+ int dataLength = data.size() - 1;
+
+ while(dataLength > 0 && data[dataLength] == 0)
+ dataLength--;
+
+ while(dataLength % byteAlign != 0)
+ dataLength++;
+
+ ByteVectorList l = ByteVectorList::split(data.mid(1, dataLength), textDelimiter(d->textEncoding), byteAlign);
+
+ d->fieldList.clear();
+
+ // append those split values to the list and make sure that the new string's
+ // type is the same specified for this frame
+
+ for(ByteVectorList::Iterator it = l.begin(); it != l.end(); it++) {
+ if(!(*it).isEmpty()) {
+ String s(*it, d->textEncoding);
+ d->fieldList.append(s);
+ }
+ }
+}
+
+ByteVector TextIdentificationFrame::renderFields() const
+{
+ String::Type encoding = checkEncoding(d->fieldList, d->textEncoding);
+
+ ByteVector v;
+
+ v.append(char(encoding));
+
+ for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) {
+
+ // Since the field list is null delimited, if this is not the first
+ // element in the list, append the appropriate delimiter for this
+ // encoding.
+
+ if(it != d->fieldList.begin())
+ v.append(textDelimiter(encoding));
+
+ v.append((*it).data(encoding));
+ }
+
+ return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TextIdentificationFrame private members
+////////////////////////////////////////////////////////////////////////////////
+
+TextIdentificationFrame::TextIdentificationFrame(const ByteVector &data, Header *h) : Frame(h)
+{
+ d = new TextIdentificationFramePrivate;
+ parseFields(fieldData(data));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// UserTextIdentificationFrame public members
+////////////////////////////////////////////////////////////////////////////////
+
+UserTextIdentificationFrame::UserTextIdentificationFrame(String::Type encoding) :
+ TextIdentificationFrame("TXXX", encoding),
+ d(0)
+{
+ StringList l;
+ l.append(String::null);
+ l.append(String::null);
+ setText(l);
+}
+
+
+UserTextIdentificationFrame::UserTextIdentificationFrame(const ByteVector &data) :
+ TextIdentificationFrame(data)
+{
+ checkFields();
+}
+
+String UserTextIdentificationFrame::toString() const
+{
+ return "[" + description() + "] " + fieldList().toString();
+}
+
+String UserTextIdentificationFrame::description() const
+{
+ return !TextIdentificationFrame::fieldList().isEmpty()
+ ? TextIdentificationFrame::fieldList().front()
+ : String::null;
+}
+
+StringList UserTextIdentificationFrame::fieldList() const
+{
+ // TODO: remove this function
+
+ return TextIdentificationFrame::fieldList();
+}
+
+void UserTextIdentificationFrame::setText(const String &text)
+{
+ if(description().isEmpty())
+ setDescription(String::null);
+
+ TextIdentificationFrame::setText(StringList(description()).append(text));
+}
+
+void UserTextIdentificationFrame::setText(const StringList &fields)
+{
+ if(description().isEmpty())
+ setDescription(String::null);
+
+ TextIdentificationFrame::setText(StringList(description()).append(fields));
+}
+
+void UserTextIdentificationFrame::setDescription(const String &s)
+{
+ StringList l = fieldList();
+
+ if(l.isEmpty())
+ l.append(s);
+ else
+ l[0] = s;
+
+ TextIdentificationFrame::setText(l);
+}
+
+UserTextIdentificationFrame *UserTextIdentificationFrame::find(
+ ID3v2::Tag *tag, const String &description) // static
+{
+ FrameList l = tag->frameList("TXXX");
+ for(FrameList::Iterator it = l.begin(); it != l.end(); ++it) {
+ UserTextIdentificationFrame *f = dynamic_cast<UserTextIdentificationFrame *>(*it);
+ if(f && f->description() == description)
+ return f;
+ }
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// UserTextIdentificationFrame private members
+////////////////////////////////////////////////////////////////////////////////
+
+UserTextIdentificationFrame::UserTextIdentificationFrame(const ByteVector &data, Header *h) :
+ TextIdentificationFrame(data, h)
+{
+ checkFields();
+}
+
+void UserTextIdentificationFrame::checkFields()
+{
+ int fields = fieldList().size();
+
+ if(fields == 0)
+ setDescription(String::null);
+ if(fields <= 1)
+ setText(String::null);
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/textidentificationframe.h b/libs/taglib/taglib/mpeg/id3v2/frames/textidentificationframe.h
new file mode 100644
index 0000000000..291cba5b8f
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/textidentificationframe.h
@@ -0,0 +1,258 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_TEXTIDENTIFICATIONFRAME_H
+#define TAGLIB_TEXTIDENTIFICATIONFRAME_H
+
+#include <tstringlist.h>
+#include "taglib_export.h"
+
+#include <id3v2frame.h>
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ class Tag;
+
+ //! An ID3v2 text identification frame implementation
+
+ /*!
+ * This is an implementation of the most common type of ID3v2 frame -- text
+ * identification frames. There are a number of variations on this. Those
+ * enumerated in the ID3v2.4 standard are:
+ *
+ * <ul>
+ * <li><b>TALB</b> Album/Movie/Show title</li>
+ * <li><b>TBPM</b> BPM (beats per minute)</li>
+ * <li><b>TCOM</b> Composer</li>
+ * <li><b>TCON</b> Content type</li>
+ * <li><b>TCOP</b> Copyright message</li>
+ * <li><b>TDEN</b> Encoding time</li>
+ * <li><b>TDLY</b> Playlist delay</li>
+ * <li><b>TDOR</b> Original release time</li>
+ * <li><b>TDRC</b> Recording time</li>
+ * <li><b>TDRL</b> Release time</li>
+ * <li><b>TDTG</b> Tagging time</li>
+ * <li><b>TENC</b> Encoded by</li>
+ * <li><b>TEXT</b> Lyricist/Text writer</li>
+ * <li><b>TFLT</b> File type</li>
+ * <li><b>TIPL</b> Involved people list</li>
+ * <li><b>TIT1</b> Content group description</li>
+ * <li><b>TIT2</b> Title/songname/content description</li>
+ * <li><b>TIT3</b> Subtitle/Description refinement</li>
+ * <li><b>TKEY</b> Initial key</li>
+ * <li><b>TLAN</b> Language(s)</li>
+ * <li><b>TLEN</b> Length</li>
+ * <li><b>TMCL</b> Musician credits list</li>
+ * <li><b>TMED</b> Media type</li>
+ * <li><b>TMOO</b> Mood</li>
+ * <li><b>TOAL</b> Original album/movie/show title</li>
+ * <li><b>TOFN</b> Original filename</li>
+ * <li><b>TOLY</b> Original lyricist(s)/text writer(s)</li>
+ * <li><b>TOPE</b> Original artist(s)/performer(s)</li>
+ * <li><b>TOWN</b> File owner/licensee</li>
+ * <li><b>TPE1</b> Lead performer(s)/Soloist(s)</li>
+ * <li><b>TPE2</b> Band/orchestra/accompaniment</li>
+ * <li><b>TPE3</b> Conductor/performer refinement</li>
+ * <li><b>TPE4</b> Interpreted, remixed, or otherwise modified by</li>
+ * <li><b>TPOS</b> Part of a set</li>
+ * <li><b>TPRO</b> Produced notice</li>
+ * <li><b>TPUB</b> Publisher</li>
+ * <li><b>TRCK</b> Track number/Position in set</li>
+ * <li><b>TRSN</b> Internet radio station name</li>
+ * <li><b>TRSO</b> Internet radio station owner</li>
+ * <li><b>TSOA</b> Album sort order</li>
+ * <li><b>TSOP</b> Performer sort order</li>
+ * <li><b>TSOT</b> Title sort order</li>
+ * <li><b>TSRC</b> ISRC (international standard recording code)</li>
+ * <li><b>TSSE</b> Software/Hardware and settings used for encoding</li>
+ * <li><b>TSST</b> Set subtitle</li>
+ * </ul>
+ *
+ * The ID3v2 Frames document gives a description of each of these formats
+ * and the expected order of strings in each. ID3v2::Header::frameID() can
+ * be used to determine the frame type.
+ *
+ * \note If non-Latin1 compatible strings are used with this class, even if
+ * the text encoding is set to Latin1, the frame will be written using UTF8
+ * (with the encoding flag appropriately set in the output).
+ */
+
+ class TAGLIB_EXPORT TextIdentificationFrame : public Frame
+ {
+ friend class FrameFactory;
+
+ public:
+ /*!
+ * Construct an empty frame of type \a type. Uses \a encoding as the
+ * default text encoding.
+ *
+ * \note In this case you must specify the text encoding as it
+ * resolves the ambiguity between constructors.
+ *
+ * \note Please see the note in the class description regarding Latin1.
+ */
+ TextIdentificationFrame(const ByteVector &type, String::Type encoding);
+
+ /*!
+ * This is a dual purpose constructor. \a data can either be binary data
+ * that should be parsed or (at a minimum) the frame ID.
+ */
+ explicit TextIdentificationFrame(const ByteVector &data);
+
+ /*!
+ * Destroys this TextIdentificationFrame instance.
+ */
+ virtual ~TextIdentificationFrame();
+
+ /*!
+ * Text identification frames are a list of string fields.
+ *
+ * This function will accept either a StringList or a String (using the
+ * StringList constructor that accepts a single String).
+ *
+ * \note This will not change the text encoding of the frame even if the
+ * strings passed in are not of the same encoding. Please use
+ * setEncoding(s.type()) if you wish to change the encoding of the frame.
+ */
+ void setText(const StringList &l);
+
+ // Reimplementations.
+
+ virtual void setText(const String &s);
+ virtual String toString() const;
+
+ /*!
+ * Returns the text encoding that will be used in rendering this frame.
+ * This defaults to the type that was either specified in the constructor
+ * or read from the frame when parsed.
+ *
+ * \note Please see the note in the class description regarding Latin1.
+ *
+ * \see setTextEncoding()
+ * \see render()
+ */
+ String::Type textEncoding() const;
+
+ /*!
+ * Sets the text encoding to be used when rendering this frame to
+ * \a encoding.
+ *
+ * \note Please see the note in the class description regarding Latin1.
+ *
+ * \see textEncoding()
+ * \see render()
+ */
+ void setTextEncoding(String::Type encoding);
+
+ /*!
+ * Returns a list of the strings in this frame.
+ */
+ StringList fieldList() const;
+
+ protected:
+ // Reimplementations.
+
+ virtual void parseFields(const ByteVector &data);
+ virtual ByteVector renderFields() const;
+
+ /*!
+ * The constructor used by the FrameFactory.
+ */
+ TextIdentificationFrame(const ByteVector &data, Header *h);
+
+ private:
+ TextIdentificationFrame(const TextIdentificationFrame &);
+ TextIdentificationFrame &operator=(const TextIdentificationFrame &);
+
+ class TextIdentificationFramePrivate;
+ TextIdentificationFramePrivate *d;
+ };
+
+ /*!
+ * This is a specialization of text identification frames that allows for
+ * user defined entries. Each entry has a description in addition to the
+ * normal list of fields that a text identification frame has.
+ *
+ * This description identifies the frame and must be unique.
+ */
+
+ //! An ID3v2 custom text identification frame implementationx
+
+ class TAGLIB_EXPORT UserTextIdentificationFrame : public TextIdentificationFrame
+ {
+ friend class FrameFactory;
+
+ public:
+ /*!
+ * Constructs an empty user defined text identification frame. For this to be
+ * a useful frame both a description and text must be set.
+ */
+ explicit UserTextIdentificationFrame(String::Type encoding = String::Latin1);
+
+ /*!
+ * Creates a frame based on \a data.
+ */
+ explicit UserTextIdentificationFrame(const ByteVector &data);
+
+ virtual String toString() const;
+
+ /*!
+ * Returns the description for this frame.
+ */
+ String description() const;
+
+ /*!
+ * Sets the description of the frame to \a s. \a s must be unique. You can
+ * check for the presence of another user defined text frame of the same type
+ * using find() and testing for null.
+ */
+ void setDescription(const String &s);
+
+ StringList fieldList() const;
+ void setText(const String &text);
+ void setText(const StringList &fields);
+
+ /*!
+ * Searches for the user defined text frame with the description \a description
+ * in \a tag. This returns null if no matching frames were found.
+ */
+ static UserTextIdentificationFrame *find(Tag *tag, const String &description);
+
+ private:
+ UserTextIdentificationFrame(const ByteVector &data, Header *h);
+ UserTextIdentificationFrame(const TextIdentificationFrame &);
+ UserTextIdentificationFrame &operator=(const UserTextIdentificationFrame &);
+
+ void checkFields();
+
+ class UserTextIdentificationFramePrivate;
+ UserTextIdentificationFramePrivate *d;
+ };
+
+ }
+}
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.cpp b/libs/taglib/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.cpp
new file mode 100644
index 0000000000..836982bdf1
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.cpp
@@ -0,0 +1,118 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include <tbytevectorlist.h>
+#include <tdebug.h>
+
+#include "uniquefileidentifierframe.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class UniqueFileIdentifierFrame::UniqueFileIdentifierFramePrivate
+{
+public:
+ String owner;
+ ByteVector identifier;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public methods
+////////////////////////////////////////////////////////////////////////////////
+
+UniqueFileIdentifierFrame::UniqueFileIdentifierFrame(const ByteVector &data) :
+ ID3v2::Frame(data)
+{
+ d = new UniqueFileIdentifierFramePrivate;
+ setData(data);
+}
+
+UniqueFileIdentifierFrame::UniqueFileIdentifierFrame(const String &owner, const ByteVector &id) :
+ ID3v2::Frame("UFID")
+{
+ d = new UniqueFileIdentifierFramePrivate;
+ d->owner = owner;
+ d->identifier = id;
+}
+
+UniqueFileIdentifierFrame::~UniqueFileIdentifierFrame()
+{
+ delete d;
+}
+
+String UniqueFileIdentifierFrame::owner() const
+{
+ return d->owner;
+}
+
+ByteVector UniqueFileIdentifierFrame::identifier() const
+{
+ return d->identifier;
+}
+
+void UniqueFileIdentifierFrame::setOwner(const String &s)
+{
+ d->owner = s;
+}
+
+void UniqueFileIdentifierFrame::setIdentifier(const ByteVector &v)
+{
+ d->identifier = v;
+}
+
+String UniqueFileIdentifierFrame::toString() const
+{
+ return String::null;
+}
+
+void UniqueFileIdentifierFrame::parseFields(const ByteVector &data)
+{
+ if(data.size() < 1) {
+ debug("An UFID frame must contain at least 1 byte.");
+ return;
+ }
+
+ int pos = 0;
+ d->owner = readStringField(data, String::Latin1, &pos);
+ d->identifier = data.mid(pos);
+}
+
+ByteVector UniqueFileIdentifierFrame::renderFields() const
+{
+ ByteVector data;
+
+ data.append(d->owner.data(String::Latin1));
+ data.append(char(0));
+ data.append(d->identifier);
+
+ return data;
+}
+
+UniqueFileIdentifierFrame::UniqueFileIdentifierFrame(const ByteVector &data, Header *h) :
+ Frame(h)
+{
+ d = new UniqueFileIdentifierFramePrivate;
+ parseFields(fieldData(data));
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.h b/libs/taglib/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.h
new file mode 100644
index 0000000000..a0a66bb17d
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/uniquefileidentifierframe.h
@@ -0,0 +1,113 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_UNIQUEFILEIDENTIFIERFRAME
+#define TAGLIB_UNIQUEFILEIDENTIFIERFRAME
+
+#include <id3v2frame.h>
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ /*!
+ * This is an implementation of ID3v2 unique file identifier frames. This
+ * frame is used to identify the file in an arbitrary database identified
+ * by the owner field.
+ */
+
+ //! An implementation of ID3v2 unique identifier frames
+
+ class TAGLIB_EXPORT UniqueFileIdentifierFrame : public ID3v2::Frame
+ {
+ friend class FrameFactory;
+
+ public:
+ /*!
+ * Creates a uniqe file identifier frame based on \a data.
+ */
+ UniqueFileIdentifierFrame(const ByteVector &data);
+
+ /*!
+ * Creates a unique file identifier frame with the owner \a owner and
+ * the identification \a id.
+ */
+ UniqueFileIdentifierFrame(const String &owner, const ByteVector &id);
+
+ /*!
+ * Destroys the frame.
+ */
+ ~UniqueFileIdentifierFrame();
+
+ /*!
+ * Returns the owner for the frame; essentially this is the key for
+ * determining which identification scheme this key belongs to. This
+ * will usually either be an email address or URL for the person or tool
+ * used to create the unique identifier.
+ *
+ * \see setOwner()
+ */
+ String owner() const;
+
+ /*!
+ * Returns the unique identifier. Though sometimes this is a text string
+ * it also may be binary data and as much should be assumed when handling
+ * it.
+ */
+ ByteVector identifier() const;
+
+ /*!
+ * Sets the owner of the identification scheme to \a s.
+ *
+ * \see owner()
+ */
+ void setOwner(const String &s);
+
+ /*!
+ * Sets the unique file identifier to \a v.
+ *
+ * \see identifier()
+ */
+ void setIdentifier(const ByteVector &v);
+
+ virtual String toString() const;
+
+ protected:
+ virtual void parseFields(const ByteVector &data);
+ virtual ByteVector renderFields() const;
+
+ private:
+ UniqueFileIdentifierFrame(const UniqueFileIdentifierFrame &);
+ UniqueFileIdentifierFrame &operator=(UniqueFileIdentifierFrame &);
+
+ UniqueFileIdentifierFrame(const ByteVector &data, Header *h);
+
+ class UniqueFileIdentifierFramePrivate;
+ UniqueFileIdentifierFramePrivate *d;
+ };
+ }
+}
+
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/unknownframe.cpp b/libs/taglib/taglib/mpeg/id3v2/frames/unknownframe.cpp
new file mode 100644
index 0000000000..42b87c6916
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/unknownframe.cpp
@@ -0,0 +1,84 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include "unknownframe.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class UnknownFrame::UnknownFramePrivate
+{
+public:
+ ByteVector fieldData;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+UnknownFrame::UnknownFrame(const ByteVector &data) : Frame(data)
+{
+ d = new UnknownFramePrivate;
+ setData(data);
+}
+
+UnknownFrame::~UnknownFrame()
+{
+ delete d;
+}
+
+String UnknownFrame::toString() const
+{
+ return String::null;
+}
+
+ByteVector UnknownFrame::data() const
+{
+ return d->fieldData;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void UnknownFrame::parseFields(const ByteVector &data)
+{
+ d->fieldData = data;
+}
+
+ByteVector UnknownFrame::renderFields() const
+{
+ return d->fieldData;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+UnknownFrame::UnknownFrame(const ByteVector &data, Header *h) : Frame(h)
+{
+ d = new UnknownFramePrivate;
+ parseFields(fieldData(data));
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/unknownframe.h b/libs/taglib/taglib/mpeg/id3v2/frames/unknownframe.h
new file mode 100644
index 0000000000..164a44a00c
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/unknownframe.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_UNKNOWNFRAME_H
+#define TAGLIB_UNKNOWNFRAME_H
+
+#include <id3v2frame.h>
+#include "taglib_export.h"
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ //! A frame type \e unknown to TagLib.
+
+ /*!
+ * This class represents a frame type not known (or more often simply
+ * unimplemented) in TagLib. This is here provide a basic API for
+ * manipulating the binary data of unknown frames and to provide a means
+ * of rendering such \e unknown frames.
+ *
+ * Please note that a cleaner way of handling frame types that TagLib
+ * does not understand is to subclass ID3v2::Frame and ID3v2::FrameFactory
+ * to have your frame type supported through the standard ID3v2 mechanism.
+ */
+
+ class TAGLIB_EXPORT UnknownFrame : public Frame
+ {
+ friend class FrameFactory;
+
+ public:
+ UnknownFrame(const ByteVector &data);
+ virtual ~UnknownFrame();
+
+ virtual String toString() const;
+
+ /*!
+ * Returns the field data (everything but the header) for this frame.
+ */
+ ByteVector data() const;
+
+ protected:
+ virtual void parseFields(const ByteVector &data);
+ virtual ByteVector renderFields() const;
+
+ private:
+ UnknownFrame(const ByteVector &data, Header *h);
+ UnknownFrame(const UnknownFrame &);
+ UnknownFrame &operator=(const UnknownFrame &);
+
+ class UnknownFramePrivate;
+ UnknownFramePrivate *d;
+ };
+
+ }
+}
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp b/libs/taglib/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp
new file mode 100644
index 0000000000..4c907dd6e9
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp
@@ -0,0 +1,162 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ copyright : (C) 2006 by Urs Fleisch
+ email : ufleisch@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include "unsynchronizedlyricsframe.h"
+#include <tbytevectorlist.h>
+#include <tdebug.h>
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class UnsynchronizedLyricsFrame::UnsynchronizedLyricsFramePrivate
+{
+public:
+ UnsynchronizedLyricsFramePrivate() : textEncoding(String::Latin1) {}
+ String::Type textEncoding;
+ ByteVector language;
+ String description;
+ String text;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+UnsynchronizedLyricsFrame::UnsynchronizedLyricsFrame(String::Type encoding) :
+ Frame("USLT")
+{
+ d = new UnsynchronizedLyricsFramePrivate;
+ d->textEncoding = encoding;
+}
+
+UnsynchronizedLyricsFrame::UnsynchronizedLyricsFrame(const ByteVector &data) :
+ Frame(data)
+{
+ d = new UnsynchronizedLyricsFramePrivate;
+ setData(data);
+}
+
+UnsynchronizedLyricsFrame::~UnsynchronizedLyricsFrame()
+{
+ delete d;
+}
+
+String UnsynchronizedLyricsFrame::toString() const
+{
+ return d->text;
+}
+
+ByteVector UnsynchronizedLyricsFrame::language() const
+{
+ return d->language;
+}
+
+String UnsynchronizedLyricsFrame::description() const
+{
+ return d->description;
+}
+
+String UnsynchronizedLyricsFrame::text() const
+{
+ return d->text;
+}
+
+void UnsynchronizedLyricsFrame::setLanguage(const ByteVector &languageEncoding)
+{
+ d->language = languageEncoding.mid(0, 3);
+}
+
+void UnsynchronizedLyricsFrame::setDescription(const String &s)
+{
+ d->description = s;
+}
+
+void UnsynchronizedLyricsFrame::setText(const String &s)
+{
+ d->text = s;
+}
+
+
+String::Type UnsynchronizedLyricsFrame::textEncoding() const
+{
+ return d->textEncoding;
+}
+
+void UnsynchronizedLyricsFrame::setTextEncoding(String::Type encoding)
+{
+ d->textEncoding = encoding;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void UnsynchronizedLyricsFrame::parseFields(const ByteVector &data)
+{
+ if(data.size() < 5) {
+ debug("An unsynchronized lyrics frame must contain at least 5 bytes.");
+ return;
+ }
+
+ d->textEncoding = String::Type(data[0]);
+ d->language = data.mid(1, 3);
+
+ int byteAlign
+ = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
+
+ ByteVectorList l =
+ ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
+
+ if(l.size() == 2) {
+ d->description = String(l.front(), d->textEncoding);
+ d->text = String(l.back(), d->textEncoding);
+ }
+}
+
+ByteVector UnsynchronizedLyricsFrame::renderFields() const
+{
+ ByteVector v;
+
+ v.append(char(d->textEncoding));
+ v.append(d->language.size() == 3 ? d->language : "XXX");
+ v.append(d->description.data(d->textEncoding));
+ v.append(textDelimiter(d->textEncoding));
+ v.append(d->text.data(d->textEncoding));
+
+ return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+UnsynchronizedLyricsFrame::UnsynchronizedLyricsFrame(const ByteVector &data, Header *h)
+ : Frame(h)
+{
+ d = new UnsynchronizedLyricsFramePrivate();
+ parseFields(fieldData(data));
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.h b/libs/taglib/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.h
new file mode 100644
index 0000000000..28cc1e8c55
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/unsynchronizedlyricsframe.h
@@ -0,0 +1,157 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ copyright : (C) 2006 by Urs Fleisch
+ email : ufleisch@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_UNSYNCHRONIZEDLYRICSFRAME_H
+#define TAGLIB_UNSYNCHRONIZEDLYRICSFRAME_H
+
+#include <id3v2frame.h>
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ //! ID3v2 unsynchronized lyrics frame
+ /*!
+ * An implementation of ID3v2 unsynchronized lyrics.
+ */
+ class TAGLIB_EXPORT UnsynchronizedLyricsFrame : public Frame
+ {
+ friend class FrameFactory;
+
+ public:
+ /*!
+ * Construct an empty unsynchronized lyrics frame that will use the text encoding
+ * \a encoding.
+ */
+ explicit UnsynchronizedLyricsFrame(String::Type encoding = String::Latin1);
+
+ /*!
+ * Construct a unsynchronized lyrics frame based on the data in \a data.
+ */
+ explicit UnsynchronizedLyricsFrame(const ByteVector &data);
+
+ /*!
+ * Destroys this UnsynchronizedLyricsFrame instance.
+ */
+ virtual ~UnsynchronizedLyricsFrame();
+
+ /*!
+ * Returns the text of this unsynchronized lyrics frame.
+ *
+ * \see text()
+ */
+ virtual String toString() const;
+
+ /*!
+ * Returns the language encoding as a 3 byte encoding as specified by
+ * <a href="http://en.wikipedia.org/wiki/ISO_639">ISO-639-2</a>.
+ *
+ * \note Most taggers simply ignore this value.
+ *
+ * \see setLanguage()
+ */
+ ByteVector language() const;
+
+ /*!
+ * Returns the description of this unsynchronized lyrics frame.
+ *
+ * \note Most taggers simply ignore this value.
+ *
+ * \see setDescription()
+ */
+ String description() const;
+
+ /*!
+ * Returns the text of this unsynchronized lyrics frame.
+ *
+ * \see setText()
+ */
+ String text() const;
+
+ /*!
+ * Set the language using the 3 byte language code from
+ * <a href="http://en.wikipedia.org/wiki/ISO_639">ISO-639-2</a> to
+ * \a languageCode.
+ *
+ * \see language()
+ */
+ void setLanguage(const ByteVector &languageCode);
+
+ /*!
+ * Sets the description of the unsynchronized lyrics frame to \a s.
+ *
+ * \see decription()
+ */
+ void setDescription(const String &s);
+
+ /*!
+ * Sets the text portion of the unsynchronized lyrics frame to \a s.
+ *
+ * \see text()
+ */
+ virtual void setText(const String &s);
+
+ /*!
+ * Returns the text encoding that will be used in rendering this frame.
+ * This defaults to the type that was either specified in the constructor
+ * or read from the frame when parsed.
+ *
+ * \see setTextEncoding()
+ * \see render()
+ */
+ String::Type textEncoding() const;
+
+ /*!
+ * Sets the text encoding to be used when rendering this frame to
+ * \a encoding.
+ *
+ * \see textEncoding()
+ * \see render()
+ */
+ void setTextEncoding(String::Type encoding);
+
+ protected:
+ // Reimplementations.
+
+ virtual void parseFields(const ByteVector &data);
+ virtual ByteVector renderFields() const;
+
+ private:
+ /*!
+ * The constructor used by the FrameFactory.
+ */
+ UnsynchronizedLyricsFrame(const ByteVector &data, Header *h);
+ UnsynchronizedLyricsFrame(const UnsynchronizedLyricsFrame &);
+ UnsynchronizedLyricsFrame &operator=(const UnsynchronizedLyricsFrame &);
+
+ class UnsynchronizedLyricsFramePrivate;
+ UnsynchronizedLyricsFramePrivate *d;
+ };
+
+ }
+}
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/urllinkframe.cpp b/libs/taglib/taglib/mpeg/id3v2/frames/urllinkframe.cpp
new file mode 100644
index 0000000000..25bdd187aa
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/urllinkframe.cpp
@@ -0,0 +1,192 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ copyright : (C) 2006 by Urs Fleisch
+ email : ufleisch@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include "urllinkframe.h"
+#include <tdebug.h>
+#include <tstringlist.h>
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class UrlLinkFrame::UrlLinkFramePrivate
+{
+public:
+ String url;
+};
+
+class UserUrlLinkFrame::UserUrlLinkFramePrivate
+{
+public:
+ UserUrlLinkFramePrivate() : textEncoding(String::Latin1) {}
+ String::Type textEncoding;
+ String description;
+};
+
+UrlLinkFrame::UrlLinkFrame(const ByteVector &data) :
+ Frame(data)
+{
+ d = new UrlLinkFramePrivate;
+ setData(data);
+}
+
+UrlLinkFrame::~UrlLinkFrame()
+{
+ delete d;
+}
+
+void UrlLinkFrame::setUrl(const String &s)
+{
+ d->url = s;
+}
+
+String UrlLinkFrame::url() const
+{
+ return d->url;
+}
+
+void UrlLinkFrame::setText(const String &s)
+{
+ setUrl(s);
+}
+
+String UrlLinkFrame::toString() const
+{
+ return url();
+}
+
+void UrlLinkFrame::parseFields(const ByteVector &data)
+{
+ d->url = String(data);
+}
+
+ByteVector UrlLinkFrame::renderFields() const
+{
+ return d->url.data(String::Latin1);
+}
+
+UrlLinkFrame::UrlLinkFrame(const ByteVector &data, Header *h) : Frame(h)
+{
+ d = new UrlLinkFramePrivate;
+ parseFields(fieldData(data));
+}
+
+
+UserUrlLinkFrame::UserUrlLinkFrame(String::Type encoding) :
+ UrlLinkFrame("WXXX")
+{
+ d = new UserUrlLinkFramePrivate;
+ d->textEncoding = encoding;
+}
+
+UserUrlLinkFrame::UserUrlLinkFrame(const ByteVector &data) :
+ UrlLinkFrame(data)
+{
+ d = new UserUrlLinkFramePrivate;
+ setData(data);
+}
+
+UserUrlLinkFrame::~UserUrlLinkFrame()
+{
+ delete d;
+}
+
+String UserUrlLinkFrame::toString() const
+{
+ return "[" + description() + "] " + url();
+}
+
+String::Type UserUrlLinkFrame::textEncoding() const
+{
+ return d->textEncoding;
+}
+
+void UserUrlLinkFrame::setTextEncoding(String::Type encoding)
+{
+ d->textEncoding = encoding;
+}
+
+String UserUrlLinkFrame::description() const
+{
+ return d->description;
+}
+
+void UserUrlLinkFrame::setDescription(const String &s)
+{
+ d->description = s;
+}
+
+void UserUrlLinkFrame::parseFields(const ByteVector &data)
+{
+ if(data.size() < 2) {
+ debug("A user URL link frame must contain at least 2 bytes.");
+ return;
+ }
+
+ int pos = 0;
+
+ d->textEncoding = String::Type(data[0]);
+ pos += 1;
+
+ if(d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8) {
+ int offset = data.find(textDelimiter(d->textEncoding), pos);
+ if(offset < pos)
+ return;
+
+ d->description = String(data.mid(pos, offset - pos), d->textEncoding);
+ pos = offset + 1;
+ }
+ else {
+ int len = data.mid(pos).find(textDelimiter(d->textEncoding), 0, 2);
+ if(len < 0)
+ return;
+
+ d->description = String(data.mid(pos, len), d->textEncoding);
+ pos += len + 2;
+ }
+
+ setUrl(String(data.mid(pos)));
+}
+
+ByteVector UserUrlLinkFrame::renderFields() const
+{
+ ByteVector v;
+
+ String::Type encoding = checkEncoding(d->description, d->textEncoding);
+
+ v.append(char(encoding));
+ v.append(d->description.data(encoding));
+ v.append(textDelimiter(encoding));
+ v.append(url().data(String::Latin1));
+
+ return v;
+}
+
+UserUrlLinkFrame::UserUrlLinkFrame(const ByteVector &data, Header *h) : UrlLinkFrame(data, h)
+{
+ d = new UserUrlLinkFramePrivate;
+ parseFields(fieldData(data));
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/frames/urllinkframe.h b/libs/taglib/taglib/mpeg/id3v2/frames/urllinkframe.h
new file mode 100644
index 0000000000..649f85dea6
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/frames/urllinkframe.h
@@ -0,0 +1,172 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ copyright : (C) 2006 by Urs Fleisch
+ email : ufleisch@users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_URLLINKFRAME_H
+#define TAGLIB_URLLINKFRAME_H
+
+#include <id3v2frame.h>
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ //! ID3v2 URL frame
+ /*!
+ * An implementation of ID3v2 URL link frames.
+ */
+ class TAGLIB_EXPORT UrlLinkFrame : public Frame
+ {
+ friend class FrameFactory;
+
+ public:
+ /*!
+ * This is a dual purpose constructor. \a data can either be binary data
+ * that should be parsed or (at a minimum) the frame ID.
+ */
+ explicit UrlLinkFrame(const ByteVector &data);
+
+ /*!
+ * Destroys this UrlLinkFrame instance.
+ */
+ virtual ~UrlLinkFrame();
+
+ /*!
+ * Returns the URL.
+ */
+ virtual String url() const;
+
+ /*!
+ * Sets the URL to \a s.
+ */
+ virtual void setUrl(const String &s);
+
+ // Reimplementations.
+
+ virtual void setText(const String &s);
+ virtual String toString() const;
+
+ protected:
+ virtual void parseFields(const ByteVector &data);
+ virtual ByteVector renderFields() const;
+
+ /*!
+ * The constructor used by the FrameFactory.
+ */
+ UrlLinkFrame(const ByteVector &data, Header *h);
+
+ private:
+ UrlLinkFrame(const UrlLinkFrame &);
+ UrlLinkFrame &operator=(const UrlLinkFrame &);
+
+ class UrlLinkFramePrivate;
+ UrlLinkFramePrivate *d;
+ };
+
+ //! ID3v2 User defined URL frame
+
+ /*!
+ * This is a specialization of URL link frames that allows for
+ * user defined entries. Each entry has a description in addition to the
+ * normal list of fields that a URL link frame has.
+ *
+ * This description identifies the frame and must be unique.
+ */
+ class TAGLIB_EXPORT UserUrlLinkFrame : public UrlLinkFrame
+ {
+ friend class FrameFactory;
+
+ public:
+ /*!
+ * Constructs an empty user defined URL link frame. For this to be
+ * a useful frame both a description and text must be set.
+ */
+ explicit UserUrlLinkFrame(String::Type encoding = String::Latin1);
+
+ /*!
+ * This is a dual purpose constructor. \a data can either be binary data
+ * that should be parsed or (at a minimum) the frame ID.
+ */
+ explicit UserUrlLinkFrame(const ByteVector &data);
+
+ /*!
+ * Destroys this UserUrlLinkFrame instance.
+ */
+ virtual ~UserUrlLinkFrame();
+
+ // Reimplementations.
+
+ virtual String toString() const;
+
+ /*!
+ * Returns the text encoding that will be used in rendering this frame.
+ * This defaults to the type that was either specified in the constructor
+ * or read from the frame when parsed.
+ *
+ * \see setTextEncoding()
+ * \see render()
+ */
+ String::Type textEncoding() const;
+
+ /*!
+ * Sets the text encoding to be used when rendering this frame to
+ * \a encoding.
+ *
+ * \see textEncoding()
+ * \see render()
+ */
+ void setTextEncoding(String::Type encoding);
+
+ /*!
+ * Returns the description for this frame.
+ */
+ String description() const;
+
+ /*!
+ * Sets the description of the frame to \a s. \a s must be unique.
+ */
+ void setDescription(const String &s);
+
+ protected:
+ virtual void parseFields(const ByteVector &data);
+ virtual ByteVector renderFields() const;
+
+ /*!
+ * The constructor used by the FrameFactory.
+ */
+ UserUrlLinkFrame(const ByteVector &data, Header *h);
+
+ private:
+ UserUrlLinkFrame(const UserUrlLinkFrame &);
+ UserUrlLinkFrame &operator=(const UserUrlLinkFrame &);
+
+ class UserUrlLinkFramePrivate;
+ UserUrlLinkFramePrivate *d;
+ };
+
+ }
+}
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2.2.0.txt b/libs/taglib/taglib/mpeg/id3v2/id3v2.2.0.txt
new file mode 100644
index 0000000000..a69bddd32a
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2.2.0.txt
@@ -0,0 +1,1660 @@
+
+Informal standard M. Nilsson
+Document: id3v2-00.txt 26th March 1998
+
+
+ ID3 tag version 2
+
+Status of this document
+
+ This document is an Informal standard and is released so that
+ implementors could have a set standard before the formal standard is
+ set. The formal standard will use another version number if not
+ identical to what is described in this document. The contents in this
+ document may change for clarifications but never for added or altered
+ functionallity.
+
+ Distribution of this document is unlimited.
+
+
+Abstract
+
+ The recent gain of popularity for MPEG layer III audio files on the
+ internet forced a standardised way of storing information about an
+ audio file within itself to determinate its origin and contents.
+
+ Today the most accepted way to do this is with the so called ID3 tag,
+ which is simple but very limited and in some cases very unsuitable.
+ The ID3 tag has very limited space in every field, very limited
+ numbers of fields, not expandable or upgradeable and is placed at the
+ end of a the file, which is unsuitable for streaming audio. This draft
+ is an attempt to answer these issues with a new version of the ID3
+ tag.
+
+
+1. Table of contents
+
+ 2. Conventions in this document
+ 3. ID3v2 overview
+ 3.1. ID3v2 header
+ 3.2. ID3v2 frames overview
+ 4. Declared ID3v2 frames
+ 4.1. Unique file identifier
+ 4.2. Text information frames
+ 4.2.1. Text information frames - details
+ 4.2.2. User defined text information frame
+ 4.3. URL link frames
+ 4.3.1. URL link frames - details
+ 4.3.2. User defined URL link frame
+ 4.4. Involved people list
+ 4.5. Music CD Identifier
+ 4.6. Event timing codes
+ 4.7. MPEG location lookup table
+ 4.8. Synced tempo codes
+ 4.9. Unsychronised lyrics/text transcription
+ 4.10. Synchronised lyrics/text
+ 4.11. Comments
+ 4.12. Relative volume adjustment
+ 4.13. Equalisation
+ 4.14. Reverb
+ 4.15. Attached picture
+ 4.16. General encapsulated object
+ 4.17. Play counter
+ 4.18. Popularimeter
+ 4.19. Recommended buffer size
+ 4.20. Encrypted meta frame
+ 4.21. Audio encryption
+ 4.22. Linked information
+ 5. The 'unsynchronisation scheme'
+ 6. Copyright
+ 7. References
+ 8. Appendix
+ A. Appendix A - ID3-Tag Specification V1.1
+ A.1. Overview
+ A.2. ID3v1 Implementation
+ A.3. Genre List
+ A.4. Track addition - ID3v1.1
+ 9. Author's Address
+
+
+2. Conventions in this document
+
+ In the examples, text within "" is a text string exactly as it appears
+ in a file. Numbers preceded with $ are hexadecimal and numbers
+ preceded with % are binary. $xx is used to indicate a byte with
+ unknown content. %x is used to indicate a bit with unknown content.
+ The most significant bit (MSB) of a byte is called 'bit 7' and the
+ least significant bit (LSB) is called 'bit 0'.
+
+ A tag is the whole tag described in this document. A frame is a block
+ of information in the tag. The tag consists of a header, frames and
+ optional padding. A field is a piece of information; one value, a
+ string etc. A numeric string is a string that consists of the
+ characters 0-9 only.
+
+
+3. ID3v2 overview
+
+ The two biggest design goals were to be able to implement ID3v2
+ without disturbing old software too much and that ID3v2 should be
+ expandable.
+
+ The first criterion is met by the simple fact that the MPEG [MPEG]
+ decoding software uses a syncsignal, embedded in the audiostream, to
+ 'lock on to' the audio. Since the ID3v2 tag doesn't contain a valid
+ syncsignal, no software will attempt to play the tag. If, for any
+ reason, coincidence make a syncsignal appear within the tag it will be
+ taken care of by the 'unsynchronisation scheme' described in section
+ 5.
+
+ The second criterion has made a more noticeable impact on the design
+ of the ID3v2 tag. It is constructed as a container for several
+ information blocks, called frames, whose format need not be known to
+ the software that encounters them. At the start of every frame there
+ is an identifier that explains the frames's format and content, and a
+ size descriptor that allows software to skip unknown frames.
+
+ If a total revision of the ID3v2 tag should be needed, there is a
+ version number and a size descriptor in the ID3v2 header.
+
+ The ID3 tag described in this document is mainly targeted to files
+ encoded with MPEG-2 layer I, MPEG-2 layer II, MPEG-2 layer III and
+ MPEG-2.5, but may work with other types of encoded audio.
+
+ The bitorder in ID3v2 is most significant bit first (MSB). The
+ byteorder in multibyte numbers is most significant byte first (e.g.
+ $12345678 would be encoded $12 34 56 78).
+
+ It is permitted to include padding after all the final frame (at the
+ end of the ID3 tag), making the size of all the frames together
+ smaller than the size given in the head of the tag. A possible purpose
+ of this padding is to allow for adding a few additional frames or
+ enlarge existing frames within the tag without having to rewrite the
+ entire file. The value of the padding bytes must be $00.
+
+
+3.1. ID3v2 header
+
+ The ID3v2 tag header, which should be the first information in the
+ file, is 10 bytes as follows:
+
+ ID3/file identifier "ID3"
+ ID3 version $02 00
+ ID3 flags %xx000000
+ ID3 size 4 * %0xxxxxxx
+
+ The first three bytes of the tag are always "ID3" to indicate that
+ this is an ID3 tag, directly followed by the two version bytes. The
+ first byte of ID3 version is it's major version, while the second byte
+ is its revision number. All revisions are backwards compatible while
+ major versions are not. If software with ID3v2 and below support
+ should encounter version three or higher it should simply ignore the
+ whole tag. Version and revision will never be $FF.
+
+ The first bit (bit 7) in the 'ID3 flags' is indicating whether or not
+ unsynchronisation is used (see section 5 for details); a set bit
+ indicates usage.
+
+ The second bit (bit 6) is indicating whether or not compression is
+ used; a set bit indicates usage. Since no compression scheme has been
+ decided yet, the ID3 decoder (for now) should just ignore the entire
+ tag if the compression bit is set.
+
+ The ID3 tag size is encoded with four bytes where the first bit (bit
+ 7) is set to zero in every byte, making a total of 28 bits. The zeroed
+ bits are ignored, so a 257 bytes long tag is represented as $00 00 02
+ 01.
+
+ The ID3 tag size is the size of the complete tag after
+ unsychronisation, including padding, excluding the header (total tag
+ size - 10). The reason to use 28 bits (representing up to 256MB) for
+ size description is that we don't want to run out of space here.
+
+ A ID3v2 tag can be detected with the following pattern:
+ $49 44 33 yy yy xx zz zz zz zz
+ Where yy is less than $FF, xx is the 'flags' byte and zz is less than
+ $80.
+
+
+3.2. ID3v2 frames overview
+
+ The headers of the frames are similar in their construction. They
+ consist of one three character identifier (capital A-Z and 0-9) and
+ one three byte size field, making a total of six bytes. The header is
+ excluded from the size. Identifiers beginning with "X", "Y" and "Z"
+ are for experimental use and free for everyone to use. Have in mind
+ that someone else might have used the same identifier as you. All
+ other identifiers are either used or reserved for future use.
+
+ The three character frame identifier is followed by a three byte size
+ descriptor, making a total header size of six bytes in every frame.
+ The size is calculated as framesize excluding frame identifier and
+ size descriptor (frame size - 6).
+
+ There is no fixed order of the frames' appearance in the tag, although
+ it is desired that the frames are arranged in order of significance
+ concerning the recognition of the file. An example of such order:
+ UFI, MCI, TT2 ...
+
+ A tag must contain at least one frame. A frame must be at least 1 byte
+ big, excluding the 6-byte header.
+
+ If nothing else is said a string is represented as ISO-8859-1
+ [ISO-8859-1] characters in the range $20 - $FF. All unicode strings
+ [UNICODE] use 16-bit unicode 2.0 (ISO/IEC 10646-1:1993, UCS-2). All
+ numeric strings are always encoded as ISO-8859-1. Terminated strings
+ are terminated with $00 if encoded with ISO-8859-1 and $00 00 if
+ encoded as unicode. If nothing else is said newline character is
+ forbidden. In ISO-8859-1 a new line is represented, when allowed, with
+ $0A only. Frames that allow different types of text encoding have a
+ text encoding description byte directly after the frame size. If
+ ISO-8859-1 is used this byte should be $00, if unicode is used it
+ should be $01.
+
+ The three byte language field is used to describe the language of the
+ frame's content, according to ISO-639-2 [ISO-639-2].
+
+ All URLs [URL] may be relative, e.g. "picture.png", "../doc.txt".
+
+ If a frame is longer than it should be, e.g. having more fields than
+ specified in this document, that indicates that additions to the
+ frame have been made in a later version of the ID3 standard. This
+ is reflected by the revision number in the header of the tag.
+
+
+4. Declared ID3v2 frames
+
+ The following frames are declared in this draft.
+
+ 4.19 BUF Recommended buffer size
+
+ 4.17 CNT Play counter
+ 4.11 COM Comments
+ 4.21 CRA Audio encryption
+ 4.20 CRM Encrypted meta frame
+
+ 4.6 ETC Event timing codes
+ 4.13 EQU Equalization
+
+ 4.16 GEO General encapsulated object
+
+ 4.4 IPL Involved people list
+
+ 4.22 LNK Linked information
+
+ 4.5 MCI Music CD Identifier
+ 4.7 MLL MPEG location lookup table
+
+ 4.15 PIC Attached picture
+ 4.18 POP Popularimeter
+
+ 4.14 REV Reverb
+ 4.12 RVA Relative volume adjustment
+
+ 4.10 SLT Synchronized lyric/text
+ 4.8 STC Synced tempo codes
+
+ 4.2.1 TAL Album/Movie/Show title
+ 4.2.1 TBP BPM (Beats Per Minute)
+ 4.2.1 TCM Composer
+ 4.2.1 TCO Content type
+ 4.2.1 TCR Copyright message
+ 4.2.1 TDA Date
+ 4.2.1 TDY Playlist delay
+ 4.2.1 TEN Encoded by
+ 4.2.1 TFT File type
+ 4.2.1 TIM Time
+ 4.2.1 TKE Initial key
+ 4.2.1 TLA Language(s)
+ 4.2.1 TLE Length
+ 4.2.1 TMT Media type
+ 4.2.1 TOA Original artist(s)/performer(s)
+ 4.2.1 TOF Original filename
+ 4.2.1 TOL Original Lyricist(s)/text writer(s)
+ 4.2.1 TOR Original release year
+ 4.2.1 TOT Original album/Movie/Show title
+ 4.2.1 TP1 Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group
+ 4.2.1 TP2 Band/Orchestra/Accompaniment
+ 4.2.1 TP3 Conductor/Performer refinement
+ 4.2.1 TP4 Interpreted, remixed, or otherwise modified by
+ 4.2.1 TPA Part of a set
+ 4.2.1 TPB Publisher
+ 4.2.1 TRC ISRC (International Standard Recording Code)
+ 4.2.1 TRD Recording dates
+ 4.2.1 TRK Track number/Position in set
+ 4.2.1 TSI Size
+ 4.2.1 TSS Software/hardware and settings used for encoding
+ 4.2.1 TT1 Content group description
+ 4.2.1 TT2 Title/Songname/Content description
+ 4.2.1 TT3 Subtitle/Description refinement
+ 4.2.1 TXT Lyricist/text writer
+ 4.2.2 TXX User defined text information frame
+ 4.2.1 TYE Year
+
+ 4.1 UFI Unique file identifier
+ 4.9 ULT Unsychronized lyric/text transcription
+
+ 4.3.1 WAF Official audio file webpage
+ 4.3.1 WAR Official artist/performer webpage
+ 4.3.1 WAS Official audio source webpage
+ 4.3.1 WCM Commercial information
+ 4.3.1 WCP Copyright/Legal information
+ 4.3.1 WPB Publishers official webpage
+ 4.3.2 WXX User defined URL link frame
+
+
+4.1. Unique file identifier
+
+ This frame's purpose is to be able to identify the audio file in a
+ database that may contain more information relevant to the content.
+ Since standardisation of such a database is beyond this document, all
+ frames begin with a null-terminated string with a URL [URL] containing
+ an email address, or a link to a location where an email address can
+ be found, that belongs to the organisation responsible for this
+ specific database implementation. Questions regarding the database
+ should be sent to the indicated email address. The URL should not be
+ used for the actual database queries. If a $00 is found directly after
+ the 'Frame size' the whole frame should be ignored, and preferably be
+ removed. The 'Owner identifier' is then followed by the actual
+ identifier, which may be up to 64 bytes. There may be more than one
+ "UFI" frame in a tag, but only one with the same 'Owner identifier'.
+
+ Unique file identifier "UFI"
+ Frame size $xx xx xx
+ Owner identifier <textstring> $00
+ Identifier <up to 64 bytes binary data>
+
+
+4.2. Text information frames
+
+ The text information frames are the most important frames, containing
+ information like artist, album and more. There may only be one text
+ information frame of its kind in an tag. If the textstring is followed
+ by a termination ($00 (00)) all the following information should be
+ ignored and not be displayed. All the text information frames have the
+ following format:
+
+ Text information identifier "T00" - "TZZ" , excluding "TXX",
+ described in 4.2.2.
+ Frame size $xx xx xx
+ Text encoding $xx
+ Information <textstring>
+
+
+4.2.1. Text information frames - details
+
+ TT1
+ The 'Content group description' frame is used if the sound belongs to
+ a larger category of sounds/music. For example, classical music is
+ often sorted in different musical sections (e.g. "Piano Concerto",
+ "Weather - Hurricane").
+
+ TT2
+ The 'Title/Songname/Content description' frame is the actual name of
+ the piece (e.g. "Adagio", "Hurricane Donna").
+
+ TT3
+ The 'Subtitle/Description refinement' frame is used for information
+ directly related to the contents title (e.g. "Op. 16" or "Performed
+ live at wembley").
+
+ TP1
+ The 'Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group' is
+ used for the main artist(s). They are seperated with the "/"
+ character.
+
+ TP2
+ The 'Band/Orchestra/Accompaniment' frame is used for additional
+ information about the performers in the recording.
+
+ TP3
+ The 'Conductor' frame is used for the name of the conductor.
+
+ TP4
+ The 'Interpreted, remixed, or otherwise modified by' frame contains
+ more information about the people behind a remix and similar
+ interpretations of another existing piece.
+
+ TCM
+ The 'Composer(s)' frame is intended for the name of the composer(s).
+ They are seperated with the "/" character.
+
+ TXT
+ The 'Lyricist(s)/text writer(s)' frame is intended for the writer(s)
+ of the text or lyrics in the recording. They are seperated with the
+ "/" character.
+
+ TLA
+ The 'Language(s)' frame should contain the languages of the text or
+ lyrics in the audio file. The language is represented with three
+ characters according to ISO-639-2. If more than one language is used
+ in the text their language codes should follow according to their
+ usage.
+
+ TCO
+ The content type, which previously (in ID3v1.1, see appendix A) was
+ stored as a one byte numeric value only, is now a numeric string. You
+ may use one or several of the types as ID3v1.1 did or, since the
+ category list would be impossible to maintain with accurate and up to
+ date categories, define your own.
+ References to the ID3v1 genres can be made by, as first byte, enter
+ "(" followed by a number from the genres list (section A.3.) and
+ ended with a ")" character. This is optionally followed by a
+ refinement, e.g. "(21)" or "(4)Eurodisco". Several references can be
+ made in the same frame, e.g. "(51)(39)". If the refinement should
+ begin with a "(" character it should be replaced with "((", e.g. "((I
+ can figure out any genre)" or "(55)((I think...)". The following new
+ content types is defined in ID3v2 and is implemented in the same way
+ as the numerig content types, e.g. "(RX)".
+
+ RX Remix
+ CR Cover
+
+ TAL
+ The 'Album/Movie/Show title' frame is intended for the title of the
+ recording(/source of sound) which the audio in the file is taken from.
+
+ TPA
+ The 'Part of a set' frame is a numeric string that describes which
+ part of a set the audio came from. This frame is used if the source
+ described in the "TAL" frame is divided into several mediums, e.g. a
+ double CD. The value may be extended with a "/" character and a
+ numeric string containing the total number of parts in the set. E.g.
+ "1/2".
+
+ TRK
+ The 'Track number/Position in set' frame is a numeric string
+ containing the order number of the audio-file on its original
+ recording. This may be extended with a "/" character and a numeric
+ string containing the total numer of tracks/elements on the original
+ recording. E.g. "4/9".
+
+ TRC
+ The 'ISRC' frame should contian the International Standard Recording
+ Code [ISRC].
+
+ TYE
+ The 'Year' frame is a numeric string with a year of the recording.
+ This frames is always four characters long (until the year 10000).
+
+ TDA
+ The 'Date' frame is a numeric string in the DDMM format containing
+ the date for the recording. This field is always four characters
+ long.
+
+ TIM
+ The 'Time' frame is a numeric string in the HHMM format containing
+ the time for the recording. This field is always four characters
+ long.
+
+ TRD
+ The 'Recording dates' frame is a intended to be used as complement to
+ the "TYE", "TDA" and "TIM" frames. E.g. "4th-7th June, 12th June" in
+ combination with the "TYE" frame.
+
+ TMT
+ The 'Media type' frame describes from which media the sound
+ originated. This may be a textstring or a reference to the predefined
+ media types found in the list below. References are made within "("
+ and ")" and are optionally followed by a text refinement, e.g. "(MC)
+ with four channels". If a text refinement should begin with a "("
+ character it should be replaced with "((" in the same way as in the
+ "TCO" frame. Predefined refinements is appended after the media type,
+ e.g. "(CD/S)" or "(VID/PAL/VHS)".
+
+ DIG Other digital media
+ /A Analog transfer from media
+
+ ANA Other analog media
+ /WAC Wax cylinder
+ /8CA 8-track tape cassette
+
+ CD CD
+ /A Analog transfer from media
+ /DD DDD
+ /AD ADD
+ /AA AAD
+
+ LD Laserdisc
+ /A Analog transfer from media
+
+ TT Turntable records
+ /33 33.33 rpm
+ /45 45 rpm
+ /71 71.29 rpm
+ /76 76.59 rpm
+ /78 78.26 rpm
+ /80 80 rpm
+
+ MD MiniDisc
+ /A Analog transfer from media
+
+ DAT DAT
+ /A Analog transfer from media
+ /1 standard, 48 kHz/16 bits, linear
+ /2 mode 2, 32 kHz/16 bits, linear
+ /3 mode 3, 32 kHz/12 bits, nonlinear, low speed
+ /4 mode 4, 32 kHz/12 bits, 4 channels
+ /5 mode 5, 44.1 kHz/16 bits, linear
+ /6 mode 6, 44.1 kHz/16 bits, 'wide track' play
+
+ DCC DCC
+ /A Analog transfer from media
+
+ DVD DVD
+ /A Analog transfer from media
+
+ TV Television
+ /PAL PAL
+ /NTSC NTSC
+ /SECAM SECAM
+
+ VID Video
+ /PAL PAL
+ /NTSC NTSC
+ /SECAM SECAM
+ /VHS VHS
+ /SVHS S-VHS
+ /BETA BETAMAX
+
+ RAD Radio
+ /FM FM
+ /AM AM
+ /LW LW
+ /MW MW
+
+ TEL Telephone
+ /I ISDN
+
+ MC MC (normal cassette)
+ /4 4.75 cm/s (normal speed for a two sided cassette)
+ /9 9.5 cm/s
+ /I Type I cassette (ferric/normal)
+ /II Type II cassette (chrome)
+ /III Type III cassette (ferric chrome)
+ /IV Type IV cassette (metal)
+
+ REE Reel
+ /9 9.5 cm/s
+ /19 19 cm/s
+ /38 38 cm/s
+ /76 76 cm/s
+ /I Type I cassette (ferric/normal)
+ /II Type II cassette (chrome)
+ /III Type III cassette (ferric chrome)
+ /IV Type IV cassette (metal)
+
+ TFT
+ The 'File type' frame indicates which type of audio this tag defines.
+ The following type and refinements are defined:
+
+ MPG MPEG Audio
+ /1 MPEG 2 layer I
+ /2 MPEG 2 layer II
+ /3 MPEG 2 layer III
+ /2.5 MPEG 2.5
+ /AAC Advanced audio compression
+
+ but other types may be used, not for these types though. This is used
+ in a similar way to the predefined types in the "TMT" frame, but
+ without parenthesis. If this frame is not present audio type is
+ assumed to be "MPG".
+
+ TBP
+ BPM is short for beats per minute, and is easily computed by
+ dividing the number of beats in a musical piece with its length. To
+ get a more accurate result, do the BPM calculation on the main-part
+ only. To acquire best result measure the time between each beat and
+ calculate individual BPM for each beat and use the median value as
+ result. BPM is an integer and represented as a numerical string.
+
+ TCR
+ The 'Copyright message' frame, which must begin with a year and a
+ space character (making five characters), is intended for the
+ copyright holder of the original sound, not the audio file itself. The
+ absence of this frame means only that the copyright information is
+ unavailable or has been removed, and must not be interpreted to mean
+ that the sound is public domain. Every time this field is displayed
+ the field must be preceded with "Copyright " (C) " ", where (C) is one
+ character showing a C in a circle.
+
+ TPB
+ The 'Publisher' frame simply contains the name of the label or
+ publisher.
+
+ TEN
+ The 'Encoded by' frame contains the name of the person or
+ organisation that encoded the audio file. This field may contain a
+ copyright message, if the audio file also is copyrighted by the
+ encoder.
+
+ TSS
+ The 'Software/hardware and settings used for encoding' frame
+ includes the used audio encoder and its settings when the file was
+ encoded. Hardware refers to hardware encoders, not the computer on
+ which a program was run.
+
+ TOF
+ The 'Original filename' frame contains the preferred filename for the
+ file, since some media doesn't allow the desired length of the
+ filename. The filename is case sensitive and includes its suffix.
+
+ TLE
+ The 'Length' frame contains the length of the audiofile in
+ milliseconds, represented as a numeric string.
+
+ TSI
+ The 'Size' frame contains the size of the audiofile in bytes
+ excluding the tag, represented as a numeric string.
+
+ TDY
+ The 'Playlist delay' defines the numbers of milliseconds of silence
+ between every song in a playlist. The player should use the "ETC"
+ frame, if present, to skip initial silence and silence at the end of
+ the audio to match the 'Playlist delay' time. The time is represented
+ as a numeric string.
+
+ TKE
+ The 'Initial key' frame contains the musical key in which the sound
+ starts. It is represented as a string with a maximum length of three
+ characters. The ground keys are represented with "A","B","C","D","E",
+ "F" and "G" and halfkeys represented with "b" and "#". Minor is
+ represented as "m". Example "Cbm". Off key is represented with an "o"
+ only.
+
+ TOT
+ The 'Original album/Movie/Show title' frame is intended for the title
+ of the original recording(/source of sound), if for example the music
+ in the file should be a cover of a previously released song.
+
+ TOA
+ The 'Original artist(s)/performer(s)' frame is intended for the
+ performer(s) of the original recording, if for example the music in
+ the file should be a cover of a previously released song. The
+ performers are seperated with the "/" character.
+
+ TOL
+ The 'Original Lyricist(s)/text writer(s)' frame is intended for the
+ text writer(s) of the original recording, if for example the music in
+ the file should be a cover of a previously released song. The text
+ writers are seperated with the "/" character.
+
+ TOR
+ The 'Original release year' frame is intended for the year when the
+ original recording, if for example the music in the file should be a
+ cover of a previously released song, was released. The field is
+ formatted as in the "TDY" frame.
+
+
+4.2.2. User defined text information frame
+
+ This frame is intended for one-string text information concerning the
+ audiofile in a similar way to the other "T"xx frames. The frame body
+ consists of a description of the string, represented as a terminated
+ string, followed by the actual string. There may be more than one
+ "TXX" frame in each tag, but only one with the same description.
+
+ User defined... "TXX"
+ Frame size $xx xx xx
+ Text encoding $xx
+ Description <textstring> $00 (00)
+ Value <textstring>
+
+
+4.3. URL link frames
+
+ With these frames dynamic data such as webpages with touring
+ information, price information or plain ordinary news can be added to
+ the tag. There may only be one URL [URL] link frame of its kind in an
+ tag, except when stated otherwise in the frame description. If the
+ textstring is followed by a termination ($00 (00)) all the following
+ information should be ignored and not be displayed. All URL link
+ frames have the following format:
+
+ URL link frame "W00" - "WZZ" , excluding "WXX"
+ (described in 4.3.2.)
+ Frame size $xx xx xx
+ URL <textstring>
+
+
+4.3.1. URL link frames - details
+
+ WAF
+ The 'Official audio file webpage' frame is a URL pointing at a file
+ specific webpage.
+
+ WAR
+ The 'Official artist/performer webpage' frame is a URL pointing at
+ the artists official webpage. There may be more than one "WAR" frame
+ in a tag if the audio contains more than one performer.
+
+ WAS
+ The 'Official audio source webpage' frame is a URL pointing at the
+ official webpage for the source of the audio file, e.g. a movie.
+
+ WCM
+ The 'Commercial information' frame is a URL pointing at a webpage
+ with information such as where the album can be bought. There may be
+ more than one "WCM" frame in a tag.
+
+ WCP
+ The 'Copyright/Legal information' frame is a URL pointing at a
+ webpage where the terms of use and ownership of the file is described.
+
+ WPB
+ The 'Publishers official webpage' frame is a URL pointing at the
+ official wepage for the publisher.
+
+
+4.3.2. User defined URL link frame
+
+ This frame is intended for URL [URL] links concerning the audiofile in
+ a similar way to the other "W"xx frames. The frame body consists of a
+ description of the string, represented as a terminated string,
+ followed by the actual URL. The URL is always encoded with ISO-8859-1
+ [ISO-8859-1]. There may be more than one "WXX" frame in each tag, but
+ only one with the same description.
+
+ User defined... "WXX"
+ Frame size $xx xx xx
+ Text encoding $xx
+ Description <textstring> $00 (00)
+ URL <textstring>
+
+
+4.4. Involved people list
+
+ Since there might be a lot of people contributing to an audio file in
+ various ways, such as musicians and technicians, the 'Text
+ information frames' are often insufficient to list everyone involved
+ in a project. The 'Involved people list' is a frame containing the
+ names of those involved, and how they were involved. The body simply
+ contains a terminated string with the involvement directly followed by
+ a terminated string with the involvee followed by a new involvement
+ and so on. There may only be one "IPL" frame in each tag.
+
+ Involved people list "IPL"
+ Frame size $xx xx xx
+ Text encoding $xx
+ People list strings <textstrings>
+
+
+4.5. Music CD Identifier
+
+ This frame is intended for music that comes from a CD, so that the CD
+ can be identified in databases such as the CDDB [CDDB]. The frame
+ consists of a binary dump of the Table Of Contents, TOC, from the CD,
+ which is a header of 4 bytes and then 8 bytes/track on the CD making a
+ maximum of 804 bytes. This frame requires a present and valid "TRK"
+ frame. There may only be one "MCI" frame in each tag.
+
+ Music CD identifier "MCI"
+ Frame size $xx xx xx
+ CD TOC <binary data>
+
+
+4.6. Event timing codes
+
+ This frame allows synchronisation with key events in a song or sound.
+ The head is:
+
+ Event timing codes "ETC"
+ Frame size $xx xx xx
+ Time stamp format $xx
+
+ Where time stamp format is:
+
+ $01 Absolute time, 32 bit sized, using MPEG [MPEG] frames as unit
+ $02 Absolute time, 32 bit sized, using milliseconds as unit
+
+ Abolute time means that every stamp contains the time from the
+ beginning of the file.
+
+ Followed by a list of key events in the following format:
+
+ Type of event $xx
+ Time stamp $xx (xx ...)
+
+ The 'Time stamp' is set to zero if directly at the beginning of the
+ sound or after the previous event. All events should be sorted in
+ chronological order. The type of event is as follows:
+
+ $00 padding (has no meaning)
+ $01 end of initial silence
+ $02 intro start
+ $03 mainpart start
+ $04 outro start
+ $05 outro end
+ $06 verse begins
+ $07 refrain begins
+ $08 interlude
+ $09 theme start
+ $0A variation
+ $0B key change
+ $0C time change
+ $0D unwanted noise (Snap, Crackle & Pop)
+
+ $0E-$DF reserved for future use
+
+ $E0-$EF not predefined sync 0-F
+
+ $F0-$FC reserved for future use
+
+ $FD audio end (start of silence)
+ $FE audio file ends
+ $FF one more byte of events follows (all the following bytes with
+ the value $FF have the same function)
+
+ The 'Not predefined sync's ($E0-EF) are for user events. You might
+ want to synchronise your music to something, like setting of an
+ explosion on-stage, turning on your screensaver etc.
+
+ There may only be one "ETC" frame in each tag.
+
+
+4.7. MPEG location lookup table
+
+ To increase performance and accuracy of jumps within a MPEG [MPEG]
+ audio file, frames with timecodes in different locations in the file
+ might be useful. The ID3 frame includes references that the software
+ can use to calculate positions in the file. After the frame header is
+ a descriptor of how much the 'frame counter' should increase for every
+ reference. If this value is two then the first reference points out
+ the second frame, the 2nd reference the 4th frame, the 3rd reference
+ the 6th frame etc. In a similar way the 'bytes between reference' and
+ 'milliseconds between reference' points out bytes and milliseconds
+ respectively.
+
+ Each reference consists of two parts; a certain number of bits, as
+ defined in 'bits for bytes deviation', that describes the difference
+ between what is said in 'bytes between reference' and the reality and
+ a certain number of bits, as defined in 'bits for milliseconds
+ deviation', that describes the difference between what is said in
+ 'milliseconds between reference' and the reality. The number of bits
+ in every reference, i.e. 'bits for bytes deviation'+'bits for
+ milliseconds deviation', must be a multiple of four. There may only be
+ one "MLL" frame in each tag.
+
+ Location lookup table "MLL"
+ ID3 frame size $xx xx xx
+ MPEG frames between reference $xx xx
+ Bytes between reference $xx xx xx
+ Milliseconds between reference $xx xx xx
+ Bits for bytes deviation $xx
+ Bits for milliseconds dev. $xx
+
+ Then for every reference the following data is included;
+
+ Deviation in bytes %xxx....
+ Deviation in milliseconds %xxx....
+
+
+4.8. Synced tempo codes
+
+ For a more accurate description of the tempo of a musical piece this
+ frame might be used. After the header follows one byte describing
+ which time stamp format should be used. Then follows one or more tempo
+ codes. Each tempo code consists of one tempo part and one time part.
+ The tempo is in BPM described with one or two bytes. If the first byte
+ has the value $FF, one more byte follows, which is added to the first
+ giving a range from 2 - 510 BPM, since $00 and $01 is reserved. $00 is
+ used to describe a beat-free time period, which is not the same as a
+ music-free time period. $01 is used to indicate one single beat-stroke
+ followed by a beat-free period.
+
+ The tempo descriptor is followed by a time stamp. Every time the tempo
+ in the music changes, a tempo descriptor may indicate this for the
+ player. All tempo descriptors should be sorted in chronological order.
+ The first beat-stroke in a time-period is at the same time as the beat
+ description occurs. There may only be one "STC" frame in each tag.
+
+ Synced tempo codes "STC"
+ Frame size $xx xx xx
+ Time stamp format $xx
+ Tempo data <binary data>
+
+ Where time stamp format is:
+
+ $01 Absolute time, 32 bit sized, using MPEG [MPEG] frames as unit
+ $02 Absolute time, 32 bit sized, using milliseconds as unit
+
+ Abolute time means that every stamp contains the time from the
+ beginning of the file.
+
+
+4.9. Unsychronised lyrics/text transcription
+
+ This frame contains the lyrics of the song or a text transcription of
+ other vocal activities. The head includes an encoding descriptor and
+ a content descriptor. The body consists of the actual text. The
+ 'Content descriptor' is a terminated string. If no descriptor is
+ entered, 'Content descriptor' is $00 (00) only. Newline characters
+ are allowed in the text. Maximum length for the descriptor is 64
+ bytes. There may be more than one lyrics/text frame in each tag, but
+ only one with the same language and content descriptor.
+
+ Unsynced lyrics/text "ULT"
+ Frame size $xx xx xx
+ Text encoding $xx
+ Language $xx xx xx
+ Content descriptor <textstring> $00 (00)
+ Lyrics/text <textstring>
+
+
+4.10. Synchronised lyrics/text
+
+ This is another way of incorporating the words, said or sung lyrics,
+ in the audio file as text, this time, however, in sync with the audio.
+ It might also be used to describing events e.g. occurring on a stage
+ or on the screen in sync with the audio. The header includes a content
+ descriptor, represented with as terminated textstring. If no
+ descriptor is entered, 'Content descriptor' is $00 (00) only.
+
+ Synced lyrics/text "SLT"
+ Frame size $xx xx xx
+ Text encoding $xx
+ Language $xx xx xx
+ Time stamp format $xx
+ Content type $xx
+ Content descriptor <textstring> $00 (00)
+
+
+ Encoding: $00 ISO-8859-1 [ISO-8859-1] character set is used => $00
+ is sync identifier.
+ $01 Unicode [UNICODE] character set is used => $00 00 is
+ sync identifier.
+
+ Content type: $00 is other
+ $01 is lyrics
+ $02 is text transcription
+ $03 is movement/part name (e.g. "Adagio")
+ $04 is events (e.g. "Don Quijote enters the stage")
+ $05 is chord (e.g. "Bb F Fsus")
+
+ Time stamp format is:
+
+ $01 Absolute time, 32 bit sized, using MPEG [MPEG] frames as unit
+ $02 Absolute time, 32 bit sized, using milliseconds as unit
+
+ Abolute time means that every stamp contains the time from the
+ beginning of the file.
+
+ The text that follows the frame header differs from that of the
+ unsynchronised lyrics/text transcription in one major way. Each
+ syllable (or whatever size of text is considered to be convenient by
+ the encoder) is a null terminated string followed by a time stamp
+ denoting where in the sound file it belongs. Each sync thus has the
+ following structure:
+
+ Terminated text to be synced (typically a syllable)
+ Sync identifier (terminator to above string) $00 (00)
+ Time stamp $xx (xx ...)
+
+ The 'time stamp' is set to zero or the whole sync is omitted if
+ located directly at the beginning of the sound. All time stamps should
+ be sorted in chronological order. The sync can be considered as a
+ validator of the subsequent string.
+
+ Newline characters are allowed in all "SLT" frames and should be used
+ after every entry (name, event etc.) in a frame with the content type
+ $03 - $04.
+
+ A few considerations regarding whitespace characters: Whitespace
+ separating words should mark the beginning of a new word, thus
+ occurring in front of the first syllable of a new word. This is also
+ valid for new line characters. A syllable followed by a comma should
+ not be broken apart with a sync (both the syllable and the comma
+ should be before the sync).
+
+ An example: The "ULT" passage
+
+ "Strangers in the night" $0A "Exchanging glances"
+
+ would be "SLT" encoded as:
+
+ "Strang" $00 xx xx "ers" $00 xx xx " in" $00 xx xx " the" $00 xx xx
+ " night" $00 xx xx 0A "Ex" $00 xx xx "chang" $00 xx xx "ing" $00 xx
+ xx "glan" $00 xx xx "ces" $00 xx xx
+
+ There may be more than one "SLT" frame in each tag, but only one with
+ the same language and content descriptor.
+
+
+4.11. Comments
+
+ This frame replaces the old 30-character comment field in ID3v1. It
+ consists of a frame head followed by encoding, language and content
+ descriptors and is ended with the actual comment as a text string.
+ Newline characters are allowed in the comment text string. There may
+ be more than one comment frame in each tag, but only one with the same
+ language and content descriptor.
+
+ Comment "COM"
+ Frame size $xx xx xx
+ Text encoding $xx
+ Language $xx xx xx
+ Short content description <textstring> $00 (00)
+ The actual text <textstring>
+
+
+4.12. Relative volume adjustment
+
+ This is a more subjective function than the previous ones. It allows
+ the user to say how much he wants to increase/decrease the volume on
+ each channel while the file is played. The purpose is to be able to
+ align all files to a reference volume, so that you don't have to
+ change the volume constantly. This frame may also be used to balance
+ adjust the audio. If the volume peak levels are known then this could
+ be described with the 'Peak volume right' and 'Peak volume left'
+ field. If Peakvolume is not known these fields could be left zeroed
+ or completely omitted. There may only be one "RVA" frame in each
+ tag.
+
+ Relative volume adjustment "RVA"
+ Frame size $xx xx xx
+ Increment/decrement %000000xx
+ Bits used for volume descr. $xx
+ Relative volume change, right $xx xx (xx ...)
+ Relative volume change, left $xx xx (xx ...)
+ Peak volume right $xx xx (xx ...)
+ Peak volume left $xx xx (xx ...)
+
+ In the increment/decrement field bit 0 is used to indicate the right
+ channel and bit 1 is used to indicate the left channel. 1 is
+ increment and 0 is decrement.
+
+ The 'bits used for volume description' field is normally $10 (16 bits)
+ for MPEG 2 layer I, II and III [MPEG] and MPEG 2.5. This value may not
+ be $00. The volume is always represented with whole bytes, padded in
+ the beginning (highest bits) when 'bits used for volume description'
+ is not a multiple of eight.
+
+
+4.13. Equalisation
+
+ This is another subjective, alignment frame. It allows the user to
+ predefine an equalisation curve within the audio file. There may only
+ be one "EQU" frame in each tag.
+
+ Equalisation "EQU"
+ Frame size $xx xx xx
+ Adjustment bits $xx
+
+ The 'adjustment bits' field defines the number of bits used for
+ representation of the adjustment. This is normally $10 (16 bits) for
+ MPEG 2 layer I, II and III [MPEG] and MPEG 2.5. This value may not be
+ $00.
+
+ This is followed by 2 bytes + ('adjustment bits' rounded up to the
+ nearest byte) for every equalisation band in the following format,
+ giving a frequency range of 0 - 32767Hz:
+
+ Increment/decrement %x (MSB of the Frequency)
+ Frequency (lower 15 bits)
+ Adjustment $xx (xx ...)
+
+ The increment/decrement bit is 1 for increment and 0 for decrement.
+ The equalisation bands should be ordered increasingly with reference
+ to frequency. All frequencies don't have to be declared. Adjustments
+ with the value $00 should be omitted. A frequency should only be
+ described once in the frame.
+
+
+4.14. Reverb
+
+ Yet another subjective one. You may here adjust echoes of different
+ kinds. Reverb left/right is the delay between every bounce in ms.
+ Reverb bounces left/right is the number of bounces that should be
+ made. $FF equals an infinite number of bounces. Feedback is the amount
+ of volume that should be returned to the next echo bounce. $00 is 0%,
+ $FF is 100%. If this value were $7F, there would be 50% volume
+ reduction on the first bounce, yet 50% on the second and so on. Left
+ to left means the sound from the left bounce to be played in the left
+ speaker, while left to right means sound from the left bounce to be
+ played in the right speaker.
+
+ 'Premix left to right' is the amount of left sound to be mixed in the
+ right before any reverb is applied, where $00 id 0% and $FF is 100%.
+ 'Premix right to left' does the same thing, but right to left. Setting
+ both premix to $FF would result in a mono output (if the reverb is
+ applied symmetric). There may only be one "REV" frame in each tag.
+
+ Reverb settings "REV"
+ Frame size $00 00 0C
+ Reverb left (ms) $xx xx
+ Reverb right (ms) $xx xx
+ Reverb bounces, left $xx
+ Reverb bounces, right $xx
+ Reverb feedback, left to left $xx
+ Reverb feedback, left to right $xx
+ Reverb feedback, right to right $xx
+ Reverb feedback, right to left $xx
+ Premix left to right $xx
+ Premix right to left $xx
+
+
+4.15. Attached picture
+
+ This frame contains a picture directly related to the audio file.
+ Image format is preferably "PNG" [PNG] or "JPG" [JFIF]. Description
+ is a short description of the picture, represented as a terminated
+ textstring. The description has a maximum length of 64 characters,
+ but may be empty. There may be several pictures attached to one file,
+ each in their individual "PIC" frame, but only one with the same
+ content descriptor. There may only be one picture with the picture
+ type declared as picture type $01 and $02 respectively. There is a
+ possibility to put only a link to the image file by using the 'image
+ format' "-->" and having a complete URL [URL] instead of picture data.
+ The use of linked files should however be used restrictively since
+ there is the risk of separation of files.
+
+ Attached picture "PIC"
+ Frame size $xx xx xx
+ Text encoding $xx
+ Image format $xx xx xx
+ Picture type $xx
+ Description <textstring> $00 (00)
+ Picture data <binary data>
+
+
+ Picture type: $00 Other
+ $01 32x32 pixels 'file icon' (PNG only)
+ $02 Other file icon
+ $03 Cover (front)
+ $04 Cover (back)
+ $05 Leaflet page
+ $06 Media (e.g. lable side of CD)
+ $07 Lead artist/lead performer/soloist
+ $08 Artist/performer
+ $09 Conductor
+ $0A Band/Orchestra
+ $0B Composer
+ $0C Lyricist/text writer
+ $0D Recording Location
+ $0E During recording
+ $0F During performance
+ $10 Movie/video screen capture
+ $11 A bright coloured fish
+ $12 Illustration
+ $13 Band/artist logotype
+ $14 Publisher/Studio logotype
+
+
+4.16. General encapsulated object
+
+ In this frame any type of file can be encapsulated. After the header,
+ 'Frame size' and 'Encoding' follows 'MIME type' [MIME] and 'Filename'
+ for the encapsulated object, both represented as terminated strings
+ encoded with ISO 8859-1 [ISO-8859-1]. The filename is case sensitive.
+ Then follows a content description as terminated string, encoded as
+ 'Encoding'. The last thing in the frame is the actual object. The
+ first two strings may be omitted, leaving only their terminations.
+ MIME type is always an ISO-8859-1 text string. There may be more than
+ one "GEO" frame in each tag, but only one with the same content
+ descriptor.
+
+ General encapsulated object "GEO"
+ Frame size $xx xx xx
+ Text encoding $xx
+ MIME type <textstring> $00
+ Filename <textstring> $00 (00)
+ Content description <textstring> $00 (00)
+ Encapsulated object <binary data>
+
+
+4.17. Play counter
+
+ This is simply a counter of the number of times a file has been
+ played. The value is increased by one every time the file begins to
+ play. There may only be one "CNT" frame in each tag. When the counter
+ reaches all one's, one byte is inserted in front of the counter thus
+ making the counter eight bits bigger. The counter must be at least
+ 32-bits long to begin with.
+
+ Play counter "CNT"
+ Frame size $xx xx xx
+ Counter $xx xx xx xx (xx ...)
+
+
+4.18. Popularimeter
+
+ The purpose of this frame is to specify how good an audio file is.
+ Many interesting applications could be found to this frame such as a
+ playlist that features better audiofiles more often than others or it
+ could be used to profile a persons taste and find other 'good' files
+ by comparing people's profiles. The frame is very simple. It contains
+ the email address to the user, one rating byte and a four byte play
+ counter, intended to be increased with one for every time the file is
+ played. The email is a terminated string. The rating is 1-255 where
+ 1 is worst and 255 is best. 0 is unknown. If no personal counter is
+ wanted it may be omitted. When the counter reaches all one's, one
+ byte is inserted in front of the counter thus making the counter
+ eight bits bigger in the same away as the play counter ("CNT").
+ There may be more than one "POP" frame in each tag, but only one with
+ the same email address.
+
+ Popularimeter "POP"
+ Frame size $xx xx xx
+ Email to user <textstring> $00
+ Rating $xx
+ Counter $xx xx xx xx (xx ...)
+
+
+4.19. Recommended buffer size
+
+ Sometimes the server from which a audio file is streamed is aware of
+ transmission or coding problems resulting in interruptions in the
+ audio stream. In these cases, the size of the buffer can be
+ recommended by the server using this frame. If the 'embedded info
+ flag' is true (1) then this indicates that an ID3 tag with the
+ maximum size described in 'Buffer size' may occur in the audiostream.
+ In such case the tag should reside between two MPEG [MPEG] frames, if
+ the audio is MPEG encoded. If the position of the next tag is known,
+ 'offset to next tag' may be used. The offset is calculated from the
+ end of tag in which this frame resides to the first byte of the header
+ in the next. This field may be omitted. Embedded tags is currently not
+ recommended since this could render unpredictable behaviour from
+ present software/hardware. The 'Buffer size' should be kept to a
+ minimum. There may only be one "BUF" frame in each tag.
+
+ Recommended buffer size "BUF"
+ Frame size $xx xx xx
+ Buffer size $xx xx xx
+ Embedded info flag %0000000x
+ Offset to next tag $xx xx xx xx
+
+
+4.20. Encrypted meta frame
+
+ This frame contains one or more encrypted frames. This enables
+ protection of copyrighted information such as pictures and text, that
+ people might want to pay extra for. Since standardisation of such an
+ encryption scheme is beyond this document, all "CRM" frames begin with
+ a terminated string with a URL [URL] containing an email address, or a
+ link to a location where an email adress can be found, that belongs to
+ the organisation responsible for this specific encrypted meta frame.
+
+ Questions regarding the encrypted frame should be sent to the
+ indicated email address. If a $00 is found directly after the 'Frame
+ size', the whole frame should be ignored, and preferably be removed.
+ The 'Owner identifier' is then followed by a short content description
+ and explanation as to why it's encrypted. After the
+ 'content/explanation' description, the actual encrypted block follows.
+
+ When an ID3v2 decoder encounters a "CRM" frame, it should send the
+ datablock to the 'plugin' with the corresponding 'owner identifier'
+ and expect to receive either a datablock with one or several ID3v2
+ frames after each other or an error. There may be more than one "CRM"
+ frames in a tag, but only one with the same 'owner identifier'.
+
+ Encrypted meta frame "CRM"
+ Frame size $xx xx xx
+ Owner identifier <textstring> $00 (00)
+ Content/explanation <textstring> $00 (00)
+ Encrypted datablock <binary data>
+
+
+4.21. Audio encryption
+
+ This frame indicates if the actual audio stream is encrypted, and by
+ whom. Since standardisation of such encrypion scheme is beyond this
+ document, all "CRA" frames begin with a terminated string with a
+ URL containing an email address, or a link to a location where an
+ email address can be found, that belongs to the organisation
+ responsible for this specific encrypted audio file. Questions
+ regarding the encrypted audio should be sent to the email address
+ specified. If a $00 is found directly after the 'Frame size' and the
+ audiofile indeed is encrypted, the whole file may be considered
+ useless.
+
+ After the 'Owner identifier', a pointer to an unencrypted part of the
+ audio can be specified. The 'Preview start' and 'Preview length' is
+ described in frames. If no part is unencrypted, these fields should be
+ left zeroed. After the 'preview length' field follows optionally a
+ datablock required for decryption of the audio. There may be more than
+ one "CRA" frames in a tag, but only one with the same 'Owner
+ identifier'.
+
+ Audio encryption "CRA"
+ Frame size $xx xx xx
+ Owner identifier <textstring> $00 (00)
+ Preview start $xx xx
+ Preview length $xx xx
+ Encryption info <binary data>
+
+
+4.22. Linked information
+
+ To keep space waste as low as possible this frame may be used to link
+ information from another ID3v2 tag that might reside in another audio
+ file or alone in a binary file. It is recommended that this method is
+ only used when the files are stored on a CD-ROM or other circumstances
+ when the risk of file seperation is low. The frame contains a frame
+ identifier, which is the frame that should be linked into this tag, a
+ URL [URL] field, where a reference to the file where the frame is
+ given, and additional ID data, if needed. Data should be retrieved
+ from the first tag found in the file to which this link points. There
+ may be more than one "LNK" frame in a tag, but only one with the same
+ contents. A linked frame is to be considered as part of the tag and
+ has the same restrictions as if it was a physical part of the tag
+ (i.e. only one "REV" frame allowed, whether it's linked or not).
+
+ Linked information "LNK"
+ Frame size $xx xx xx
+ Frame identifier $xx xx xx
+ URL <textstring> $00 (00)
+ Additional ID data <textstring(s)>
+
+ Frames that may be linked and need no additional data are "IPL",
+ "MCI", "ETC", "LLT", "STC", "RVA", "EQU", "REV", "BUF", the text
+ information frames and the URL link frames.
+
+ The "TXX", "PIC", "GEO", "CRM" and "CRA" frames may be linked with the
+ content descriptor as additional ID data.
+
+ The "COM", "SLT" and "ULT" frames may be linked with three bytes of
+ language descriptor directly followed by a content descriptor as
+ additional ID data.
+
+
+5. The 'unsynchronisation scheme'
+
+ The only purpose of the 'unsychronisation scheme' is to make the ID3v2
+ tag as compatible as possible with existing software. There is no use
+ in 'unsynchronising' tags if the file is only to be processed by new
+ software. Unsynchronisation may only be made with MPEG 2 layer I, II
+ and III and MPEG 2.5 files.
+
+ Whenever a false synchronisation is found within the tag, one zeroed
+ byte is inserted after the first false synchronisation byte. The
+ format of a correct sync that should be altered by ID3 encoders is as
+ follows:
+
+ %11111111 111xxxxx
+
+ And should be replaced with:
+
+ %11111111 00000000 111xxxxx
+
+ This has the side effect that all $FF 00 combinations have to be
+ altered, so they won't be affected by the decoding process. Therefore
+ all the $FF 00 combinations have to be replaced with the $FF 00 00
+ combination during the unsynchonisation.
+
+ To indicate usage of the unsynchronisation, the first bit in 'ID3
+ flags' should be set. This bit should only be set if the tag
+ contained a, now corrected, false synchronisation. The bit should
+ only be clear if the tag does not contain any false synchronisations.
+
+ Do bear in mind, that if a compression scheme is used by the encoder,
+ the unsyncronisation scheme should be applied *afterwards*. When
+ decoding a compressed, 'unsyncronised' file, the 'unsyncronisation
+ scheme' should be parsed first, compression afterwards.
+
+
+6. Copyright
+
+ Copyright (C) Martin Nilsson 1998. All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that a reference to this document is included on all
+ such copies and derivative works. However, this document itself may
+ not be modified in any way and reissued as the original document.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE AUTHORS DISCLAIMS ALL WARRANTIES, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+ INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+7. References
+
+ [CDDB] Compact Disc Data Base
+
+ <url:http://www.cddb.com>
+
+ [ISO-639-2] ISO/FDIS 639-2.
+ Codes for the representation of names of languages, Part 2: Alpha-3
+ code. Technical committee / subcommittee: TC 37 / SC 2
+
+ [ISO-8859-1] ISO/IEC DIS 8859-1.
+ 8-bit single-byte coded graphic character sets, Part 1: Latin
+ alphabet No. 1. Technical committee / subcommittee: JTC 1 / SC 2
+
+ [ISRC] ISO 3901:1986
+ International Standard Recording Code (ISRC).
+ Technical committee / subcommittee: TC 46 / SC 9
+
+ [JFIF] JPEG File Interchange Format, version 1.02
+
+ <url:http://www.w3.org/Graphics/JPEG/jfif.txt>
+
+ [MIME] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part One: Format of Internet Message Bodies",
+ RFC 2045, November 1996.
+
+ <url:ftp://ftp.isi.edu/in-notes/rfc2045.txt>
+
+ [MPEG] ISO/IEC 11172-3:1993.
+ Coding of moving pictures and associated audio for digital storage
+ media at up to about 1,5 Mbit/s, Part 3: Audio.
+ Technical committee / subcommittee: JTC 1 / SC 29
+ and
+ ISO/IEC 13818-3:1995
+ Generic coding of moving pictures and associated audio information,
+ Part 3: Audio.
+ Technical committee / subcommittee: JTC 1 / SC 29
+ and
+ ISO/IEC DIS 13818-3
+ Generic coding of moving pictures and associated audio information,
+ Part 3: Audio (Revision of ISO/IEC 13818-3:1995)
+
+
+ [PNG] Portable Network Graphics, version 1.0
+
+ <url:http://www.w3.org/TR/REC-png-multi.html>
+
+ [UNICODE] ISO/IEC 10646-1:1993.
+ Universal Multiple-Octet Coded Character Set (UCS), Part 1:
+ Architecture and Basic Multilingual Plane. Technical committee
+ / subcommittee: JTC 1 / SC 2
+
+ <url:http://www.unicode.org>
+
+ [URL] T. Berners-Lee, L. Masinter & M. McCahill, "Uniform Resource
+ Locators (URL).", RFC 1738, December 1994.
+
+ <url:ftp://ftp.isi.edu/in-notes/rfc1738.txt>
+
+
+8. Appendix
+
+
+A. Appendix A - ID3-Tag Specification V1.1
+
+ ID3-Tag Specification V1.1 (12 dec 1997) by Michael Mutschler
+ <amiga2@info2.rus.uni-stuttgart.de>, edited for space and clarity
+ reasons.
+
+
+A.1. Overview
+
+ The ID3-Tag is an information field for MPEG Layer 3 audio files.
+ Since a standalone MP3 doesn't provide a method of storing other
+ information than those directly needed for replay reasons, the
+ ID3-tag was invented by Eric Kemp in 1996.
+
+ A revision from ID3v1 to ID3v1.1 was made by Michael Mutschler to
+ support track number information is described in A.4.
+
+
+A.2. ID3v1 Implementation
+
+ The Information is stored in the last 128 bytes of an MP3. The Tag
+ has got the following fields, and the offsets given here, are from
+ 0-127.
+
+ Field Length Offsets
+ Tag 3 0-2
+ Songname 30 3-32
+ Artist 30 33-62
+ Album 30 63-92
+ Year 4 93-96
+ Comment 30 97-126
+ Genre 1 127
+
+
+ The string-fields contain ASCII-data, coded in ISO-Latin 1 codepage.
+ Strings which are smaller than the field length are padded with zero-
+ bytes.
+
+ Tag: The tag is valid if this field contains the string "TAG". This
+ has to be uppercase!
+
+ Songname: This field contains the title of the MP3 (string as
+ above).
+
+ Artist: This field contains the artist of the MP3 (string as above).
+
+ Album: this field contains the album where the MP3 comes from
+ (string as above).
+
+ Year: this field contains the year when this song has originally
+ been released (string as above).
+
+ Comment: this field contains a comment for the MP3 (string as
+ above). Revision to this field has been made in ID3v1.1. See
+ A.4.
+
+ Genre: this byte contains the offset of a genre in a predefined
+ list the byte is treated as an unsigned byte. The offset is
+ starting from 0. See A.3.
+
+
+A.3. Genre List
+
+ The following genres is defined in ID3v1
+
+ 0.Blues
+ 1.Classic Rock
+ 2.Country
+ 3.Dance
+ 4.Disco
+ 5.Funk
+ 6.Grunge
+ 7.Hip-Hop
+ 8.Jazz
+ 9.Metal
+ 10.New Age
+ 11.Oldies
+ 12.Other
+ 13.Pop
+ 14.R&B
+ 15.Rap
+ 16.Reggae
+ 17.Rock
+ 18.Techno
+ 19.Industrial
+ 20.Alternative
+ 21.Ska
+ 22.Death Metal
+ 23.Pranks
+ 24.Soundtrack
+ 25.Euro-Techno
+ 26.Ambient
+ 27.Trip-Hop
+ 28.Vocal
+ 29.Jazz+Funk
+ 30.Fusion
+ 31.Trance
+ 32.Classical
+ 33.Instrumental
+ 34.Acid
+ 35.House
+ 36.Game
+ 37.Sound Clip
+ 38.Gospel
+ 39.Noise
+ 40.AlternRock
+ 41.Bass
+ 42.Soul
+ 43.Punk
+ 44.Space
+ 45.Meditative
+ 46.Instrumental Pop
+ 47.Instrumental Rock
+ 48.Ethnic
+ 49.Gothic
+ 50.Darkwave
+ 51.Techno-Industrial
+ 52.Electronic
+ 53.Pop-Folk
+ 54.Eurodance
+ 55.Dream
+ 56.Southern Rock
+ 57.Comedy
+ 58.Cult
+ 59.Gangsta
+ 60.Top 40
+ 61.Christian Rap
+ 62.Pop/Funk
+ 63.Jungle
+ 64.Native American
+ 65.Cabaret
+ 66.New Wave
+ 67.Psychadelic
+ 68.Rave
+ 69.Showtunes
+ 70.Trailer
+ 71.Lo-Fi
+ 72.Tribal
+ 73.Acid Punk
+ 74.Acid Jazz
+ 75.Polka
+ 76.Retro
+ 77.Musical
+ 78.Rock & Roll
+ 79.Hard Rock
+
+ The following genres are Winamp extensions
+
+ 80.Folk
+ 81.Folk-Rock
+ 82.National Folk
+ 83.Swing
+ 84.Fast Fusion
+ 85.Bebob
+ 86.Latin
+ 87.Revival
+ 88.Celtic
+ 89.Bluegrass
+ 90.Avantgarde
+ 91.Gothic Rock
+ 92.Progressive Rock
+ 93.Psychedelic Rock
+ 94.Symphonic Rock
+ 95.Slow Rock
+ 96.Big Band
+ 97.Chorus
+ 98.Easy Listening
+ 99.Acoustic
+ 100.Humour
+ 101.Speech
+ 102.Chanson
+ 103.Opera
+ 104.Chamber Music
+ 105.Sonata
+ 106.Symphony
+ 107.Booty Bass
+ 108.Primus
+ 109.Porn Groove
+ 110.Satire
+ 111.Slow Jam
+ 112.Club
+ 113.Tango
+ 114.Samba
+ 115.Folklore
+ 116.Ballad
+ 117.Power Ballad
+ 118.Rhythmic Soul
+ 119.Freestyle
+ 120.Duet
+ 121.Punk Rock
+ 122.Drum Solo
+ 123.A capella
+ 124.Euro-House
+ 125.Dance Hall
+
+
+A.4. Track addition - ID3v1.1
+
+ In ID3v1.1, Michael Mutschler revised the specification of the
+ comment field in order to implement the track number. The new format
+ of the comment field is a 28 character string followed by a mandatory
+ null ($00) character and the original album tracknumber stored as an
+ unsigned byte-size integer. In such cases where the 29th byte is not
+ the null character or when the 30th is a null character, the
+ tracknumber is to be considered undefined.
+
+
+9. Author's Address
+
+ Martin Nilsson
+ Rydsvägen 246 C. 30
+ S-584 34 Linköping
+ Sweden
+
+ Email: nilsson@id3.org
+
+ Co-authors:
+
+ Johan Sundström Email: johan@id3.org
+
+
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2.3.0.txt b/libs/taglib/taglib/mpeg/id3v2/id3v2.3.0.txt
new file mode 100644
index 0000000000..b4ed763ee1
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2.3.0.txt
@@ -0,0 +1,2022 @@
+Informal standard M. Nilsson
+Document: id3v2.3.0.txt 3rd February 1999
+
+
+ ID3 tag version 2.3.0
+
+Status of this document
+
+ This document is an informal standard and replaces the ID3v2.2.0
+ standard [ID3v2]. The informal standard is released so that
+ implementors could have a set standard before a formal standard is
+ set. The formal standard will use another version or revision number
+ if not identical to what is described in this document. The contents
+ in this document may change for clarifications but never for added or
+ altered functionallity.
+
+ Distribution of this document is unlimited.
+
+
+Abstract
+
+ This document describes the ID3v2.3.0, which is a more developed
+ version of the ID3v2 informal standard [ID3v2] (version 2.2.0),
+ evolved from the ID3 tagging system. The ID3v2 offers a flexible way
+ of storing information about an audio file within itself to determine
+ its origin and contents. The information may be technical
+ information, such as equalisation curves, as well as related meta
+ information, such as title, performer, copyright etc.
+
+
+1. Table of contents
+
+ 2. Conventions in this document
+ 3. ID3v2 overview
+ 3.1. ID3v2 header
+ 3.2. ID3v2 extended header
+ 3.3. ID3v2 frames overview
+ 3.3.1. Frame header flags
+ 3.3.2. Default flags
+ 4. Declared ID3v2 frames
+ 4.1. Unique file identifier
+ 4.2. Text information frames
+ 4.2.1. Text information frames - details
+ 4.2.2. User defined text information frame
+ 4.3. URL link frames
+ 4.3.1. URL link frames - details
+ 4.3.2. User defined URL link frame
+ 4.4. Involved people list
+ 4.5. Music CD Identifier
+ 4.6. Event timing codes
+ 4.7. MPEG location lookup table
+ 4.8. Synced tempo codes
+ 4.9. Unsychronised lyrics/text transcription
+ 4.10. Synchronised lyrics/text
+ 4.11. Comments
+ 4.12. Relative volume adjustment
+ 4.13. Equalisation
+ 4.14. Reverb
+ 4.15. Attached picture
+ 4.16. General encapsulated object
+ 4.17. Play counter
+ 4.18. Popularimeter
+ 4.19. Recommended buffer size
+ 4.20. Audio encryption
+ 4.21. Linked information
+ 4.22. Position synchronisation frame
+ 4.23. Terms of use
+ 4.24. Ownership frame
+ 4.25. Commercial frame
+ 4.26. Encryption method registration
+ 4.27. Group identification registration
+ 4.28. Private frame
+ 5. The 'unsynchronisation scheme'
+ 6. Copyright
+ 7. References
+ 8. Appendix
+ A. Appendix A - Genre List from ID3v1
+ 9. Author's Address
+
+
+2. Conventions in this document
+
+ In the examples, text within "" is a text string exactly as it
+ appears in a file. Numbers preceded with $ are hexadecimal and
+ numbers preceded with % are binary. $xx is used to indicate a byte
+ with unknown content. %x is used to indicate a bit with unknown
+ content. The most significant bit (MSB) of a byte is called 'bit 7'
+ and the least significant bit (LSB) is called 'bit 0'.
+
+ A tag is the whole tag described in this document. A frame is a block
+ of information in the tag. The tag consists of a header, frames and
+ optional padding. A field is a piece of information; one value, a
+ string etc. A numeric string is a string that consists of the
+ characters 0-9 only.
+
+
+3. ID3v2 overview
+
+ The two biggest design goals were to be able to implement ID3v2
+ without disturbing old software too much and that ID3v2 should be
+ as flexible and expandable as possible.
+
+ The first criterion is met by the simple fact that the MPEG [MPEG]
+ decoding software uses a syncsignal, embedded in the audiostream, to
+ 'lock on to' the audio. Since the ID3v2 tag doesn't contain a valid
+ syncsignal, no software will attempt to play the tag. If, for any
+ reason, coincidence make a syncsignal appear within the tag it will
+ be taken care of by the 'unsynchronisation scheme' described in
+ section 5.
+
+ The second criterion has made a more noticeable impact on the design
+ of the ID3v2 tag. It is constructed as a container for several
+ information blocks, called frames, whose format need not be known to
+ the software that encounters them. At the start of every frame there
+ is an identifier that explains the frames' format and content, and a
+ size descriptor that allows software to skip unknown frames.
+
+ If a total revision of the ID3v2 tag should be needed, there is a
+ version number and a size descriptor in the ID3v2 header.
+
+ The ID3 tag described in this document is mainly targeted at files
+ encoded with MPEG-1/2 layer I, MPEG-1/2 layer II, MPEG-1/2 layer III
+ and MPEG-2.5, but may work with other types of encoded audio.
+
+ The bitorder in ID3v2 is most significant bit first (MSB). The
+ byteorder in multibyte numbers is most significant byte first (e.g.
+ $12345678 would be encoded $12 34 56 78).
+
+ It is permitted to include padding after all the final frame (at the
+ end of the ID3 tag), making the size of all the frames together
+ smaller than the size given in the head of the tag. A possible
+ purpose of this padding is to allow for adding a few additional
+ frames or enlarge existing frames within the tag without having to
+ rewrite the entire file. The value of the padding bytes must be $00.
+
+
+3.1. ID3v2 header
+
+ The ID3v2 tag header, which should be the first information in the
+ file, is 10 bytes as follows:
+
+ ID3v2/file identifier "ID3"
+ ID3v2 version $03 00
+ ID3v2 flags %abc00000
+ ID3v2 size 4 * %0xxxxxxx
+
+ The first three bytes of the tag are always "ID3" to indicate that
+ this is an ID3v2 tag, directly followed by the two version bytes. The
+ first byte of ID3v2 version is it's major version, while the second
+ byte is its revision number. In this case this is ID3v2.3.0. All
+ revisions are backwards compatible while major versions are not. If
+ software with ID3v2.2.0 and below support should encounter version
+ three or higher it should simply ignore the whole tag. Version and
+ revision will never be $FF.
+
+ The version is followed by one the ID3v2 flags field, of which
+ currently only three flags are used.
+
+
+ a - Unsynchronisation
+
+ Bit 7 in the 'ID3v2 flags' indicates whether or not
+ unsynchronisation is used (see section 5 for details); a set bit
+ indicates usage.
+
+
+ b - Extended header
+
+ The second bit (bit 6) indicates whether or not the header is
+ followed by an extended header. The extended header is described in
+ section 3.2.
+
+
+ c - Experimental indicator
+
+ The third bit (bit 5) should be used as an 'experimental
+ indicator'. This flag should always be set when the tag is in an
+ experimental stage.
+
+ All the other flags should be cleared. If one of these undefined
+ flags are set that might mean that the tag is not readable for a
+ parser that does not know the flags function.
+
+ The ID3v2 tag size is encoded with four bytes where the most
+ significant bit (bit 7) is set to zero in every byte, making a total
+ of 28 bits. The zeroed bits are ignored, so a 257 bytes long tag is
+ represented as $00 00 02 01.
+
+ The ID3v2 tag size is the size of the complete tag after
+ unsychronisation, including padding, excluding the header but not
+ excluding the extended header (total tag size - 10). Only 28 bits
+ (representing up to 256MB) are used in the size description to avoid
+ the introducuction of 'false syncsignals'.
+
+ An ID3v2 tag can be detected with the following pattern:
+ $49 44 33 yy yy xx zz zz zz zz
+ Where yy is less than $FF, xx is the 'flags' byte and zz is less than
+ $80.
+
+
+3.2. ID3v2 extended header
+
+ The extended header contains information that is not vital to the
+ correct parsing of the tag information, hence the extended header is
+ optional.
+
+ Extended header size $xx xx xx xx
+ Extended Flags $xx xx
+ Size of padding $xx xx xx xx
+
+ Where the 'Extended header size', currently 6 or 10 bytes, excludes
+ itself. The 'Size of padding' is simply the total tag size excluding
+ the frames and the headers, in other words the padding. The extended
+ header is considered separate from the header proper, and as such is
+ subject to unsynchronisation.
+
+ The extended flags are a secondary flag set which describes further
+ attributes of the tag. These attributes are currently defined as
+ follows
+
+ %x0000000 00000000
+
+
+ x - CRC data present
+
+ If this flag is set four bytes of CRC-32 data is appended to the
+ extended header. The CRC should be calculated before
+ unsynchronisation on the data between the extended header and the
+ padding, i.e. the frames and only the frames.
+
+ Total frame CRC $xx xx xx xx
+
+
+3.3. ID3v2 frame overview
+
+ As the tag consists of a tag header and a tag body with one or more
+ frames, all the frames consists of a frame header followed by one or
+ more fields containing the actual information. The layout of the
+ frame header:
+
+ Frame ID $xx xx xx xx (four characters)
+ Size $xx xx xx xx
+ Flags $xx xx
+
+ The frame ID made out of the characters capital A-Z and 0-9.
+ Identifiers beginning with "X", "Y" and "Z" are for experimental use
+ and free for everyone to use, without the need to set the
+ experimental bit in the tag header. Have in mind that someone else
+ might have used the same identifier as you. All other identifiers are
+ either used or reserved for future use.
+
+ The frame ID is followed by a size descriptor, making a total header
+ size of ten bytes in every frame. The size is calculated as frame
+ size excluding frame header (frame size - 10).
+
+ In the frame header the size descriptor is followed by two flags
+ bytes. These flags are described in section 3.3.1.
+
+ There is no fixed order of the frames' appearance in the tag,
+ although it is desired that the frames are arranged in order of
+ significance concerning the recognition of the file. An example of
+ such order: UFID, TIT2, MCDI, TRCK ...
+
+ A tag must contain at least one frame. A frame must be at least 1
+ byte big, excluding the header.
+
+ If nothing else is said a string is represented as ISO-8859-1
+ [ISO-8859-1] characters in the range $20 - $FF. Such strings are
+ represented as <text string>, or <full text string> if newlines are
+ allowed, in the frame descriptions. All Unicode strings [UNICODE] use
+ 16-bit unicode 2.0 (ISO/IEC 10646-1:1993, UCS-2). Unicode strings
+ must begin with the Unicode BOM ($FF FE or $FE FF) to identify the
+ byte order.
+
+ All numeric strings and URLs [URL] are always encoded as ISO-8859-1.
+ Terminated strings are terminated with $00 if encoded with ISO-8859-1
+ and $00 00 if encoded as unicode. If nothing else is said newline
+ character is forbidden. In ISO-8859-1 a new line is represented, when
+ allowed, with $0A only. Frames that allow different types of text
+ encoding have a text encoding description byte directly after the
+ frame size. If ISO-8859-1 is used this byte should be $00, if Unicode
+ is used it should be $01. Strings dependent on encoding is
+ represented as <text string according to encoding>, or <full text
+ string according to encoding> if newlines are allowed. Any empty
+ Unicode strings which are NULL-terminated may have the Unicode BOM
+ followed by a Unicode NULL ($FF FE 00 00 or $FE FF 00 00).
+
+ The three byte language field is used to describe the language of the
+ frame's content, according to ISO-639-2 [ISO-639-2].
+
+ All URLs [URL] may be relative, e.g. "picture.png", "../doc.txt".
+
+ If a frame is longer than it should be, e.g. having more fields than
+ specified in this document, that indicates that additions to the
+ frame have been made in a later version of the ID3v2 standard. This
+ is reflected by the revision number in the header of the tag.
+
+
+3.3.1. Frame header flags
+
+ In the frame header the size descriptor is followed by two flags
+ bytes. All unused flags must be cleared. The first byte is for
+ 'status messages' and the second byte is for encoding purposes. If an
+ unknown flag is set in the first byte the frame may not be changed
+ without the bit cleared. If an unknown flag is set in the second byte
+ it is likely to not be readable. The flags field is defined as
+ follows.
+
+ %abc00000 %ijk00000
+
+
+ a - Tag alter preservation
+
+ This flag tells the software what to do with this frame if it is
+ unknown and the tag is altered in any way. This applies to all
+ kinds of alterations, including adding more padding and reordering
+ the frames.
+
+ 0 Frame should be preserved.
+ 1 Frame should be discarded.
+
+
+ b - File alter preservation
+
+ This flag tells the software what to do with this frame if it is
+ unknown and the file, excluding the tag, is altered. This does not
+ apply when the audio is completely replaced with other audio data.
+
+ 0 Frame should be preserved.
+ 1 Frame should be discarded.
+
+
+ c - Read only
+
+ This flag, if set, tells the software that the contents of this
+ frame is intended to be read only. Changing the contents might
+ break something, e.g. a signature. If the contents are changed,
+ without knowledge in why the frame was flagged read only and
+ without taking the proper means to compensate, e.g. recalculating
+ the signature, the bit should be cleared.
+
+
+ i - Compression
+
+ This flag indicates whether or not the frame is compressed.
+
+ 0 Frame is not compressed.
+ 1 Frame is compressed using zlib [zlib] with 4 bytes for
+ 'decompressed size' appended to the frame header.
+
+
+ j - Encryption
+
+ This flag indicates wether or not the frame is enrypted. If set
+ one byte indicating with which method it was encrypted will be
+ appended to the frame header. See section 4.26. for more
+ information about encryption method registration.
+
+ 0 Frame is not encrypted.
+ 1 Frame is encrypted.
+
+
+ k - Grouping identity
+
+ This flag indicates whether or not this frame belongs in a group
+ with other frames. If set a group identifier byte is added to the
+ frame header. Every frame with the same group identifier belongs
+ to the same group.
+
+ 0 Frame does not contain group information
+ 1 Frame contains group information
+
+
+ Some flags indicates that the frame header is extended with
+ additional information. This information will be added to the frame
+ header in the same order as the flags indicating the additions. I.e.
+ the four bytes of decompressed size will preceed the encryption
+ method byte. These additions to the frame header, while not included
+ in the frame header size but are included in the 'frame size' field,
+ are not subject to encryption or compression.
+
+
+3.3.2. Default flags
+
+ The default settings for the frames described in this document can be
+ divided into the following classes. The flags may be set differently
+ if found more suitable by the software.
+
+ 1. Discarded if tag is altered, discarded if file is altered.
+
+ None.
+
+ 2. Discarded if tag is altered, preserved if file is altered.
+
+ None.
+
+ 3. Preserved if tag is altered, discarded if file is altered.
+
+ AENC, ETCO, EQUA, MLLT, POSS, SYLT, SYTC, RVAD, TENC, TLEN, TSIZ
+
+ 4. Preserved if tag is altered, preserved if file is altered.
+
+ The rest of the frames.
+
+
+4. Declared ID3v2 frames
+
+ The following frames are declared in this draft.
+
+ 4.21 AENC Audio encryption
+ 4.15 APIC Attached picture
+
+ 4.11 COMM Comments
+ 4.25 COMR Commercial frame
+
+ 4.26 ENCR Encryption method registration
+ 4.13 EQUA Equalization
+ 4.6 ETCO Event timing codes
+
+ 4.16 GEOB General encapsulated object
+ 4.27 GRID Group identification registration
+
+ 4.4 IPLS Involved people list
+
+ 4.21 LINK Linked information
+
+ 4.5 MCDI Music CD identifier
+ 4.7 MLLT MPEG location lookup table
+
+ 4.24 OWNE Ownership frame
+
+ 4.28. PRIV Private frame
+ 4.17 PCNT Play counter
+ 4.18 POPM Popularimeter
+ 4.22 POSS Position synchronisation frame
+
+ 4.19 RBUF Recommended buffer size
+ 4.12 RVAD Relative volume adjustment
+ 4.14 RVRB Reverb
+
+ 4.10 SYLT Synchronized lyric/text
+ 4.8 SYTC Synchronized tempo codes
+
+ 4.2.1 TALB Album/Movie/Show title
+ 4.2.1 TBPM BPM (beats per minute)
+ 4.2.1 TCOM Composer
+ 4.2.1 TCON Content type
+ 4.2.1 TCOP Copyright message
+ 4.2.1 TDAT Date
+ 4.2.1 TDLY Playlist delay
+ 4.2.1 TENC Encoded by
+ 4.2.1 TEXT Lyricist/Text writer
+ 4.2.1 TFLT File type
+ 4.2.1 TIME Time
+ 4.2.1 TIT1 Content group description
+ 4.2.1 TIT2 Title/songname/content description
+ 4.2.1 TIT3 Subtitle/Description refinement
+ 4.2.1 TKEY Initial key
+ 4.2.1 TLAN Language(s)
+ 4.2.1 TLEN Length
+ 4.2.1 TMED Media type
+ 4.2.1 TOAL Original album/movie/show title
+ 4.2.1 TOFN Original filename
+ 4.2.1 TOLY Original lyricist(s)/text writer(s)
+ 4.2.1 TOPE Original artist(s)/performer(s)
+ 4.2.1 TORY Original release year
+ 4.2.1 TOWN File owner/licensee
+ 4.2.1 TPE1 Lead performer(s)/Soloist(s)
+ 4.2.1 TPE2 Band/orchestra/accompaniment
+ 4.2.1 TPE3 Conductor/performer refinement
+ 4.2.1 TPE4 Interpreted, remixed, or otherwise modified by
+ 4.2.1 TPOS Part of a set
+ 4.2.1 TPUB Publisher
+ 4.2.1 TRCK Track number/Position in set
+ 4.2.1 TRDA Recording dates
+ 4.2.1 TRSN Internet radio station name
+ 4.2.1 TRSO Internet radio station owner
+ 4.2.1 TSIZ Size
+ 4.2.1 TSRC ISRC (international standard recording code)
+ 4.2.1 TSSE Software/Hardware and settings used for encoding
+ 4.2.1 TYER Year
+ 4.2.2 TXXX User defined text information frame
+
+ 4.1 UFID Unique file identifier
+ 4.23 USER Terms of use
+ 4.9 USLT Unsychronized lyric/text transcription
+
+ 4.3.1 WCOM Commercial information
+ 4.3.1 WCOP Copyright/Legal information
+ 4.3.1 WOAF Official audio file webpage
+ 4.3.1 WOAR Official artist/performer webpage
+ 4.3.1 WOAS Official audio source webpage
+ 4.3.1 WORS Official internet radio station homepage
+ 4.3.1 WPAY Payment
+ 4.3.1 WPUB Publishers official webpage
+ 4.3.2 WXXX User defined URL link frame
+
+
+4.1. Unique file identifier
+
+ This frame's purpose is to be able to identify the audio file in a
+ database that may contain more information relevant to the content.
+ Since standardisation of such a database is beyond this document, all
+ frames begin with a null-terminated string with a URL [URL]
+ containing an email address, or a link to a location where an email
+ address can be found, that belongs to the organisation responsible
+ for this specific database implementation. Questions regarding the
+ database should be sent to the indicated email address. The URL
+ should not be used for the actual database queries. The string
+ "<a href="http://www.id3.org/dummy/ufid.html">http://www.id3.org/dummy/ufid.html</a>" should be used for tests.
+ Software that isn't told otherwise may safely remove such frames. The
+ 'Owner identifier' must be non-empty (more than just a termination).
+ The 'Owner identifier' is then followed by the actual identifier,
+ which may be up to 64 bytes. There may be more than one "UFID" frame
+ in a tag, but only one with the same 'Owner identifier'.
+
+ <Header for 'Unique file identifier', ID: "UFID">
+ Owner identifier <text string> $00
+ Identifier <up to 64 bytes binary data>
+
+
+4.2. Text information frames
+
+ The text information frames are the most important frames, containing
+ information like artist, album and more. There may only be one text
+ information frame of its kind in an tag. If the textstring is
+ followed by a termination ($00 (00)) all the following information
+ should be ignored and not be displayed. All text frame identifiers
+ begin with "T". Only text frame identifiers begin with "T", with the
+ exception of the "TXXX" frame. All the text information frames have
+ the following format:
+
+ <Header for 'Text information frame', ID: "T000" - "TZZZ",
+ excluding "TXXX" described in 4.2.2.>
+ Text encoding $xx
+ Information <text string according to encoding>
+
+
+4.2.1. Text information frames - details
+
+ TALB
+ The 'Album/Movie/Show title' frame is intended for the title of the
+ recording(/source of sound) which the audio in the file is taken
+ from.
+
+ TBPM
+ The 'BPM' frame contains the number of beats per minute in the
+ mainpart of the audio. The BPM is an integer and represented as a
+ numerical string.
+
+ TCOM
+ The 'Composer(s)' frame is intended for the name of the composer(s).
+ They are seperated with the "/" character.
+
+ TCON
+ The 'Content type', which previously was stored as a one byte numeric
+ value only, is now a numeric string. You may use one or several of
+ the types as ID3v1.1 did or, since the category list would be
+ impossible to maintain with accurate and up to date categories,
+ define your own.
+
+ References to the ID3v1 genres can be made by, as first byte, enter
+ "(" followed by a number from the genres list (appendix A.) and
+ ended with a ")" character. This is optionally followed by a
+ refinement, e.g. "(21)" or "(4)Eurodisco". Several references can be
+ made in the same frame, e.g. "(51)(39)". If the refinement should
+ begin with a "(" character it should be replaced with "((", e.g. "((I
+ can figure out any genre)" or "(55)((I think...)". The following new
+ content types is defined in ID3v2 and is implemented in the same way
+ as the numerig content types, e.g. "(RX)".
+
+ RX Remix
+ CR Cover
+
+ TCOP
+ The 'Copyright message' frame, which must begin with a year and a
+ space character (making five characters), is intended for the
+ copyright holder of the original sound, not the audio file itself.
+ The absence of this frame means only that the copyright information
+ is unavailable or has been removed, and must not be interpreted to
+ mean that the sound is public domain. Every time this field is
+ displayed the field must be preceded with "Copyright " (C) " ", where
+ (C) is one character showing a C in a circle.
+
+ TDAT
+ The 'Date' frame is a numeric string in the DDMM format containing
+ the date for the recording. This field is always four characters
+ long.
+
+ TDLY
+ The 'Playlist delay' defines the numbers of milliseconds of silence
+ between every song in a playlist. The player should use the "ETC"
+ frame, if present, to skip initial silence and silence at the end of
+ the audio to match the 'Playlist delay' time. The time is represented
+ as a numeric string.
+
+ TENC
+ The 'Encoded by' frame contains the name of the person or
+ organisation that encoded the audio file. This field may contain a
+ copyright message, if the audio file also is copyrighted by the
+ encoder.
+
+ TEXT
+ The 'Lyricist(s)/Text writer(s)' frame is intended for the writer(s)
+ of the text or lyrics in the recording. They are seperated with the
+ "/" character.
+
+ TFLT
+ The 'File type' frame indicates which type of audio this tag defines.
+ The following type and refinements are defined:
+
+ MPG MPEG Audio
+ /1 MPEG 1/2 layer I
+ /2 MPEG 1/2 layer II
+ /3 MPEG 1/2 layer III
+ /2.5 MPEG 2.5
+ /AAC Advanced audio compression
+ VQF Transform-domain Weighted Interleave Vector Quantization
+ PCM Pulse Code Modulated audio
+
+ but other types may be used, not for these types though. This is used
+ in a similar way to the predefined types in the "TMED" frame, but
+ without parentheses. If this frame is not present audio type is
+ assumed to be "MPG".
+
+ TIME
+ The 'Time' frame is a numeric string in the HHMM format containing
+ the time for the recording. This field is always four characters
+ long.
+
+ TIT1
+ The 'Content group description' frame is used if the sound belongs to
+ a larger category of sounds/music. For example, classical music is
+ often sorted in different musical sections (e.g. "Piano Concerto",
+ "Weather - Hurricane").
+
+ TIT2
+ The 'Title/Songname/Content description' frame is the actual name of
+ the piece (e.g. "Adagio", "Hurricane Donna").
+
+ TIT3
+ The 'Subtitle/Description refinement' frame is used for information
+ directly related to the contents title (e.g. "Op. 16" or "Performed
+ live at Wembley").
+
+ TKEY
+ The 'Initial key' frame contains the musical key in which the sound
+ starts. It is represented as a string with a maximum length of three
+ characters. The ground keys are represented with "A","B","C","D","E",
+ "F" and "G" and halfkeys represented with "b" and "#". Minor is
+ represented as "m". Example "Cbm". Off key is represented with an "o"
+ only.
+
+ TLAN
+ The 'Language(s)' frame should contain the languages of the text or
+ lyrics spoken or sung in the audio. The language is represented with
+ three characters according to ISO-639-2. If more than one language is
+ used in the text their language codes should follow according to
+ their usage.
+
+ TLEN
+ The 'Length' frame contains the length of the audiofile in
+ milliseconds, represented as a numeric string.
+
+ TMED
+ The 'Media type' frame describes from which media the sound
+ originated. This may be a text string or a reference to the
+ predefined media types found in the list below. References are made
+ within "(" and ")" and are optionally followed by a text refinement,
+ e.g. "(MC) with four channels". If a text refinement should begin
+ with a "(" character it should be replaced with "((" in the same way
+ as in the "TCO" frame. Predefined refinements is appended after the
+ media type, e.g. "(CD/A)" or "(VID/PAL/VHS)".
+
+ DIG Other digital media
+ /A Analog transfer from media
+
+ ANA Other analog media
+ /WAC Wax cylinder
+ /8CA 8-track tape cassette
+
+ CD CD
+ /A Analog transfer from media
+ /DD DDD
+ /AD ADD
+ /AA AAD
+
+ LD Laserdisc
+ /A Analog transfer from media
+
+ TT Turntable records
+ /33 33.33 rpm
+ /45 45 rpm
+ /71 71.29 rpm
+ /76 76.59 rpm
+ /78 78.26 rpm
+ /80 80 rpm
+
+ MD MiniDisc
+ /A Analog transfer from media
+
+ DAT DAT
+ /A Analog transfer from media
+ /1 standard, 48 kHz/16 bits, linear
+ /2 mode 2, 32 kHz/16 bits, linear
+ /3 mode 3, 32 kHz/12 bits, nonlinear, low speed
+ /4 mode 4, 32 kHz/12 bits, 4 channels
+ /5 mode 5, 44.1 kHz/16 bits, linear
+ /6 mode 6, 44.1 kHz/16 bits, 'wide track' play
+
+ DCC DCC
+ /A Analog transfer from media
+
+ DVD DVD
+ /A Analog transfer from media
+
+ TV Television
+ /PAL PAL
+ /NTSC NTSC
+ /SECAM SECAM
+
+ VID Video
+ /PAL PAL
+ /NTSC NTSC
+ /SECAM SECAM
+ /VHS VHS
+ /SVHS S-VHS
+ /BETA BETAMAX
+
+ RAD Radio
+ /FM FM
+ /AM AM
+ /LW LW
+ /MW MW
+
+ TEL Telephone
+ /I ISDN
+
+ MC MC (normal cassette)
+ /4 4.75 cm/s (normal speed for a two sided cassette)
+ /9 9.5 cm/s
+ /I Type I cassette (ferric/normal)
+ /II Type II cassette (chrome)
+ /III Type III cassette (ferric chrome)
+ /IV Type IV cassette (metal)
+
+ REE Reel
+ /9 9.5 cm/s
+ /19 19 cm/s
+ /38 38 cm/s
+ /76 76 cm/s
+ /I Type I cassette (ferric/normal)
+ /II Type II cassette (chrome)
+ /III Type III cassette (ferric chrome)
+ /IV Type IV cassette (metal)
+
+ TOAL
+ The 'Original album/movie/show title' frame is intended for the title
+ of the original recording (or source of sound), if for example the
+ music in the file should be a cover of a previously released song.
+
+ TOFN
+ The 'Original filename' frame contains the preferred filename for the
+ file, since some media doesn't allow the desired length of the
+ filename. The filename is case sensitive and includes its suffix.
+
+ TOLY
+ The 'Original lyricist(s)/text writer(s)' frame is intended for the
+ text writer(s) of the original recording, if for example the music in
+ the file should be a cover of a previously released song. The text
+ writers are seperated with the "/" character.
+
+ TOPE
+ The 'Original artist(s)/performer(s)' frame is intended for the
+ performer(s) of the original recording, if for example the music in
+ the file should be a cover of a previously released song. The
+ performers are seperated with the "/" character.
+
+ TORY
+ The 'Original release year' frame is intended for the year when the
+ original recording, if for example the music in the file should be a
+ cover of a previously released song, was released. The field is
+ formatted as in the "TYER" frame.
+
+ TOWN
+ The 'File owner/licensee' frame contains the name of the owner or
+ licensee of the file and it's contents.
+
+ TPE1
+ The 'Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group' is
+ used for the main artist(s). They are seperated with the "/"
+ character.
+
+ TPE2
+ The 'Band/Orchestra/Accompaniment' frame is used for additional
+ information about the performers in the recording.
+
+ TPE3
+ The 'Conductor' frame is used for the name of the conductor.
+
+ TPE4
+ The 'Interpreted, remixed, or otherwise modified by' frame contains
+ more information about the people behind a remix and similar
+ interpretations of another existing piece.
+
+ TPOS
+ The 'Part of a set' frame is a numeric string that describes which
+ part of a set the audio came from. This frame is used if the source
+ described in the "TALB" frame is divided into several mediums, e.g. a
+ double CD. The value may be extended with a "/" character and a
+ numeric string containing the total number of parts in the set. E.g.
+ "1/2".
+
+ TPUB
+ The 'Publisher' frame simply contains the name of the label or
+ publisher.
+
+ TRCK
+ The 'Track number/Position in set' frame is a numeric string
+ containing the order number of the audio-file on its original
+ recording. This may be extended with a "/" character and a numeric
+ string containing the total numer of tracks/elements on the original
+ recording. E.g. "4/9".
+
+ TRDA
+ The 'Recording dates' frame is a intended to be used as complement to
+ the "TYER", "TDAT" and "TIME" frames. E.g. "4th-7th June, 12th June"
+ in combination with the "TYER" frame.
+
+ TRSN
+ The 'Internet radio station name' frame contains the name of the
+ internet radio station from which the audio is streamed.
+
+ TRSO
+ The 'Internet radio station owner' frame contains the name of the
+ owner of the internet radio station from which the audio is
+ streamed.
+
+ TSIZ
+ The 'Size' frame contains the size of the audiofile in bytes,
+ excluding the ID3v2 tag, represented as a numeric string.
+
+ TSRC
+ The 'ISRC' frame should contain the International Standard Recording
+ Code [ISRC] (12 characters).
+
+ TSSE
+ The 'Software/Hardware and settings used for encoding' frame
+ includes the used audio encoder and its settings when the file was
+ encoded. Hardware refers to hardware encoders, not the computer on
+ which a program was run.
+
+ TYER
+ The 'Year' frame is a numeric string with a year of the recording.
+ This frames is always four characters long (until the year 10000).
+
+
+4.2.2. User defined text information frame
+
+ This frame is intended for one-string text information concerning the
+ audiofile in a similar way to the other "T"-frames. The frame body
+ consists of a description of the string, represented as a terminated
+ string, followed by the actual string. There may be more than one
+ "TXXX" frame in each tag, but only one with the same description.
+
+ <Header for 'User defined text information frame', ID: "TXXX">
+ Text encoding $xx
+ Description <text string according to encoding> $00 (00)
+ Value <text string according to encoding>
+
+
+4.3. URL link frames
+
+ With these frames dynamic data such as webpages with touring
+ information, price information or plain ordinary news can be added to
+ the tag. There may only be one URL [URL] link frame of its kind in an
+ tag, except when stated otherwise in the frame description. If the
+ textstring is followed by a termination ($00 (00)) all the following
+ information should be ignored and not be displayed. All URL link
+ frame identifiers begins with "W". Only URL link frame identifiers
+ begins with "W". All URL link frames have the following format:
+
+ <Header for 'URL link frame', ID: "W000" - "WZZZ", excluding "WXXX"
+ described in 4.3.2.>
+ URL <text string>
+
+
+4.3.1. URL link frames - details
+
+ WCOM
+ The 'Commercial information' frame is a URL pointing at a webpage
+ with information such as where the album can be bought. There may be
+ more than one "WCOM" frame in a tag, but not with the same content.
+
+ WCOP
+ The 'Copyright/Legal information' frame is a URL pointing at a
+ webpage where the terms of use and ownership of the file is
+ described.
+
+ WOAF
+ The 'Official audio file webpage' frame is a URL pointing at a file
+ specific webpage.
+
+ WOAR
+ The 'Official artist/performer webpage' frame is a URL pointing at
+ the artists official webpage. There may be more than one "WOAR" frame
+ in a tag if the audio contains more than one performer, but not with
+ the same content.
+
+ WOAS
+ The 'Official audio source webpage' frame is a URL pointing at the
+ official webpage for the source of the audio file, e.g. a movie.
+
+ WORS
+ The 'Official internet radio station homepage' contains a URL
+ pointing at the homepage of the internet radio station.
+
+ WPAY
+ The 'Payment' frame is a URL pointing at a webpage that will handle
+ the process of paying for this file.
+
+ WPUB
+ The 'Publishers official webpage' frame is a URL pointing at the
+ official wepage for the publisher.
+
+
+4.3.2. User defined URL link frame
+
+ This frame is intended for URL [URL] links concerning the audiofile
+ in a similar way to the other "W"-frames. The frame body consists
+ of a description of the string, represented as a terminated string,
+ followed by the actual URL. The URL is always encoded with ISO-8859-1
+ [ISO-8859-1]. There may be more than one "WXXX" frame in each tag,
+ but only one with the same description.
+
+ <Header for 'User defined URL link frame', ID: "WXXX">
+ Text encoding $xx
+ Description <text string according to encoding> $00 (00)
+ URL <text string>
+
+
+4.4. Involved people list
+
+ Since there might be a lot of people contributing to an audio file in
+ various ways, such as musicians and technicians, the 'Text
+ information frames' are often insufficient to list everyone involved
+ in a project. The 'Involved people list' is a frame containing the
+ names of those involved, and how they were involved. The body simply
+ contains a terminated string with the involvement directly followed
+ by a terminated string with the involvee followed by a new
+ involvement and so on. There may only be one "IPLS" frame in each
+ tag.
+
+ <Header for 'Involved people list', ID: "IPLS">
+ Text encoding $xx
+ People list strings <text strings according to encoding>
+
+
+4.5. Music CD identifier
+
+ This frame is intended for music that comes from a CD, so that the CD
+ can be identified in databases such as the CDDB [CDDB]. The frame
+ consists of a binary dump of the Table Of Contents, TOC, from the CD,
+ which is a header of 4 bytes and then 8 bytes/track on the CD plus 8
+ bytes for the 'lead out' making a maximum of 804 bytes. The offset to
+ the beginning of every track on the CD should be described with a
+ four bytes absolute CD-frame address per track, and not with absolute
+ time. This frame requires a present and valid "TRCK" frame, even if
+ the CD's only got one track. There may only be one "MCDI" frame in
+ each tag.
+
+ <Header for 'Music CD identifier', ID: "MCDI">
+ CD TOC <binary data>
+
+
+4.6. Event timing codes
+
+ This frame allows synchronisation with key events in a song or sound.
+ The header is:
+
+ <Header for 'Event timing codes', ID: "ETCO">
+ Time stamp format $xx
+
+ Where time stamp format is:
+
+ $01 Absolute time, 32 bit sized, using MPEG [MPEG] frames as unit
+ $02 Absolute time, 32 bit sized, using milliseconds as unit
+
+ Abolute time means that every stamp contains the time from the
+ beginning of the file.
+
+ Followed by a list of key events in the following format:
+
+ Type of event $xx
+ Time stamp $xx (xx ...)
+
+ The 'Time stamp' is set to zero if directly at the beginning of the
+ sound or after the previous event. All events should be sorted in
+ chronological order. The type of event is as follows:
+
+ $00 padding (has no meaning)
+ $01 end of initial silence
+ $02 intro start
+ $03 mainpart start
+ $04 outro start
+ $05 outro end
+ $06 verse start
+ $07 refrain start
+ $08 interlude start
+ $09 theme start
+ $0A variation start
+ $0B key change
+ $0C time change
+ $0D momentary unwanted noise (Snap, Crackle & Pop)
+ $0E sustained noise
+ $0F sustained noise end
+ $10 intro end
+ $11 mainpart end
+ $12 verse end
+ $13 refrain end
+ $14 theme end
+
+ $15-$DF reserved for future use
+
+ $E0-$EF not predefined sync 0-F
+
+ $F0-$FC reserved for future use
+
+ $FD audio end (start of silence)
+ $FE audio file ends
+ $FF one more byte of events follows (all the following bytes with
+ the value $FF have the same function)
+
+ Terminating the start events such as "intro start" is not required.
+ The 'Not predefined sync's ($E0-EF) are for user events. You might
+ want to synchronise your music to something, like setting of an
+ explosion on-stage, turning on your screensaver etc.
+
+ There may only be one "ETCO" frame in each tag.
+
+
+4.7. MPEG location lookup table
+
+ To increase performance and accuracy of jumps within a MPEG [MPEG]
+ audio file, frames with timecodes in different locations in the file
+ might be useful. The ID3v2 frame includes references that the
+ software can use to calculate positions in the file. After the frame
+ header is a descriptor of how much the 'frame counter' should
+ increase for every reference. If this value is two then the first
+ reference points out the second frame, the 2nd reference the 4th
+ frame, the 3rd reference the 6th frame etc. In a similar way the
+ 'bytes between reference' and 'milliseconds between reference' points
+ out bytes and milliseconds respectively.
+
+ Each reference consists of two parts; a certain number of bits, as
+ defined in 'bits for bytes deviation', that describes the difference
+ between what is said in 'bytes between reference' and the reality and
+ a certain number of bits, as defined in 'bits for milliseconds
+ deviation', that describes the difference between what is said in
+ 'milliseconds between reference' and the reality. The number of bits
+ in every reference, i.e. 'bits for bytes deviation'+'bits for
+ milliseconds deviation', must be a multiple of four. There may only
+ be one "MLLT" frame in each tag.
+
+ <Header for 'Location lookup table', ID: "MLLT">
+ MPEG frames between reference $xx xx
+ Bytes between reference $xx xx xx
+ Milliseconds between reference $xx xx xx
+ Bits for bytes deviation $xx
+ Bits for milliseconds dev. $xx
+
+ Then for every reference the following data is included;
+
+ Deviation in bytes %xxx....
+ Deviation in milliseconds %xxx....
+
+
+4.8. Synchronised tempo codes
+
+ For a more accurate description of the tempo of a musical piece this
+ frame might be used. After the header follows one byte describing
+ which time stamp format should be used. Then follows one or more
+ tempo codes. Each tempo code consists of one tempo part and one time
+ part. The tempo is in BPM described with one or two bytes. If the
+ first byte has the value $FF, one more byte follows, which is added
+ to the first giving a range from 2 - 510 BPM, since $00 and $01 is
+ reserved. $00 is used to describe a beat-free time period, which is
+ not the same as a music-free time period. $01 is used to indicate one
+ single beat-stroke followed by a beat-free period.
+
+ The tempo descriptor is followed by a time stamp. Every time the
+ tempo in the music changes, a tempo descriptor may indicate this for
+ the player. All tempo descriptors should be sorted in chronological
+ order. The first beat-stroke in a time-period is at the same time as
+ the beat description occurs. There may only be one "SYTC" frame in
+ each tag.
+
+ <Header for 'Synchronised tempo codes', ID: "SYTC">
+ Time stamp format $xx
+ Tempo data <binary data>
+
+ Where time stamp format is:
+
+ $01 Absolute time, 32 bit sized, using MPEG [MPEG] frames as unit
+ $02 Absolute time, 32 bit sized, using milliseconds as unit
+
+ Abolute time means that every stamp contains the time from the
+ beginning of the file.
+
+
+4.9. Unsychronised lyrics/text transcription
+
+ This frame contains the lyrics of the song or a text transcription of
+ other vocal activities. The head includes an encoding descriptor and
+ a content descriptor. The body consists of the actual text. The
+ 'Content descriptor' is a terminated string. If no descriptor is
+ entered, 'Content descriptor' is $00 (00) only. Newline characters
+ are allowed in the text. There may be more than one 'Unsynchronised
+ lyrics/text transcription' frame in each tag, but only one with the
+ same language and content descriptor.
+
+ <Header for 'Unsynchronised lyrics/text transcription', ID: "USLT">
+ Text encoding $xx
+ Language $xx xx xx
+ Content descriptor <text string according to encoding> $00 (00)
+ Lyrics/text <full text string according to encoding>
+
+
+4.10. Synchronised lyrics/text
+
+ This is another way of incorporating the words, said or sung lyrics,
+ in the audio file as text, this time, however, in sync with the
+ audio. It might also be used to describing events e.g. occurring on a
+ stage or on the screen in sync with the audio. The header includes a
+ content descriptor, represented with as terminated textstring. If no
+ descriptor is entered, 'Content descriptor' is $00 (00) only.
+
+ <Header for 'Synchronised lyrics/text', ID: "SYLT">
+ Text encoding $xx
+ Language $xx xx xx
+ Time stamp format $xx
+ Content type $xx
+ Content descriptor <text string according to encoding> $00 (00)
+
+
+ Encoding: $00 ISO-8859-1 [ISO-8859-1] character set is used => $00
+ is sync identifier.
+ $01 Unicode [UNICODE] character set is used => $00 00 is
+ sync identifier.
+
+ Content type: $00 is other
+ $01 is lyrics
+ $02 is text transcription
+ $03 is movement/part name (e.g. "Adagio")
+ $04 is events (e.g. "Don Quijote enters the stage")
+ $05 is chord (e.g. "Bb F Fsus")
+ $06 is trivia/'pop up' information
+
+ Time stamp format is:
+
+ $01 Absolute time, 32 bit sized, using MPEG [MPEG] frames as unit
+ $02 Absolute time, 32 bit sized, using milliseconds as unit
+
+ Abolute time means that every stamp contains the time from the
+ beginning of the file.
+
+ The text that follows the frame header differs from that of the
+ unsynchronised lyrics/text transcription in one major way. Each
+ syllable (or whatever size of text is considered to be convenient by
+ the encoder) is a null terminated string followed by a time stamp
+ denoting where in the sound file it belongs. Each sync thus has the
+ following structure:
+
+ Terminated text to be synced (typically a syllable)
+ Sync identifier (terminator to above string) $00 (00)
+ Time stamp $xx (xx ...)
+
+ The 'time stamp' is set to zero or the whole sync is omitted if
+ located directly at the beginning of the sound. All time stamps
+ should be sorted in chronological order. The sync can be considered
+ as a validator of the subsequent string.
+
+ Newline ($0A) characters are allowed in all "SYLT" frames and should
+ be used after every entry (name, event etc.) in a frame with the
+ content type $03 - $04.
+
+ A few considerations regarding whitespace characters: Whitespace
+ separating words should mark the beginning of a new word, thus
+ occurring in front of the first syllable of a new word. This is also
+ valid for new line characters. A syllable followed by a comma should
+ not be broken apart with a sync (both the syllable and the comma
+ should be before the sync).
+
+ An example: The "USLT" passage
+
+ "Strangers in the night" $0A "Exchanging glances"
+
+ would be "SYLT" encoded as:
+
+ "Strang" $00 xx xx "ers" $00 xx xx " in" $00 xx xx " the" $00 xx xx
+ " night" $00 xx xx 0A "Ex" $00 xx xx "chang" $00 xx xx "ing" $00 xx
+ xx "glan" $00 xx xx "ces" $00 xx xx
+
+ There may be more than one "SYLT" frame in each tag, but only one
+ with the same language and content descriptor.
+
+
+4.11. Comments
+
+ This frame is indended for any kind of full text information that
+ does not fit in any other frame. It consists of a frame header
+ followed by encoding, language and content descriptors and is ended
+ with the actual comment as a text string. Newline characters are
+ allowed in the comment text string. There may be more than one
+ comment frame in each tag, but only one with the same language and
+ content descriptor.
+
+ <Header for 'Comment', ID: "COMM">
+ Text encoding $xx
+ Language $xx xx xx
+ Short content descrip. <text string according to encoding> $00 (00)
+ The actual text <full text string according to encoding>
+
+
+4.12. Relative volume adjustment
+
+ This is a more subjective function than the previous ones. It allows
+ the user to say how much he wants to increase/decrease the volume on
+ each channel while the file is played. The purpose is to be able to
+ align all files to a reference volume, so that you don't have to
+ change the volume constantly. This frame may also be used to balance
+ adjust the audio. If the volume peak levels are known then this could
+ be described with the 'Peak volume right' and 'Peak volume left'
+ field. If Peakvolume is not known these fields could be left zeroed
+ or, if no other data follows, be completely omitted. There may only
+ be one "RVAD" frame in each tag.
+
+ <Header for 'Relative volume adjustment', ID: "RVAD">
+ Increment/decrement %00xxxxxx
+ Bits used for volume descr. $xx
+ Relative volume change, right $xx xx (xx ...)
+ Relative volume change, left $xx xx (xx ...)
+ Peak volume right $xx xx (xx ...)
+ Peak volume left $xx xx (xx ...)
+
+ In the increment/decrement field bit 0 is used to indicate the right
+ channel and bit 1 is used to indicate the left channel. 1 is
+ increment and 0 is decrement.
+
+ The 'bits used for volume description' field is normally $10 (16
+ bits) for MPEG 2 layer I, II and III [MPEG] and MPEG 2.5. This value
+ may not be $00. The volume is always represented with whole bytes,
+ padded in the beginning (highest bits) when 'bits used for volume
+ description' is not a multiple of eight.
+
+ This datablock is then optionally followed by a volume definition for
+ the left and right back channels. If this information is appended to
+ the frame the first two channels will be treated as front channels.
+ In the increment/decrement field bit 2 is used to indicate the right
+ back channel and bit 3 for the left back channel.
+
+ Relative volume change, right back $xx xx (xx ...)
+ Relative volume change, left back $xx xx (xx ...)
+ Peak volume right back $xx xx (xx ...)
+ Peak volume left back $xx xx (xx ...)
+
+ If the center channel adjustment is present the following is appended
+ to the existing frame, after the left and right back channels. The
+ center channel is represented by bit 4 in the increase/decrease
+ field.
+
+ Relative volume change, center $xx xx (xx ...)
+ Peak volume center $xx xx (xx ...)
+
+ If the bass channel adjustment is present the following is appended
+ to the existing frame, after the center channel. The bass channel is
+ represented by bit 5 in the increase/decrease field.
+
+ Relative volume change, bass $xx xx (xx ...)
+ Peak volume bass $xx xx (xx ...)
+
+
+4.13. Equalisation
+
+ This is another subjective, alignment frame. It allows the user to
+ predefine an equalisation curve within the audio file. There may only
+ be one "EQUA" frame in each tag.
+
+ <Header of 'Equalisation', ID: "EQUA">
+ Adjustment bits $xx
+
+ The 'adjustment bits' field defines the number of bits used for
+ representation of the adjustment. This is normally $10 (16 bits) for
+ MPEG 2 layer I, II and III [MPEG] and MPEG 2.5. This value may not be
+ $00.
+
+ This is followed by 2 bytes + ('adjustment bits' rounded up to the
+ nearest byte) for every equalisation band in the following format,
+ giving a frequency range of 0 - 32767Hz:
+
+ Increment/decrement %x (MSB of the Frequency)
+ Frequency (lower 15 bits)
+ Adjustment $xx (xx ...)
+
+ The increment/decrement bit is 1 for increment and 0 for decrement.
+ The equalisation bands should be ordered increasingly with reference
+ to frequency. All frequencies don't have to be declared. The
+ equalisation curve in the reading software should be interpolated
+ between the values in this frame. Three equal adjustments for three
+ subsequent frequencies. A frequency should only be described once in
+ the frame.
+
+
+4.14. Reverb
+
+ Yet another subjective one. You may here adjust echoes of different
+ kinds. Reverb left/right is the delay between every bounce in ms.
+ Reverb bounces left/right is the number of bounces that should be
+ made. $FF equals an infinite number of bounces. Feedback is the
+ amount of volume that should be returned to the next echo bounce. $00
+ is 0%, $FF is 100%. If this value were $7F, there would be 50% volume
+ reduction on the first bounce, 50% of that on the second and so on.
+ Left to left means the sound from the left bounce to be played in the
+ left speaker, while left to right means sound from the left bounce to
+ be played in the right speaker.
+
+ 'Premix left to right' is the amount of left sound to be mixed in the
+ right before any reverb is applied, where $00 id 0% and $FF is 100%.
+ 'Premix right to left' does the same thing, but right to left.
+ Setting both premix to $FF would result in a mono output (if the
+ reverb is applied symmetric). There may only be one "RVRB" frame in
+ each tag.
+
+ <Header for 'Reverb', ID: "RVRB">
+ Reverb left (ms) $xx xx
+ Reverb right (ms) $xx xx
+ Reverb bounces, left $xx
+ Reverb bounces, right $xx
+ Reverb feedback, left to left $xx
+ Reverb feedback, left to right $xx
+ Reverb feedback, right to right $xx
+ Reverb feedback, right to left $xx
+ Premix left to right $xx
+ Premix right to left $xx
+
+
+4.15. Attached picture
+
+ This frame contains a picture directly related to the audio file.
+ Image format is the MIME type and subtype [MIME] for the image. In
+ the event that the MIME media type name is omitted, "image/" will be
+ implied. The "image/png" [PNG] or "image/jpeg" [JFIF] picture format
+ should be used when interoperability is wanted. Description is a
+ short description of the picture, represented as a terminated
+ textstring. The description has a maximum length of 64 characters,
+ but may be empty. There may be several pictures attached to one file,
+ each in their individual "APIC" frame, but only one with the same
+ content descriptor. There may only be one picture with the picture
+ type declared as picture type $01 and $02 respectively. There is the
+ possibility to put only a link to the image file by using the 'MIME
+ type' "-->" and having a complete URL [URL] instead of picture data.
+ The use of linked files should however be used sparingly since there
+ is the risk of separation of files.
+
+ <Header for 'Attached picture', ID: "APIC">
+ Text encoding $xx
+ MIME type <text string> $00
+ Picture type $xx
+ Description <text string according to encoding> $00 (00)
+ Picture data <binary data>
+
+
+ Picture type: $00 Other
+ $01 32x32 pixels 'file icon' (PNG only)
+ $02 Other file icon
+ $03 Cover (front)
+ $04 Cover (back)
+ $05 Leaflet page
+ $06 Media (e.g. lable side of CD)
+ $07 Lead artist/lead performer/soloist
+ $08 Artist/performer
+ $09 Conductor
+ $0A Band/Orchestra
+ $0B Composer
+ $0C Lyricist/text writer
+ $0D Recording Location
+ $0E During recording
+ $0F During performance
+ $10 Movie/video screen capture
+ $11 A bright coloured fish
+ $12 Illustration
+ $13 Band/artist logotype
+ $14 Publisher/Studio logotype
+
+
+4.16. General encapsulated object
+
+ In this frame any type of file can be encapsulated. After the header,
+ 'Frame size' and 'Encoding' follows 'MIME type' [MIME] represented as
+ as a terminated string encoded with ISO 8859-1 [ISO-8859-1]. The
+ filename is case sensitive and is encoded as 'Encoding'. Then follows
+ a content description as terminated string, encoded as 'Encoding'.
+ The last thing in the frame is the actual object. The first two
+ strings may be omitted, leaving only their terminations. MIME type is
+ always an ISO-8859-1 text string. There may be more than one "GEOB"
+ frame in each tag, but only one with the same content descriptor.
+
+ <Header for 'General encapsulated object', ID: "GEOB">
+ Text encoding $xx
+ MIME type <text string> $00
+ Filename <text string according to encoding> $00 (00)
+ Content description <text string according to encóding> $00 (00)
+ Encapsulated object <binary data>
+
+
+4.17. Play counter
+
+ This is simply a counter of the number of times a file has been
+ played. The value is increased by one every time the file begins to
+ play. There may only be one "PCNT" frame in each tag. When the
+ counter reaches all one's, one byte is inserted in front of the
+ counter thus making the counter eight bits bigger. The counter must
+ be at least 32-bits long to begin with.
+
+ <Header for 'Play counter', ID: "PCNT">
+ Counter $xx xx xx xx (xx ...)
+
+
+4.18. Popularimeter
+
+ The purpose of this frame is to specify how good an audio file is.
+ Many interesting applications could be found to this frame such as a
+ playlist that features better audiofiles more often than others or it
+ could be used to profile a person's taste and find other 'good' files
+ by comparing people's profiles. The frame is very simple. It contains
+ the email address to the user, one rating byte and a four byte play
+ counter, intended to be increased with one for every time the file is
+ played. The email is a terminated string. The rating is 1-255 where
+ 1 is worst and 255 is best. 0 is unknown. If no personal counter is
+ wanted it may be omitted. When the counter reaches all one's, one
+ byte is inserted in front of the counter thus making the counter
+ eight bits bigger in the same away as the play counter ("PCNT").
+ There may be more than one "POPM" frame in each tag, but only one
+ with the same email address.
+
+ <Header for 'Popularimeter', ID: "POPM">
+ Email to user <text string> $00
+ Rating $xx
+ Counter $xx xx xx xx (xx ...)
+
+
+4.19. Recommended buffer size
+
+ Sometimes the server from which a audio file is streamed is aware of
+ transmission or coding problems resulting in interruptions in the
+ audio stream. In these cases, the size of the buffer can be
+ recommended by the server using this frame. If the 'embedded info
+ flag' is true (1) then this indicates that an ID3 tag with the
+ maximum size described in 'Buffer size' may occur in the audiostream.
+ In such case the tag should reside between two MPEG [MPEG] frames, if
+ the audio is MPEG encoded. If the position of the next tag is known,
+ 'offset to next tag' may be used. The offset is calculated from the
+ end of tag in which this frame resides to the first byte of the
+ header in the next. This field may be omitted. Embedded tags are
+ generally not recommended since this could render unpredictable
+ behaviour from present software/hardware.
+
+ For applications like streaming audio it might be an idea to embed
+ tags into the audio stream though. If the clients connects to
+ individual connections like HTTP and there is a possibility to begin
+ every transmission with a tag, then this tag should include a
+ 'recommended buffer size' frame. If the client is connected to a
+ arbitrary point in the stream, such as radio or multicast, then the
+ 'recommended buffer size' frame should be included in every tag.
+ Every tag that is picked up after the initial/first tag is to be
+ considered as an update of the previous one. E.g. if there is a
+ "TIT2" frame in the first received tag and one in the second tag,
+ then the first should be 'replaced' with the second.
+
+ The 'Buffer size' should be kept to a minimum. There may only be one
+ "RBUF" frame in each tag.
+
+ <Header for 'Recommended buffer size', ID: "RBUF">
+ Buffer size $xx xx xx
+ Embedded info flag %0000000x
+ Offset to next tag $xx xx xx xx
+
+
+4.20. Audio encryption
+
+ This frame indicates if the actual audio stream is encrypted, and by
+ whom. Since standardisation of such encrypion scheme is beyond this
+ document, all "AENC" frames begin with a terminated string with a
+ URL containing an email address, or a link to a location where an
+ email address can be found, that belongs to the organisation
+ responsible for this specific encrypted audio file. Questions
+ regarding the encrypted audio should be sent to the email address
+ specified. If a $00 is found directly after the 'Frame size' and the
+ audiofile indeed is encrypted, the whole file may be considered
+ useless.
+
+ After the 'Owner identifier', a pointer to an unencrypted part of the
+ audio can be specified. The 'Preview start' and 'Preview length' is
+ described in frames. If no part is unencrypted, these fields should
+ be left zeroed. After the 'preview length' field follows optionally a
+ datablock required for decryption of the audio. There may be more
+ than one "AENC" frames in a tag, but only one with the same 'Owner
+ identifier'.
+
+ <Header for 'Audio encryption', ID: "AENC">
+ Owner identifier <text string> $00
+ Preview start $xx xx
+ Preview length $xx xx
+ Encryption info <binary data>
+
+
+4.21. Linked information
+
+ To keep space waste as low as possible this frame may be used to link
+ information from another ID3v2 tag that might reside in another audio
+ file or alone in a binary file. It is recommended that this method is
+ only used when the files are stored on a CD-ROM or other
+ circumstances when the risk of file seperation is low. The frame
+ contains a frame identifier, which is the frame that should be linked
+ into this tag, a URL [URL] field, where a reference to the file where
+ the frame is given, and additional ID data, if needed. Data should be
+ retrieved from the first tag found in the file to which this link
+ points. There may be more than one "LINK" frame in a tag, but only
+ one with the same contents. A linked frame is to be considered as
+ part of the tag and has the same restrictions as if it was a physical
+ part of the tag (i.e. only one "RVRB" frame allowed, whether it's
+ linked or not).
+
+ <Header for 'Linked information', ID: "LINK">
+ Frame identifier $xx xx xx
+ URL <text string> $00
+ ID and additional data <text string(s)>
+
+ Frames that may be linked and need no additional data are "IPLS",
+ "MCID", "ETCO", "MLLT", "SYTC", "RVAD", "EQUA", "RVRB", "RBUF", the
+ text information frames and the URL link frames.
+
+ The "TXXX", "APIC", "GEOB" and "AENC" frames may be linked with
+ the content descriptor as additional ID data.
+
+ The "COMM", "SYLT" and "USLT" frames may be linked with three bytes
+ of language descriptor directly followed by a content descriptor as
+ additional ID data.
+
+
+4.22. Position synchronisation frame
+
+ This frame delivers information to the listener of how far into the
+ audio stream he picked up; in effect, it states the time offset of
+ the first frame in the stream. The frame layout is:
+
+ <Head for 'Position synchronisation', ID: "POSS">
+ Time stamp format $xx
+ Position $xx (xx ...)
+
+ Where time stamp format is:
+
+ $01 Absolute time, 32 bit sized, using MPEG frames as unit
+ $02 Absolute time, 32 bit sized, using milliseconds as unit
+
+ and position is where in the audio the listener starts to receive,
+ i.e. the beginning of the next frame. If this frame is used in the
+ beginning of a file the value is always 0. There may only be one
+ "POSS" frame in each tag.
+
+
+4.23. Terms of use frame
+
+ This frame contains a brief description of the terms of use and
+ ownership of the file. More detailed information concerning the legal
+ terms might be available through the "WCOP" frame. Newlines are
+ allowed in the text. There may only be one "USER" frame in a tag.
+
+ <Header for 'Terms of use frame', ID: "USER">
+ Text encoding $xx
+ Language $xx xx xx
+ The actual text <text string according to encoding>
+
+
+4.24. Ownership frame
+
+ The ownership frame might be used as a reminder of a made transaction
+ or, if signed, as proof. Note that the "USER" and "TOWN" frames are
+ good to use in conjunction with this one. The frame begins, after the
+ frame ID, size and encoding fields, with a 'price payed' field. The
+ first three characters of this field contains the currency used for
+ the transaction, encoded according to ISO 4217 [ISO-4217] alphabetic
+ currency code. Concatenated to this is the actual price payed, as a
+ numerical string using "." as the decimal separator. Next is an 8
+ character date string (YYYYMMDD) followed by a string with the name
+ of the seller as the last field in the frame. There may only be one
+ "OWNE" frame in a tag.
+
+ <Header for 'Ownership frame', ID: "OWNE">
+ Text encoding $xx
+ Price payed <text string> $00
+ Date of purch. <text string>
+ Seller <text string according to encoding>
+
+
+4.25. Commercial frame
+
+ This frame enables several competing offers in the same tag by
+ bundling all needed information. That makes this frame rather complex
+ but it's an easier solution than if one tries to achieve the same
+ result with several frames. The frame begins, after the frame ID,
+ size and encoding fields, with a price string field. A price is
+ constructed by one three character currency code, encoded according
+ to ISO 4217 [ISO-4217] alphabetic currency code, followed by a
+ numerical value where "." is used as decimal seperator. In the price
+ string several prices may be concatenated, seperated by a "/"
+ character, but there may only be one currency of each type.
+
+ The price string is followed by an 8 character date string in the
+ format YYYYMMDD, describing for how long the price is valid. After
+ that is a contact URL, with which the user can contact the seller,
+ followed by a one byte 'received as' field. It describes how the
+ audio is delivered when bought according to the following list:
+
+ $00 Other
+ $01 Standard CD album with other songs
+ $02 Compressed audio on CD
+ $03 File over the Internet
+ $04 Stream over the Internet
+ $05 As note sheets
+ $06 As note sheets in a book with other sheets
+ $07 Music on other media
+ $08 Non-musical merchandise
+
+ Next follows a terminated string with the name of the seller followed
+ by a terminated string with a short description of the product. The
+ last thing is the ability to include a company logotype. The first of
+ them is the 'Picture MIME type' field containing information about
+ which picture format is used. In the event that the MIME media type
+ name is omitted, "image/" will be implied. Currently only "image/png"
+ and "image/jpeg" are allowed. This format string is followed by the
+ binary picture data. This two last fields may be omitted if no
+ picture is to attach.
+
+ <Header for 'Commercial frame', ID: "COMR">
+ Text encoding $xx
+ Price string <text string> $00
+ Valid until <text string>
+ Contact URL <text string> $00
+ Received as $xx
+ Name of seller <text string according to encoding> $00 (00)
+ Description <text string according to encoding> $00 (00)
+ Picture MIME type <string> $00
+ Seller logo <binary data>
+
+
+4.26. Encryption method registration
+
+ To identify with which method a frame has been encrypted the
+ encryption method must be registered in the tag with this frame. The
+ 'Owner identifier' is a null-terminated string with a URL [URL]
+ containing an email address, or a link to a location where an email
+ address can be found, that belongs to the organisation responsible
+ for this specific encryption method. Questions regarding the
+ encryption method should be sent to the indicated email address. The
+ 'Method symbol' contains a value that is associated with this method
+ throughout the whole tag. Values below $80 are reserved. The 'Method
+ symbol' may optionally be followed by encryption specific data. There
+ may be several "ENCR" frames in a tag but only one containing the
+ same symbol and only one containing the same owner identifier. The
+ method must be used somewhere in the tag. See section 3.3.1, flag j
+ for more information.
+
+ <Header for 'Encryption method registration', ID: "ENCR">
+ Owner identifier <text string> $00
+ Method symbol $xx
+ Encryption data <binary data>
+
+
+4.27. Group identification registration
+
+ This frame enables grouping of otherwise unrelated frames. This can
+ be used when some frames are to be signed. To identify which frames
+ belongs to a set of frames a group identifier must be registered in
+ the tag with this frame. The 'Owner identifier' is a null-terminated
+ string with a URL [URL] containing an email address, or a link to a
+ location where an email address can be found, that belongs to the
+ organisation responsible for this grouping. Questions regarding the
+ grouping should be sent to the indicated email address. The 'Group
+ symbol' contains a value that associates the frame with this group
+ throughout the whole tag. Values below $80 are reserved. The 'Group
+ symbol' may optionally be followed by some group specific data, e.g.
+ a digital signature. There may be several "GRID" frames in a tag but
+ only one containing the same symbol and only one containing the same
+ owner identifier. The group symbol must be used somewhere in the tag.
+ See section 3.3.1, flag j for more information.
+
+ <Header for 'Group ID registration', ID: "GRID">
+ Owner identifier <text string> $00
+ Group symbol $xx
+ Group dependent data <binary data>
+
+
+4.28. Private frame
+
+ This frame is used to contain information from a software producer
+ that its program uses and does not fit into the other frames. The
+ frame consists of an 'Owner identifier' string and the binary data.
+ The 'Owner identifier' is a null-terminated string with a URL [URL]
+ containing an email address, or a link to a location where an email
+ address can be found, that belongs to the organisation responsible
+ for the frame. Questions regarding the frame should be sent to the
+ indicated email address. The tag may contain more than one "PRIV"
+ frame but only with different contents. It is recommended to keep the
+ number of "PRIV" frames as low as possible.
+
+ <Header for 'Private frame', ID: "PRIV">
+ Owner identifier <text string> $00
+ The private data <binary data>
+
+
+5. The 'unsynchronisation scheme'
+
+ The only purpose of the 'unsynchronisation scheme' is to make the
+ ID3v2 tag as compatible as possible with existing software. There is
+ no use in 'unsynchronising' tags if the file is only to be processed
+ by new software. Unsynchronisation may only be made with MPEG 2 layer
+ I, II and III and MPEG 2.5 files.
+
+ Whenever a false synchronisation is found within the tag, one zeroed
+ byte is inserted after the first false synchronisation byte. The
+ format of a correct sync that should be altered by ID3 encoders is as
+ follows:
+
+ %11111111 111xxxxx
+
+ And should be replaced with:
+
+ %11111111 00000000 111xxxxx
+
+ This has the side effect that all $FF 00 combinations have to be
+ altered, so they won't be affected by the decoding process. Therefore
+ all the $FF 00 combinations have to be replaced with the $FF 00 00
+ combination during the unsynchronisation.
+
+ To indicate usage of the unsynchronisation, the first bit in 'ID3
+ flags' should be set. This bit should only be set if the tag
+ contains a, now corrected, false synchronisation. The bit should
+ only be clear if the tag does not contain any false synchronisations.
+
+ Do bear in mind, that if a compression scheme is used by the encoder,
+ the unsynchronisation scheme should be applied *afterwards*. When
+ decoding a compressed, 'unsynchronised' file, the 'unsynchronisation
+ scheme' should be parsed first, decompression afterwards.
+
+ If the last byte in the tag is $FF, and there is a need to eliminate
+ false synchronisations in the tag, at least one byte of padding
+ should be added.
+
+
+6. Copyright
+
+ Copyright (C) Martin Nilsson 1998. All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that a reference to this document is included on all
+ such copies and derivative works. However, this document itself may
+ not be modified in any way and reissued as the original document.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE AUTHORS DISCLAIMS ALL WARRANTIES, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+ THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+7. References
+
+ [CDDB] Compact Disc Data Base
+
+ http://www.cddb.com
+
+ [ID3v2] Martin Nilsson, "ID3v2 informal standard".
+
+ http://www.id3lib.org/id3/id3v2-00.txt
+
+ [ISO-639-2] ISO/FDIS 639-2.
+ Codes for the representation of names of languages, Part 2: Alpha-3
+ code. Technical committee / subcommittee: TC 37 / SC 2
+
+ [ISO-4217] ISO 4217:1995.
+ Codes for the representation of currencies and funds.
+ Technical committee / subcommittee: TC 68
+
+ [ISO-8859-1] ISO/IEC DIS 8859-1.
+ 8-bit single-byte coded graphic character sets, Part 1: Latin
+ alphabet No. 1. Technical committee / subcommittee: JTC 1 / SC 2
+
+ [ISRC] ISO 3901:1986
+ International Standard Recording Code (ISRC).
+ Technical committee / subcommittee: TC 46 / SC 9
+
+ [JFIF] JPEG File Interchange Format, version 1.02
+
+ http://www.w3.org/Graphics/JPEG/jfif.txt">http://www.w3.org/Graphics/JPEG/jfif.txt
+
+ [MIME] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part One: Format of Internet Message Bodies",
+ RFC 2045, November 1996.
+
+ ftp://ftp.isi.edu/in-notes/rfc2045.txt">ftp://ftp.isi.edu/in-notes/rfc2045.txt
+
+ [MPEG] ISO/IEC 11172-3:1993.
+ Coding of moving pictures and associated audio for digital storage
+ media at up to about 1,5 Mbit/s, Part 3: Audio.
+ Technical committee / subcommittee: JTC 1 / SC 29
+ and
+ ISO/IEC 13818-3:1995
+ Generic coding of moving pictures and associated audio information,
+ Part 3: Audio.
+ Technical committee / subcommittee: JTC 1 / SC 29
+ and
+ ISO/IEC DIS 13818-3
+ Generic coding of moving pictures and associated audio information,
+ Part 3: Audio (Revision of ISO/IEC 13818-3:1995)
+
+
+ [PNG] Portable Network Graphics, version 1.0
+
+ http://www.w3.org/TR/REC-png-multi.html
+
+ [UNICODE] ISO/IEC 10646-1:1993.
+ Universal Multiple-Octet Coded Character Set (UCS), Part 1:
+ Architecture and Basic Multilingual Plane.
+ Technical committee / subcommittee: JTC 1 / SC 2
+
+ http://www.unicode.org/
+
+ [URL] T. Berners-Lee, L. Masinter & M. McCahill, "Uniform Resource
+ Locators (URL).", RFC 1738, December 1994.
+
+ ftp://ftp.isi.edu/in-notes/rfc1738.txt
+
+ [ZLIB] P. Deutsch, Aladdin Enterprises & J-L. Gailly, "ZLIB
+ Compressed
+ Data Format Specification version 3.3", RFC 1950, May 1996.
+
+ ftp://ftp.isi.edu/in-notes/rfc1950.txt
+
+
+8. Appendix
+
+
+A. Appendix A - Genre List from ID3v1
+
+ The following genres is defined in ID3v1
+
+ 0.Blues
+ 1.Classic Rock
+ 2.Country
+ 3.Dance
+ 4.Disco
+ 5.Funk
+ 6.Grunge
+ 7.Hip-Hop
+ 8.Jazz
+ 9.Metal
+ 10.New Age
+ 11.Oldies
+ 12.Other
+ 13.Pop
+ 14.R&B
+ 15.Rap
+ 16.Reggae
+ 17.Rock
+ 18.Techno
+ 19.Industrial
+ 20.Alternative
+ 21.Ska
+ 22.Death Metal
+ 23.Pranks
+ 24.Soundtrack
+ 25.Euro-Techno
+ 26.Ambient
+ 27.Trip-Hop
+ 28.Vocal
+ 29.Jazz+Funk
+ 30.Fusion
+ 31.Trance
+ 32.Classical
+ 33.Instrumental
+ 34.Acid
+ 35.House
+ 36.Game
+ 37.Sound Clip
+ 38.Gospel
+ 39.Noise
+ 40.AlternRock
+ 41.Bass
+ 42.Soul
+ 43.Punk
+ 44.Space
+ 45.Meditative
+ 46.Instrumental Pop
+ 47.Instrumental Rock
+ 48.Ethnic
+ 49.Gothic
+ 50.Darkwave
+ 51.Techno-Industrial
+ 52.Electronic
+ 53.Pop-Folk
+ 54.Eurodance
+ 55.Dream
+ 56.Southern Rock
+ 57.Comedy
+ 58.Cult
+ 59.Gangsta
+ 60.Top 40
+ 61.Christian Rap
+ 62.Pop/Funk
+ 63.Jungle
+ 64.Native American
+ 65.Cabaret
+ 66.New Wave
+ 67.Psychadelic
+ 68.Rave
+ 69.Showtunes
+ 70.Trailer
+ 71.Lo-Fi
+ 72.Tribal
+ 73.Acid Punk
+ 74.Acid Jazz
+ 75.Polka
+ 76.Retro
+ 77.Musical
+ 78.Rock & Roll
+ 79.Hard Rock
+
+ The following genres are Winamp extensions
+
+ 80.Folk
+ 81.Folk-Rock
+ 82.National Folk
+ 83.Swing
+ 84.Fast Fusion
+ 85.Bebob
+ 86.Latin
+ 87.Revival
+ 88.Celtic
+ 89.Bluegrass
+ 90.Avantgarde
+ 91.Gothic Rock
+ 92.Progressive Rock
+ 93.Psychedelic Rock
+ 94.Symphonic Rock
+ 95.Slow Rock
+ 96.Big Band
+ 97.Chorus
+ 98.Easy Listening
+ 99.Acoustic
+ 100.Humour
+ 101.Speech
+ 102.Chanson
+ 103.Opera
+ 104.Chamber Music
+ 105.Sonata
+ 106.Symphony
+ 107.Booty Bass
+ 108.Primus
+ 109.Porn Groove
+ 110.Satire
+ 111.Slow Jam
+ 112.Club
+ 113.Tango
+ 114.Samba
+ 115.Folklore
+ 116.Ballad
+ 117.Power Ballad
+ 118.Rhythmic Soul
+ 119.Freestyle
+ 120.Duet
+ 121.Punk Rock
+ 122.Drum Solo
+ 123.Acapella
+ 124.Euro-House
+ 125.Dance Hall
+
+
+9. Author's Address
+
+ Written by
+
+ Martin Nilsson
+ Rydsvägen 246 C. 30
+ S-584 34 Linköping
+ Sweden
+
+ Email: nilsson@id3.org
+
+
+ Edited by
+
+ Dirk Mahoney
+ 57 Pechey Street
+ Chermside Q
+ Australia 4032
+
+ Email: dirk@id3.org
+
+
+ Johan Sundström
+ Alsättersgatan 5 A. 34
+ S-584 35 Linköping
+ Sweden
+
+ Email: johan@id3.org
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2.4.0-frames.txt b/libs/taglib/taglib/mpeg/id3v2/id3v2.4.0-frames.txt
new file mode 100644
index 0000000000..457acaa25c
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2.4.0-frames.txt
@@ -0,0 +1,1734 @@
+$Id: id3v2.4.0-frames.txt 168944 2002-07-26 20:59:59Z wheeler $
+
+Informal standard M. Nilsson
+Document: id3v2.4.0-frames.txt 1st November 2000
+
+
+ ID3 tag version 2.4.0 - Native Frames
+
+Status of this document
+
+ This document is an informal standard and replaces the ID3v2.3.0
+ standard [ID3v2]. A formal standard will use another revision number
+ even if the content is identical to document. The contents in this
+ document may change for clarifications but never for added or altered
+ functionallity.
+
+ Distribution of this document is unlimited.
+
+
+Abstract
+
+ This document describes the frames natively supported by ID3v2.4.0,
+ which is a revised version of the ID3v2 informal standard [ID3v2.3.0]
+ version 2.3.0. The ID3v2 offers a flexible way of storing audio meta
+ information within audio file itself. The information may be
+ technical information, such as equalisation curves, as well as title,
+ performer, copyright etc.
+
+ ID3v2.4.0 is meant to be as close as possible to ID3v2.3.0 in order
+ to allow for implementations to be revised as easily as possible.
+
+
+1. Table of contents
+
+ 2. Conventions in this document
+ 3. Default flags
+ 4. Declared ID3v2 frames
+ 4.1. Unique file identifier
+ 4.2. Text information frames
+ 4.2.1. Identification frames
+ 4.2.2. Involved persons frames
+ 4.2.3. Derived and subjective properties frames
+ 4.2.4. Rights and license frames
+ 4.2.5. Other text frames
+ 4.2.6. User defined text information frame
+ 4.3. URL link frames
+ 4.3.1. URL link frames - details
+ 4.3.2. User defined URL link frame
+ 4.4. Music CD Identifier
+ 4.5. Event timing codes
+ 4.6. MPEG location lookup table
+ 4.7. Synced tempo codes
+ 4.8. Unsynchronised lyrics/text transcription
+ 4.9. Synchronised lyrics/text
+ 4.10. Comments
+ 4.11. Relative volume adjustment (2)
+ 4.12. Equalisation (2)
+ 4.13. Reverb
+ 4.14. Attached picture
+ 4.15. General encapsulated object
+ 4.16. Play counter
+ 4.17. Popularimeter
+ 4.18. Recommended buffer size
+ 4.19. Audio encryption
+ 4.20. Linked information
+ 4.21. Position synchronisation frame
+ 4.22. Terms of use
+ 4.23. Ownership frame
+ 4.24. Commercial frame
+ 4.25. Encryption method registration
+ 4.26. Group identification registration
+ 4.27. Private frame
+ 4.28. Signature frame
+ 4.29. Seek frame
+ 4.30. Audio seek point index
+ 5. Copyright
+ 6. References
+ 7. Appendix
+ A. Appendix A - Genre List from ID3v1
+ 8. Author's Address
+
+
+2. Conventions in this document
+
+ Text within "" is a text string exactly as it appears in a tag.
+ Numbers preceded with $ are hexadecimal and numbers preceded with %
+ are binary. $xx is used to indicate a byte with unknown content. %x
+ is used to indicate a bit with unknown content. The most significant
+ bit (MSB) of a byte is called 'bit 7' and the least significant bit
+ (LSB) is called 'bit 0'.
+
+ A tag is the whole tag described the ID3v2 main structure document
+ [ID3v2-strct]. A frame is a block of information in the tag. The tag
+ consists of a header, frames and optional padding. A field is a piece
+ of information; one value, a string etc. A numeric string is a string
+ that consists of the characters "0123456789" only.
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in RFC 2119 [KEYWORDS].
+
+
+3. Default flags
+
+ The default settings for the frames described in this document can be
+ divided into the following classes. The flags may be set differently
+ if found more suitable by the software.
+
+ 1. Discarded if tag is altered, discarded if file is altered.
+
+ None.
+
+ 2. Discarded if tag is altered, preserved if file is altered.
+
+ None.
+
+ 3. Preserved if tag is altered, discarded if file is altered.
+
+ ASPI, AENC, ETCO, EQU2, MLLT, POSS, SEEK, SYLT, SYTC, RVA2, TENC,
+ TLEN
+
+ 4. Preserved if tag is altered, preserved if file is altered.
+
+ The rest of the frames.
+
+
+4. Declared ID3v2 frames
+
+ The following frames are declared in this draft.
+
+ 4.19 AENC Audio encryption
+ 4.14 APIC Attached picture
+ 4.30 ASPI Audio seek point index
+
+ 4.10 COMM Comments
+ 4.24 COMR Commercial frame
+
+ 4.25 ENCR Encryption method registration
+ 4.12 EQU2 Equalisation (2)
+ 4.5 ETCO Event timing codes
+
+ 4.15 GEOB General encapsulated object
+ 4.26 GRID Group identification registration
+
+ 4.20 LINK Linked information
+
+ 4.4 MCDI Music CD identifier
+ 4.6 MLLT MPEG location lookup table
+
+ 4.23 OWNE Ownership frame
+
+ 4.27 PRIV Private frame
+ 4.16 PCNT Play counter
+ 4.17 POPM Popularimeter
+ 4.21 POSS Position synchronisation frame
+
+ 4.18 RBUF Recommended buffer size
+ 4.11 RVA2 Relative volume adjustment (2)
+ 4.13 RVRB Reverb
+
+ 4.29 SEEK Seek frame
+ 4.28 SIGN Signature frame
+ 4.9 SYLT Synchronised lyric/text
+ 4.7 SYTC Synchronised tempo codes
+
+ 4.2.1 TALB Album/Movie/Show title
+ 4.2.3 TBPM BPM (beats per minute)
+ 4.2.2 TCOM Composer
+ 4.2.3 TCON Content type
+ 4.2.4 TCOP Copyright message
+ 4.2.5 TDEN Encoding time
+ 4.2.5 TDLY Playlist delay
+ 4.2.5 TDOR Original release time
+ 4.2.5 TDRC Recording time
+ 4.2.5 TDRL Release time
+ 4.2.5 TDTG Tagging time
+ 4.2.2 TENC Encoded by
+ 4.2.2 TEXT Lyricist/Text writer
+ 4.2.3 TFLT File type
+ 4.2.2 TIPL Involved people list
+ 4.2.1 TIT1 Content group description
+ 4.2.1 TIT2 Title/songname/content description
+ 4.2.1 TIT3 Subtitle/Description refinement
+ 4.2.3 TKEY Initial key
+ 4.2.3 TLAN Language(s)
+ 4.2.3 TLEN Length
+ 4.2.2 TMCL Musician credits list
+ 4.2.3 TMED Media type
+ 4.2.3 TMOO Mood
+ 4.2.1 TOAL Original album/movie/show title
+ 4.2.5 TOFN Original filename
+ 4.2.2 TOLY Original lyricist(s)/text writer(s)
+ 4.2.2 TOPE Original artist(s)/performer(s)
+ 4.2.4 TOWN File owner/licensee
+ 4.2.2 TPE1 Lead performer(s)/Soloist(s)
+ 4.2.2 TPE2 Band/orchestra/accompaniment
+ 4.2.2 TPE3 Conductor/performer refinement
+ 4.2.2 TPE4 Interpreted, remixed, or otherwise modified by
+ 4.2.1 TPOS Part of a set
+ 4.2.4 TPRO Produced notice
+ 4.2.4 TPUB Publisher
+ 4.2.1 TRCK Track number/Position in set
+ 4.2.4 TRSN Internet radio station name
+ 4.2.4 TRSO Internet radio station owner
+ 4.2.5 TSOA Album sort order
+ 4.2.5 TSOP Performer sort order
+ 4.2.5 TSOT Title sort order
+ 4.2.1 TSRC ISRC (international standard recording code)
+ 4.2.5 TSSE Software/Hardware and settings used for encoding
+ 4.2.1 TSST Set subtitle
+ 4.2.2 TXXX User defined text information frame
+
+ 4.1 UFID Unique file identifier
+ 4.22 USER Terms of use
+ 4.8 USLT Unsynchronised lyric/text transcription
+
+ 4.3.1 WCOM Commercial information
+ 4.3.1 WCOP Copyright/Legal information
+ 4.3.1 WOAF Official audio file webpage
+ 4.3.1 WOAR Official artist/performer webpage
+ 4.3.1 WOAS Official audio source webpage
+ 4.3.1 WORS Official Internet radio station homepage
+ 4.3.1 WPAY Payment
+ 4.3.1 WPUB Publishers official webpage
+ 4.3.2 WXXX User defined URL link frame
+
+
+4.1. Unique file identifier
+
+ This frame's purpose is to be able to identify the audio file in a
+ database, that may provide more information relevant to the content.
+ Since standardisation of such a database is beyond this document, all
+ UFID frames begin with an 'owner identifier' field. It is a null-
+ terminated string with a URL [URL] containing an email address, or a
+ link to a location where an email address can be found, that belongs
+ to the organisation responsible for this specific database
+ implementation. Questions regarding the database should be sent to
+ the indicated email address. The URL should not be used for the
+ actual database queries. The string
+ "http://www.id3.org/dummy/ufid.html" should be used for tests. The
+ 'Owner identifier' must be non-empty (more than just a termination).
+ The 'Owner identifier' is then followed by the actual identifier,
+ which may be up to 64 bytes. There may be more than one "UFID" frame
+ in a tag, but only one with the same 'Owner identifier'.
+
+ <Header for 'Unique file identifier', ID: "UFID">
+ Owner identifier <text string> $00
+ Identifier <up to 64 bytes binary data>
+
+
+4.2. Text information frames
+
+ The text information frames are often the most important frames,
+ containing information like artist, album and more. There may only be
+ one text information frame of its kind in an tag. All text
+ information frames supports multiple strings, stored as a null
+ separated list, where null is reperesented by the termination code
+ for the charater encoding. All text frame identifiers begin with "T".
+ Only text frame identifiers begin with "T", with the exception of the
+ "TXXX" frame. All the text information frames have the following
+ format:
+
+ <Header for 'Text information frame', ID: "T000" - "TZZZ",
+ excluding "TXXX" described in 4.2.6.>
+ Text encoding $xx
+ Information <text string(s) according to encoding>
+
+
+4.2.1. Identification frames
+
+ TIT1
+ The 'Content group description' frame is used if the sound belongs to
+ a larger category of sounds/music. For example, classical music is
+ often sorted in different musical sections (e.g. "Piano Concerto",
+ "Weather - Hurricane").
+
+ TIT2
+ The 'Title/Songname/Content description' frame is the actual name of
+ the piece (e.g. "Adagio", "Hurricane Donna").
+
+ TIT3
+ The 'Subtitle/Description refinement' frame is used for information
+ directly related to the contents title (e.g. "Op. 16" or "Performed
+ live at Wembley").
+
+ TALB
+ The 'Album/Movie/Show title' frame is intended for the title of the
+ recording (or source of sound) from which the audio in the file is
+ taken.
+
+ TOAL
+ The 'Original album/movie/show title' frame is intended for the title
+ of the original recording (or source of sound), if for example the
+ music in the file should be a cover of a previously released song.
+
+ TRCK
+ The 'Track number/Position in set' frame is a numeric string
+ containing the order number of the audio-file on its original
+ recording. This MAY be extended with a "/" character and a numeric
+ string containing the total number of tracks/elements on the original
+ recording. E.g. "4/9".
+
+ TPOS
+ The 'Part of a set' frame is a numeric string that describes which
+ part of a set the audio came from. This frame is used if the source
+ described in the "TALB" frame is divided into several mediums, e.g. a
+ double CD. The value MAY be extended with a "/" character and a
+ numeric string containing the total number of parts in the set. E.g.
+ "1/2".
+
+ TSST
+ The 'Set subtitle' frame is intended for the subtitle of the part of
+ a set this track belongs to.
+
+ TSRC
+ The 'ISRC' frame should contain the International Standard Recording
+ Code [ISRC] (12 characters).
+
+
+4.2.2. Involved persons frames
+
+ TPE1
+ The 'Lead artist/Lead performer/Soloist/Performing group' is
+ used for the main artist.
+
+ TPE2
+ The 'Band/Orchestra/Accompaniment' frame is used for additional
+ information about the performers in the recording.
+
+ TPE3
+ The 'Conductor' frame is used for the name of the conductor.
+
+ TPE4
+ The 'Interpreted, remixed, or otherwise modified by' frame contains
+ more information about the people behind a remix and similar
+ interpretations of another existing piece.
+
+ TOPE
+ The 'Original artist/performer' frame is intended for the performer
+ of the original recording, if for example the music in the file
+ should be a cover of a previously released song.
+
+ TEXT
+ The 'Lyricist/Text writer' frame is intended for the writer of the
+ text or lyrics in the recording.
+
+ TOLY
+ The 'Original lyricist/text writer' frame is intended for the
+ text writer of the original recording, if for example the music in
+ the file should be a cover of a previously released song.
+
+ TCOM
+ The 'Composer' frame is intended for the name of the composer.
+
+ TMCL
+ The 'Musician credits list' is intended as a mapping between
+ instruments and the musician that played it. Every odd field is an
+ instrument and every even is an artist or a comma delimited list of
+ artists.
+
+ TIPL
+ The 'Involved people list' is very similar to the musician credits
+ list, but maps between functions, like producer, and names.
+
+ TENC
+ The 'Encoded by' frame contains the name of the person or
+ organisation that encoded the audio file. This field may contain a
+ copyright message, if the audio file also is copyrighted by the
+ encoder.
+
+
+4.2.3. Derived and subjective properties frames
+
+ TBPM
+ The 'BPM' frame contains the number of beats per minute in the
+ main part of the audio. The BPM is an integer and represented as a
+ numerical string.
+
+ TLEN
+ The 'Length' frame contains the length of the audio file in
+ milliseconds, represented as a numeric string.
+
+ TKEY
+ The 'Initial key' frame contains the musical key in which the sound
+ starts. It is represented as a string with a maximum length of three
+ characters. The ground keys are represented with "A","B","C","D","E",
+ "F" and "G" and halfkeys represented with "b" and "#". Minor is
+ represented as "m", e.g. "Dbm" $00. Off key is represented with an
+ "o" only.
+
+ TLAN
+ The 'Language' frame should contain the languages of the text or
+ lyrics spoken or sung in the audio. The language is represented with
+ three characters according to ISO-639-2 [ISO-639-2]. If more than one
+ language is used in the text their language codes should follow
+ according to the amount of their usage, e.g. "eng" $00 "sve" $00.
+
+ TCON
+ The 'Content type', which ID3v1 was stored as a one byte numeric
+ value only, is now a string. You may use one or several of the ID3v1
+ types as numerical strings, or, since the category list would be
+ impossible to maintain with accurate and up to date categories,
+ define your own. Example: "21" $00 "Eurodisco" $00
+
+ You may also use any of the following keywords:
+
+ RX Remix
+ CR Cover
+
+ TFLT
+ The 'File type' frame indicates which type of audio this tag defines.
+ The following types and refinements are defined:
+
+ MIME MIME type follows
+ MPG MPEG Audio
+ /1 MPEG 1/2 layer I
+ /2 MPEG 1/2 layer II
+ /3 MPEG 1/2 layer III
+ /2.5 MPEG 2.5
+ /AAC Advanced audio compression
+ VQF Transform-domain Weighted Interleave Vector Quantisation
+ PCM Pulse Code Modulated audio
+
+ but other types may be used, but not for these types though. This is
+ used in a similar way to the predefined types in the "TMED" frame,
+ but without parentheses. If this frame is not present audio type is
+ assumed to be "MPG".
+
+ TMED
+ The 'Media type' frame describes from which media the sound
+ originated. This may be a text string or a reference to the
+ predefined media types found in the list below. Example:
+ "VID/PAL/VHS" $00.
+
+ DIG Other digital media
+ /A Analogue transfer from media
+
+ ANA Other analogue media
+ /WAC Wax cylinder
+ /8CA 8-track tape cassette
+
+ CD CD
+ /A Analogue transfer from media
+ /DD DDD
+ /AD ADD
+ /AA AAD
+
+ LD Laserdisc
+
+ TT Turntable records
+ /33 33.33 rpm
+ /45 45 rpm
+ /71 71.29 rpm
+ /76 76.59 rpm
+ /78 78.26 rpm
+ /80 80 rpm
+
+ MD MiniDisc
+ /A Analogue transfer from media
+
+ DAT DAT
+ /A Analogue transfer from media
+ /1 standard, 48 kHz/16 bits, linear
+ /2 mode 2, 32 kHz/16 bits, linear
+ /3 mode 3, 32 kHz/12 bits, non-linear, low speed
+ /4 mode 4, 32 kHz/12 bits, 4 channels
+ /5 mode 5, 44.1 kHz/16 bits, linear
+ /6 mode 6, 44.1 kHz/16 bits, 'wide track' play
+
+ DCC DCC
+ /A Analogue transfer from media
+
+ DVD DVD
+ /A Analogue transfer from media
+
+ TV Television
+ /PAL PAL
+ /NTSC NTSC
+ /SECAM SECAM
+
+ VID Video
+ /PAL PAL
+ /NTSC NTSC
+ /SECAM SECAM
+ /VHS VHS
+ /SVHS S-VHS
+ /BETA BETAMAX
+
+ RAD Radio
+ /FM FM
+ /AM AM
+ /LW LW
+ /MW MW
+
+ TEL Telephone
+ /I ISDN
+
+ MC MC (normal cassette)
+ /4 4.75 cm/s (normal speed for a two sided cassette)
+ /9 9.5 cm/s
+ /I Type I cassette (ferric/normal)
+ /II Type II cassette (chrome)
+ /III Type III cassette (ferric chrome)
+ /IV Type IV cassette (metal)
+
+ REE Reel
+ /9 9.5 cm/s
+ /19 19 cm/s
+ /38 38 cm/s
+ /76 76 cm/s
+ /I Type I cassette (ferric/normal)
+ /II Type II cassette (chrome)
+ /III Type III cassette (ferric chrome)
+ /IV Type IV cassette (metal)
+
+ TMOO
+ The 'Mood' frame is intended to reflect the mood of the audio with a
+ few keywords, e.g. "Romantic" or "Sad".
+
+
+4.2.4. Rights and license frames
+
+ TCOP
+ The 'Copyright message' frame, in which the string must begin with a
+ year and a space character (making five characters), is intended for
+ the copyright holder of the original sound, not the audio file
+ itself. The absence of this frame means only that the copyright
+ information is unavailable or has been removed, and must not be
+ interpreted to mean that the audio is public domain. Every time this
+ field is displayed the field must be preceded with "Copyright " (C) "
+ ", where (C) is one character showing a C in a circle.
+
+ TPRO
+ The 'Produced notice' frame, in which the string must begin with a
+ year and a space character (making five characters), is intended for
+ the production copyright holder of the original sound, not the audio
+ file itself. The absence of this frame means only that the production
+ copyright information is unavailable or has been removed, and must
+ not be interpreted to mean that the audio is public domain. Every
+ time this field is displayed the field must be preceded with
+ "Produced " (P) " ", where (P) is one character showing a P in a
+ circle.
+
+ TPUB
+ The 'Publisher' frame simply contains the name of the label or
+ publisher.
+
+ TOWN
+ The 'File owner/licensee' frame contains the name of the owner or
+ licensee of the file and it's contents.
+
+ TRSN
+ The 'Internet radio station name' frame contains the name of the
+ internet radio station from which the audio is streamed.
+
+ TRSO
+ The 'Internet radio station owner' frame contains the name of the
+ owner of the internet radio station from which the audio is
+ streamed.
+
+4.2.5. Other text frames
+
+ TOFN
+ The 'Original filename' frame contains the preferred filename for the
+ file, since some media doesn't allow the desired length of the
+ filename. The filename is case sensitive and includes its suffix.
+
+ TDLY
+ The 'Playlist delay' defines the numbers of milliseconds of silence
+ that should be inserted before this audio. The value zero indicates
+ that this is a part of a multifile audio track that should be played
+ continuously.
+
+ TDEN
+ The 'Encoding time' frame contains a timestamp describing when the
+ audio was encoded. Timestamp format is described in the ID3v2
+ structure document [ID3v2-strct].
+
+ TDOR
+ The 'Original release time' frame contains a timestamp describing
+ when the original recording of the audio was released. Timestamp
+ format is described in the ID3v2 structure document [ID3v2-strct].
+
+ TDRC
+ The 'Recording time' frame contains a timestamp describing when the
+ audio was recorded. Timestamp format is described in the ID3v2
+ structure document [ID3v2-strct].
+
+ TDRL
+ The 'Release time' frame contains a timestamp describing when the
+ audio was first released. Timestamp format is described in the ID3v2
+ structure document [ID3v2-strct].
+
+ TDTG
+ The 'Tagging time' frame contains a timestamp describing then the
+ audio was tagged. Timestamp format is described in the ID3v2
+ structure document [ID3v2-strct].
+
+ TSSE
+ The 'Software/Hardware and settings used for encoding' frame
+ includes the used audio encoder and its settings when the file was
+ encoded. Hardware refers to hardware encoders, not the computer on
+ which a program was run.
+
+ TSOA
+ The 'Album sort order' frame defines a string which should be used
+ instead of the album name (TALB) for sorting purposes. E.g. an album
+ named "A Soundtrack" might preferably be sorted as "Soundtrack".
+
+ TSOP
+ The 'Performer sort order' frame defines a string which should be
+ used instead of the performer (TPE2) for sorting purposes.
+
+ TSOT
+ The 'Title sort order' frame defines a string which should be used
+ instead of the title (TIT2) for sorting purposes.
+
+
+4.2.6. User defined text information frame
+
+ This frame is intended for one-string text information concerning the
+ audio file in a similar way to the other "T"-frames. The frame body
+ consists of a description of the string, represented as a terminated
+ string, followed by the actual string. There may be more than one
+ "TXXX" frame in each tag, but only one with the same description.
+
+ <Header for 'User defined text information frame', ID: "TXXX">
+ Text encoding $xx
+ Description <text string according to encoding> $00 (00)
+ Value <text string according to encoding>
+
+
+4.3. URL link frames
+
+ With these frames dynamic data such as webpages with touring
+ information, price information or plain ordinary news can be added to
+ the tag. There may only be one URL [URL] link frame of its kind in an
+ tag, except when stated otherwise in the frame description. If the
+ text string is followed by a string termination, all the following
+ information should be ignored and not be displayed. All URL link
+ frame identifiers begins with "W". Only URL link frame identifiers
+ begins with "W", except for "WXXX". All URL link frames have the
+ following format:
+
+ <Header for 'URL link frame', ID: "W000" - "WZZZ", excluding "WXXX"
+ described in 4.3.2.>
+ URL <text string>
+
+
+4.3.1. URL link frames - details
+
+ WCOM
+ The 'Commercial information' frame is a URL pointing at a webpage
+ with information such as where the album can be bought. There may be
+ more than one "WCOM" frame in a tag, but not with the same content.
+
+ WCOP
+ The 'Copyright/Legal information' frame is a URL pointing at a
+ webpage where the terms of use and ownership of the file is
+ described.
+
+ WOAF
+ The 'Official audio file webpage' frame is a URL pointing at a file
+ specific webpage.
+
+ WOAR
+ The 'Official artist/performer webpage' frame is a URL pointing at
+ the artists official webpage. There may be more than one "WOAR" frame
+ in a tag if the audio contains more than one performer, but not with
+ the same content.
+
+ WOAS
+ The 'Official audio source webpage' frame is a URL pointing at the
+ official webpage for the source of the audio file, e.g. a movie.
+
+ WORS
+ The 'Official Internet radio station homepage' contains a URL
+ pointing at the homepage of the internet radio station.
+
+ WPAY
+ The 'Payment' frame is a URL pointing at a webpage that will handle
+ the process of paying for this file.
+
+ WPUB
+ The 'Publishers official webpage' frame is a URL pointing at the
+ official webpage for the publisher.
+
+
+4.3.2. User defined URL link frame
+
+ This frame is intended for URL [URL] links concerning the audio file
+ in a similar way to the other "W"-frames. The frame body consists
+ of a description of the string, represented as a terminated string,
+ followed by the actual URL. The URL is always encoded with ISO-8859-1
+ [ISO-8859-1]. There may be more than one "WXXX" frame in each tag,
+ but only one with the same description.
+
+ <Header for 'User defined URL link frame', ID: "WXXX">
+ Text encoding $xx
+ Description <text string according to encoding> $00 (00)
+ URL <text string>
+
+
+4.4. Music CD identifier
+
+ This frame is intended for music that comes from a CD, so that the CD
+ can be identified in databases such as the CDDB [CDDB]. The frame
+ consists of a binary dump of the Table Of Contents, TOC, from the CD,
+ which is a header of 4 bytes and then 8 bytes/track on the CD plus 8
+ bytes for the 'lead out', making a maximum of 804 bytes. The offset
+ to the beginning of every track on the CD should be described with a
+ four bytes absolute CD-frame address per track, and not with absolute
+ time. When this frame is used the presence of a valid "TRCK" frame is
+ REQUIRED, even if the CD's only got one track. It is recommended that
+ this frame is always added to tags originating from CDs. There may
+ only be one "MCDI" frame in each tag.
+
+ <Header for 'Music CD identifier', ID: "MCDI">
+ CD TOC <binary data>
+
+
+4.5. Event timing codes
+
+ This frame allows synchronisation with key events in the audio. The
+ header is:
+
+ <Header for 'Event timing codes', ID: "ETCO">
+ Time stamp format $xx
+
+ Where time stamp format is:
+
+ $01 Absolute time, 32 bit sized, using MPEG [MPEG] frames as unit
+ $02 Absolute time, 32 bit sized, using milliseconds as unit
+
+ Absolute time means that every stamp contains the time from the
+ beginning of the file.
+
+ Followed by a list of key events in the following format:
+
+ Type of event $xx
+ Time stamp $xx (xx ...)
+
+ The 'Time stamp' is set to zero if directly at the beginning of the
+ sound or after the previous event. All events MUST be sorted in
+ chronological order. The type of event is as follows:
+
+ $00 padding (has no meaning)
+ $01 end of initial silence
+ $02 intro start
+ $03 main part start
+ $04 outro start
+ $05 outro end
+ $06 verse start
+ $07 refrain start
+ $08 interlude start
+ $09 theme start
+ $0A variation start
+ $0B key change
+ $0C time change
+ $0D momentary unwanted noise (Snap, Crackle & Pop)
+ $0E sustained noise
+ $0F sustained noise end
+ $10 intro end
+ $11 main part end
+ $12 verse end
+ $13 refrain end
+ $14 theme end
+ $15 profanity
+ $16 profanity end
+
+ $17-$DF reserved for future use
+
+ $E0-$EF not predefined synch 0-F
+
+ $F0-$FC reserved for future use
+
+ $FD audio end (start of silence)
+ $FE audio file ends
+ $FF one more byte of events follows (all the following bytes with
+ the value $FF have the same function)
+
+ Terminating the start events such as "intro start" is OPTIONAL. The
+ 'Not predefined synch's ($E0-EF) are for user events. You might want
+ to synchronise your music to something, like setting off an explosion
+ on-stage, activating a screensaver etc.
+
+ There may only be one "ETCO" frame in each tag.
+
+
+4.6. MPEG location lookup table
+
+ To increase performance and accuracy of jumps within a MPEG [MPEG]
+ audio file, frames with time codes in different locations in the file
+ might be useful. This ID3v2 frame includes references that the
+ software can use to calculate positions in the file. After the frame
+ header follows a descriptor of how much the 'frame counter' should be
+ increased for every reference. If this value is two then the first
+ reference points out the second frame, the 2nd reference the 4th
+ frame, the 3rd reference the 6th frame etc. In a similar way the
+ 'bytes between reference' and 'milliseconds between reference' points
+ out bytes and milliseconds respectively.
+
+ Each reference consists of two parts; a certain number of bits, as
+ defined in 'bits for bytes deviation', that describes the difference
+ between what is said in 'bytes between reference' and the reality and
+ a certain number of bits, as defined in 'bits for milliseconds
+ deviation', that describes the difference between what is said in
+ 'milliseconds between reference' and the reality. The number of bits
+ in every reference, i.e. 'bits for bytes deviation'+'bits for
+ milliseconds deviation', must be a multiple of four. There may only
+ be one "MLLT" frame in each tag.
+
+ <Header for 'Location lookup table', ID: "MLLT">
+ MPEG frames between reference $xx xx
+ Bytes between reference $xx xx xx
+ Milliseconds between reference $xx xx xx
+ Bits for bytes deviation $xx
+ Bits for milliseconds dev. $xx
+
+ Then for every reference the following data is included;
+
+ Deviation in bytes %xxx....
+ Deviation in milliseconds %xxx....
+
+
+4.7. Synchronised tempo codes
+
+ For a more accurate description of the tempo of a musical piece, this
+ frame might be used. After the header follows one byte describing
+ which time stamp format should be used. Then follows one or more
+ tempo codes. Each tempo code consists of one tempo part and one time
+ part. The tempo is in BPM described with one or two bytes. If the
+ first byte has the value $FF, one more byte follows, which is added
+ to the first giving a range from 2 - 510 BPM, since $00 and $01 is
+ reserved. $00 is used to describe a beat-free time period, which is
+ not the same as a music-free time period. $01 is used to indicate one
+ single beat-stroke followed by a beat-free period.
+
+ The tempo descriptor is followed by a time stamp. Every time the
+ tempo in the music changes, a tempo descriptor may indicate this for
+ the player. All tempo descriptors MUST be sorted in chronological
+ order. The first beat-stroke in a time-period is at the same time as
+ the beat description occurs. There may only be one "SYTC" frame in
+ each tag.
+
+ <Header for 'Synchronised tempo codes', ID: "SYTC">
+ Time stamp format $xx
+ Tempo data <binary data>
+
+ Where time stamp format is:
+
+ $01 Absolute time, 32 bit sized, using MPEG [MPEG] frames as unit
+ $02 Absolute time, 32 bit sized, using milliseconds as unit
+
+ Absolute time means that every stamp contains the time from the
+ beginning of the file.
+
+
+4.8. Unsynchronised lyrics/text transcription
+
+ This frame contains the lyrics of the song or a text transcription of
+ other vocal activities. The head includes an encoding descriptor and
+ a content descriptor. The body consists of the actual text. The
+ 'Content descriptor' is a terminated string. If no descriptor is
+ entered, 'Content descriptor' is $00 (00) only. Newline characters
+ are allowed in the text. There may be more than one 'Unsynchronised
+ lyrics/text transcription' frame in each tag, but only one with the
+ same language and content descriptor.
+
+ <Header for 'Unsynchronised lyrics/text transcription', ID: "USLT">
+ Text encoding $xx
+ Language $xx xx xx
+ Content descriptor <text string according to encoding> $00 (00)
+ Lyrics/text <full text string according to encoding>
+
+
+4.9. Synchronised lyrics/text
+
+ This is another way of incorporating the words, said or sung lyrics,
+ in the audio file as text, this time, however, in sync with the
+ audio. It might also be used to describing events e.g. occurring on a
+ stage or on the screen in sync with the audio. The header includes a
+ content descriptor, represented with as terminated text string. If no
+ descriptor is entered, 'Content descriptor' is $00 (00) only.
+
+ <Header for 'Synchronised lyrics/text', ID: "SYLT">
+ Text encoding $xx
+ Language $xx xx xx
+ Time stamp format $xx
+ Content type $xx
+ Content descriptor <text string according to encoding> $00 (00)
+
+ Content type: $00 is other
+ $01 is lyrics
+ $02 is text transcription
+ $03 is movement/part name (e.g. "Adagio")
+ $04 is events (e.g. "Don Quijote enters the stage")
+ $05 is chord (e.g. "Bb F Fsus")
+ $06 is trivia/'pop up' information
+ $07 is URLs to webpages
+ $08 is URLs to images
+
+ Time stamp format:
+
+ $01 Absolute time, 32 bit sized, using MPEG [MPEG] frames as unit
+ $02 Absolute time, 32 bit sized, using milliseconds as unit
+
+ Absolute time means that every stamp contains the time from the
+ beginning of the file.
+
+ The text that follows the frame header differs from that of the
+ unsynchronised lyrics/text transcription in one major way. Each
+ syllable (or whatever size of text is considered to be convenient by
+ the encoder) is a null terminated string followed by a time stamp
+ denoting where in the sound file it belongs. Each sync thus has the
+ following structure:
+
+ Terminated text to be synced (typically a syllable)
+ Sync identifier (terminator to above string) $00 (00)
+ Time stamp $xx (xx ...)
+
+ The 'time stamp' is set to zero or the whole sync is omitted if
+ located directly at the beginning of the sound. All time stamps
+ should be sorted in chronological order. The sync can be considered
+ as a validator of the subsequent string.
+
+ Newline characters are allowed in all "SYLT" frames and MUST be used
+ after every entry (name, event etc.) in a frame with the content type
+ $03 - $04.
+
+ A few considerations regarding whitespace characters: Whitespace
+ separating words should mark the beginning of a new word, thus
+ occurring in front of the first syllable of a new word. This is also
+ valid for new line characters. A syllable followed by a comma should
+ not be broken apart with a sync (both the syllable and the comma
+ should be before the sync).
+
+ An example: The "USLT" passage
+
+ "Strangers in the night" $0A "Exchanging glances"
+
+ would be "SYLT" encoded as:
+
+ "Strang" $00 xx xx "ers" $00 xx xx " in" $00 xx xx " the" $00 xx xx
+ " night" $00 xx xx 0A "Ex" $00 xx xx "chang" $00 xx xx "ing" $00 xx
+ xx "glan" $00 xx xx "ces" $00 xx xx
+
+ There may be more than one "SYLT" frame in each tag, but only one
+ with the same language and content descriptor.
+
+
+4.10. Comments
+
+ This frame is intended for any kind of full text information that
+ does not fit in any other frame. It consists of a frame header
+ followed by encoding, language and content descriptors and is ended
+ with the actual comment as a text string. Newline characters are
+ allowed in the comment text string. There may be more than one
+ comment frame in each tag, but only one with the same language and
+ content descriptor.
+
+ <Header for 'Comment', ID: "COMM">
+ Text encoding $xx
+ Language $xx xx xx
+ Short content descrip. <text string according to encoding> $00 (00)
+ The actual text <full text string according to encoding>
+
+
+4.11. Relative volume adjustment (2)
+
+ This is a more subjective frame than the previous ones. It allows the
+ user to say how much he wants to increase/decrease the volume on each
+ channel when the file is played. The purpose is to be able to align
+ all files to a reference volume, so that you don't have to change the
+ volume constantly. This frame may also be used to balance adjust the
+ audio. The volume adjustment is encoded as a fixed point decibel
+ value, 16 bit signed integer representing (adjustment*512), giving
+ +/- 64 dB with a precision of 0.001953125 dB. E.g. +2 dB is stored as
+ $04 00 and -2 dB is $FC 00. There may be more than one "RVA2" frame
+ in each tag, but only one with the same identification string.
+
+ <Header for 'Relative volume adjustment (2)', ID: "RVA2">
+ Identification <text string> $00
+
+ The 'identification' string is used to identify the situation and/or
+ device where this adjustment should apply. The following is then
+ repeated for every channel
+
+ Type of channel $xx
+ Volume adjustment $xx xx
+ Bits representing peak $xx
+ Peak volume $xx (xx ...)
+
+
+ Type of channel: $00 Other
+ $01 Master volume
+ $02 Front right
+ $03 Front left
+ $04 Back right
+ $05 Back left
+ $06 Front centre
+ $07 Back centre
+ $08 Subwoofer
+
+ Bits representing peak can be any number between 0 and 255. 0 means
+ that there is no peak volume field. The peak volume field is always
+ padded to whole bytes, setting the most significant bits to zero.
+
+
+4.12. Equalisation (2)
+
+ This is another subjective, alignment frame. It allows the user to
+ predefine an equalisation curve within the audio file. There may be
+ more than one "EQU2" frame in each tag, but only one with the same
+ identification string.
+
+ <Header of 'Equalisation (2)', ID: "EQU2">
+ Interpolation method $xx
+ Identification <text string> $00
+
+ The 'interpolation method' describes which method is preferred when
+ an interpolation between the adjustment point that follows. The
+ following methods are currently defined:
+
+ $00 Band
+ No interpolation is made. A jump from one adjustment level to
+ another occurs in the middle between two adjustment points.
+ $01 Linear
+ Interpolation between adjustment points is linear.
+
+ The 'identification' string is used to identify the situation and/or
+ device where this adjustment should apply. The following is then
+ repeated for every adjustment point
+
+ Frequency $xx xx
+ Volume adjustment $xx xx
+
+ The frequency is stored in units of 1/2 Hz, giving it a range from 0
+ to 32767 Hz.
+
+ The volume adjustment is encoded as a fixed point decibel value, 16
+ bit signed integer representing (adjustment*512), giving +/- 64 dB
+ with a precision of 0.001953125 dB. E.g. +2 dB is stored as $04 00
+ and -2 dB is $FC 00.
+
+ Adjustment points should be ordered by frequency and one frequency
+ should only be described once in the frame.
+
+
+4.13. Reverb
+
+ Yet another subjective frame, with which you can adjust echoes of
+ different kinds. Reverb left/right is the delay between every bounce
+ in ms. Reverb bounces left/right is the number of bounces that should
+ be made. $FF equals an infinite number of bounces. Feedback is the
+ amount of volume that should be returned to the next echo bounce. $00
+ is 0%, $FF is 100%. If this value were $7F, there would be 50% volume
+ reduction on the first bounce, 50% of that on the second and so on.
+ Left to left means the sound from the left bounce to be played in the
+ left speaker, while left to right means sound from the left bounce to
+ be played in the right speaker.
+
+ 'Premix left to right' is the amount of left sound to be mixed in the
+ right before any reverb is applied, where $00 id 0% and $FF is 100%.
+ 'Premix right to left' does the same thing, but right to left.
+ Setting both premix to $FF would result in a mono output (if the
+ reverb is applied symmetric). There may only be one "RVRB" frame in
+ each tag.
+
+ <Header for 'Reverb', ID: "RVRB">
+ Reverb left (ms) $xx xx
+ Reverb right (ms) $xx xx
+ Reverb bounces, left $xx
+ Reverb bounces, right $xx
+ Reverb feedback, left to left $xx
+ Reverb feedback, left to right $xx
+ Reverb feedback, right to right $xx
+ Reverb feedback, right to left $xx
+ Premix left to right $xx
+ Premix right to left $xx
+
+
+4.14. Attached picture
+
+ This frame contains a picture directly related to the audio file.
+ Image format is the MIME type and subtype [MIME] for the image. In
+ the event that the MIME media type name is omitted, "image/" will be
+ implied. The "image/png" [PNG] or "image/jpeg" [JFIF] picture format
+ should be used when interoperability is wanted. Description is a
+ short description of the picture, represented as a terminated
+ text string. There may be several pictures attached to one file, each
+ in their individual "APIC" frame, but only one with the same content
+ descriptor. There may only be one picture with the picture type
+ declared as picture type $01 and $02 respectively. There is the
+ possibility to put only a link to the image file by using the 'MIME
+ type' "-->" and having a complete URL [URL] instead of picture data.
+ The use of linked files should however be used sparingly since there
+ is the risk of separation of files.
+
+ <Header for 'Attached picture', ID: "APIC">
+ Text encoding $xx
+ MIME type <text string> $00
+ Picture type $xx
+ Description <text string according to encoding> $00 (00)
+ Picture data <binary data>
+
+
+ Picture type: $00 Other
+ $01 32x32 pixels 'file icon' (PNG only)
+ $02 Other file icon
+ $03 Cover (front)
+ $04 Cover (back)
+ $05 Leaflet page
+ $06 Media (e.g. label side of CD)
+ $07 Lead artist/lead performer/soloist
+ $08 Artist/performer
+ $09 Conductor
+ $0A Band/Orchestra
+ $0B Composer
+ $0C Lyricist/text writer
+ $0D Recording Location
+ $0E During recording
+ $0F During performance
+ $10 Movie/video screen capture
+ $11 A bright coloured fish
+ $12 Illustration
+ $13 Band/artist logotype
+ $14 Publisher/Studio logotype
+
+
+4.15. General encapsulated object
+
+ In this frame any type of file can be encapsulated. After the header,
+ 'Frame size' and 'Encoding' follows 'MIME type' [MIME] represented as
+ as a terminated string encoded with ISO 8859-1 [ISO-8859-1]. The
+ filename is case sensitive and is encoded as 'Encoding'. Then follows
+ a content description as terminated string, encoded as 'Encoding'.
+ The last thing in the frame is the actual object. The first two
+ strings may be omitted, leaving only their terminations. MIME type is
+ always an ISO-8859-1 text string. There may be more than one "GEOB"
+ frame in each tag, but only one with the same content descriptor.
+
+ <Header for 'General encapsulated object', ID: "GEOB">
+ Text encoding $xx
+ MIME type <text string> $00
+ Filename <text string according to encoding> $00 (00)
+ Content description <text string according to encoding> $00 (00)
+ Encapsulated object <binary data>
+
+
+4.16. Play counter
+
+ This is simply a counter of the number of times a file has been
+ played. The value is increased by one every time the file begins to
+ play. There may only be one "PCNT" frame in each tag. When the
+ counter reaches all one's, one byte is inserted in front of the
+ counter thus making the counter eight bits bigger. The counter must
+ be at least 32-bits long to begin with.
+
+ <Header for 'Play counter', ID: "PCNT">
+ Counter $xx xx xx xx (xx ...)
+
+
+4.17. Popularimeter
+
+ The purpose of this frame is to specify how good an audio file is.
+ Many interesting applications could be found to this frame such as a
+ playlist that features better audio files more often than others or
+ it could be used to profile a person's taste and find other 'good'
+ files by comparing people's profiles. The frame contains the email
+ address to the user, one rating byte and a four byte play counter,
+ intended to be increased with one for every time the file is played.
+ The email is a terminated string. The rating is 1-255 where 1 is
+ worst and 255 is best. 0 is unknown. If no personal counter is wanted
+ it may be omitted. When the counter reaches all one's, one byte is
+ inserted in front of the counter thus making the counter eight bits
+ bigger in the same away as the play counter ("PCNT"). There may be
+ more than one "POPM" frame in each tag, but only one with the same
+ email address.
+
+ <Header for 'Popularimeter', ID: "POPM">
+ Email to user <text string> $00
+ Rating $xx
+ Counter $xx xx xx xx (xx ...)
+
+
+4.18. Recommended buffer size
+
+ Sometimes the server from which an audio file is streamed is aware of
+ transmission or coding problems resulting in interruptions in the
+ audio stream. In these cases, the size of the buffer can be
+ recommended by the server using this frame. If the 'embedded info
+ flag' is true (1) then this indicates that an ID3 tag with the
+ maximum size described in 'Buffer size' may occur in the audio
+ stream. In such case the tag should reside between two MPEG [MPEG]
+ frames, if the audio is MPEG encoded. If the position of the next tag
+ is known, 'offset to next tag' may be used. The offset is calculated
+ from the end of tag in which this frame resides to the first byte of
+ the header in the next. This field may be omitted. Embedded tags are
+ generally not recommended since this could render unpredictable
+ behaviour from present software/hardware.
+
+ For applications like streaming audio it might be an idea to embed
+ tags into the audio stream though. If the clients connects to
+ individual connections like HTTP and there is a possibility to begin
+ every transmission with a tag, then this tag should include a
+ 'recommended buffer size' frame. If the client is connected to a
+ arbitrary point in the stream, such as radio or multicast, then the
+ 'recommended buffer size' frame SHOULD be included in every tag.
+
+ The 'Buffer size' should be kept to a minimum. There may only be one
+ "RBUF" frame in each tag.
+
+ <Header for 'Recommended buffer size', ID: "RBUF">
+ Buffer size $xx xx xx
+ Embedded info flag %0000000x
+ Offset to next tag $xx xx xx xx
+
+
+4.19. Audio encryption
+
+ This frame indicates if the actual audio stream is encrypted, and by
+ whom. Since standardisation of such encryption scheme is beyond this
+ document, all "AENC" frames begin with a terminated string with a
+ URL containing an email address, or a link to a location where an
+ email address can be found, that belongs to the organisation
+ responsible for this specific encrypted audio file. Questions
+ regarding the encrypted audio should be sent to the email address
+ specified. If a $00 is found directly after the 'Frame size' and the
+ audio file indeed is encrypted, the whole file may be considered
+ useless.
+
+ After the 'Owner identifier', a pointer to an unencrypted part of the
+ audio can be specified. The 'Preview start' and 'Preview length' is
+ described in frames. If no part is unencrypted, these fields should
+ be left zeroed. After the 'preview length' field follows optionally a
+ data block required for decryption of the audio. There may be more
+ than one "AENC" frames in a tag, but only one with the same 'Owner
+ identifier'.
+
+ <Header for 'Audio encryption', ID: "AENC">
+ Owner identifier <text string> $00
+ Preview start $xx xx
+ Preview length $xx xx
+ Encryption info <binary data>
+
+
+4.20. Linked information
+
+ To keep information duplication as low as possible this frame may be
+ used to link information from another ID3v2 tag that might reside in
+ another audio file or alone in a binary file. It is RECOMMENDED that
+ this method is only used when the files are stored on a CD-ROM or
+ other circumstances when the risk of file separation is low. The
+ frame contains a frame identifier, which is the frame that should be
+ linked into this tag, a URL [URL] field, where a reference to the
+ file where the frame is given, and additional ID data, if needed.
+ Data should be retrieved from the first tag found in the file to
+ which this link points. There may be more than one "LINK" frame in a
+ tag, but only one with the same contents. A linked frame is to be
+ considered as part of the tag and has the same restrictions as if it
+ was a physical part of the tag (i.e. only one "RVRB" frame allowed,
+ whether it's linked or not).
+
+ <Header for 'Linked information', ID: "LINK">
+ Frame identifier $xx xx xx xx
+ URL <text string> $00
+ ID and additional data <text string(s)>
+
+ Frames that may be linked and need no additional data are "ASPI",
+ "ETCO", "EQU2", "MCID", "MLLT", "OWNE", "RVA2", "RVRB", "SYTC", the
+ text information frames and the URL link frames.
+
+ The "AENC", "APIC", "GEOB" and "TXXX" frames may be linked with
+ the content descriptor as additional ID data.
+
+ The "USER" frame may be linked with the language field as additional
+ ID data.
+
+ The "PRIV" frame may be linked with the owner identifier as
+ additional ID data.
+
+ The "COMM", "SYLT" and "USLT" frames may be linked with three bytes
+ of language descriptor directly followed by a content descriptor as
+ additional ID data.
+
+
+4.21. Position synchronisation frame
+
+ This frame delivers information to the listener of how far into the
+ audio stream he picked up; in effect, it states the time offset from
+ the first frame in the stream. The frame layout is:
+
+ <Head for 'Position synchronisation', ID: "POSS">
+ Time stamp format $xx
+ Position $xx (xx ...)
+
+ Where time stamp format is:
+
+ $01 Absolute time, 32 bit sized, using MPEG frames as unit
+ $02 Absolute time, 32 bit sized, using milliseconds as unit
+
+ and position is where in the audio the listener starts to receive,
+ i.e. the beginning of the next frame. If this frame is used in the
+ beginning of a file the value is always 0. There may only be one
+ "POSS" frame in each tag.
+
+
+4.22. Terms of use frame
+
+ This frame contains a brief description of the terms of use and
+ ownership of the file. More detailed information concerning the legal
+ terms might be available through the "WCOP" frame. Newlines are
+ allowed in the text. There may be more than one 'Terms of use' frame
+ in a tag, but only one with the same 'Language'.
+
+ <Header for 'Terms of use frame', ID: "USER">
+ Text encoding $xx
+ Language $xx xx xx
+ The actual text <text string according to encoding>
+
+
+4.23. Ownership frame
+
+ The ownership frame might be used as a reminder of a made transaction
+ or, if signed, as proof. Note that the "USER" and "TOWN" frames are
+ good to use in conjunction with this one. The frame begins, after the
+ frame ID, size and encoding fields, with a 'price paid' field. The
+ first three characters of this field contains the currency used for
+ the transaction, encoded according to ISO 4217 [ISO-4217] alphabetic
+ currency code. Concatenated to this is the actual price paid, as a
+ numerical string using "." as the decimal separator. Next is an 8
+ character date string (YYYYMMDD) followed by a string with the name
+ of the seller as the last field in the frame. There may only be one
+ "OWNE" frame in a tag.
+
+ <Header for 'Ownership frame', ID: "OWNE">
+ Text encoding $xx
+ Price paid <text string> $00
+ Date of purch. <text string>
+ Seller <text string according to encoding>
+
+
+4.24. Commercial frame
+
+ This frame enables several competing offers in the same tag by
+ bundling all needed information. That makes this frame rather complex
+ but it's an easier solution than if one tries to achieve the same
+ result with several frames. The frame begins, after the frame ID,
+ size and encoding fields, with a price string field. A price is
+ constructed by one three character currency code, encoded according
+ to ISO 4217 [ISO-4217] alphabetic currency code, followed by a
+ numerical value where "." is used as decimal separator. In the price
+ string several prices may be concatenated, separated by a "/"
+ character, but there may only be one currency of each type.
+
+ The price string is followed by an 8 character date string in the
+ format YYYYMMDD, describing for how long the price is valid. After
+ that is a contact URL, with which the user can contact the seller,
+ followed by a one byte 'received as' field. It describes how the
+ audio is delivered when bought according to the following list:
+
+ $00 Other
+ $01 Standard CD album with other songs
+ $02 Compressed audio on CD
+ $03 File over the Internet
+ $04 Stream over the Internet
+ $05 As note sheets
+ $06 As note sheets in a book with other sheets
+ $07 Music on other media
+ $08 Non-musical merchandise
+
+ Next follows a terminated string with the name of the seller followed
+ by a terminated string with a short description of the product. The
+ last thing is the ability to include a company logotype. The first of
+ them is the 'Picture MIME type' field containing information about
+ which picture format is used. In the event that the MIME media type
+ name is omitted, "image/" will be implied. Currently only "image/png"
+ and "image/jpeg" are allowed. This format string is followed by the
+ binary picture data. This two last fields may be omitted if no
+ picture is attached. There may be more than one 'commercial frame' in
+ a tag, but no two may be identical.
+
+ <Header for 'Commercial frame', ID: "COMR">
+ Text encoding $xx
+ Price string <text string> $00
+ Valid until <text string>
+ Contact URL <text string> $00
+ Received as $xx
+ Name of seller <text string according to encoding> $00 (00)
+ Description <text string according to encoding> $00 (00)
+ Picture MIME type <string> $00
+ Seller logo <binary data>
+
+
+4.25. Encryption method registration
+
+ To identify with which method a frame has been encrypted the
+ encryption method must be registered in the tag with this frame. The
+ 'Owner identifier' is a null-terminated string with a URL [URL]
+ containing an email address, or a link to a location where an email
+ address can be found, that belongs to the organisation responsible
+ for this specific encryption method. Questions regarding the
+ encryption method should be sent to the indicated email address. The
+ 'Method symbol' contains a value that is associated with this method
+ throughout the whole tag, in the range $80-F0. All other values are
+ reserved. The 'Method symbol' may optionally be followed by
+ encryption specific data. There may be several "ENCR" frames in a tag
+ but only one containing the same symbol and only one containing the
+ same owner identifier. The method must be used somewhere in the tag.
+ See the description of the frame encryption flag in the ID3v2
+ structure document [ID3v2-strct] for more information.
+
+ <Header for 'Encryption method registration', ID: "ENCR">
+ Owner identifier <text string> $00
+ Method symbol $xx
+ Encryption data <binary data>
+
+
+4.26. Group identification registration
+
+ This frame enables grouping of otherwise unrelated frames. This can
+ be used when some frames are to be signed. To identify which frames
+ belongs to a set of frames a group identifier must be registered in
+ the tag with this frame. The 'Owner identifier' is a null-terminated
+ string with a URL [URL] containing an email address, or a link to a
+ location where an email address can be found, that belongs to the
+ organisation responsible for this grouping. Questions regarding the
+ grouping should be sent to the indicated email address. The 'Group
+ symbol' contains a value that associates the frame with this group
+ throughout the whole tag, in the range $80-F0. All other values are
+ reserved. The 'Group symbol' may optionally be followed by some group
+ specific data, e.g. a digital signature. There may be several "GRID"
+ frames in a tag but only one containing the same symbol and only one
+ containing the same owner identifier. The group symbol must be used
+ somewhere in the tag. See the description of the frame grouping flag
+ in the ID3v2 structure document [ID3v2-strct] for more information.
+
+ <Header for 'Group ID registration', ID: "GRID">
+ Owner identifier <text string> $00
+ Group symbol $xx
+ Group dependent data <binary data>
+
+
+4.27. Private frame
+
+ This frame is used to contain information from a software producer
+ that its program uses and does not fit into the other frames. The
+ frame consists of an 'Owner identifier' string and the binary data.
+ The 'Owner identifier' is a null-terminated string with a URL [URL]
+ containing an email address, or a link to a location where an email
+ address can be found, that belongs to the organisation responsible
+ for the frame. Questions regarding the frame should be sent to the
+ indicated email address. The tag may contain more than one "PRIV"
+ frame but only with different contents.
+
+ <Header for 'Private frame', ID: "PRIV">
+ Owner identifier <text string> $00
+ The private data <binary data>
+
+
+4.28. Signature frame
+
+ This frame enables a group of frames, grouped with the 'Group
+ identification registration', to be signed. Although signatures can
+ reside inside the registration frame, it might be desired to store
+ the signature elsewhere, e.g. in watermarks. There may be more than
+ one 'signature frame' in a tag, but no two may be identical.
+
+ <Header for 'Signature frame', ID: "SIGN">
+ Group symbol $xx
+ Signature <binary data>
+
+
+4.29. Seek frame
+
+ This frame indicates where other tags in a file/stream can be found.
+ The 'minimum offset to next tag' is calculated from the end of this
+ tag to the beginning of the next. There may only be one 'seek frame'
+ in a tag.
+
+ <Header for 'Seek frame', ID: "SEEK">
+ Minimum offset to next tag $xx xx xx xx
+
+
+4.30. Audio seek point index
+
+ Audio files with variable bit rates are intrinsically difficult to
+ deal with in the case of seeking within the file. The ASPI frame
+ makes seeking easier by providing a list a seek points within the
+ audio file. The seek points are a fractional offset within the audio
+ data, providing a starting point from which to find an appropriate
+ point to start decoding. The presence of an ASPI frame requires the
+ existence of a TLEN frame, indicating the duration of the file in
+ milliseconds. There may only be one 'audio seek point index' frame in
+ a tag.
+
+ <Header for 'Seek Point Index', ID: "ASPI">
+ Indexed data start (S) $xx xx xx xx
+ Indexed data length (L) $xx xx xx xx
+ Number of index points (N) $xx xx
+ Bits per index point (b) $xx
+
+ Then for every index point the following data is included;
+
+ Fraction at index (Fi) $xx (xx)
+
+ 'Indexed data start' is a byte offset from the beginning of the file.
+ 'Indexed data length' is the byte length of the audio data being
+ indexed. 'Number of index points' is the number of index points, as
+ the name implies. The recommended number is 100. 'Bits per index
+ point' is 8 or 16, depending on the chosen precision. 8 bits works
+ well for short files (less than 5 minutes of audio), while 16 bits is
+ advantageous for long files. 'Fraction at index' is the numerator of
+ the fraction representing a relative position in the data. The
+ denominator is 2 to the power of b.
+
+ Here are the algorithms to be used in the calculation. The known data
+ must be the offset of the start of the indexed data (S), the offset
+ of the end of the indexed data (E), the number of index points (N),
+ the offset at index i (Oi). We calculate the fraction at index i
+ (Fi).
+
+ Oi is the offset of the frame whose start is soonest after the point
+ for which the time offset is (i/N * duration).
+
+ The frame data should be calculated as follows:
+
+ Fi = Oi/L * 2^b (rounded down to the nearest integer)
+
+ Offset calculation should be calculated as follows from data in the
+ frame:
+
+ Oi = (Fi/2^b)*L (rounded up to the nearest integer)
+
+
+5. Copyright
+
+ Copyright (C) Martin Nilsson 2000. All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that a reference to this document is included on all
+ such copies and derivative works. However, this document itself may
+ not be modified in any way and reissued as the original document.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE AUTHORS DISCLAIMS ALL WARRANTIES, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+ THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+6. References
+
+ [CDDB] Compact Disc Data Base
+
+ <url:http://www.cddb.com>
+
+ [ID3v2.3.0] Martin Nilsson, "ID3v2 informal standard".
+
+ <url:http://www.id3.org/id3v2.3.0.txt>
+
+ [ID3v2-strct] Martin Nilsson,
+ "ID3 tag version 2.4.0 - Main Structure"
+
+ <url:http//www.id3.org/id3v2.4.0-structure.txt>
+
+ [ISO-639-2] ISO/FDIS 639-2.
+ Codes for the representation of names of languages, Part 2: Alpha-3
+ code. Technical committee / subcommittee: TC 37 / SC 2
+
+ [ISO-4217] ISO 4217:1995.
+ Codes for the representation of currencies and funds.
+ Technical committee / subcommittee: TC 68
+
+ [ISO-8859-1] ISO/IEC DIS 8859-1.
+ 8-bit single-byte coded graphic character sets, Part 1: Latin
+ alphabet No. 1. Technical committee / subcommittee: JTC 1 / SC 2
+
+ [ISRC] ISO 3901:1986
+ International Standard Recording Code (ISRC).
+ Technical committee / subcommittee: TC 46 / SC 9
+
+ [JFIF] JPEG File Interchange Format, version 1.02
+
+ <url:http://www.w3.org/Graphics/JPEG/jfif.txt>
+
+ [KEYWORDS] S. Bradner, 'Key words for use in RFCs to Indicate
+ Requirement Levels', RFC 2119, March 1997.
+
+ <url:ftp://ftp.isi.edu/in-notes/rfc2119.txt>
+
+ [MIME] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part One: Format of Internet Message Bodies",
+ RFC 2045, November 1996.
+
+ <url:ftp://ftp.isi.edu/in-notes/rfc2045.txt>
+
+ [MPEG] ISO/IEC 11172-3:1993.
+ Coding of moving pictures and associated audio for digital storage
+ media at up to about 1,5 Mbit/s, Part 3: Audio.
+ Technical committee / subcommittee: JTC 1 / SC 29
+ and
+ ISO/IEC 13818-3:1995
+ Generic coding of moving pictures and associated audio information,
+ Part 3: Audio.
+ Technical committee / subcommittee: JTC 1 / SC 29
+ and
+ ISO/IEC DIS 13818-3
+ Generic coding of moving pictures and associated audio information,
+ Part 3: Audio (Revision of ISO/IEC 13818-3:1995)
+
+
+ [PNG] Portable Network Graphics, version 1.0
+
+ <url:http://www.w3.org/TR/REC-png-multi.html>
+
+ [URL] T. Berners-Lee, L. Masinter & M. McCahill, "Uniform Resource
+ Locators (URL).", RFC 1738, December 1994.
+
+ <url:ftp://ftp.isi.edu/in-notes/rfc1738.txt>
+
+ [ZLIB] P. Deutsch, Aladdin Enterprises & J-L. Gailly, "ZLIB
+ Compressed
+ Data Format Specification version 3.3", RFC 1950, May 1996.
+
+ <url:ftp://ftp.isi.edu/in-notes/rfc1950.txt>
+
+
+7. Appendix
+
+
+A. Appendix A - Genre List from ID3v1
+
+ The following genres is defined in ID3v1
+
+ 0.Blues
+ 1.Classic Rock
+ 2.Country
+ 3.Dance
+ 4.Disco
+ 5.Funk
+ 6.Grunge
+ 7.Hip-Hop
+ 8.Jazz
+ 9.Metal
+ 10.New Age
+ 11.Oldies
+ 12.Other
+ 13.Pop
+ 14.R&B
+ 15.Rap
+ 16.Reggae
+ 17.Rock
+ 18.Techno
+ 19.Industrial
+ 20.Alternative
+ 21.Ska
+ 22.Death Metal
+ 23.Pranks
+ 24.Soundtrack
+ 25.Euro-Techno
+ 26.Ambient
+ 27.Trip-Hop
+ 28.Vocal
+ 29.Jazz+Funk
+ 30.Fusion
+ 31.Trance
+ 32.Classical
+ 33.Instrumental
+ 34.Acid
+ 35.House
+ 36.Game
+ 37.Sound Clip
+ 38.Gospel
+ 39.Noise
+ 40.AlternRock
+ 41.Bass
+ 42.Soul
+ 43.Punk
+ 44.Space
+ 45.Meditative
+ 46.Instrumental Pop
+ 47.Instrumental Rock
+ 48.Ethnic
+ 49.Gothic
+ 50.Darkwave
+ 51.Techno-Industrial
+ 52.Electronic
+ 53.Pop-Folk
+ 54.Eurodance
+ 55.Dream
+ 56.Southern Rock
+ 57.Comedy
+ 58.Cult
+ 59.Gangsta
+ 60.Top 40
+ 61.Christian Rap
+ 62.Pop/Funk
+ 63.Jungle
+ 64.Native American
+ 65.Cabaret
+ 66.New Wave
+ 67.Psychadelic
+ 68.Rave
+ 69.Showtunes
+ 70.Trailer
+ 71.Lo-Fi
+ 72.Tribal
+ 73.Acid Punk
+ 74.Acid Jazz
+ 75.Polka
+ 76.Retro
+ 77.Musical
+ 78.Rock & Roll
+ 79.Hard Rock
+
+
+8. Author's Address
+
+ Written by
+
+ Martin Nilsson
+ Rydsvägen 246 C. 30
+ SE-584 34 Linköping
+ Sweden
+
+ Email: nilsson@id3.org
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2.4.0-structure.txt b/libs/taglib/taglib/mpeg/id3v2/id3v2.4.0-structure.txt
new file mode 100644
index 0000000000..5fa156a0ad
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2.4.0-structure.txt
@@ -0,0 +1,733 @@
+
+Informal standard M. Nilsson
+Document: id3v2.4.0-structure.txt 16 September 2001
+
+
+ ID3 tag version 2.4.0 - Main Structure
+
+Status of this document
+
+ This document is an informal standard and replaces the ID3v2.3.0
+ standard [ID3v2]. A formal standard will use another revision number
+ even if the content is identical to document. The contents in this
+ document may change for clarifications but never for added or altered
+ functionallity.
+
+ Distribution of this document is unlimited.
+
+
+Abstract
+
+ This document describes the main structure of ID3v2.4.0, which is a
+ revised version of the ID3v2 informal standard [ID3v2] version
+ 2.3.0. The ID3v2 offers a flexible way of storing audio meta
+ information within the audio file itself. The information may be
+ technical information, such as equalisation curves, as well as
+ title, performer, copyright etc.
+
+ ID3v2.4.0 is meant to be as close as possible to ID3v2.3.0 in order
+ to allow for implementations to be revised as easily as possible.
+
+
+1. Table of contents
+
+ Status of this document
+ Abstract
+ 1. Table of contents
+ 2. Conventions in this document
+ 2. Standard overview
+ 3. ID3v2 overview
+ 3.1. ID3v2 header
+ 3.2. ID3v2 extended header
+ 3.3. Padding
+ 3.4. ID3v2 footer
+ 4. ID3v2 frames overview
+ 4.1. Frame header flags
+ 4.1.1. Frame status flags
+ 4.1.2. Frame format flags
+ 5. Tag location
+ 6. Unsynchronisation
+ 6.1. The unsynchronisation scheme
+ 6.2. Synchsafe integers
+ 7. Copyright
+ 8. References
+ 9. Author's Address
+
+
+2. Conventions in this document
+
+ Text within "" is a text string exactly as it appears in a tag.
+ Numbers preceded with $ are hexadecimal and numbers preceded with %
+ are binary. $xx is used to indicate a byte with unknown content. %x
+ is used to indicate a bit with unknown content. The most significant
+ bit (MSB) of a byte is called 'bit 7' and the least significant bit
+ (LSB) is called 'bit 0'.
+
+ A tag is the whole tag described in this document. A frame is a block
+ of information in the tag. The tag consists of a header, frames and
+ optional padding. A field is a piece of information; one value, a
+ string etc. A numeric string is a string that consists of the
+ characters "0123456789" only.
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in RFC 2119 [KEYWORDS].
+
+
+3. ID3v2 overview
+
+ ID3v2 is a general tagging format for audio, which makes it possible
+ to store meta data about the audio inside the audio file itself. The
+ ID3 tag described in this document is mainly targeted at files
+ encoded with MPEG-1/2 layer I, MPEG-1/2 layer II, MPEG-1/2 layer III
+ and MPEG-2.5, but may work with other types of encoded audio or as a
+ stand alone format for audio meta data.
+
+ ID3v2 is designed to be as flexible and expandable as possible to
+ meet new meta information needs that might arise. To achieve that
+ ID3v2 is constructed as a container for several information blocks,
+ called frames, whose format need not be known to the software that
+ encounters them. At the start of every frame is an unique and
+ predefined identifier, a size descriptor that allows software to skip
+ unknown frames and a flags field. The flags describes encoding
+ details and if the frame should remain in the tag, should it be
+ unknown to the software, if the file is altered.
+
+ The bitorder in ID3v2 is most significant bit first (MSB). The
+ byteorder in multibyte numbers is most significant byte first (e.g.
+ $12345678 would be encoded $12 34 56 78), also known as big endian
+ and network byte order.
+
+ Overall tag structure:
+
+ +-----------------------------+
+ | Header (10 bytes) |
+ +-----------------------------+
+ | Extended Header |
+ | (variable length, OPTIONAL) |
+ +-----------------------------+
+ | Frames (variable length) |
+ +-----------------------------+
+ | Padding |
+ | (variable length, OPTIONAL) |
+ +-----------------------------+
+ | Footer (10 bytes, OPTIONAL) |
+ +-----------------------------+
+
+ In general, padding and footer are mutually exclusive. See details in
+ sections 3.3, 3.4 and 5.
+
+
+3.1. ID3v2 header
+
+ The first part of the ID3v2 tag is the 10 byte tag header, laid out
+ as follows:
+
+ ID3v2/file identifier "ID3"
+ ID3v2 version $04 00
+ ID3v2 flags %abcd0000
+ ID3v2 size 4 * %0xxxxxxx
+
+ The first three bytes of the tag are always "ID3", to indicate that
+ this is an ID3v2 tag, directly followed by the two version bytes. The
+ first byte of ID3v2 version is its major version, while the second
+ byte is its revision number. In this case this is ID3v2.4.0. All
+ revisions are backwards compatible while major versions are not. If
+ software with ID3v2.4.0 and below support should encounter version
+ five or higher it should simply ignore the whole tag. Version or
+ revision will never be $FF.
+
+ The version is followed by the ID3v2 flags field, of which currently
+ four flags are used.
+
+
+ a - Unsynchronisation
+
+ Bit 7 in the 'ID3v2 flags' indicates whether or not
+ unsynchronisation is applied on all frames (see section 6.1 for
+ details); a set bit indicates usage.
+
+
+ b - Extended header
+
+ The second bit (bit 6) indicates whether or not the header is
+ followed by an extended header. The extended header is described in
+ section 3.2. A set bit indicates the presence of an extended
+ header.
+
+
+ c - Experimental indicator
+
+ The third bit (bit 5) is used as an 'experimental indicator'. This
+ flag SHALL always be set when the tag is in an experimental stage.
+
+
+ d - Footer present
+
+ Bit 4 indicates that a footer (section 3.4) is present at the very
+ end of the tag. A set bit indicates the presence of a footer.
+
+
+ All the other flags MUST be cleared. If one of these undefined flags
+ are set, the tag might not be readable for a parser that does not
+ know the flags function.
+
+ The ID3v2 tag size is stored as a 32 bit synchsafe integer (section
+ 6.2), making a total of 28 effective bits (representing up to 256MB).
+
+ The ID3v2 tag size is the sum of the byte length of the extended
+ header, the padding and the frames after unsynchronisation. If a
+ footer is present this equals to ('total size' - 20) bytes, otherwise
+ ('total size' - 10) bytes.
+
+ An ID3v2 tag can be detected with the following pattern:
+ $49 44 33 yy yy xx zz zz zz zz
+ Where yy is less than $FF, xx is the 'flags' byte and zz is less than
+ $80.
+
+
+3.2. Extended header
+
+ The extended header contains information that can provide further
+ insight in the structure of the tag, but is not vital to the correct
+ parsing of the tag information; hence the extended header is
+ optional.
+
+ Extended header size 4 * %0xxxxxxx
+ Number of flag bytes $01
+ Extended Flags $xx
+
+ Where the 'Extended header size' is the size of the whole extended
+ header, stored as a 32 bit synchsafe integer. An extended header can
+ thus never have a size of fewer than six bytes.
+
+ The extended flags field, with its size described by 'number of flag
+ bytes', is defined as:
+
+ %0bcd0000
+
+ Each flag that is set in the extended header has data attached, which
+ comes in the order in which the flags are encountered (i.e. the data
+ for flag 'b' comes before the data for flag 'c'). Unset flags cannot
+ have any attached data. All unknown flags MUST be unset and their
+ corresponding data removed when a tag is modified.
+
+ Every set flag's data starts with a length byte, which contains a
+ value between 0 and 127 ($00 - $7f), followed by data that has the
+ field length indicated by the length byte. If a flag has no attached
+ data, the value $00 is used as length byte.
+
+
+ b - Tag is an update
+
+ If this flag is set, the present tag is an update of a tag found
+ earlier in the present file or stream. If frames defined as unique
+ are found in the present tag, they are to override any
+ corresponding ones found in the earlier tag. This flag has no
+ corresponding data.
+
+ Flag data length $00
+
+ c - CRC data present
+
+ If this flag is set, a CRC-32 [ISO-3309] data is included in the
+ extended header. The CRC is calculated on all the data between the
+ header and footer as indicated by the header's tag length field,
+ minus the extended header. Note that this includes the padding (if
+ there is any), but excludes the footer. The CRC-32 is stored as an
+ 35 bit synchsafe integer, leaving the upper four bits always
+ zeroed.
+
+ Flag data length $05
+ Total frame CRC 5 * %0xxxxxxx
+
+ d - Tag restrictions
+
+ For some applications it might be desired to restrict a tag in more
+ ways than imposed by the ID3v2 specification. Note that the
+ presence of these restrictions does not affect how the tag is
+ decoded, merely how it was restricted before encoding. If this flag
+ is set the tag is restricted as follows:
+
+ Flag data length $01
+ Restrictions %ppqrrstt
+
+ p - Tag size restrictions
+
+ 00 No more than 128 frames and 1 MB total tag size.
+ 01 No more than 64 frames and 128 KB total tag size.
+ 10 No more than 32 frames and 40 KB total tag size.
+ 11 No more than 32 frames and 4 KB total tag size.
+
+ q - Text encoding restrictions
+
+ 0 No restrictions
+ 1 Strings are only encoded with ISO-8859-1 [ISO-8859-1] or
+ UTF-8 [UTF-8].
+
+ r - Text fields size restrictions
+
+ 00 No restrictions
+ 01 No string is longer than 1024 characters.
+ 10 No string is longer than 128 characters.
+ 11 No string is longer than 30 characters.
+
+ Note that nothing is said about how many bytes is used to
+ represent those characters, since it is encoding dependent. If a
+ text frame consists of more than one string, the sum of the
+ strungs is restricted as stated.
+
+ s - Image encoding restrictions
+
+ 0 No restrictions
+ 1 Images are encoded only with PNG [PNG] or JPEG [JFIF].
+
+ t - Image size restrictions
+
+ 00 No restrictions
+ 01 All images are 256x256 pixels or smaller.
+ 10 All images are 64x64 pixels or smaller.
+ 11 All images are exactly 64x64 pixels, unless required
+ otherwise.
+
+
+3.3. Padding
+
+ It is OPTIONAL to include padding after the final frame (at the end
+ of the ID3 tag), making the size of all the frames together smaller
+ than the size given in the tag header. A possible purpose of this
+ padding is to allow for adding a few additional frames or enlarge
+ existing frames within the tag without having to rewrite the entire
+ file. The value of the padding bytes must be $00. A tag MUST NOT have
+ any padding between the frames or between the tag header and the
+ frames. Furthermore it MUST NOT have any padding when a tag footer is
+ added to the tag.
+
+
+3.4. ID3v2 footer
+
+ To speed up the process of locating an ID3v2 tag when searching from
+ the end of a file, a footer can be added to the tag. It is REQUIRED
+ to add a footer to an appended tag, i.e. a tag located after all
+ audio data. The footer is a copy of the header, but with a different
+ identifier.
+
+ ID3v2 identifier "3DI"
+ ID3v2 version $04 00
+ ID3v2 flags %abcd0000
+ ID3v2 size 4 * %0xxxxxxx
+
+
+4. ID3v2 frame overview
+
+ All ID3v2 frames consists of one frame header followed by one or more
+ fields containing the actual information. The header is always 10
+ bytes and laid out as follows:
+
+ Frame ID $xx xx xx xx (four characters)
+ Size 4 * %0xxxxxxx
+ Flags $xx xx
+
+ The frame ID is made out of the characters capital A-Z and 0-9.
+ Identifiers beginning with "X", "Y" and "Z" are for experimental
+ frames and free for everyone to use, without the need to set the
+ experimental bit in the tag header. Bear in mind that someone else
+ might have used the same identifier as you. All other identifiers are
+ either used or reserved for future use.
+
+ The frame ID is followed by a size descriptor containing the size of
+ the data in the final frame, after encryption, compression and
+ unsynchronisation. The size is excluding the frame header ('total
+ frame size' - 10 bytes) and stored as a 32 bit synchsafe integer.
+
+ In the frame header the size descriptor is followed by two flag
+ bytes. These flags are described in section 4.1.
+
+ There is no fixed order of the frames' appearance in the tag,
+ although it is desired that the frames are arranged in order of
+ significance concerning the recognition of the file. An example of
+ such order: UFID, TIT2, MCDI, TRCK ...
+
+ A tag MUST contain at least one frame. A frame must be at least 1
+ byte big, excluding the header.
+
+ If nothing else is said, strings, including numeric strings and URLs
+ [URL], are represented as ISO-8859-1 [ISO-8859-1] characters in the
+ range $20 - $FF. Such strings are represented in frame descriptions
+ as <text string>, or <full text string> if newlines are allowed. If
+ nothing else is said newline character is forbidden. In ISO-8859-1 a
+ newline is represented, when allowed, with $0A only.
+
+ Frames that allow different types of text encoding contains a text
+ encoding description byte. Possible encodings:
+
+ $00 ISO-8859-1 [ISO-8859-1]. Terminated with $00.
+ $01 UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM. All
+ strings in the same frame SHALL have the same byteorder.
+ Terminated with $00 00.
+ $02 UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
+ Terminated with $00 00.
+ $03 UTF-8 [UTF-8] encoded Unicode [UNICODE]. Terminated with $00.
+
+ Strings dependent on encoding are represented in frame descriptions
+ as <text string according to encoding>, or <full text string
+ according to encoding> if newlines are allowed. Any empty strings of
+ type $01 which are NULL-terminated may have the Unicode BOM followed
+ by a Unicode NULL ($FF FE 00 00 or $FE FF 00 00).
+
+ The timestamp fields are based on a subset of ISO 8601. When being as
+ precise as possible the format of a time string is
+ yyyy-MM-ddTHH:mm:ss (year, "-", month, "-", day, "T", hour (out of
+ 24), ":", minutes, ":", seconds), but the precision may be reduced by
+ removing as many time indicators as wanted. Hence valid timestamps
+ are
+ yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddTHH, yyyy-MM-ddTHH:mm and
+ yyyy-MM-ddTHH:mm:ss. All time stamps are UTC. For durations, use
+ the slash character as described in 8601, and for multiple non-
+ contiguous dates, use multiple strings, if allowed by the frame
+ definition.
+
+ The three byte language field, present in several frames, is used to
+ describe the language of the frame's content, according to ISO-639-2
+ [ISO-639-2]. The language should be represented in lower case. If the
+ language is not known the string "XXX" should be used.
+
+ All URLs [URL] MAY be relative, e.g. "picture.png", "../doc.txt".
+
+ If a frame is longer than it should be, e.g. having more fields than
+ specified in this document, that indicates that additions to the
+ frame have been made in a later version of the ID3v2 standard. This
+ is reflected by the revision number in the header of the tag.
+
+
+4.1. Frame header flags
+
+ In the frame header the size descriptor is followed by two flag
+ bytes. All unused flags MUST be cleared. The first byte is for
+ 'status messages' and the second byte is a format description. If an
+ unknown flag is set in the first byte the frame MUST NOT be changed
+ without that bit cleared. If an unknown flag is set in the second
+ byte the frame is likely to not be readable. Some flags in the second
+ byte indicates that extra information is added to the header. These
+ fields of extra information is ordered as the flags that indicates
+ them. The flags field is defined as follows (l and o left out because
+ ther resemblence to one and zero):
+
+ %0abc0000 %0h00kmnp
+
+ Some frame format flags indicate that additional information fields
+ are added to the frame. This information is added after the frame
+ header and before the frame data in the same order as the flags that
+ indicates them. I.e. the four bytes of decompressed size will precede
+ the encryption method byte. These additions affects the 'frame size'
+ field, but are not subject to encryption or compression.
+
+ The default status flags setting for a frame is, unless stated
+ otherwise, 'preserved if tag is altered' and 'preserved if file is
+ altered', i.e. %00000000.
+
+
+4.1.1. Frame status flags
+
+ a - Tag alter preservation
+
+ This flag tells the tag parser what to do with this frame if it is
+ unknown and the tag is altered in any way. This applies to all
+ kinds of alterations, including adding more padding and reordering
+ the frames.
+
+ 0 Frame should be preserved.
+ 1 Frame should be discarded.
+
+
+ b - File alter preservation
+
+ This flag tells the tag parser what to do with this frame if it is
+ unknown and the file, excluding the tag, is altered. This does not
+ apply when the audio is completely replaced with other audio data.
+
+ 0 Frame should be preserved.
+ 1 Frame should be discarded.
+
+
+ c - Read only
+
+ This flag, if set, tells the software that the contents of this
+ frame are intended to be read only. Changing the contents might
+ break something, e.g. a signature. If the contents are changed,
+ without knowledge of why the frame was flagged read only and
+ without taking the proper means to compensate, e.g. recalculating
+ the signature, the bit MUST be cleared.
+
+
+4.1.2. Frame format flags
+
+ h - Grouping identity
+
+ This flag indicates whether or not this frame belongs in a group
+ with other frames. If set, a group identifier byte is added to the
+ frame. Every frame with the same group identifier belongs to the
+ same group.
+
+ 0 Frame does not contain group information
+ 1 Frame contains group information
+
+
+ k - Compression
+
+ This flag indicates whether or not the frame is compressed.
+ A 'Data Length Indicator' byte MUST be included in the frame.
+
+ 0 Frame is not compressed.
+ 1 Frame is compressed using zlib [zlib] deflate method.
+ If set, this requires the 'Data Length Indicator' bit
+ to be set as well.
+
+
+ m - Encryption
+
+ This flag indicates whether or not the frame is encrypted. If set,
+ one byte indicating with which method it was encrypted will be
+ added to the frame. See description of the ENCR frame for more
+ information about encryption method registration. Encryption
+ should be done after compression. Whether or not setting this flag
+ requires the presence of a 'Data Length Indicator' depends on the
+ specific algorithm used.
+
+ 0 Frame is not encrypted.
+ 1 Frame is encrypted.
+
+ n - Unsynchronisation
+
+ This flag indicates whether or not unsynchronisation was applied
+ to this frame. See section 6 for details on unsynchronisation.
+ If this flag is set all data from the end of this header to the
+ end of this frame has been unsynchronised. Although desirable, the
+ presence of a 'Data Length Indicator' is not made mandatory by
+ unsynchronisation.
+
+ 0 Frame has not been unsynchronised.
+ 1 Frame has been unsyrchronised.
+
+ p - Data length indicator
+
+ This flag indicates that a data length indicator has been added to
+ the frame. The data length indicator is the value one would write
+ as the 'Frame length' if all of the frame format flags were
+ zeroed, represented as a 32 bit synchsafe integer.
+
+ 0 There is no Data Length Indicator.
+ 1 A data length Indicator has been added to the frame.
+
+
+5. Tag location
+
+ The default location of an ID3v2 tag is prepended to the audio so
+ that players can benefit from the information when the data is
+ streamed. It is however possible to append the tag, or make a
+ prepend/append combination. When deciding upon where an unembedded
+ tag should be located, the following order of preference SHOULD be
+ considered.
+
+ 1. Prepend the tag.
+
+ 2. Prepend a tag with all vital information and add a second tag at
+ the end of the file, before tags from other tagging systems. The
+ first tag is required to have a SEEK frame.
+
+ 3. Add a tag at the end of the file, before tags from other tagging
+ systems.
+
+ In case 2 and 3 the tag can simply be appended if no other known tags
+ are present. The suggested method to find ID3v2 tags are:
+
+ 1. Look for a prepended tag using the pattern found in section 3.1.
+
+ 2. If a SEEK frame was found, use its values to guide further
+ searching.
+
+ 3. Look for a tag footer, scanning from the back of the file.
+
+ For every new tag that is found, the old tag should be discarded
+ unless the update flag in the extended header (section 3.2) is set.
+
+
+6. Unsynchronisation
+
+ The only purpose of unsynchronisation is to make the ID3v2 tag as
+ compatible as possible with existing software and hardware. There is
+ no use in 'unsynchronising' tags if the file is only to be processed
+ only by ID3v2 aware software and hardware. Unsynchronisation is only
+ useful with tags in MPEG 1/2 layer I, II and III, MPEG 2.5 and AAC
+ files.
+
+
+6.1. The unsynchronisation scheme
+
+ Whenever a false synchronisation is found within the tag, one zeroed
+ byte is inserted after the first false synchronisation byte. The
+ format of synchronisations that should be altered by ID3 encoders is
+ as follows:
+
+ %11111111 111xxxxx
+
+ and should be replaced with:
+
+ %11111111 00000000 111xxxxx
+
+ This has the side effect that all $FF 00 combinations have to be
+ altered, so they will not be affected by the decoding process.
+ Therefore all the $FF 00 combinations have to be replaced with the
+ $FF 00 00 combination during the unsynchronisation.
+
+ To indicate usage of the unsynchronisation, the unsynchronisation
+ flag in the frame header should be set. This bit MUST be set if the
+ frame was altered by the unsynchronisation and SHOULD NOT be set if
+ unaltered. If all frames in the tag are unsynchronised the
+ unsynchronisation flag in the tag header SHOULD be set. It MUST NOT
+ be set if the tag has a frame which is not unsynchronised.
+
+ Assume the first byte of the audio to be $FF. The special case when
+ the last byte of the last frame is $FF and no padding nor footer is
+ used will then introduce a false synchronisation. This can be solved
+ by adding a footer, adding padding or unsynchronising the frame and
+ add $00 to the end of the frame data, thus adding more byte to the
+ frame size than a normal unsynchronisation would. Although not
+ preferred, it is allowed to apply the last method on all frames
+ ending with $FF.
+
+ It is preferred that the tag is either completely unsynchronised or
+ not unsynchronised at all. A completely unsynchronised tag has no
+ false synchonisations in it, as defined above, and does not end with
+ $FF. A completely non-unsynchronised tag contains no unsynchronised
+ frames, and thus the unsynchronisation flag in the header is cleared.
+
+ Do bear in mind, that if compression or encryption is used, the
+ unsynchronisation scheme MUST be applied afterwards. When decoding an
+ unsynchronised frame, the unsynchronisation scheme MUST be reversed
+ first, encryption and decompression afterwards.
+
+
+6.2. Synchsafe integers
+
+ In some parts of the tag it is inconvenient to use the
+ unsychronisation scheme because the size of unsynchronised data is
+ not known in advance, which is particularly problematic with size
+ descriptors. The solution in ID3v2 is to use synchsafe integers, in
+ which there can never be any false synchs. Synchsafe integers are
+ integers that keep its highest bit (bit 7) zeroed, making seven bits
+ out of eight available. Thus a 32 bit synchsafe integer can store 28
+ bits of information.
+
+ Example:
+
+ 255 (%11111111) encoded as a 16 bit synchsafe integer is 383
+ (%00000001 01111111).
+
+
+7. Copyright
+
+ Copyright (C) Martin Nilsson 2000. All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that a reference to this document is included on all
+ such copies and derivative works. However, this document itself may
+ not be modified in any way and reissued as the original document.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked.
+
+ This document and the information contained herein is provided on an
+ 'AS IS' basis and THE AUTHORS DISCLAIMS ALL WARRANTIES, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
+ THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+8. References
+
+ [ID3v2] Martin Nilsson, 'ID3v2 informal standard'.
+
+ <url:http://www.id3.org/id3v2.3.0.txt>
+
+ [ISO-639-2] ISO/FDIS 639-2.
+ 'Codes for the representation of names of languages, Part 2: Alpha-3
+ code.' Technical committee / subcommittee: TC 37 / SC 2
+
+ [ISO-3309] ISO 3309
+ 'Information Processing Systems--Data Communication High-Level Data
+ Link Control Procedure--Frame Structure', IS 3309, October 1984, 3rd
+ Edition.
+
+ [ISO-8859-1] ISO/IEC DIS 8859-1.
+ '8-bit single-byte coded graphic character sets, Part 1: Latin
+ alphabet No. 1.' Technical committee / subcommittee: JTC 1 / SC 2
+
+ [JFIF] 'JPEG File Interchange Format, version 1.02'
+
+ <url:http://www.w3.org/Graphics/JPEG/jfif.txt>
+
+ [KEYWORDS] S. Bradner, 'Key words for use in RFCs to Indicate
+ Requirement Levels', RFC 2119, March 1997.
+
+ <url:ftp://ftp.isi.edu/in-notes/rfc2119.txt>
+
+ [MPEG] ISO/IEC 11172-3:1993.
+ 'Coding of moving pictures and associated audio for digital storage
+ media at up to about 1,5 Mbit/s, Part 3: Audio.'
+ Technical committee / subcommittee: JTC 1 / SC 29
+ and
+ ISO/IEC 13818-3:1995
+ 'Generic coding of moving pictures and associated audio information,
+ Part 3: Audio.'
+ Technical committee / subcommittee: JTC 1 / SC 29
+ and
+ ISO/IEC DIS 13818-3
+ 'Generic coding of moving pictures and associated audio information,
+ Part 3: Audio (Revision of ISO/IEC 13818-3:1995)'
+
+ [PNG] 'Portable Network Graphics, version 1.0'
+
+ <url:http://www.w3.org/TR/REC-png-multi.html>
+
+ [UNICODE] The Unicode Consortium,
+ 'The Unicode Standard Version 3.0', ISBN 0-201-61633-5.
+
+ <url:http://www.unicode.org/unicode/standard/versions/Unicode3.0.htm>
+
+ [URL] T. Berners-Lee, L. Masinter & M. McCahill, 'Uniform Resource
+ Locators (URL)', RFC 1738, December 1994.
+
+ <url:ftp://ftp.isi.edu/in-notes/rfc1738.txt>
+
+ [UTF-8] F. Yergeau, 'UTF-8, a transformation format of ISO 10646',
+ RFC 2279, January 1998.
+
+ <url:ftp://ftp.isi.edu/in-notes/rfc2279.txt>
+
+ [UTF-16] F. Yergeau, 'UTF-16, an encoding of ISO 10646', RFC 2781,
+ February 2000.
+
+ <url:ftp://ftp.isi.edu/in-notes/rfc2781.txt>
+
+ [ZLIB] P. Deutsch, Aladdin Enterprises & J-L. Gailly, 'ZLIB
+ Compressed Data Format Specification version 3.3', RFC 1950,
+ May 1996.
+
+ <url:ftp://ftp.isi.edu/in-notes/rfc1950.txt>
+
+
+9. Author's Address
+
+ Written by
+
+ Martin Nilsson
+ Rydsvägen 246 C. 30
+ SE-584 34 Linköping
+ Sweden
+
+ Email: nilsson@id3.org
+
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2extendedheader.cpp b/libs/taglib/taglib/mpeg/id3v2/id3v2extendedheader.cpp
new file mode 100644
index 0000000000..bd470a0add
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2extendedheader.cpp
@@ -0,0 +1,71 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include "id3v2extendedheader.h"
+#include "id3v2synchdata.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class ExtendedHeader::ExtendedHeaderPrivate
+{
+public:
+ ExtendedHeaderPrivate() : size(0) {}
+
+ uint size;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public methods
+////////////////////////////////////////////////////////////////////////////////
+
+ExtendedHeader::ExtendedHeader()
+{
+ d = new ExtendedHeaderPrivate();
+}
+
+ExtendedHeader::~ExtendedHeader()
+{
+ delete d;
+}
+
+TagLib::uint ExtendedHeader::size() const
+{
+ return d->size;
+}
+
+void ExtendedHeader::setData(const ByteVector &data)
+{
+ parse(data);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void ExtendedHeader::parse(const ByteVector &data)
+{
+ d->size = SynchData::toUInt(data.mid(0, 4)); // (structure 3.2 "Extended header size")
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2extendedheader.h b/libs/taglib/taglib/mpeg/id3v2/id3v2extendedheader.h
new file mode 100644
index 0000000000..9750fae69a
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2extendedheader.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ID3V2EXTENDEDHEADER_H
+#define TAGLIB_ID3V2EXTENDEDHEADER_H
+
+#include "taglib_export.h"
+#include "tbytevector.h"
+#include "taglib.h"
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ //! ID3v2 extended header implementation
+
+ /*!
+ * This class implements ID3v2 extended headers. It attempts to follow,
+ * both semantically and programatically, the structure specified in
+ * the ID3v2 standard. The API is based on the properties of ID3v2 extended
+ * headers specified there. If any of the terms used in this documentation
+ * are unclear please check the specification in the linked section.
+ * (Structure, <a href="id3v2-structure.html#3.2">3.2</a>)
+ */
+
+ class TAGLIB_EXPORT ExtendedHeader
+ {
+ public:
+ /*!
+ * Constructs an empty ID3v2 extended header.
+ */
+ ExtendedHeader();
+
+ /*!
+ * Destroys the extended header.
+ */
+ virtual ~ExtendedHeader();
+
+ /*!
+ * Returns the size of the extended header. This is variable for the
+ * extended header.
+ */
+ uint size() const;
+
+ /*!
+ * Sets the data that will be used as the extended header. Since the
+ * length is not known before the extended header has been parsed, this
+ * should just be a pointer to the first byte of the extended header. It
+ * will determine the length internally and make that available through
+ * size().
+ */
+ void setData(const ByteVector &data);
+
+ protected:
+ /*!
+ * Called by setData() to parse the extended header data. It makes this
+ * information available through the public API.
+ */
+ void parse(const ByteVector &data);
+
+ private:
+ ExtendedHeader(const ExtendedHeader &);
+ ExtendedHeader &operator=(const ExtendedHeader &);
+
+ class ExtendedHeaderPrivate;
+ ExtendedHeaderPrivate *d;
+ };
+
+ }
+}
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2footer.cpp b/libs/taglib/taglib/mpeg/id3v2/id3v2footer.cpp
new file mode 100644
index 0000000000..387bcf3229
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2footer.cpp
@@ -0,0 +1,60 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include "id3v2footer.h"
+#include "id3v2header.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class Footer::FooterPrivate
+{
+public:
+ static const uint size = 10;
+};
+
+Footer::Footer()
+{
+
+}
+
+Footer::~Footer()
+{
+
+}
+
+const unsigned int Footer::size()
+{
+ return FooterPrivate::size;
+}
+
+ByteVector Footer::render(const Header *header) const
+{
+ ByteVector headerData = header->render();
+ headerData[0] = '3';
+ headerData[1] = 'D';
+ headerData[2] = 'I';
+ return headerData;
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2footer.h b/libs/taglib/taglib/mpeg/id3v2/id3v2footer.h
new file mode 100644
index 0000000000..112e75810a
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2footer.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ID3V2FOOTER_H
+#define TAGLIB_ID3V2FOOTER_H
+
+#include "taglib_export.h"
+#include "tbytevector.h"
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ class Header;
+
+ //! ID3v2 footer implementation
+
+ /*!
+ * Per the ID3v2 specification, the tag's footer is just a copy of the
+ * information in the header. As such there is no API for reading the
+ * data from the header, it can just as easily be done from the header.
+ *
+ * In fact, at this point, TagLib does not even parse the footer since
+ * it is not useful internally. However, if the flag to include a footer
+ * has been set in the ID3v2::Tag, TagLib will render a footer.
+ */
+
+ class TAGLIB_EXPORT Footer
+ {
+ public:
+ /*!
+ * Constructs an empty ID3v2 footer.
+ */
+ Footer();
+ /*!
+ * Destroys the footer.
+ */
+ virtual ~Footer();
+
+ /*!
+ * Returns the size of the footer. Presently this is always 10 bytes.
+ */
+ static const unsigned int size();
+
+ /*!
+ * Renders the footer based on the data in \a header.
+ */
+ ByteVector render(const Header *header) const;
+
+ private:
+ Footer(const Footer &);
+ Footer &operator=(const Footer &);
+
+ class FooterPrivate;
+ FooterPrivate *d;
+ };
+
+ }
+}
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2frame.cpp b/libs/taglib/taglib/mpeg/id3v2/id3v2frame.cpp
new file mode 100644
index 0000000000..7c76ac7b94
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2frame.cpp
@@ -0,0 +1,549 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef HAVE_ZLIB
+#include <config.h>
+#endif
+
+#if HAVE_ZLIB
+#include <zlib.h>
+#endif
+
+#include <bitset>
+
+#include <tdebug.h>
+#include <tstringlist.h>
+
+#include "id3v2frame.h"
+#include "id3v2synchdata.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class Frame::FramePrivate
+{
+public:
+ FramePrivate() :
+ header(0)
+ {}
+
+ ~FramePrivate()
+ {
+ delete header;
+ }
+
+ Frame::Header *header;
+};
+
+namespace
+{
+ bool isValidFrameID(const ByteVector &frameID)
+ {
+ if(frameID.size() != 4)
+ return false;
+
+ for(ByteVector::ConstIterator it = frameID.begin(); it != frameID.end(); it++) {
+ if( (*it < 'A' || *it > 'Z') && (*it < '1' || *it > '9') ) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// static methods
+////////////////////////////////////////////////////////////////////////////////
+
+TagLib::uint Frame::headerSize()
+{
+ return Header::size();
+}
+
+TagLib::uint Frame::headerSize(uint version)
+{
+ return Header::size(version);
+}
+
+ByteVector Frame::textDelimiter(String::Type t)
+{
+ ByteVector d = char(0);
+ if(t == String::UTF16 || t == String::UTF16BE || t == String::UTF16LE)
+ d.append(char(0));
+ return d;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+Frame::~Frame()
+{
+ delete d;
+}
+
+ByteVector Frame::frameID() const
+{
+ if(d->header)
+ return d->header->frameID();
+ else
+ return ByteVector::null;
+}
+
+TagLib::uint Frame::size() const
+{
+ if(d->header)
+ return d->header->frameSize();
+ else
+ return 0;
+}
+
+void Frame::setData(const ByteVector &data)
+{
+ parse(data);
+}
+
+void Frame::setText(const String &)
+{
+
+}
+
+ByteVector Frame::render() const
+{
+ ByteVector fieldData = renderFields();
+ d->header->setFrameSize(fieldData.size());
+ ByteVector headerData = d->header->render();
+
+ return headerData + fieldData;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+Frame::Frame(const ByteVector &data)
+{
+ d = new FramePrivate;
+ d->header = new Header(data);
+}
+
+Frame::Frame(Header *h)
+{
+ d = new FramePrivate;
+ d->header = h;
+}
+
+Frame::Header *Frame::header() const
+{
+ return d->header;
+}
+
+void Frame::setHeader(Header *h, bool deleteCurrent)
+{
+ if(deleteCurrent)
+ delete d->header;
+
+ d->header = h;
+}
+
+void Frame::parse(const ByteVector &data)
+{
+ if(d->header)
+ d->header->setData(data);
+ else
+ d->header = new Header(data);
+
+ parseFields(fieldData(data));
+}
+
+ByteVector Frame::fieldData(const ByteVector &frameData) const
+{
+ uint headerSize = Header::size(d->header->version());
+
+ uint frameDataOffset = headerSize;
+ uint frameDataLength = size();
+
+ if(d->header->compression() || d->header->dataLengthIndicator()) {
+ frameDataLength = SynchData::toUInt(frameData.mid(headerSize, 4));
+ frameDataOffset += 4;
+ }
+
+#if HAVE_ZLIB
+ if(d->header->compression() &&
+ !d->header->encryption())
+ {
+ ByteVector data(frameDataLength);
+ uLongf uLongTmp = frameDataLength;
+ ::uncompress((Bytef *) data.data(),
+ (uLongf *) &uLongTmp,
+ (Bytef *) frameData.data() + frameDataOffset,
+ size());
+ return data;
+ }
+ else
+#endif
+ return frameData.mid(frameDataOffset, frameDataLength);
+}
+
+String Frame::readStringField(const ByteVector &data, String::Type encoding, int *position)
+{
+ int start = 0;
+
+ if(!position)
+ position = &start;
+
+ ByteVector delimiter = textDelimiter(encoding);
+
+ int end = data.find(delimiter, *position, delimiter.size());
+
+ if(end < *position)
+ return String::null;
+
+ String str = String(data.mid(*position, end - *position), encoding);
+
+ *position = end + delimiter.size();
+
+ return str;
+}
+
+String::Type Frame::checkEncoding(const StringList &fields, String::Type encoding) // static
+{
+ if(encoding != String::Latin1)
+ return encoding;
+
+ for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) {
+ if(!(*it).isLatin1()) {
+ debug("Frame::checkEncoding() -- Rendering using UTF8.");
+ return String::UTF8;
+ }
+ }
+
+ return String::Latin1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Frame::Header class
+////////////////////////////////////////////////////////////////////////////////
+
+class Frame::Header::HeaderPrivate
+{
+public:
+ HeaderPrivate() :
+ frameSize(0),
+ version(4),
+ tagAlterPreservation(false),
+ fileAlterPreservation(false),
+ readOnly(false),
+ groupingIdentity(false),
+ compression(false),
+ encryption(false),
+ unsynchronisation(false),
+ dataLengthIndicator(false)
+ {}
+
+ ByteVector frameID;
+ uint frameSize;
+ uint version;
+
+ // flags
+
+ bool tagAlterPreservation;
+ bool fileAlterPreservation;
+ bool readOnly;
+ bool groupingIdentity;
+ bool compression;
+ bool encryption;
+ bool unsynchronisation;
+ bool dataLengthIndicator;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// static members (Frame::Header)
+////////////////////////////////////////////////////////////////////////////////
+
+TagLib::uint Frame::Header::size()
+{
+ return size(4);
+}
+
+TagLib::uint Frame::Header::size(uint version)
+{
+ switch(version) {
+ case 0:
+ case 1:
+ case 2:
+ return 6;
+ case 3:
+ case 4:
+ default:
+ return 10;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// public members (Frame::Header)
+////////////////////////////////////////////////////////////////////////////////
+
+Frame::Header::Header(const ByteVector &data, bool synchSafeInts)
+{
+ d = new HeaderPrivate;
+ setData(data, synchSafeInts);
+}
+
+Frame::Header::Header(const ByteVector &data, uint version)
+{
+ d = new HeaderPrivate;
+ setData(data, version);
+}
+
+Frame::Header::~Header()
+{
+ delete d;
+}
+
+void Frame::Header::setData(const ByteVector &data, bool synchSafeInts)
+{
+ setData(data, uint(synchSafeInts ? 4 : 3));
+}
+
+void Frame::Header::setData(const ByteVector &data, uint version)
+{
+ d->version = version;
+
+ switch(version) {
+ case 0:
+ case 1:
+ case 2:
+ {
+ // ID3v2.2
+
+ if(data.size() < 3) {
+ debug("You must at least specify a frame ID.");
+ return;
+ }
+
+ // Set the frame ID -- the first three bytes
+
+ d->frameID = data.mid(0, 3);
+
+ // If the full header information was not passed in, do not continue to the
+ // steps to parse the frame size and flags.
+
+ if(data.size() < 6) {
+ d->frameSize = 0;
+ return;
+ }
+
+ d->frameSize = data.mid(3, 3).toUInt();
+
+ break;
+ }
+ case 3:
+ {
+ // ID3v2.3
+
+ if(data.size() < 4) {
+ debug("You must at least specify a frame ID.");
+ return;
+ }
+
+ // Set the frame ID -- the first four bytes
+
+ d->frameID = data.mid(0, 4);
+
+ // If the full header information was not passed in, do not continue to the
+ // steps to parse the frame size and flags.
+
+ if(data.size() < 10) {
+ d->frameSize = 0;
+ return;
+ }
+
+ // Set the size -- the frame size is the four bytes starting at byte four in
+ // the frame header (structure 4)
+
+ d->frameSize = data.mid(4, 4).toUInt();
+
+ { // read the first byte of flags
+ std::bitset<8> flags(data[8]);
+ d->tagAlterPreservation = flags[7]; // (structure 3.3.1.a)
+ d->fileAlterPreservation = flags[6]; // (structure 3.3.1.b)
+ d->readOnly = flags[5]; // (structure 3.3.1.c)
+ }
+
+ { // read the second byte of flags
+ std::bitset<8> flags(data[9]);
+ d->compression = flags[7]; // (structure 3.3.1.i)
+ d->encryption = flags[6]; // (structure 3.3.1.j)
+ d->groupingIdentity = flags[5]; // (structure 3.3.1.k)
+ }
+ break;
+ }
+ case 4:
+ default:
+ {
+ // ID3v2.4
+
+ if(data.size() < 4) {
+ debug("You must at least specify a frame ID.");
+ return;
+ }
+
+ // Set the frame ID -- the first four bytes
+
+ d->frameID = data.mid(0, 4);
+
+ // If the full header information was not passed in, do not continue to the
+ // steps to parse the frame size and flags.
+
+ if(data.size() < 10) {
+ d->frameSize = 0;
+ return;
+ }
+
+ // Set the size -- the frame size is the four bytes starting at byte four in
+ // the frame header (structure 4)
+
+ d->frameSize = SynchData::toUInt(data.mid(4, 4));
+#ifndef NO_ITUNES_HACKS
+ // iTunes writes v2.4 tags with v2.3-like frame sizes
+ if(d->frameSize > 127) {
+ if(!isValidFrameID(data.mid(d->frameSize + 10, 4))) {
+ unsigned int uintSize = data.mid(4, 4).toUInt();
+ if(isValidFrameID(data.mid(uintSize + 10, 4))) {
+ d->frameSize = uintSize;
+ }
+ }
+ }
+#endif
+
+ { // read the first byte of flags
+ std::bitset<8> flags(data[8]);
+ d->tagAlterPreservation = flags[6]; // (structure 4.1.1.a)
+ d->fileAlterPreservation = flags[5]; // (structure 4.1.1.b)
+ d->readOnly = flags[4]; // (structure 4.1.1.c)
+ }
+
+ { // read the second byte of flags
+ std::bitset<8> flags(data[9]);
+ d->groupingIdentity = flags[6]; // (structure 4.1.2.h)
+ d->compression = flags[3]; // (structure 4.1.2.k)
+ d->encryption = flags[2]; // (structure 4.1.2.m)
+ d->unsynchronisation = flags[1]; // (structure 4.1.2.n)
+ d->dataLengthIndicator = flags[0]; // (structure 4.1.2.p)
+ }
+ break;
+ }
+ }
+}
+
+ByteVector Frame::Header::frameID() const
+{
+ return d->frameID;
+}
+
+void Frame::Header::setFrameID(const ByteVector &id)
+{
+ d->frameID = id.mid(0, 4);
+}
+
+TagLib::uint Frame::Header::frameSize() const
+{
+ return d->frameSize;
+}
+
+void Frame::Header::setFrameSize(uint size)
+{
+ d->frameSize = size;
+}
+
+TagLib::uint Frame::Header::version() const
+{
+ return d->version;
+}
+
+bool Frame::Header::tagAlterPreservation() const
+{
+ return d->tagAlterPreservation;
+}
+
+void Frame::Header::setTagAlterPreservation(bool preserve)
+{
+ d->tagAlterPreservation = preserve;
+}
+
+bool Frame::Header::fileAlterPreservation() const
+{
+ return d->fileAlterPreservation;
+}
+
+bool Frame::Header::readOnly() const
+{
+ return d->readOnly;
+}
+
+bool Frame::Header::groupingIdentity() const
+{
+ return d->groupingIdentity;
+}
+
+bool Frame::Header::compression() const
+{
+ return d->compression;
+}
+
+bool Frame::Header::encryption() const
+{
+ return d->encryption;
+}
+
+bool Frame::Header::unsycronisation() const
+{
+ return unsynchronisation();
+}
+
+bool Frame::Header::unsynchronisation() const
+{
+ return d->unsynchronisation;
+}
+
+bool Frame::Header::dataLengthIndicator() const
+{
+ return d->dataLengthIndicator;
+}
+
+ByteVector Frame::Header::render() const
+{
+ ByteVector flags(2, char(0)); // just blank for the moment
+
+ ByteVector v = d->frameID + SynchData::fromUInt(d->frameSize) + flags;
+
+ return v;
+}
+
+bool Frame::Header::frameAlterPreservation() const
+{
+ return fileAlterPreservation();
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2frame.h b/libs/taglib/taglib/mpeg/id3v2/id3v2frame.h
new file mode 100644
index 0000000000..e76d060820
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2frame.h
@@ -0,0 +1,414 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ID3V2FRAME_H
+#define TAGLIB_ID3V2FRAME_H
+
+#include "tstring.h"
+#include "tbytevector.h"
+#include "taglib_export.h"
+
+namespace TagLib {
+
+ class StringList;
+
+ namespace ID3v2 {
+
+ class Tag;
+ class FrameFactory;
+
+ //! ID3v2 frame implementation
+
+ /*!
+ * This class is the main ID3v2 frame implementation. In ID3v2, a tag is
+ * split between a collection of frames (which are in turn split into fields
+ * (Structure, <a href="id3v2-structure.html#4">4</a>)
+ * (<a href="id3v2-frames.html">Frames</a>). This class provides an API for
+ * gathering information about and modifying ID3v2 frames. Funtionallity
+ * specific to a given frame type is handed in one of the many subclasses.
+ */
+
+ class TAGLIB_EXPORT Frame
+ {
+ friend class Tag;
+ friend class FrameFactory;
+
+ public:
+ /*!
+ * Destroys this Frame instance.
+ */
+ virtual ~Frame();
+
+ /*!
+ * Returns the Frame ID (Structure, <a href="id3v2-structure.html#4">4</a>)
+ * (Frames, <a href="id3v2-frames.html#4">4</a>)
+ */
+ ByteVector frameID() const;
+
+ /*!
+ * Returns the size of the frame.
+ */
+ uint size() const;
+
+ /*!
+ * Returns the size of the frame header
+ *
+ * \deprecated This is only accurate for ID3v2.3 or ID3v2.4. Please use
+ * the call below which accepts an ID3v2 version number. In the next
+ * non-binary compatible release this will be made into a non-static
+ * member that checks the internal ID3v2 version.
+ */
+ static uint headerSize(); // BIC: remove and make non-static
+
+ /*!
+ * Returns the size of the frame header for the given ID3v2 version.
+ *
+ * \deprecated Please see the explanation above.
+ */
+ static uint headerSize(uint version); // BIC: remove and make non-static
+
+ /*!
+ * Sets the data that will be used as the frame. Since the length is not
+ * known before the frame has been parsed, this should just be a pointer to
+ * the first byte of the frame. It will determine the length internally
+ * and make that available through size().
+ */
+ void setData(const ByteVector &data);
+
+ /*!
+ * Set the text of frame in the sanest way possible. This should only be
+ * reimplemented in frames where there is some logical mapping to text.
+ *
+ * \note If the frame type supports multiple text encodings, this will not
+ * change the text encoding of the frame; the string will be converted to
+ * that frame's encoding. Please use the specific APIs of the frame types
+ * to set the encoding if that is desired.
+ */
+ virtual void setText(const String &text);
+
+ /*!
+ * This returns the textual representation of the data in the frame.
+ * Subclasses must reimplement this method to provide a string
+ * representation of the frame's data.
+ */
+ virtual String toString() const = 0;
+
+ /*!
+ * Render the frame back to its binary format in a ByteVector.
+ */
+ ByteVector render() const;
+
+ /*!
+ * Returns the text delimiter that is used between fields for the string
+ * type \a t.
+ */
+ static ByteVector textDelimiter(String::Type t);
+
+ protected:
+ class Header;
+
+ /*!
+ * Constructs an ID3v2 frame using \a data to read the header information.
+ * All other processing of \a data should be handled in a subclass.
+ *
+ * \note This need not contain anything more than a frame ID, but
+ * \e must constain at least that.
+ */
+ explicit Frame(const ByteVector &data);
+
+ /*!
+ * This creates an Frame using the header \a h.
+ *
+ * The ownership of this header will be assigned to the frame and the
+ * header will be deleted when the frame is destroyed.
+ */
+ Frame(Header *h);
+
+ /*!
+ * Returns a pointer to the frame header.
+ */
+ Header *header() const;
+
+ /*!
+ * Sets the header to \a h. If \a deleteCurrent is true, this will free
+ * the memory of the current header.
+ *
+ * The ownership of this header will be assigned to the frame and the
+ * header will be deleted when the frame is destroyed.
+ */
+ void setHeader(Header *h, bool deleteCurrent = true);
+
+ /*!
+ * Called by setData() to parse the frame data. It makes this information
+ * available through the public API.
+ */
+ void parse(const ByteVector &data);
+
+ /*!
+ * Called by parse() to parse the field data. It makes this information
+ * available through the public API. This must be overridden by the
+ * subclasses.
+ */
+ virtual void parseFields(const ByteVector &data) = 0;
+
+ /*!
+ * Render the field data back to a binary format in a ByteVector. This
+ * must be overridden by subclasses.
+ */
+ virtual ByteVector renderFields() const = 0;
+
+ /*!
+ * Returns a ByteVector containing the field data given the frame data.
+ * This correctly adjusts for the header size plus any additional frame
+ * data that's specified in the frame header flags.
+ */
+ ByteVector fieldData(const ByteVector &frameData) const;
+
+ /*!
+ * Reads a String of type \a encodiong from the ByteVector \a data. If \a
+ * position is passed in it is used both as the starting point and is
+ * updated to replect the position just after the string that has been read.
+ * This is useful for reading strings sequentially.
+ */
+ String readStringField(const ByteVector &data, String::Type encoding,
+ int *positon = 0);
+
+ /*!
+ * Checks a the list of string values to see if they can be used with the
+ * specified encoding and returns the recommended encoding.
+ */
+ static String::Type checkEncoding(const StringList &fields,
+ String::Type encoding);
+
+ private:
+ Frame(const Frame &);
+ Frame &operator=(const Frame &);
+
+ class FramePrivate;
+ friend class FramePrivate;
+ FramePrivate *d;
+ };
+
+ //! ID3v2 frame header implementation
+
+ /*!
+ * The ID3v2 Frame Header (Structure, <a href="id3v2-structure.html#4">4</a>)
+ *
+ * Every ID3v2::Frame has an associated header that gives some general
+ * properties of the frame and also makes it possible to identify the frame
+ * type.
+ *
+ * As such when reading an ID3v2 tag ID3v2::FrameFactory first creates the
+ * frame headers and then creates the appropriate Frame subclass based on
+ * the type and attaches the header.
+ */
+
+ class TAGLIB_EXPORT Frame::Header
+ {
+ public:
+ /*!
+ * Construct a Frame Header based on \a data. \a data must at least
+ * contain a 4 byte frame ID, and optionally can contain flag data and the
+ * frame size. i.e. Just the frame id -- "TALB" -- is a valid value.
+ *
+ * \deprecated Please use the constructor below that accepts a version
+ * number.
+ */
+ Header(const ByteVector &data, bool synchSafeInts);
+
+ /*!
+ * Construct a Frame Header based on \a data. \a data must at least
+ * contain a 4 byte frame ID, and optionally can contain flag data and the
+ * frame size. i.e. Just the frame id -- "TALB" -- is a valid value.
+ *
+ * \a version should be the ID3v2 version of the tag.
+ */
+ explicit Header(const ByteVector &data, uint version = 4);
+
+ /*!
+ * Destroys this Header instance.
+ */
+ virtual ~Header();
+
+ /*!
+ * Sets the data for the Header.
+ *
+ * \deprecated Please use the version below that accepts an ID3v2 version
+ * number.
+ */
+ void setData(const ByteVector &data, bool synchSafeInts);
+
+ /*!
+ * Sets the data for the Header. \a version should indicate the ID3v2
+ * version number of the tag that this frame is contained in.
+ */
+ void setData(const ByteVector &data, uint version = 4);
+
+ /*!
+ * Returns the Frame ID (Structure, <a href="id3v2-structure.html#4">4</a>)
+ * (Frames, <a href="id3v2-frames.html#4">4</a>)
+ */
+ ByteVector frameID() const;
+
+ /*!
+ * Sets the frame's ID to \a id. Only the first four bytes of \a id will
+ * be used.
+ *
+ * \warning This method should in general be avoided. It exists simply to
+ * provide a mechanism for transforming frames from a deprecated frame type
+ * to a newer one -- i.e. TYER to TDRC from ID3v2.3 to ID3v2.4.
+ */
+ void setFrameID(const ByteVector &id);
+
+ /*!
+ * Returns the size of the frame data portion, as set when setData() was
+ * called or set explicitly via setFrameSize().
+ */
+ uint frameSize() const;
+
+ /*!
+ * Sets the size of the frame data portion.
+ */
+ void setFrameSize(uint size);
+
+ /*!
+ * Returns the ID3v2 version of the header (as passed in from the
+ * construction of the header).
+ */
+ uint version() const;
+
+ /*!
+ * Returns the size of the frame header in bytes.
+ *
+ * \deprecated Please use the version of this method that accepts a
+ * version. This is only accurate for ID3v2.3 and ID3v2.4. This will be
+ * removed in the next binary incompatible release (2.0) and will be
+ * replaced with a non-static method that checks the frame version.
+ */
+ static uint size();
+
+ /*!
+ * Returns the size of the frame header in bytes for the ID3v2 version
+ * that's given.
+ *
+ * \deprecated Please see the explanation in the version above.
+ */
+ static uint size(uint version);
+
+ /*!
+ * Returns true if the flag for tag alter preservation is set.
+ *
+ * The semantics are a little backwards from what would seem natural
+ * (setting the preservation flag to throw away the frame), but this
+ * follows the ID3v2 standard.
+ *
+ * \see setTagAlterPreservation()
+ */
+ bool tagAlterPreservation() const;
+
+ /*!
+ * Sets the flag for preservation of this frame if the tag is set. If
+ * this is set to true the frame will not be written when the tag is
+ * saved.
+ *
+ * The semantics are a little backwards from what would seem natural
+ * (setting the preservation flag to throw away the frame), but this
+ * follows the ID3v2 standard.
+ *
+ * \see tagAlterPreservation()
+ */
+ void setTagAlterPreservation(bool discard);
+
+ /*!
+ * Returns true if the flag for file alter preservation is set.
+ *
+ * \note This flag is currently ignored internally in TagLib.
+ */
+ bool fileAlterPreservation() const;
+
+ /*!
+ * Returns true if the frame is meant to be read only.
+ *
+ * \note This flag is currently ignored internally in TagLib.
+ */
+ bool readOnly() const;
+
+ /*!
+ * Returns true if the flag for the grouping identifity is set.
+ *
+ * \note This flag is currently ignored internally in TagLib.
+ */
+ bool groupingIdentity() const;
+
+ /*!
+ * Returns true if compression is enabled for this frame.
+ *
+ * \note This flag is currently ignored internally in TagLib.
+ */
+ bool compression() const;
+
+ /*!
+ * Returns true if encryption is enabled for this frame.
+ *
+ * \note This flag is currently ignored internally in TagLib.
+ */
+ bool encryption() const;
+
+#ifndef DO_NOT_DOCUMENT
+ bool unsycronisation() const;
+#endif
+
+ /*!
+ * Returns true if unsynchronisation is enabled for this frame.
+ */
+ bool unsynchronisation() const;
+
+ /*!
+ * Returns true if the flag for a data length indicator is set.
+ */
+ bool dataLengthIndicator() const;
+
+ /*!
+ * Render the Header back to binary format in a ByteVector.
+ */
+ ByteVector render() const;
+
+ /*!
+ * \deprecated
+ */
+ bool frameAlterPreservation() const;
+
+ private:
+ Header(const Header &);
+ Header &operator=(const Header &);
+
+ class HeaderPrivate;
+ HeaderPrivate *d;
+ };
+
+ }
+}
+
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2framefactory.cpp b/libs/taglib/taglib/mpeg/id3v2/id3v2framefactory.cpp
new file mode 100644
index 0000000000..48a202216c
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2framefactory.cpp
@@ -0,0 +1,407 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef HAVE_ZLIB
+#include <config.h>
+#endif
+
+#include <tdebug.h>
+
+#include "id3v2framefactory.h"
+#include "id3v2synchdata.h"
+
+#include "frames/attachedpictureframe.h"
+#include "frames/commentsframe.h"
+#include "frames/relativevolumeframe.h"
+#include "frames/textidentificationframe.h"
+#include "frames/uniquefileidentifierframe.h"
+#include "frames/unknownframe.h"
+#include "frames/generalencapsulatedobjectframe.h"
+#include "frames/urllinkframe.h"
+#include "frames/unsynchronizedlyricsframe.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class FrameFactory::FrameFactoryPrivate
+{
+public:
+ FrameFactoryPrivate() :
+ defaultEncoding(String::Latin1),
+ useDefaultEncoding(false) {}
+
+ String::Type defaultEncoding;
+ bool useDefaultEncoding;
+
+ template <class T> void setTextEncoding(T *frame)
+ {
+ if(useDefaultEncoding)
+ frame->setTextEncoding(defaultEncoding);
+ }
+};
+
+FrameFactory *FrameFactory::factory = 0;
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+FrameFactory *FrameFactory::instance()
+{
+ if(!factory)
+ factory = new FrameFactory;
+ return factory;
+}
+
+Frame *FrameFactory::createFrame(const ByteVector &data, bool synchSafeInts) const
+{
+ return createFrame(data, uint(synchSafeInts ? 4 : 3));
+}
+
+Frame *FrameFactory::createFrame(const ByteVector &data, uint version) const
+{
+ Header tagHeader;
+ tagHeader.setMajorVersion(version);
+ return createFrame(data, &tagHeader);
+}
+
+Frame *FrameFactory::createFrame(const ByteVector &origData, Header *tagHeader) const
+{
+ ByteVector data = origData;
+ uint version = tagHeader->majorVersion();
+ Frame::Header *header = new Frame::Header(data, version);
+ ByteVector frameID = header->frameID();
+
+ // A quick sanity check -- make sure that the frameID is 4 uppercase Latin1
+ // characters. Also make sure that there is data in the frame.
+
+ if(!frameID.size() == (version < 3 ? 3 : 4) ||
+ header->frameSize() <= uint(header->dataLengthIndicator() ? 4 : 0) ||
+ header->frameSize() > data.size())
+ {
+ delete header;
+ return 0;
+ }
+
+ for(ByteVector::ConstIterator it = frameID.begin(); it != frameID.end(); it++) {
+ if( (*it < 'A' || *it > 'Z') && (*it < '1' || *it > '9') ) {
+ delete header;
+ return 0;
+ }
+ }
+
+ if(version > 3 && (tagHeader->unsynchronisation() || header->unsynchronisation())) {
+ // Data lengths are not part of the encoded data, but since they are synch-safe
+ // integers they will be never actually encoded.
+ ByteVector frameData = data.mid(Frame::Header::size(version), header->frameSize());
+ frameData = SynchData::decode(frameData);
+ data = data.mid(0, Frame::Header::size(version)) + frameData;
+ }
+
+ // TagLib doesn't mess with encrypted frames, so just treat them
+ // as unknown frames.
+
+#if HAVE_ZLIB == 0
+ if(header->compression()) {
+ debug("Compressed frames are currently not supported.");
+ return new UnknownFrame(data, header);
+ }
+#endif
+ if(header->encryption()) {
+ debug("Encrypted frames are currently not supported.");
+ return new UnknownFrame(data, header);
+ }
+
+ if(!updateFrame(header)) {
+ header->setTagAlterPreservation(true);
+ return new UnknownFrame(data, header);
+ }
+
+ // updateFrame() might have updated the frame ID.
+
+ frameID = header->frameID();
+
+ // This is where things get necissarily nasty. Here we determine which
+ // Frame subclass (or if none is found simply an Frame) based
+ // on the frame ID. Since there are a lot of possibilities, that means
+ // a lot of if blocks.
+
+ // Text Identification (frames 4.2)
+
+ if(frameID.startsWith("T")) {
+
+ TextIdentificationFrame *f = frameID != "TXXX"
+ ? new TextIdentificationFrame(data, header)
+ : new UserTextIdentificationFrame(data, header);
+
+ d->setTextEncoding(f);
+
+ if(frameID == "TCON")
+ updateGenre(f);
+
+ return f;
+ }
+
+ // Comments (frames 4.10)
+
+ if(frameID == "COMM") {
+ CommentsFrame *f = new CommentsFrame(data, header);
+ d->setTextEncoding(f);
+ return f;
+ }
+
+ // Attached Picture (frames 4.14)
+
+ if(frameID == "APIC") {
+ AttachedPictureFrame *f = new AttachedPictureFrame(data, header);
+ d->setTextEncoding(f);
+ return f;
+ }
+
+ // Relative Volume Adjustment (frames 4.11)
+
+ if(frameID == "RVA2")
+ return new RelativeVolumeFrame(data, header);
+
+ // Unique File Identifier (frames 4.1)
+
+ if(frameID == "UFID")
+ return new UniqueFileIdentifierFrame(data, header);
+
+ // General Encapsulated Object (frames 4.15)
+
+ if(frameID == "GEOB") {
+ GeneralEncapsulatedObjectFrame *f = new GeneralEncapsulatedObjectFrame(data, header);
+ d->setTextEncoding(f);
+ return f;
+ }
+
+ // URL link (frames 4.3)
+
+ if(frameID.startsWith("W")) {
+ if(frameID != "WXXX") {
+ return new UrlLinkFrame(data, header);
+ }
+ else {
+ UserUrlLinkFrame *f = new UserUrlLinkFrame(data, header);
+ d->setTextEncoding(f);
+ return f;
+ }
+ }
+
+ // Unsynchronized lyric/text transcription (frames 4.8)
+
+ if(frameID == "USLT") {
+ UnsynchronizedLyricsFrame *f = new UnsynchronizedLyricsFrame(data, header);
+ if(d->useDefaultEncoding)
+ f->setTextEncoding(d->defaultEncoding);
+ return f;
+ }
+
+ return new UnknownFrame(data, header);
+}
+
+String::Type FrameFactory::defaultTextEncoding() const
+{
+ return d->defaultEncoding;
+}
+
+void FrameFactory::setDefaultTextEncoding(String::Type encoding)
+{
+ d->useDefaultEncoding = true;
+ d->defaultEncoding = encoding;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+FrameFactory::FrameFactory()
+{
+ d = new FrameFactoryPrivate;
+}
+
+FrameFactory::~FrameFactory()
+{
+ delete d;
+}
+
+bool FrameFactory::updateFrame(Frame::Header *header) const
+{
+ TagLib::ByteVector frameID = header->frameID();
+
+ switch(header->version()) {
+
+ case 2: // ID3v2.2
+ {
+ if(frameID == "CRM" ||
+ frameID == "EQU" ||
+ frameID == "LNK" ||
+ frameID == "RVA" ||
+ frameID == "TIM" ||
+ frameID == "TSI")
+ {
+ debug("ID3v2.4 no longer supports the frame type " + String(frameID) +
+ ". It will be discarded from the tag.");
+ return false;
+ }
+
+ // ID3v2.2 only used 3 bytes for the frame ID, so we need to convert all of
+ // the frames to their 4 byte ID3v2.4 equivalent.
+
+ convertFrame("BUF", "RBUF", header);
+ convertFrame("CNT", "PCNT", header);
+ convertFrame("COM", "COMM", header);
+ convertFrame("CRA", "AENC", header);
+ convertFrame("ETC", "ETCO", header);
+ convertFrame("GEO", "GEOB", header);
+ convertFrame("IPL", "TIPL", header);
+ convertFrame("MCI", "MCDI", header);
+ convertFrame("MLL", "MLLT", header);
+ convertFrame("PIC", "APIC", header);
+ convertFrame("POP", "POPM", header);
+ convertFrame("REV", "RVRB", header);
+ convertFrame("SLT", "SYLT", header);
+ convertFrame("STC", "SYTC", header);
+ convertFrame("TAL", "TALB", header);
+ convertFrame("TBP", "TBPM", header);
+ convertFrame("TCM", "TCOM", header);
+ convertFrame("TCO", "TCON", header);
+ convertFrame("TCR", "TCOP", header);
+ convertFrame("TDA", "TDRC", header);
+ convertFrame("TDY", "TDLY", header);
+ convertFrame("TEN", "TENC", header);
+ convertFrame("TFT", "TFLT", header);
+ convertFrame("TKE", "TKEY", header);
+ convertFrame("TLA", "TLAN", header);
+ convertFrame("TLE", "TLEN", header);
+ convertFrame("TMT", "TMED", header);
+ convertFrame("TOA", "TOAL", header);
+ convertFrame("TOF", "TOFN", header);
+ convertFrame("TOL", "TOLY", header);
+ convertFrame("TOR", "TDOR", header);
+ convertFrame("TOT", "TOAL", header);
+ convertFrame("TP1", "TPE1", header);
+ convertFrame("TP2", "TPE2", header);
+ convertFrame("TP3", "TPE3", header);
+ convertFrame("TP4", "TPE4", header);
+ convertFrame("TPA", "TPOS", header);
+ convertFrame("TPB", "TPUB", header);
+ convertFrame("TRC", "TSRC", header);
+ convertFrame("TRD", "TDRC", header);
+ convertFrame("TRK", "TRCK", header);
+ convertFrame("TSS", "TSSE", header);
+ convertFrame("TT1", "TIT1", header);
+ convertFrame("TT2", "TIT2", header);
+ convertFrame("TT3", "TIT3", header);
+ convertFrame("TXT", "TOLY", header);
+ convertFrame("TXX", "TXXX", header);
+ convertFrame("TYE", "TDRC", header);
+ convertFrame("UFI", "UFID", header);
+ convertFrame("ULT", "USLT", header);
+ convertFrame("WAF", "WOAF", header);
+ convertFrame("WAR", "WOAR", header);
+ convertFrame("WAS", "WOAS", header);
+ convertFrame("WCM", "WCOM", header);
+ convertFrame("WCP", "WCOP", header);
+ convertFrame("WPB", "WPUB", header);
+ convertFrame("WXX", "WXXX", header);
+
+ break;
+ }
+
+ case 3: // ID3v2.3
+ {
+ if(frameID == "EQUA" ||
+ frameID == "RVAD" ||
+ frameID == "TIME" ||
+ frameID == "TRDA" ||
+ frameID == "TSIZ" ||
+ frameID == "TDAT")
+ {
+ debug("ID3v2.4 no longer supports the frame type " + String(frameID) +
+ ". It will be discarded from the tag.");
+ return false;
+ }
+
+ convertFrame("TORY", "TDOR", header);
+ convertFrame("TYER", "TDRC", header);
+
+ break;
+ }
+
+ default:
+
+ // This should catch a typo that existed in TagLib up to and including
+ // version 1.1 where TRDC was used for the year rather than TDRC.
+
+ convertFrame("TRDC", "TDRC", header);
+ break;
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// private members
+////////////////////////////////////////////////////////////////////////////////
+
+void FrameFactory::convertFrame(const char *from, const char *to,
+ Frame::Header *header) const
+{
+ if(header->frameID() != from)
+ return;
+
+ // debug("ID3v2.4 no longer supports the frame type " + String(from) + " It has" +
+ // "been converted to the type " + String(to) + ".");
+
+ header->setFrameID(to);
+}
+
+void FrameFactory::updateGenre(TextIdentificationFrame *frame) const
+{
+ StringList fields;
+ String s = frame->toString();
+
+ while(s.startsWith("(")) {
+
+ int closing = s.find(")");
+
+ if(closing < 0)
+ break;
+
+ fields.append(s.substr(1, closing - 1));
+
+ s = s.substr(closing + 1);
+ }
+
+ if(!s.isEmpty())
+ fields.append(s);
+
+ if(fields.isEmpty())
+ fields.append(String::null);
+
+ frame->setText(fields);
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2framefactory.h b/libs/taglib/taglib/mpeg/id3v2/id3v2framefactory.h
new file mode 100644
index 0000000000..15eb61b7dd
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2framefactory.h
@@ -0,0 +1,167 @@
+ /***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ID3V2FRAMEFACTORY_H
+#define TAGLIB_ID3V2FRAMEFACTORY_H
+
+#include "taglib_export.h"
+#include "tbytevector.h"
+#include "id3v2frame.h"
+#include "id3v2header.h"
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ class TAGLIB_EXPORT TextIdentificationFrame;
+
+ //! A factory for creating ID3v2 frames during parsing
+
+ /*!
+ * This factory abstracts away the frame creation process and instantiates
+ * the appropriate ID3v2::Frame subclasses based on the contents of the
+ * data.
+ *
+ * Reimplementing this factory is the key to adding support for frame types
+ * not directly supported by TagLib to your application. To do so you would
+ * subclass this factory reimplement createFrame(). Then by setting your
+ * factory to be the default factory in ID3v2::Tag constructor or with
+ * MPEG::File::setID3v2FrameFactory() you can implement behavior that will
+ * allow for new ID3v2::Frame subclasses (also provided by you) to be used.
+ *
+ * This implements both <i>abstract factory</i> and <i>singleton</i> patterns
+ * of which more information is available on the web and in software design
+ * textbooks (Notably <i>Design Patters</i>).
+ *
+ * \note You do not need to use this factory to create new frames to add to
+ * an ID3v2::Tag. You can instantiate frame subclasses directly (with new)
+ * and add them to a tag using ID3v2::Tag::addFrame()
+ *
+ * \see ID3v2::Tag::addFrame()
+ */
+
+ class TAGLIB_EXPORT FrameFactory
+ {
+ public:
+ static FrameFactory *instance();
+ /*!
+ * Create a frame based on \a data. \a synchSafeInts should only be set
+ * false if we are parsing an old tag (v2.3 or older) that does not support
+ * synchsafe ints.
+ *
+ * \deprecated Please use the method below that accepts a ID3v2::Header
+ * instance in new code.
+ */
+ Frame *createFrame(const ByteVector &data, bool synchSafeInts) const;
+
+ /*!
+ * Create a frame based on \a data. \a version should indicate the ID3v2
+ * version of the tag. As ID3v2.4 is the most current version of the
+ * standard 4 is the default.
+ *
+ * \deprecated Please use the method below that accepts a ID3v2::Header
+ * instance in new code.
+ */
+ Frame *createFrame(const ByteVector &data, uint version = 4) const;
+
+ /*!
+ * Create a frame based on \a data. \a tagHeader should be a valid
+ * ID3v2::Header instance.
+ */
+ // BIC: make virtual
+ Frame *createFrame(const ByteVector &data, Header *tagHeader) const;
+
+ /*!
+ * Returns the default text encoding for text frames. If setTextEncoding()
+ * has not been explicitly called this will only be used for new text
+ * frames. However, if this value has been set explicitly all frames will be
+ * converted to this type (unless it's explitly set differently for the
+ * individual frame) when being rendered.
+ *
+ * \see setDefaultTextEncoding()
+ */
+ String::Type defaultTextEncoding() const;
+
+ /*!
+ * Set the default text encoding for all text frames that are created to
+ * \a encoding. If no value is set the frames with either default to the
+ * encoding type that was parsed and new frames default to Latin1.
+ *
+ * Valid string types for ID3v2 tags are Latin1, UTF8, UTF16 and UTF16BE.
+ *
+ * \see defaultTextEncoding()
+ */
+ void setDefaultTextEncoding(String::Type encoding);
+
+ protected:
+ /*!
+ * Constructs a frame factory. Because this is a singleton this method is
+ * protected, but may be used for subclasses.
+ */
+ FrameFactory();
+
+ /*!
+ * Destroys the frame factory. In most cases this will never be called (as
+ * is typical of singletons).
+ */
+ virtual ~FrameFactory();
+
+ /*!
+ * This method checks for compliance to the current ID3v2 standard (2.4)
+ * and does nothing in the common case. However if a frame is found that
+ * is not compatible with the current standard, this method either updates
+ * the frame or indicates that it should be discarded.
+ *
+ * This method with return true (with or without changes to the frame) if
+ * this frame should be kept or false if it should be discarded.
+ *
+ * See the id3v2.4.0-changes.txt document for further information.
+ */
+ virtual bool updateFrame(Frame::Header *header) const;
+
+ private:
+ FrameFactory(const FrameFactory &);
+ FrameFactory &operator=(const FrameFactory &);
+
+ /*!
+ * This method is used internally to convert a frame from ID \a from to ID
+ * \a to. If the frame matches the \a from pattern and converts the frame
+ * ID in the \a header or simply does nothing if the frame ID does not match.
+ */
+ void convertFrame(const char *from, const char *to,
+ Frame::Header *header) const;
+
+ void updateGenre(TextIdentificationFrame *frame) const;
+
+ static FrameFactory *factory;
+
+ class FrameFactoryPrivate;
+ FrameFactoryPrivate *d;
+ };
+
+ }
+}
+
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2header.cpp b/libs/taglib/taglib/mpeg/id3v2/id3v2header.cpp
new file mode 100644
index 0000000000..e14adcce15
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2header.cpp
@@ -0,0 +1,243 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include <iostream>
+#include <bitset>
+
+#include <tstring.h>
+#include <tdebug.h>
+
+#include "id3v2header.h"
+#include "id3v2footer.h"
+#include "id3v2synchdata.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class Header::HeaderPrivate
+{
+public:
+ HeaderPrivate() : majorVersion(4),
+ revisionNumber(0),
+ unsynchronisation(false),
+ extendedHeader(false),
+ experimentalIndicator(false),
+ footerPresent(false),
+ tagSize(0) {}
+
+ ~HeaderPrivate() {}
+
+ uint majorVersion;
+ uint revisionNumber;
+
+ bool unsynchronisation;
+ bool extendedHeader;
+ bool experimentalIndicator;
+ bool footerPresent;
+
+ uint tagSize;
+
+ static const uint size = 10;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// static members
+////////////////////////////////////////////////////////////////////////////////
+
+TagLib::uint Header::size()
+{
+ return HeaderPrivate::size;
+}
+
+ByteVector Header::fileIdentifier()
+{
+ return ByteVector::fromCString("ID3");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+Header::Header()
+{
+ d = new HeaderPrivate;
+}
+
+Header::Header(const ByteVector &data)
+{
+ d = new HeaderPrivate;
+ parse(data);
+}
+
+Header::~Header()
+{
+ delete d;
+}
+
+TagLib::uint Header::majorVersion() const
+{
+ return d->majorVersion;
+}
+
+void Header::setMajorVersion(TagLib::uint version)
+{
+ d->majorVersion = version;
+}
+
+TagLib::uint Header::revisionNumber() const
+{
+ return d->revisionNumber;
+}
+
+bool Header::unsynchronisation() const
+{
+ return d->unsynchronisation;
+}
+
+bool Header::extendedHeader() const
+{
+ return d->extendedHeader;
+}
+
+bool Header::experimentalIndicator() const
+{
+ return d->experimentalIndicator;
+}
+
+bool Header::footerPresent() const
+{
+ return d->footerPresent;
+}
+
+TagLib::uint Header::tagSize() const
+{
+ return d->tagSize;
+}
+
+TagLib::uint Header::completeTagSize() const
+{
+ if(d->footerPresent)
+ return d->tagSize + d->size + Footer::size();
+ else
+ return d->tagSize + d->size;
+}
+
+void Header::setTagSize(uint s)
+{
+ d->tagSize = s;
+}
+
+void Header::setData(const ByteVector &data)
+{
+ parse(data);
+}
+
+ByteVector Header::render() const
+{
+ ByteVector v;
+
+ // add the file identifier -- "ID3"
+ v.append(fileIdentifier());
+
+ // add the version number -- we always render a 2.4.0 tag regardless of what
+ // the tag originally was.
+
+ v.append(char(4));
+ v.append(char(0));
+
+ // Currently we don't actually support writing extended headers, footers or
+ // unsynchronized tags, make sure that the flags are set accordingly.
+
+ d->extendedHeader = false;
+ d->footerPresent = false;
+ d->unsynchronisation = false;
+
+ // render and add the flags
+ std::bitset<8> flags;
+
+ flags[7] = d->unsynchronisation;
+ flags[6] = d->extendedHeader;
+ flags[5] = d->experimentalIndicator;
+ flags[4] = d->footerPresent;
+
+ v.append(char(flags.to_ulong()));
+
+ // add the size
+ v.append(SynchData::fromUInt(d->tagSize));
+
+ return v;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void Header::parse(const ByteVector &data)
+{
+ if(data.size() < size())
+ return;
+
+
+ // do some sanity checking -- even in ID3v2.3.0 and less the tag size is a
+ // synch-safe integer, so all bytes must be less than 128. If this is not
+ // true then this is an invalid tag.
+
+ // note that we're doing things a little out of order here -- the size is
+ // later in the bytestream than the version
+
+ ByteVector sizeData = data.mid(6, 4);
+
+ if(sizeData.size() != 4) {
+ d->tagSize = 0;
+ debug("TagLib::ID3v2::Header::parse() - The tag size as read was 0 bytes!");
+ return;
+ }
+
+ for(ByteVector::Iterator it = sizeData.begin(); it != sizeData.end(); it++) {
+ if(uchar(*it) >= 128) {
+ d->tagSize = 0;
+ debug("TagLib::ID3v2::Header::parse() - One of the size bytes in the id3v2 header was greater than the allowed 128.");
+ return;
+ }
+ }
+
+ // The first three bytes, data[0..2], are the File Identifier, "ID3". (structure 3.1 "file identifier")
+
+ // Read the version number from the fourth and fifth bytes.
+ d->majorVersion = data[3]; // (structure 3.1 "major version")
+ d->revisionNumber = data[4]; // (structure 3.1 "revision number")
+
+ // Read the flags, the first four bits of the sixth byte.
+ std::bitset<8> flags(data[5]);
+
+ d->unsynchronisation = flags[7]; // (structure 3.1.a)
+ d->extendedHeader = flags[6]; // (structure 3.1.b)
+ d->experimentalIndicator = flags[5]; // (structure 3.1.c)
+ d->footerPresent = flags[4]; // (structure 3.1.d)
+
+ // Get the size from the remaining four bytes (read above)
+
+ d->tagSize = SynchData::toUInt(sizeData); // (structure 3.1 "size")
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2header.h b/libs/taglib/taglib/mpeg/id3v2/id3v2header.h
new file mode 100644
index 0000000000..99a7e7ff7c
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2header.h
@@ -0,0 +1,175 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ID3V2HEADER_H
+#define TAGLIB_ID3V2HEADER_H
+
+#include "tbytevector.h"
+#include "taglib_export.h"
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ //! An implementation of ID3v2 headers
+
+ /*!
+ * This class implements ID3v2 headers. It attempts to follow, both
+ * semantically and programatically, the structure specified in
+ * the ID3v2 standard. The API is based on the properties of ID3v2 headers
+ * specified there. If any of the terms used in this documentation are
+ * unclear please check the specification in the linked section.
+ * (Structure, <a href="id3v2-structure.html#3.1">3.1</a>)
+ */
+
+ class TAGLIB_EXPORT Header
+ {
+ public:
+ /*!
+ * Constructs an empty ID3v2 header.
+ */
+ Header();
+
+ /*!
+ * Constructs an ID3v2 header based on \a data. parse() is called
+ * immediately.
+ */
+ Header(const ByteVector &data);
+
+ /*!
+ * Destroys the header.
+ */
+ virtual ~Header();
+
+ /*!
+ * Returns the major version number. (Note: This is the 4, not the 2 in
+ * ID3v2.4.0. The 2 is implied.)
+ */
+ uint majorVersion() const;
+
+ /*!
+ * Set the the major version number to \a version. (Note: This is
+ * the 4, not the 2 in ID3v2.4.0. The 2 is implied.)
+ * \see majorVersion()
+ *
+ * \note This is used by the internal parser; this will not change the
+ * version which is written and in general should not be called by API
+ * users.
+ */
+ void setMajorVersion(uint version);
+
+ /*!
+ * Returns the revision number. (Note: This is the 0, not the 4 in
+ * ID3v2.4.0. The 2 is implied.)
+ */
+ uint revisionNumber() const;
+
+ /*!
+ * Returns true if unsynchronisation has been applied to all frames.
+ */
+ bool unsynchronisation() const;
+
+ /*!
+ * Returns true if an extended header is present in the tag.
+ */
+ bool extendedHeader() const;
+
+ /*!
+ * Returns true if the experimental indicator flag is set.
+ */
+ bool experimentalIndicator() const;
+
+ /*!
+ * Returns true if a footer is present in the tag.
+ */
+ bool footerPresent() const;
+ /*!
+ * Returns the tag size in bytes. This is the size of the frame content.
+ * The size of the \e entire tag will be this plus the header size (10
+ * bytes) and, if present, the footer size (potentially another 10 bytes).
+ *
+ * \note This is the value as read from the header to which TagLib attempts
+ * to provide an API to; it was not a design decision on the part of TagLib
+ * to not include the mentioned portions of the tag in the \e size.
+ *
+ * \see completeTagSize()
+ */
+ uint tagSize() const;
+
+ /*!
+ * Returns the tag size, including the header and, if present, the footer
+ * size.
+ *
+ * \see tagSize()
+ */
+ uint completeTagSize() const;
+
+ /*!
+ * Set the tag size to \a s.
+ * \see tagSize()
+ */
+ void setTagSize(uint s);
+
+ /*!
+ * Returns the size of the header. Presently this is always 10 bytes.
+ */
+ static uint size();
+
+ /*!
+ * Returns the string used to identify and ID3v2 tag inside of a file.
+ * Presently this is always "ID3".
+ */
+ static ByteVector fileIdentifier();
+
+ /*!
+ * Sets the data that will be used as the header. 10 bytes, starting from
+ * the beginning of \a data are used.
+ */
+ void setData(const ByteVector &data);
+
+ /*!
+ * Renders the Header back to binary format.
+ */
+ ByteVector render() const;
+
+ protected:
+ /*!
+ * Called by setData() to parse the header data. It makes this information
+ * available through the public API.
+ */
+ void parse(const ByteVector &data);
+
+ private:
+ Header(const Header &);
+ Header &operator=(const Header &);
+
+ class HeaderPrivate;
+ HeaderPrivate *d;
+ };
+
+ }
+}
+
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2synchdata.cpp b/libs/taglib/taglib/mpeg/id3v2/id3v2synchdata.cpp
new file mode 100644
index 0000000000..17503ba543
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2synchdata.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include <iostream>
+
+#include "id3v2synchdata.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+TagLib::uint SynchData::toUInt(const ByteVector &data)
+{
+ uint sum = 0;
+ int last = data.size() > 4 ? 3 : data.size() - 1;
+
+ for(int i = 0; i <= last; i++)
+ sum |= (data[i] & 0x7f) << ((last - i) * 7);
+
+ return sum;
+}
+
+ByteVector SynchData::fromUInt(uint value)
+{
+ ByteVector v(4, 0);
+
+ for(int i = 0; i < 4; i++)
+ v[i] = uchar(value >> ((3 - i) * 7) & 0x7f);
+
+ return v;
+}
+
+ByteVector SynchData::decode(const ByteVector &data)
+{
+ ByteVector result = data;
+
+ ByteVector pattern(2, char(0));
+ pattern[0] = '\xFF';
+ pattern[1] = '\x00';
+
+ return result.replace(pattern, '\xFF');
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2synchdata.h b/libs/taglib/taglib/mpeg/id3v2/id3v2synchdata.h
new file mode 100644
index 0000000000..86e0bfe551
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2synchdata.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ID3V2SYNCHDATA_H
+#define TAGLIB_ID3V2SYNCHDATA_H
+
+#include "tbytevector.h"
+#include "taglib.h"
+
+namespace TagLib {
+
+ namespace ID3v2 {
+
+ //! A few functions for ID3v2 synch safe integer conversion
+
+ /*!
+ * In the ID3v2.4 standard most integer values are encoded as "synch safe"
+ * integers which are encoded in such a way that they will not give false
+ * MPEG syncs and confuse MPEG decoders. This namespace provides some
+ * methods for converting to and from these values to ByteVectors for
+ * things rendering and parsing ID3v2 data.
+ */
+
+ namespace SynchData
+ {
+ /*!
+ * This returns the unsigned integer value of \a data where \a data is a
+ * ByteVector that contains a \e synchsafe integer (Structure,
+ * <a href="id3v2-structure.html#6.2">6.2</a>). The default \a length of
+ * 4 is used if another value is not specified.
+ */
+ TAGLIB_EXPORT uint toUInt(const ByteVector &data);
+
+ /*!
+ * Returns a 4 byte (32 bit) synchsafe integer based on \a value.
+ */
+ TAGLIB_EXPORT ByteVector fromUInt(uint value);
+
+ /*!
+ * Convert the data from unsynchronized data to its original format.
+ */
+ TAGLIB_EXPORT ByteVector decode(const ByteVector &input);
+ }
+
+ }
+}
+
+#endif
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2tag.cpp b/libs/taglib/taglib/mpeg/id3v2/id3v2tag.cpp
new file mode 100644
index 0000000000..beb496c8a0
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2tag.cpp
@@ -0,0 +1,474 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#include <tfile.h>
+#include <tdebug.h>
+
+#include "id3v2tag.h"
+#include "id3v2header.h"
+#include "id3v2extendedheader.h"
+#include "id3v2footer.h"
+#include "id3v2synchdata.h"
+
+#include "id3v1genres.h"
+
+#include "frames/textidentificationframe.h"
+#include "frames/commentsframe.h"
+
+using namespace TagLib;
+using namespace ID3v2;
+
+class ID3v2::Tag::TagPrivate
+{
+public:
+ TagPrivate() : file(0), tagOffset(-1), extendedHeader(0), footer(0), paddingSize(0)
+ {
+ frameList.setAutoDelete(true);
+ }
+ ~TagPrivate()
+ {
+ delete extendedHeader;
+ delete footer;
+ }
+
+ File *file;
+ long tagOffset;
+ const FrameFactory *factory;
+
+ Header header;
+ ExtendedHeader *extendedHeader;
+ Footer *footer;
+
+ int paddingSize;
+
+ FrameListMap frameListMap;
+ FrameList frameList;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// public members
+////////////////////////////////////////////////////////////////////////////////
+
+ID3v2::Tag::Tag() : TagLib::Tag()
+{
+ d = new TagPrivate;
+ d->factory = FrameFactory::instance();
+}
+
+ID3v2::Tag::Tag(File *file, long tagOffset, const FrameFactory *factory) :
+ TagLib::Tag()
+{
+ d = new TagPrivate;
+
+ d->file = file;
+ d->tagOffset = tagOffset;
+ d->factory = factory;
+
+ read();
+}
+
+ID3v2::Tag::~Tag()
+{
+ delete d;
+}
+
+
+String ID3v2::Tag::title() const
+{
+ if(!d->frameListMap["TIT2"].isEmpty())
+ return d->frameListMap["TIT2"].front()->toString();
+ return String::null;
+}
+
+String ID3v2::Tag::artist() const
+{
+ if(!d->frameListMap["TPE1"].isEmpty())
+ return d->frameListMap["TPE1"].front()->toString();
+ return String::null;
+}
+
+String ID3v2::Tag::album() const
+{
+ if(!d->frameListMap["TALB"].isEmpty())
+ return d->frameListMap["TALB"].front()->toString();
+ return String::null;
+}
+
+String ID3v2::Tag::comment() const
+{
+ const FrameList &comments = d->frameListMap["COMM"];
+
+ if(comments.isEmpty())
+ return String::null;
+
+ for(FrameList::ConstIterator it = comments.begin(); it != comments.end(); ++it)
+ {
+ if(static_cast<CommentsFrame *>(*it)->description().isEmpty())
+ return (*it)->toString();
+ }
+
+ return comments.front()->toString();
+}
+
+String ID3v2::Tag::genre() const
+{
+ // TODO: In the next major version (TagLib 2.0) a list of multiple genres
+ // should be separated by " / " instead of " ". For the moment to keep
+ // the behavior the same as released versions it is being left with " ".
+
+ if(d->frameListMap["TCON"].isEmpty() ||
+ !dynamic_cast<TextIdentificationFrame *>(d->frameListMap["TCON"].front()))
+ {
+ return String::null;
+ }
+
+ // ID3v2.4 lists genres as the fields in its frames field list. If the field
+ // is simply a number it can be assumed that it is an ID3v1 genre number.
+ // Here was assume that if an ID3v1 string is present that it should be
+ // appended to the genre string. Multiple fields will be appended as the
+ // string is built.
+
+ TextIdentificationFrame *f = static_cast<TextIdentificationFrame *>(
+ d->frameListMap["TCON"].front());
+
+ StringList fields = f->fieldList();
+
+ StringList genres;
+
+ for(StringList::Iterator it = fields.begin(); it != fields.end(); ++it) {
+
+ bool isNumber = true;
+
+ for(String::ConstIterator charIt = (*it).begin();
+ isNumber && charIt != (*it).end();
+ ++charIt)
+ {
+ isNumber = *charIt >= '0' && *charIt <= '9';
+ }
+
+ if(isNumber) {
+ int number = (*it).toInt();
+ if(number >= 0 && number <= 255)
+ *it = ID3v1::genre(number);
+ }
+
+ if(std::find(genres.begin(), genres.end(), *it) == genres.end())
+ genres.append(*it);
+ }
+
+ return genres.toString();
+}
+
+TagLib::uint ID3v2::Tag::year() const
+{
+ if(!d->frameListMap["TDRC"].isEmpty())
+ return d->frameListMap["TDRC"].front()->toString().substr(0, 4).toInt();
+ return 0;
+}
+
+TagLib::uint ID3v2::Tag::track() const
+{
+ if(!d->frameListMap["TRCK"].isEmpty())
+ return d->frameListMap["TRCK"].front()->toString().toInt();
+ return 0;
+}
+
+void ID3v2::Tag::setTitle(const String &s)
+{
+ setTextFrame("TIT2", s);
+}
+
+void ID3v2::Tag::setArtist(const String &s)
+{
+ setTextFrame("TPE1", s);
+}
+
+void ID3v2::Tag::setAlbum(const String &s)
+{
+ setTextFrame("TALB", s);
+}
+
+void ID3v2::Tag::setComment(const String &s)
+{
+ if(s.isEmpty()) {
+ removeFrames("COMM");
+ return;
+ }
+
+ if(!d->frameListMap["COMM"].isEmpty())
+ d->frameListMap["COMM"].front()->setText(s);
+ else {
+ CommentsFrame *f = new CommentsFrame(d->factory->defaultTextEncoding());
+ addFrame(f);
+ f->setText(s);
+ }
+}
+
+void ID3v2::Tag::setGenre(const String &s)
+{
+ if(s.isEmpty()) {
+ removeFrames("TCON");
+ return;
+ }
+
+ // iTunes can't handle correctly encoded ID3v2.4 numerical genres. Just use
+ // strings until iTunes sucks less.
+
+#ifdef NO_ITUNES_HACKS
+
+ int index = ID3v1::genreIndex(s);
+
+ if(index != 255)
+ setTextFrame("TCON", String::number(index));
+ else
+ setTextFrame("TCON", s);
+
+#else
+
+ setTextFrame("TCON", s);
+
+#endif
+}
+
+void ID3v2::Tag::setYear(uint i)
+{
+ if(i <= 0) {
+ removeFrames("TDRC");
+ return;
+ }
+ setTextFrame("TDRC", String::number(i));
+}
+
+void ID3v2::Tag::setTrack(uint i)
+{
+ if(i <= 0) {
+ removeFrames("TRCK");
+ return;
+ }
+ setTextFrame("TRCK", String::number(i));
+}
+
+bool ID3v2::Tag::isEmpty() const
+{
+ return d->frameList.isEmpty();
+}
+
+Header *ID3v2::Tag::header() const
+{
+ return &(d->header);
+}
+
+ExtendedHeader *ID3v2::Tag::extendedHeader() const
+{
+ return d->extendedHeader;
+}
+
+Footer *ID3v2::Tag::footer() const
+{
+ return d->footer;
+}
+
+const FrameListMap &ID3v2::Tag::frameListMap() const
+{
+ return d->frameListMap;
+}
+
+const FrameList &ID3v2::Tag::frameList() const
+{
+ return d->frameList;
+}
+
+const FrameList &ID3v2::Tag::frameList(const ByteVector &frameID) const
+{
+ return d->frameListMap[frameID];
+}
+
+void ID3v2::Tag::addFrame(Frame *frame)
+{
+ d->frameList.append(frame);
+ d->frameListMap[frame->frameID()].append(frame);
+}
+
+void ID3v2::Tag::removeFrame(Frame *frame, bool del)
+{
+ // remove the frame from the frame list
+ FrameList::Iterator it = d->frameList.find(frame);
+ d->frameList.erase(it);
+
+ // ...and from the frame list map
+ it = d->frameListMap[frame->frameID()].find(frame);
+ d->frameListMap[frame->frameID()].erase(it);
+
+ // ...and delete as desired
+ if(del)
+ delete frame;
+}
+
+void ID3v2::Tag::removeFrames(const ByteVector &id)
+{
+ FrameList l = d->frameListMap[id];
+ for(FrameList::Iterator it = l.begin(); it != l.end(); ++it)
+ removeFrame(*it, true);
+}
+
+ByteVector ID3v2::Tag::render() const
+{
+ // We need to render the "tag data" first so that we have to correct size to
+ // render in the tag's header. The "tag data" -- everything that is included
+ // in ID3v2::Header::tagSize() -- includes the extended header, frames and
+ // padding, but does not include the tag's header or footer.
+
+ ByteVector tagData;
+
+ // TODO: Render the extended header.
+
+ // Loop through the frames rendering them and adding them to the tagData.
+
+ for(FrameList::Iterator it = d->frameList.begin(); it != d->frameList.end(); it++) {
+ if(!(*it)->header()->tagAlterPreservation())
+ tagData.append((*it)->render());
+ }
+
+ // Compute the amount of padding, and append that to tagData.
+
+ uint paddingSize = 0;
+ uint originalSize = d->header.tagSize();
+
+ if(tagData.size() < originalSize)
+ paddingSize = originalSize - tagData.size();
+ else
+ paddingSize = 1024;
+
+ tagData.append(ByteVector(paddingSize, char(0)));
+
+ // Set the tag size.
+ d->header.setTagSize(tagData.size());
+
+ // TODO: This should eventually include d->footer->render().
+ return d->header.render() + tagData;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// protected members
+////////////////////////////////////////////////////////////////////////////////
+
+void ID3v2::Tag::read()
+{
+ if(d->file && d->file->isOpen()) {
+
+ d->file->seek(d->tagOffset);
+ d->header.setData(d->file->readBlock(Header::size()));
+
+ // if the tag size is 0, then this is an invalid tag (tags must contain at
+ // least one frame)
+
+ if(d->header.tagSize() == 0)
+ return;
+
+ parse(d->file->readBlock(d->header.tagSize()));
+ }
+}
+
+void ID3v2::Tag::parse(const ByteVector &origData)
+{
+ ByteVector data = origData;
+
+ if(d->header.unsynchronisation() && d->header.majorVersion() <= 3)
+ data = SynchData::decode(data);
+
+ uint frameDataPosition = 0;
+ uint frameDataLength = data.size();
+
+ // check for extended header
+
+ if(d->header.extendedHeader()) {
+ if(!d->extendedHeader)
+ d->extendedHeader = new ExtendedHeader;
+ d->extendedHeader->setData(data);
+ if(d->extendedHeader->size() <= data.size()) {
+ frameDataPosition += d->extendedHeader->size();
+ frameDataLength -= d->extendedHeader->size();
+ }
+ }
+
+ // check for footer -- we don't actually need to parse it, as it *must*
+ // contain the same data as the header, but we do need to account for its
+ // size.
+
+ if(d->header.footerPresent() && Footer::size() <= frameDataLength)
+ frameDataLength -= Footer::size();
+
+ // parse frames
+
+ // Make sure that there is at least enough room in the remaining frame data for
+ // a frame header.
+
+ while(frameDataPosition < frameDataLength - Frame::headerSize(d->header.majorVersion())) {
+
+ // If the next data is position is 0, assume that we've hit the padding
+ // portion of the frame data.
+
+ if(data.at(frameDataPosition) == 0) {
+ if(d->header.footerPresent())
+ debug("Padding *and* a footer found. This is not allowed by the spec.");
+
+ d->paddingSize = frameDataLength - frameDataPosition;
+ return;
+ }
+
+ Frame *frame = d->factory->createFrame(data.mid(frameDataPosition),
+ &d->header);
+
+ if(!frame)
+ return;
+
+ // Checks to make sure that frame parsed correctly.
+
+ if(frame->size() <= 0) {
+ delete frame;
+ return;
+ }
+
+ frameDataPosition += frame->size() + Frame::headerSize(d->header.majorVersion());
+ addFrame(frame);
+ }
+}
+
+void ID3v2::Tag::setTextFrame(const ByteVector &id, const String &value)
+{
+ if(value.isEmpty()) {
+ removeFrames(id);
+ return;
+ }
+
+ if(!d->frameListMap[id].isEmpty())
+ d->frameListMap[id].front()->setText(value);
+ else {
+ const String::Type encoding = d->factory->defaultTextEncoding();
+ TextIdentificationFrame *f = new TextIdentificationFrame(id, encoding);
+ addFrame(f);
+ f->setText(value);
+ }
+}
diff --git a/libs/taglib/taglib/mpeg/id3v2/id3v2tag.h b/libs/taglib/taglib/mpeg/id3v2/id3v2tag.h
new file mode 100644
index 0000000000..f43f6b7682
--- /dev/null
+++ b/libs/taglib/taglib/mpeg/id3v2/id3v2tag.h
@@ -0,0 +1,300 @@
+/***************************************************************************
+ copyright : (C) 2002 - 2008 by Scott Wheeler
+ email : wheeler@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License version *
+ * 2.1 as published by the Free Software Foundation. *
+ * *
+ * This library is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
+ * USA *
+ * *
+ * Alternatively, this file is available under the Mozilla Public *
+ * License Version 1.1. You may obtain a copy of the License at *
+ * http://www.mozilla.org/MPL/ *
+ ***************************************************************************/
+
+#ifndef TAGLIB_ID3V2TAG_H
+#define TAGLIB_ID3V2TAG_H
+
+#include "tag.h"
+#include "tbytevector.h"
+#include "tstring.h"
+#include "tlist.h"
+#include "tmap.h"
+#include "taglib_export.h"
+
+#include "id3v2framefactory.h"
+
+namespace TagLib {
+
+ class File;
+
+ //! An ID3v2 implementation
+
+ /*!
+ * This is a relatively complete and flexible framework for working with ID3v2
+ * tags.
+ *
+ * \see ID3v2::Tag
+ */
+
+ namespace ID3v2 {
+
+ class Header;
+ class ExtendedHeader;
+ class Footer;
+
+ typedef List<Frame *> FrameList;
+ typedef Map<ByteVector, FrameList> FrameListMap;
+
+ //! The main class in the ID3v2 implementation
+
+ /*!
+ * This is the main class in the ID3v2 implementation. It serves two
+ * functions. This first, as is obvious from the public API, is to provide a
+ * container for the other ID3v2 related classes. In addition, through the
+ * read() and parse() protected methods, it provides the most basic level of
+ * parsing. In these methods the ID3v2 tag is extracted from the file and
+ * split into data components.
+ *
+ * ID3v2 tags have several parts, TagLib attempts to provide an interface
+ * for them all. header(), footer() and extendedHeader() corespond to those
+ * data structures in the ID3v2 standard and the APIs for the classes that
+ * they return attempt to reflect this.
+ *
+ * Also ID3v2 tags are built up from a list of frames, which are in turn
+ * have a header and a list of fields. TagLib provides two ways of accessing
+ * the list of frames that are in a given ID3v2 tag. The first is simply
+ * via the frameList() method. This is just a list of pointers to the frames.
+ * The second is a map from the frame type -- i.e. "COMM" for comments -- and
+ * a list of frames of that type. (In some cases ID3v2 allows for multiple
+ * frames of the same type, hence this being a map to a list rather than just
+ * a map to an individual frame.)
+ *
+ * More information on the structure of frames can be found in the ID3v2::Frame
+ * class.
+ *
+ * read() and parse() pass binary data to the other ID3v2 class structures,
+ * they do not handle parsing of flags or fields, for instace. Those are
+ * handled by similar functions within those classes.
+ *
+ * \note All pointers to data structures within the tag will become invalid
+ * when the tag is destroyed.
+ *
+ * \warning Dealing with the nasty details of ID3v2 is not for the faint of
+ * heart and should not be done without much meditation on the spec. It's
+ * rather long, but if you're planning on messing with this class and others
+ * that deal with the details of ID3v2 (rather than the nice, safe, abstract
+ * TagLib::Tag and friends), it's worth your time to familiarize yourself
+ * with said spec (which is distrubuted with the TagLib sources). TagLib
+ * tries to do most of the work, but with a little luck, you can still
+ * convince it to generate invalid ID3v2 tags. The APIs for ID3v2 assume a
+ * working knowledge of ID3v2 structure. You're been warned.
+ */
+
+ class TAGLIB_EXPORT Tag : public TagLib::Tag
+ {
+ public:
+ /*!
+ * Constructs an empty ID3v2 tag.
+ *
+ * \note You must create at least one frame for this tag to be valid.
+ */
+ Tag();
+
+ /*!
+ * Constructs an ID3v2 tag read from \a file starting at \a tagOffset.
+ * \a factory specifies which FrameFactory will be used for the
+ * construction of new frames.
+ *
+ * \note You should be able to ignore the \a factory parameter in almost
+ * all situations. You would want to specify your own FrameFactory
+ * subclass in the case that you are extending TagLib to support additional
+ * frame types, which would be incorperated into your factory.
+ *
+ * \see FrameFactory
+ */
+ Tag(File *file, long tagOffset,
+ const FrameFactory *factory = FrameFactory::instance());
+
+ /*!
+ * 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(uint i);
+ virtual void setTrack(uint i);
+
+ virtual bool isEmpty() const;
+
+ /*!
+ * Returns a pointer to the tag's header.
+ */
+ Header *header() const;
+
+ /*!
+ * Returns a pointer to the tag's extended header or null if there is no
+ * extended header.
+ */
+ ExtendedHeader *extendedHeader() const;
+
+ /*!
+ * Returns a pointer to the tag's footer or null if there is no footer.
+ *
+ * \deprecated I don't see any reason to keep this around since there's
+ * nothing useful to be retrieved from the footer, but well, again, I'm
+ * prone to change my mind, so this gets to stay around until near a
+ * release.
+ */
+ Footer *footer() const;
+
+ /*!
+ * Returns a reference to the frame list map. This is an FrameListMap of
+ * all of the frames in the tag.
+ *
+ * This is the most convenient structure for accessing the tag's frames.
+ * Many frame types allow multiple instances of the same frame type so this
+ * is a map of lists. In most cases however there will only be a single
+ * frame of a certain type.
+ *
+ * Let's say for instance that you wanted to access the frame for total
+ * beats per minute -- the TBPM frame.
+ *
+ * \code
+ * TagLib::MPEG::File f("foo.mp3");
+ *
+ * // Check to make sure that it has an ID3v2 tag
+ *
+ * if(f.ID3v2Tag()) {
+ *
+ * // Get the list of frames for a specific frame type
+ *
+ * TagLib::ID3v2::FrameList l = f.ID3v2Tag()->frameListMap()["TBPM"];
+ *
+ * if(!l.isEmpty())
+ * std::cout << l.front()->toString() << std::endl;
+ * }
+ *
+ * \endcode
+ *
+ * \warning You should not modify this data structure directly, instead
+ * use addFrame() and removeFrame().
+ *
+ * \see frameList()
+ */
+ const FrameListMap &frameListMap() const;
+
+ /*!
+ * Returns a reference to the frame list. This is an FrameList of all of
+ * the frames in the tag in the order that they were parsed.
+ *
+ * This can be useful if for example you want iterate over the tag's frames
+ * in the order that they occur in the tag.
+ *
+ * \warning You should not modify this data structure directly, instead
+ * use addFrame() and removeFrame().
+ */
+ const FrameList &frameList() const;
+
+ /*!
+ * Returns the frame list for frames with the id \a frameID or an empty
+ * list if there are no frames of that type. This is just a convenience
+ * and is equivalent to:
+ *
+ * \code
+ * frameListMap()[frameID];
+ * \endcode
+ *
+ * \see frameListMap()
+ */
+ const FrameList &frameList(const ByteVector &frameID) const;
+
+ /*!
+ * Add a frame to the tag. At this point the tag takes ownership of
+ * the frame and will handle freeing its memory.
+ *
+ * \note Using this method will invalidate any pointers on the list
+ * returned by frameList()
+ */
+ void addFrame(Frame *frame);
+
+ /*!
+ * Remove a frame from the tag. If \a del is true the frame's memory
+ * will be freed; if it is false, it must be deleted by the user.
+ *
+ * \note Using this method will invalidate any pointers on the list
+ * returned by frameList()
+ */
+ void removeFrame(Frame *frame, bool del = true);
+
+ /*!
+ * Remove all frames of type \a id from the tag and free their memory.
+ *
+ * \note Using this method will invalidate any pointers on the list
+ * returned by frameList()
+ */
+ void removeFrames(const ByteVector &id);
+
+ /*!
+ * Render the tag back to binary data, suitable to be written to disk.
+ */
+ ByteVector render() const;
+
+ protected:
+ /*!
+ * Reads data from the file specified in the constructor. It does basic
+ * parsing of the data in the largest chunks. It partitions the tag into
+ * the Header, the body of the tag (which contains the ExtendedHeader and
+ * frames) and Footer.
+ */
+ void read();
+
+ /*!
+ * This is called by read to parse the body of the tag. It determines if an
+ * extended header exists and adds frames to the FrameListMap.
+ */
+ void parse(const ByteVector &data);
+
+ /*!
+ * Sets the value of the text frame with the Frame ID \a id to \a value.
+ * If the frame does not exist, it is created.
+ */
+ void setTextFrame(const ByteVector &id, const String &value);
+
+ private:
+ Tag(const Tag &);
+ Tag &operator=(const Tag &);
+
+ class TagPrivate;
+ TagPrivate *d;
+ };
+
+ }
+}
+
+#endif