diff --git a/livesupport/modules/getid3/Makefile b/livesupport/modules/getid3/Makefile new file mode 100644 index 000000000..5937ae7d4 --- /dev/null +++ b/livesupport/modules/getid3/Makefile @@ -0,0 +1,129 @@ +#------------------------------------------------------------------------------- +# getID3 - read and writes tags in media files - see getid3.readme.txt +# getID3 by James Heinrich +# +# This file is part of the LiveSupport project. +# Copyright (c) 2004 Media Development Loan Fund +# +# LiveSupport is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LiveSupport 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LiveSupport; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# +# Author : Author: James Heinrich +# Version : $Revision: 1.1 $ +# Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/getid3/Attic/Makefile,v $ +# +# @configure_input@ +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# General command definitions +#------------------------------------------------------------------------------- +MKDIR = mkdir -p +RM = rm -f +RMDIR = rm -rf +DOXYGEN = doxygen + +#------------------------------------------------------------------------------- +# Misc +#------------------------------------------------------------------------------- + +MODULE_NAME = getid3 +TAR_C = tar -cj --exclude CVS --exclude '*~' -C ${BASE_DIR} -f +DIST_EXT = .tgz +DATE = `date +%y%m%d` + +#------------------------------------------------------------------------------- +# Basic directory and file definitions +#------------------------------------------------------------------------------- +#BASE_DIR = @builddir@ +BASE_DIR = . +DOC_DIR = ${BASE_DIR}/doc +DOXYGEN_DIR = ${DOC_DIR}/doxygen +ETC_DIR = ${BASE_DIR}/etc +INCLUDE_DIR = ${BASE_DIR}/include +LIB_DIR = ${BASE_DIR}/lib +SRC_DIR = ${BASE_DIR}/src +TMP_DIR = ${BASE_DIR}/tmp + +USR_DIR = ${BASE_DIR}/../../usr +USR_INCLUDE_DIR = ${USR_DIR}/include +USR_LIB_DIR = ${USR_DIR}/lib + +DOXYGEN_CONFIG = ${ETC_DIR}/doxygen.config + +PHP_DIR = ${BASE_DIR}/var +#TEST_RUNNER = ${PHP_DIR}/tests/index.php + +#------------------------------------------------------------------------------- +# Configuration parameters +#------------------------------------------------------------------------------- +#CPPFLAGS = @CPPFLAGS@ +#CXXFLAGS = @CXXFLAGS@ @DEFS@ -I${USR_INCLUDE_DIR} -I${INCLUDE_DIR} -I${TMP_DIR}\ +# -pedantic -Wall +#LDFLAGS = @LDFLAGS@ -L${USR_LIB_DIR} -L${LIB_DIR} + + +#------------------------------------------------------------------------------- +# Dependencies +#------------------------------------------------------------------------------- +#HELLO_LIB_OBJS = ${TMP_DIR}/Hello.o +#TEST_RUNNER_OBJS = ${TMP_DIR}/HelloTest.o ${TMP_DIR}/TestRunner.o + + +#------------------------------------------------------------------------------- +# Targets +#------------------------------------------------------------------------------- +.PHONY: all dir_setup doc clean docclean depclean distclean dist + +all: dir_setup + +#dir_setup: ${TMP_DIR} ${DOXYGEN_DIR} +dir_setup: ${DOXYGEN_DIR} + +doc: + ${DOXYGEN} ${DOXYGEN_CONFIG} + +clean: +# ${RM} ... + +docclean: + ${RMDIR} ${DOXYGEN_DIR}/html + +depclean: clean + +dist: all + ${TAR_C} ${MODULE_NAME}${DATE}${DIST_EXT} * + +distclean: clean docclean +# ${RMDIR} ${TMP_DIR}/config* ${TMP_DIR}/autom4te* + +#check: all ${TEST_RUNNER} +# ${TEST_RUNNER} +check: all + +#------------------------------------------------------------------------------- +# Specific targets +#------------------------------------------------------------------------------- +${DOXYGEN_DIR}: + ${MKDIR} ${DOXYGEN_DIR} + +#${TEST_RUNNER}: + +#------------------------------------------------------------------------------- +# Pattern rules +#------------------------------------------------------------------------------- +#${TMP_DIR}/%.o : ${SRC_DIR}/%.cxx +# ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c -o $@ $< + diff --git a/livesupport/modules/getid3/etc/doxygen.config b/livesupport/modules/getid3/etc/doxygen.config new file mode 100644 index 000000000..b8e098ab8 --- /dev/null +++ b/livesupport/modules/getid3/etc/doxygen.config @@ -0,0 +1,1144 @@ +#------------------------------------------------------------------------------- +# doxygen.config +# Copyright (c) 2004 Media Development Loan Fund +# +# This file is part of the LiveSupport project. +# +# LiveSupport is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# LiveSupport 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LiveSupport; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# +# Author : $Author: tomas $ +# Version : $Revision: 1.1 $ +# Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/getid3/etc/doxygen.config,v $ +#------------------------------------------------------------------------------- + +# Doxyfile 1.3.6 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = LiveSupport + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc/doxygen + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with English messages), Korean, Korean-en, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" +# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = YES + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +#EXTRACT_ALL = NO +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = var + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc + +FILE_PATTERNS = *.php + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = include + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/livesupport/modules/getid3/var/audioinfo.class.php b/livesupport/modules/getid3/var/audioinfo.class.php new file mode 100644 index 000000000..0814b6425 --- /dev/null +++ b/livesupport/modules/getid3/var/audioinfo.class.php @@ -0,0 +1,312 @@ +Info('file.flac'); | +// +----------------------------------------------------------------------+ +// | Authors: Allan Hansen | +// +----------------------------------------------------------------------+ +// +// $Id: audioinfo.class.php,v 1.1 2004/09/12 21:32:36 tomas Exp $ + + + +/** +* getID3() settings +*/ + +include_once('getid3.php'); + + + + +/** +* Class for extracting information from audio files with getID3(). +*/ + +class AudioInfo { + + /** + * Private variables + */ + var $result = NULL; + var $info = NULL; + + + /** + * Extract information - only public function + * + * @access public + * @param string file Audio file to extract info from. + */ + + function Info($file) { + + // Too many mp3 encoders on the market put gabage in front of mpeg files - use assume format on these + $assume_mpeg = eregi('\.mp[123a]$', $file); + + // Extract info with GetAllFileInfo() - in this example we want MD5data (fourth param). + // If MD5data is not needed, set to FALSE for performance improvement. + $this->info = GetAllFileInfo($file, ($assume_mpeg ? 'mp3' : ''), FALSE, TRUE); + //dump($this->info, false); + + // Exit here on error + if (isset($this->info['error'])) { + return array ('error' => $this->info['error']); + } + + // Init wrapper object + $this->result = array (); + $this->result['format_name'] = @$this->info['fileformat'].'/'.@$this->info['audio']['dataformat'].(isset($this->info['video']['dataformat']) ? '/'.@$this->info['video']['dataformat'] : ''); + $this->result['encoder_version'] = @$this->info['audio']['encoder']; + $this->result['encoder_options'] = NULL; + $this->result['bitrate_mode'] = @$this->info['audio']['bitrate_mode']; + $this->result['channels'] = @$this->info['audio']['channels']; + $this->result['sample_rate'] = @$this->info['audio']['sample_rate']; + $this->result['bits_per_sample'] = @$this->info['audio']['bits_per_sample']; + $this->result['playing_time'] = @$this->info['playtime_seconds']; + $this->result['avg_bit_rate'] = @$this->info['audio']['bitrate']; + $this->result['tags'] = @$this->info['tags']; + $this->result['comments'] = @$this->info['comments']; + $this->result['warning'] = @$this->info['warning']; + $this->result['md5'] = @$this->info['md5_data']; + + // Post getID3() data handling based on file format + $method = @$this->info['fileformat'].'Info'; + if (@$this->info['fileformat'] && method_exists($this, $method)) { + $this->$method(); + } + + return $this->result; + } + + + + + /** + * post-getID3() data handling for AAC files. + * + * @access private + */ + + function aacInfo() { + $this->result['format_name'] = 'AAC'; + $this->result['encoder_options'] = $this->info['aac']['header_type'].' '.$this->info['aac']['header']['profile_text']; + } + + + + + /** + * post-getID3() data handling for Wave files. + * + * @access private + */ + + function riffInfo() { + if ($this->info['audio']['dataformat'] == 'wav') { + + $this->result['format_name'] = 'Wave'; + + } else if (ereg('^mp[1-3]$', $this->info['audio']['dataformat'])) { + + $this->result['format_name'] = strtoupper($this->info['audio']['dataformat']); + + } else { + + $this->result['format_name'] = 'riff/'.$this->info['audio']['dataformat']; + + } + } + + + + + /** + * * post-getID3() data handling for FLAC files. + * + * @access private + */ + + function flacInfo() { + $this->result['format_name'] = 'FLAC'; + } + + + + + + /** + * post-getID3() data handling for Monkey's Audio files. + * + * @access private + */ + + function macInfo() { + $this->result['format_name'] = 'Monkey\'s Audio'; + $this->result['encoder_options'] = $this->info['monkeys_audio']['compression'].' compression'; + } + + + + + + /** + * post-getID3() data handling for Monkey's Audio files. + * + * @access private + */ + + function laInfo() { + $this->result['format_name'] = 'La'; + } + + + + + + /** + * post-getID3() data handling for Ogg Vorbis files. + * + * @access private + */ + + function oggInfo() { + if ($this->info['audio']['dataformat'] == 'vorbis') { + + $this->result['format_name'] = 'Ogg Vorbis'; + $this->result['encoder_options'] = 'Nominal bitrate: '.$this->info['ogg']['bitrate_nominal']; + + } else if ($this->info['audio']['dataformat'] == 'flac') { + + $this->result['format_name'] = 'Ogg FLAC'; + + } else if ($this->info['audio']['dataformat'] == 'speex') { + + $this->result['format_name'] = 'Ogg Speex'; + + } else { + + $this->result['format_name'] = 'Ogg '.$this->info['audio']['dataformat']; + + } + } + + + + + /** + * post-getID3() data handling for Musepack files. + * + * @access private + */ + + function mpcInfo() { + $this->result['format_name'] = 'Musepack'; + $this->result['encoder_options'] = $this->info['mpc']['header']['profile']; + } + + + + + /** + * post-getID3() data handling for MPEG files. + * + * @access private + */ + + function mp3Info() { + $this->result['format_name'] = 'MP3'; + } + + + + + /** + * post-getID3() data handling for MPEG files. + * + * @access private + */ + + function mp2Info() { + $this->result['format_name'] = 'MP2'; + } + + + + + + /** + * post-getID3() data handling for MPEG files. + * + * @access private + */ + + function mp1Info() { + $this->result['format_name'] = 'MP1'; + } + + + + + /** + * post-getID3() data handling for WMA files. + * + * @access private + */ + + function asfInfo() { + $this->result['format_name'] = strtoupper($this->info['audio']['dataformat']); + $this->result['encoder_options'] = trim($this->info['asf']['codec_list']['codec_entries'][0]['description_ascii']); + } + + + + /** + * post-getID3() data handling for Real files. + * + * @access private + */ + + function realInfo() { + $this->result['format_name'] = 'Real'; + } + + + + + + /** + * post-getID3() data handling for VQF files. + * + * @access private + */ + + function vqfInfo() { + $this->result['format_name'] = 'VQF'; + } + +} + + +?> \ No newline at end of file diff --git a/livesupport/modules/getid3/var/getid3.aac.php b/livesupport/modules/getid3/var/getid3.aac.php new file mode 100644 index 000000000..48b774694 --- /dev/null +++ b/livesupport/modules/getid3/var/getid3.aac.php @@ -0,0 +1,507 @@ + // +// available at http://getid3.sourceforge.net /// +///////////////////////////////////////////////////////////////// +// // +// getid3.aac.php - part of getID3() // +// See getid3.readme.txt for more details // +// // +///////////////////////////////////////////////////////////////// + +function getAACADIFheaderFilepointer(&$fd, &$ThisFileInfo) { + $ThisFileInfo['fileformat'] = 'aac'; + $ThisFileInfo['audio']['dataformat'] = 'aac'; + + fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET); + $AACheader = fread($fd, 1024); + $offset = 0; + + if (substr($AACheader, 0, 4) == 'ADIF') { + + // http://faac.sourceforge.net/wiki/index.php?page=ADIF + + // http://libmpeg.org/mpeg4/doc/w2203tfs.pdf + // adif_header() { + // adif_id 32 + // copyright_id_present 1 + // if( copyright_id_present ) + // copyright_id 72 + // original_copy 1 + // home 1 + // bitstream_type 1 + // bitrate 23 + // num_program_config_elements 4 + // for (i = 0; i < num_program_config_elements + 1; i++ ) { + // if( bitstream_type == '0' ) + // adif_buffer_fullness 20 + // program_config_element() + // } + // } + + $AACheaderBitstream = BigEndian2Bin($AACheader); + $bitoffset = 0; + + $ThisFileInfo['aac']['header_type'] = 'ADIF'; + $bitoffset += 32; + $ThisFileInfo['aac']['header']['mpeg_version'] = 4; + + $ThisFileInfo['aac']['header']['copyright'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1'); + $bitoffset += 1; + if ($ThisFileInfo['aac']['header']['copyright']) { + $ThisFileInfo['aac']['header']['copyright_id'] = Bin2String(substr($AACheaderBitstream, $bitoffset, 72)); + $bitoffset += 72; + } + $ThisFileInfo['aac']['header']['original_copy'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1'); + $bitoffset += 1; + $ThisFileInfo['aac']['header']['home'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1'); + $bitoffset += 1; + $ThisFileInfo['aac']['header']['is_vbr'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1'); + $bitoffset += 1; + if ($ThisFileInfo['aac']['header']['is_vbr']) { + $ThisFileInfo['audio']['bitrate_mode'] = 'vbr'; + $ThisFileInfo['aac']['header']['bitrate_max'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 23)); + $bitoffset += 23; + } else { + $ThisFileInfo['audio']['bitrate_mode'] = 'cbr'; + $ThisFileInfo['aac']['header']['bitrate'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 23)); + $bitoffset += 23; + $ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['aac']['header']['bitrate']; + } + if ($ThisFileInfo['audio']['bitrate'] == 0) { + $ThisFileInfo['error'] .= "\n".'Corrupt AAC file: bitrate_audio == zero'; + return false; + } + $ThisFileInfo['aac']['header']['num_program_configs'] = 1 + Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + + for ($i = 0; $i < $ThisFileInfo['aac']['header']['num_program_configs']; $i++) { + // http://www.audiocoding.com/wiki/index.php?page=program_config_element + + // buffer_fullness 20 + + // element_instance_tag 4 + // object_type 2 + // sampling_frequency_index 4 + // num_front_channel_elements 4 + // num_side_channel_elements 4 + // num_back_channel_elements 4 + // num_lfe_channel_elements 2 + // num_assoc_data_elements 3 + // num_valid_cc_elements 4 + // mono_mixdown_present 1 + // mono_mixdown_element_number 4 if mono_mixdown_present == 1 + // stereo_mixdown_present 1 + // stereo_mixdown_element_number 4 if stereo_mixdown_present == 1 + // matrix_mixdown_idx_present 1 + // matrix_mixdown_idx 2 if matrix_mixdown_idx_present == 1 + // pseudo_surround_enable 1 if matrix_mixdown_idx_present == 1 + // for (i = 0; i < num_front_channel_elements; i++) { + // front_element_is_cpe[i] 1 + // front_element_tag_select[i] 4 + // } + // for (i = 0; i < num_side_channel_elements; i++) { + // side_element_is_cpe[i] 1 + // side_element_tag_select[i] 4 + // } + // for (i = 0; i < num_back_channel_elements; i++) { + // back_element_is_cpe[i] 1 + // back_element_tag_select[i] 4 + // } + // for (i = 0; i < num_lfe_channel_elements; i++) { + // lfe_element_tag_select[i] 4 + // } + // for (i = 0; i < num_assoc_data_elements; i++) { + // assoc_data_element_tag_select[i] 4 + // } + // for (i = 0; i < num_valid_cc_elements; i++) { + // cc_element_is_ind_sw[i] 1 + // valid_cc_element_tag_select[i] 4 + // } + // byte_alignment() VAR + // comment_field_bytes 8 + // for (i = 0; i < comment_field_bytes; i++) { + // comment_field_data[i] 8 + // } + + if (!$ThisFileInfo['aac']['header']['is_vbr']) { + $ThisFileInfo['aac']['program_configs'][$i]['buffer_fullness'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 20)); + $bitoffset += 20; + } + $ThisFileInfo['aac']['program_configs'][$i]['element_instance_tag'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + $ThisFileInfo['aac']['program_configs'][$i]['object_type'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2)); + $bitoffset += 2; + $ThisFileInfo['aac']['program_configs'][$i]['sampling_frequency_index'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + $ThisFileInfo['aac']['program_configs'][$i]['num_front_channel_elements'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + $ThisFileInfo['aac']['program_configs'][$i]['num_side_channel_elements'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + $ThisFileInfo['aac']['program_configs'][$i]['num_back_channel_elements'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + $ThisFileInfo['aac']['program_configs'][$i]['num_lfe_channel_elements'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2)); + $bitoffset += 2; + $ThisFileInfo['aac']['program_configs'][$i]['num_assoc_data_elements'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 3)); + $bitoffset += 3; + $ThisFileInfo['aac']['program_configs'][$i]['num_valid_cc_elements'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + $ThisFileInfo['aac']['program_configs'][$i]['mono_mixdown_present'] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + if ($ThisFileInfo['aac']['program_configs'][$i]['mono_mixdown_present']) { + $ThisFileInfo['aac']['program_configs'][$i]['mono_mixdown_element_number'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + } + $ThisFileInfo['aac']['program_configs'][$i]['stereo_mixdown_present'] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + if ($ThisFileInfo['aac']['program_configs'][$i]['stereo_mixdown_present']) { + $ThisFileInfo['aac']['program_configs'][$i]['stereo_mixdown_element_number'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + } + $ThisFileInfo['aac']['program_configs'][$i]['matrix_mixdown_idx_present'] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + if ($ThisFileInfo['aac']['program_configs'][$i]['matrix_mixdown_idx_present']) { + $ThisFileInfo['aac']['program_configs'][$i]['matrix_mixdown_idx'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2)); + $bitoffset += 2; + $ThisFileInfo['aac']['program_configs'][$i]['pseudo_surround_enable'] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + } + for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_front_channel_elements']; $j++) { + $ThisFileInfo['aac']['program_configs'][$i]['front_element_is_cpe'][$j] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + $ThisFileInfo['aac']['program_configs'][$i]['front_element_tag_select'][$j] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + } + for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_side_channel_elements']; $j++) { + $ThisFileInfo['aac']['program_configs'][$i]['side_element_is_cpe'][$j] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + $ThisFileInfo['aac']['program_configs'][$i]['side_element_tag_select'][$j] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + } + for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_back_channel_elements']; $j++) { + $ThisFileInfo['aac']['program_configs'][$i]['back_element_is_cpe'][$j] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + $ThisFileInfo['aac']['program_configs'][$i]['back_element_tag_select'][$j] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + } + for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_lfe_channel_elements']; $j++) { + $ThisFileInfo['aac']['program_configs'][$i]['lfe_element_tag_select'][$j] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + } + for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_assoc_data_elements']; $j++) { + $ThisFileInfo['aac']['program_configs'][$i]['assoc_data_element_tag_select'][$j] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + } + for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_valid_cc_elements']; $j++) { + $ThisFileInfo['aac']['program_configs'][$i]['cc_element_is_ind_sw'][$j] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + $ThisFileInfo['aac']['program_configs'][$i]['valid_cc_element_tag_select'][$j] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + } + + $bitoffset = ceil($bitoffset / 8) * 8; + + $ThisFileInfo['aac']['program_configs'][$i]['comment_field_bytes'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 8)); + $bitoffset += 8; + $ThisFileInfo['aac']['program_configs'][$i]['comment_field'] = Bin2String(substr($AACheaderBitstream, $bitoffset, 8 * $ThisFileInfo['aac']['program_configs'][$i]['comment_field_bytes'])); + $bitoffset += 8 * $ThisFileInfo['aac']['program_configs'][$i]['comment_field_bytes']; + + + $ThisFileInfo['aac']['header']['profile_text'] = AACprofileLookup($ThisFileInfo['aac']['program_configs'][$i]['object_type'], $ThisFileInfo['aac']['header']['mpeg_version']); + $ThisFileInfo['aac']['program_configs'][$i]['sampling_frequency'] = AACsampleRateLookup($ThisFileInfo['aac']['program_configs'][$i]['sampling_frequency_index']); + $ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['aac']['program_configs'][$i]['sampling_frequency']; + $ThisFileInfo['audio']['channels'] = AACchannelCountCalculate($ThisFileInfo['aac']['program_configs'][$i]); + if ($ThisFileInfo['aac']['program_configs'][$i]['comment_field']) { + $ThisFileInfo['comments']['comment'][] = $ThisFileInfo['aac']['program_configs'][$i]['comment_field']; + } + } + $ThisFileInfo['playtime_seconds'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['audio']['bitrate']; + + return true; + + } else { + + unset($ThisFileInfo['fileformat']); + unset($ThisFileInfo['aac']); + $ThisFileInfo['error'] .= "\n".'AAC-ADIF synch not found (expected "ADIF", found "'.substr($AACheader, 0, 4).'" instead)'; + return false; + + } + +} + + +function getAACADTSheaderFilepointer(&$fd, &$ThisFileInfo, $MaxFramesToScan=1000000, $ReturnExtendedInfo=false) { + // based loosely on code from AACfile by Jurgen Faul + // jfaul@gmx.de http://jfaul.de/atl + + + // http://faac.sourceforge.net/wiki/index.php?page=ADTS + + // * ADTS Fixed Header: these don't change from frame to frame + // syncword 12 always: '111111111111' + // ID 1 0: MPEG-4, 1: MPEG-2 + // layer 2 always: '00' + // protection_absent 1 + // profile 2 + // sampling_frequency_index 4 + // private_bit 1 + // channel_configuration 3 + // original/copy 1 + // home 1 + // emphasis 2 only if ID == 0 (ie MPEG-4) + + // * ADTS Variable Header: these can change from frame to frame + // copyright_identification_bit 1 + // copyright_identification_start 1 + // aac_frame_length 13 length of the frame including header (in bytes) + // adts_buffer_fullness 11 0x7FF indicates VBR + // no_raw_data_blocks_in_frame 2 + + // * ADTS Error check + // crc_check 16 only if protection_absent == 0 + + $byteoffset = 0; + $framenumber = 0; + + // Init bit pattern array + static $decbin = array(); + + // Populate $bindec + for ($i = 0; $i < 256; $i++) { + $decbin[chr($i)] = str_pad(decbin($i), 8, '0', STR_PAD_LEFT); + } + + // used to calculate bitrate below + static $BitrateCache = array(); + + + while (true) { + // breaks out when end-of-file encountered, or invalid data found, + // or MaxFramesToScan frames have been scanned + + fseek($fd, $byteoffset, SEEK_SET); + + // First get substring + $substring = fread($fd, 10); + $substringlength = strlen($substring); + if ($substringlength != 10) { + $ThisFileInfo['error'] .= "\n".'Failed to read 10 bytes at offset '.(ftell($fd) - $substringlength).' (only read '.$substringlength.' bytes)'; + return false; + } + + // Initialise $AACheaderBitstream + $AACheaderBitstream = ''; + + // Loop thru substring chars + for ($i = 0; $i < 10; $i++) { + $AACheaderBitstream .= $decbin[$substring{$i}]; + } + + $bitoffset = 0; + + $synctest = bindec(substr($AACheaderBitstream, $bitoffset, 12)); + + $bitoffset += 12; + if ($synctest != 0x0FFF) { + $ThisFileInfo['error'] .= "\n".'Synch pattern (0x0FFF) not found at offset '.(ftell($fd) - 10).' (found 0x0'.strtoupper(dechex($synctest)).' instead)'; + if ($ThisFileInfo['fileformat'] == 'aac') { + return true; + } + return false; + } + + // Gather info for first frame only - this takes time to do 1000 times! + if ($framenumber > 0) { + + if (!$AACheaderBitstream[$bitoffset]) { + + // MPEG-4 + $bitoffset += 20; + + } else { + + // MPEG-2 + $bitoffset += 18; + + } + + } else { + + $ThisFileInfo['aac']['header_type'] = 'ADTS'; + $ThisFileInfo['aac']['header']['synch'] = $synctest; + $ThisFileInfo['fileformat'] = 'aac'; + $ThisFileInfo['audio']['dataformat'] = 'aac'; + + $ThisFileInfo['aac']['header']['mpeg_version'] = ((substr($AACheaderBitstream, $bitoffset, 1) == '0') ? 4 : 2); + $bitoffset += 1; + $ThisFileInfo['aac']['header']['layer'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2)); + $bitoffset += 2; + if ($ThisFileInfo['aac']['header']['layer'] != 0) { + $ThisFileInfo['error'] .= "\n".'Layer error - expected 0x00, found 0x'.dechex($ThisFileInfo['aac']['header']['layer']).' instead'; + return false; + } + $ThisFileInfo['aac']['header']['crc_present'] = ((substr($AACheaderBitstream, $bitoffset, 1) == '0') ? true : false); + $bitoffset += 1; + $ThisFileInfo['aac']['header']['profile_id'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2)); + $bitoffset += 2; + $ThisFileInfo['aac']['header']['profile_text'] = AACprofileLookup($ThisFileInfo['aac']['header']['profile_id'], $ThisFileInfo['aac']['header']['mpeg_version']); + + $ThisFileInfo['aac']['header']['sample_frequency_index'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); + $bitoffset += 4; + $ThisFileInfo['aac']['header']['sample_frequency'] = AACsampleRateLookup($ThisFileInfo['aac']['header']['sample_frequency_index']); + if ($ThisFileInfo['aac']['header']['sample_frequency'] == 0) { + $ThisFileInfo['error'] .= "\n".'Corrupt AAC file: sample_frequency == zero'; + return false; + } + $ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['aac']['header']['sample_frequency']; + + $ThisFileInfo['aac']['header']['private'] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + $ThisFileInfo['aac']['header']['channel_configuration'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 3)); + $bitoffset += 3; + $ThisFileInfo['audio']['channels'] = $ThisFileInfo['aac']['header']['channel_configuration']; + $ThisFileInfo['aac']['header']['original'] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + $ThisFileInfo['aac']['header']['home'] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + + if ($ThisFileInfo['aac']['header']['mpeg_version'] == 4) { + $ThisFileInfo['aac']['header']['emphasis'] = Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2)); + $bitoffset += 2; + } + + if ($ReturnExtendedInfo) { + + $ThisFileInfo['aac'][$framenumber]['copyright_id_bit'] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + $ThisFileInfo['aac'][$framenumber]['copyright_id_start'] = (bool) Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); + $bitoffset += 1; + + } else { + + $bitoffset += 2; + + } + + } + + $FrameLength = bindec(substr($AACheaderBitstream, $bitoffset, 13)); + + if (!isset($BitrateCache[$FrameLength])) { + $BitrateCache[$FrameLength] = ($ThisFileInfo['aac']['header']['sample_frequency'] / 1024) * $FrameLength * 8; + } + safe_inc($ThisFileInfo['aac']['bitrate_distribution'][$BitrateCache[$FrameLength]]); + + $ThisFileInfo['aac'][$framenumber]['aac_frame_length'] = $FrameLength; + $bitoffset += 13; + $ThisFileInfo['aac'][$framenumber]['adts_buffer_fullness'] = bindec(substr($AACheaderBitstream, $bitoffset, 11)); + $bitoffset += 11; + if ($ThisFileInfo['aac'][$framenumber]['adts_buffer_fullness'] == 0x07FF) { + $ThisFileInfo['audio']['bitrate_mode'] = 'vbr'; + } else { + $ThisFileInfo['audio']['bitrate_mode'] = 'cbr'; + } + $ThisFileInfo['aac'][$framenumber]['num_raw_data_blocks'] = bindec(substr($AACheaderBitstream, $bitoffset, 2)); + $bitoffset += 2; + + if ($ThisFileInfo['aac']['header']['crc_present']) { + //$ThisFileInfo['aac'][$framenumber]['crc'] = bindec(substr($AACheaderBitstream, $bitoffset, 16)); + $bitoffset += 16; + } + + if (!$ReturnExtendedInfo) { + unset($ThisFileInfo['aac'][$framenumber]); + } + + $byteoffset += $FrameLength; + if ((++$framenumber < $MaxFramesToScan) && (($byteoffset + 10) < $ThisFileInfo['avdataend'])) { + + // keep scanning + + } else { + + $ThisFileInfo['aac']['frames'] = $framenumber; + $ThisFileInfo['playtime_seconds'] = ($ThisFileInfo['avdataend'] / $byteoffset) * (($framenumber * 1024) / $ThisFileInfo['aac']['header']['sample_frequency']); // (1 / % of file scanned) * (samples / (samples/sec)) = seconds + if ($ThisFileInfo['playtime_seconds'] == 0) { + $ThisFileInfo['error'] .= "\n".'Corrupt AAC file: playtime_seconds == zero'; + return false; + } + $ThisFileInfo['audio']['bitrate'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['playtime_seconds']; + ksort($ThisFileInfo['aac']['bitrate_distribution']); + + return true; + + } + } + // should never get here. +} + +function AACsampleRateLookup($samplerateid) { + static $AACsampleRateLookup = array(); + if (empty($AACsampleRateLookup)) { + $AACsampleRateLookup[0] = 96000; + $AACsampleRateLookup[1] = 88200; + $AACsampleRateLookup[2] = 64000; + $AACsampleRateLookup[3] = 48000; + $AACsampleRateLookup[4] = 44100; + $AACsampleRateLookup[5] = 32000; + $AACsampleRateLookup[6] = 24000; + $AACsampleRateLookup[7] = 22050; + $AACsampleRateLookup[8] = 16000; + $AACsampleRateLookup[9] = 12000; + $AACsampleRateLookup[10] = 11025; + $AACsampleRateLookup[11] = 8000; + $AACsampleRateLookup[12] = 0; + $AACsampleRateLookup[13] = 0; + $AACsampleRateLookup[14] = 0; + $AACsampleRateLookup[15] = 0; + } + return (isset($AACsampleRateLookup[$samplerateid]) ? $AACsampleRateLookup[$samplerateid] : 'invalid'); +} + +function AACprofileLookup($profileid, $mpegversion) { + static $AACprofileLookup = array(); + if (empty($AACprofileLookup)) { + $AACprofileLookup[2][0] = 'Main profile'; + $AACprofileLookup[2][1] = 'Low Complexity profile (LC)'; + $AACprofileLookup[2][2] = 'Scalable Sample Rate profile (SSR)'; + $AACprofileLookup[2][3] = '(reserved)'; + $AACprofileLookup[4][0] = 'AAC_MAIN'; + $AACprofileLookup[4][1] = 'AAC_LC'; + $AACprofileLookup[4][2] = 'AAC_SSR'; + $AACprofileLookup[4][3] = 'AAC_LTP'; + } + return (isset($AACprofileLookup[$mpegversion][$profileid]) ? $AACprofileLookup[$mpegversion][$profileid] : 'invalid'); +} + +function AACchannelCountCalculate($program_configs) { + $channels = 0; + for ($i = 0; $i < $program_configs['num_front_channel_elements']; $i++) { + $channels++; + if ($program_configs['front_element_is_cpe'][$i]) { + // each front element is channel pair (CPE = Channel Pair Element) + $channels++; + } + } + for ($i = 0; $i < $program_configs['num_side_channel_elements']; $i++) { + $channels++; + if ($program_configs['side_element_is_cpe'][$i]) { + // each side element is channel pair (CPE = Channel Pair Element) + $channels++; + } + } + for ($i = 0; $i < $program_configs['num_back_channel_elements']; $i++) { + $channels++; + if ($program_configs['back_element_is_cpe'][$i]) { + // each back element is channel pair (CPE = Channel Pair Element) + $channels++; + } + } + for ($i = 0; $i < $program_configs['num_lfe_channel_elements']; $i++) { + $channels++; + } + return $channels; +} + +?> \ No newline at end of file diff --git a/livesupport/modules/getid3/var/getid3.ape.php b/livesupport/modules/getid3/var/getid3.ape.php new file mode 100644 index 000000000..e0840a384 --- /dev/null +++ b/livesupport/modules/getid3/var/getid3.ape.php @@ -0,0 +1,188 @@ + // +// available at http://getid3.sourceforge.net /// +///////////////////////////////////////////////////////////////// +// // +// getid3.ape.php - part of getID3() // +// See getid3.readme.txt for more details // +// // +///////////////////////////////////////////////////////////////// + +function getAPEtagFilepointer(&$fd, &$ThisFileInfo) { + $id3v1tagsize = 128; + $apetagheadersize = 32; + fseek($fd, 0 - $id3v1tagsize - $apetagheadersize, SEEK_END); + $APEfooterID3v1 = fread($fd, $id3v1tagsize + $apetagheadersize); + if (substr($APEfooterID3v1, 0, strlen('APETAGEX')) == 'APETAGEX') { + + // APE tag found before ID3v1 + $APEfooterData = substr($APEfooterID3v1, 0, $apetagheadersize); + $APEfooterOffset = 0 - $apetagheadersize - $id3v1tagsize; + + } elseif (substr($APEfooterID3v1, $id3v1tagsize, strlen('APETAGEX')) == 'APETAGEX') { + + // APE tag found, no ID3v1 + $APEfooterData = substr($APEfooterID3v1, $id3v1tagsize, $apetagheadersize); + $APEfooterOffset = 0 - $apetagheadersize; + + } else { + + // APE tag not found + return false; + + } + + if (empty($ThisFileInfo['fileformat'])) { + $ThisFileInfo['fileformat'] = 'ape'; + } + $ThisFileInfo['ape']['footer'] = parseAPEheaderFooter($APEfooterData); + + if (isset($ThisFileInfo['ape']['footer']['flags']['header']) && $ThisFileInfo['ape']['footer']['flags']['header']) { + fseek($fd, $APEfooterOffset - $ThisFileInfo['ape']['footer']['raw']['tagsize'] + $apetagheadersize - $apetagheadersize, SEEK_END); + $APEtagData = fread($fd, $ThisFileInfo['ape']['footer']['raw']['tagsize'] + $apetagheadersize); + } else { + fseek($fd, $APEfooterOffset - $ThisFileInfo['ape']['footer']['raw']['tagsize'] + $apetagheadersize, SEEK_END); + $APEtagData = fread($fd, $ThisFileInfo['ape']['footer']['raw']['tagsize']); + } + $offset = 0; + if (isset($ThisFileInfo['ape']['footer']['flags']['header']) && $ThisFileInfo['ape']['footer']['flags']['header']) { + $ThisFileInfo['ape']['header'] = parseAPEheaderFooter(substr($APEtagData, 0, $apetagheadersize)); + $offset += $apetagheadersize; + } + + for ($i = 0; $i < $ThisFileInfo['ape']['footer']['raw']['tag_items']; $i++) { + $value_size = LittleEndian2Int(substr($APEtagData, $offset, 4)); + $offset += 4; + $item_flags = LittleEndian2Int(substr($APEtagData, $offset, 4)); + $offset += 4; + $ItemKeyLength = strpos($APEtagData, chr(0), $offset) - $offset; + $item_key = strtolower(substr($APEtagData, $offset, $ItemKeyLength)); + $offset += $ItemKeyLength + 1; // skip 0x00 terminator + $data = substr($APEtagData, $offset, $value_size); + $offset += $value_size; + + $ThisFileInfo['ape']['items']["$item_key"]['raw']['value_size'] = $value_size; + $ThisFileInfo['ape']['items']["$item_key"]['raw']['item_flags'] = $item_flags; + if ($ThisFileInfo['ape']['footer']['tag_version'] >= 2) { + $ThisFileInfo['ape']['items']["$item_key"]['flags'] = parseAPEtagFlags($item_flags); + } + $ThisFileInfo['ape']['items']["$item_key"]['data'] = $data; + $ThisFileInfo['ape']['items']["$item_key"]['data_ascii'] = $data; + if (APEtagItemIsUTF8Lookup($item_key)) { + $ThisFileInfo['ape']['items']["$item_key"]['data_ascii'] = RoughTranslateUnicodeToASCII($ThisFileInfo['ape']['items']["$item_key"]['data'], 3); + } + + switch ($item_key) { + case 'replaygain_track_gain': + $ThisFileInfo['replay_gain']['radio']['adjustment'] = (float) $ThisFileInfo['ape']['items']["$item_key"]['data_ascii']; + $ThisFileInfo['replay_gain']['radio']['originator'] = 'unspecified'; + break; + + case 'replaygain_track_peak': + $ThisFileInfo['replay_gain']['radio']['peak'] = (float) $ThisFileInfo['ape']['items']["$item_key"]['data_ascii']; + $ThisFileInfo['replay_gain']['radio']['originator'] = 'unspecified'; + break; + + case 'replaygain_album_gain': + $ThisFileInfo['replay_gain']['audiophile']['adjustment'] = (float) $ThisFileInfo['ape']['items']["$item_key"]['data_ascii']; + $ThisFileInfo['replay_gain']['audiophile']['originator'] = 'unspecified'; + break; + + case 'replaygain_album_peak': + $ThisFileInfo['replay_gain']['audiophile']['peak'] = (float) $ThisFileInfo['ape']['items']["$item_key"]['data_ascii']; + $ThisFileInfo['replay_gain']['audiophile']['originator'] = 'unspecified'; + break; + + case 'title': + case 'artist': + case 'album': + case 'track': + case 'genre': + case 'comment': + case 'year': + $ThisFileInfo['ape']['comments']["$item_key"][] = $ThisFileInfo['ape']['items']["$item_key"]['data_ascii']; + break; + + } + + } + if (isset($ThisFileInfo['ape']['comments'])) { + CopyFormatCommentsToRootComments($ThisFileInfo['ape']['comments'], $ThisFileInfo, true, true, true); + } + + return true; +} + +function parseAPEheaderFooter($APEheaderFooterData) { + // http://www.uni-jena.de/~pfk/mpp/sv8/apeheader.html + $headerfooterinfo['raw']['footer_tag'] = substr($APEheaderFooterData, 0, 8); + $headerfooterinfo['raw']['version'] = LittleEndian2Int(substr($APEheaderFooterData, 8, 4)); + $headerfooterinfo['raw']['tagsize'] = LittleEndian2Int(substr($APEheaderFooterData, 12, 4)); + $headerfooterinfo['raw']['tag_items'] = LittleEndian2Int(substr($APEheaderFooterData, 16, 4)); + $headerfooterinfo['raw']['global_flags'] = LittleEndian2Int(substr($APEheaderFooterData, 20, 4)); + $headerfooterinfo['raw']['reserved'] = substr($APEheaderFooterData, 24, 8); + + $headerfooterinfo['tag_version'] = $headerfooterinfo['raw']['version'] / 1000; + if ($headerfooterinfo['tag_version'] >= 2) { + $headerfooterinfo['flags'] = parseAPEtagFlags($headerfooterinfo['raw']['global_flags']); + } + return $headerfooterinfo; +} + +function parseAPEtagFlags($rawflagint) { + // "Note: APE Tags 1.0 do not use any of the APE Tag flags. + // All are set to zero on creation and ignored on reading." + // http://www.uni-jena.de/~pfk/mpp/sv8/apetagflags.html + $flags['header'] = (bool) ($rawflagint & 0x80000000); + $flags['footer'] = (bool) ($rawflagint & 0x40000000); + $flags['this_is_header'] = (bool) ($rawflagint & 0x20000000); + $flags['item_contents_raw'] = ($rawflagint & 0x00000006) >> 1; + $flags['item_contents'] = APEcontentTypeFlagLookup($flags['item_contents_raw']); + $flags['read_only'] = (bool) ($rawflagint & 0x00000001); + + return $flags; +} + +function APEcontentTypeFlagLookup($contenttypeid) { + static $APEcontentTypeFlagLookup = array(); + if (empty($APEcontentTypeFlagLookup)) { + $APEcontentTypeFlagLookup[0] = 'utf-8'; + $APEcontentTypeFlagLookup[1] = 'binary'; + $APEcontentTypeFlagLookup[2] = 'external'; + $APEcontentTypeFlagLookup[3] = 'reserved'; + } + return (isset($APEcontentTypeFlagLookup[$contenttypeid]) ? $APEcontentTypeFlagLookup[$contenttypeid] : 'invalid'); +} + +function APEtagItemIsUTF8Lookup($itemkey) { + static $APEtagItemIsUTF8Lookup = array(); + if (empty($APEtagItemIsUTF8Lookup)) { + $APEtagItemIsUTF8Lookup[] = 'Title'; + $APEtagItemIsUTF8Lookup[] = 'Subtitle'; + $APEtagItemIsUTF8Lookup[] = 'Artist'; + $APEtagItemIsUTF8Lookup[] = 'Album'; + $APEtagItemIsUTF8Lookup[] = 'Debut Album'; + $APEtagItemIsUTF8Lookup[] = 'Publisher'; + $APEtagItemIsUTF8Lookup[] = 'Conductor'; + $APEtagItemIsUTF8Lookup[] = 'Track'; + $APEtagItemIsUTF8Lookup[] = 'Composer'; + $APEtagItemIsUTF8Lookup[] = 'Comment'; + $APEtagItemIsUTF8Lookup[] = 'Copyright'; + $APEtagItemIsUTF8Lookup[] = 'Publicationright'; + $APEtagItemIsUTF8Lookup[] = 'File'; + $APEtagItemIsUTF8Lookup[] = 'Year'; + $APEtagItemIsUTF8Lookup[] = 'Record Date'; + $APEtagItemIsUTF8Lookup[] = 'Record Location'; + $APEtagItemIsUTF8Lookup[] = 'Genre'; + $APEtagItemIsUTF8Lookup[] = 'Media'; + $APEtagItemIsUTF8Lookup[] = 'Related'; + $APEtagItemIsUTF8Lookup[] = 'ISRC'; + $APEtagItemIsUTF8Lookup[] = 'Abstract'; + $APEtagItemIsUTF8Lookup[] = 'Language'; + $APEtagItemIsUTF8Lookup[] = 'Bibliography'; + } + return in_array($itemkey, $APEtagItemIsUTF8Lookup); +} + +?> \ No newline at end of file diff --git a/livesupport/modules/getid3/var/getid3.changelog.txt b/livesupport/modules/getid3/var/getid3.changelog.txt new file mode 100644 index 000000000..d331f4e82 --- /dev/null +++ b/livesupport/modules/getid3/var/getid3.changelog.txt @@ -0,0 +1,1375 @@ +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich // +// available at http://getid3.sourceforge.net /// +///////////////////////////////////////////////////////////////// +// // +// getid3.changelog.txt - part of getID3() // +// See getid3.readme.txt for more details // +// // +///////////////////////////////////////////////////////////////// + + » denotes a major feature addition/change + Ø denotes a change in the returned structure +* Bugfix: denote a fixed bug + +Version History +=============== + +1.6.0: [Jan-30-2003] + » Added support for OggFLAC (FLAC data stored in an Ogg container) + (thanks ah@artemis.dk for the idea) + » Added support for Speex (the data stored in an Ogg container) + » Comments are now available in the root 2-dimensional array + ['comments'] - each entry in this array will contain one or more + strings. For example, if there are two artists then + ['comments']['artist'][0] will contain the first one and + ['comments']['artist'][0] the other. All keys are forced + lowercase. Comments will be stored in the ['comments'] array in + this order of precedence: + 1) Native format tags (ASF, VQF, NSV, RIFF, Quicktime, Vorbis) + 2) APE tags + 3) ID3v2 + 4) Lyrics3 + 5) ID3v1 + Lower-priority tags will not overwrite or append existing values + of higher-priority tags (for example, 'artist' in ID3v1 will be + ignored if already specified in APE), but missing values will be + filled in (for example, if 'album' is specified in ID3v2 but not + in APE, it will be included in the ['comments'] array). + Note: Root keys (['title'], ['artist'], etc) are NOT available + in this or future versions of getID3(). + (thanks ah@artemis.dk) + » MD5 hashes are now available for all formats for both the entire + file (['md5_file']) and the portion of the file containing only + the audio/video data, stripped of all prepended/appended tags + like ID3v2, ID3v1, APE, etc - ['md5_data'] + (thanks ah@artemis.dk for alternate md5_file() function that + runs on UNIX system running PHP < 4.2.0) + NOTE: Ogg files require the use of vorbiscomment to obtain the + md5_data value. vorbiscomment must be downloaded from + http://www.vorbis.com/download.psp and placed in the getID3() + directory. All Ogg formats (Vorbis, OggFLAC, Speex) are affected + by this problem, but only OggVorbis files can be processed with + vorbiscomment. OggFLAC and Speex files will be processed by + getID3(), but this may result in an incorrect value for md5_data + in the event that VorbisComments are larger than 1 page (4-8kB). + NOTE: md5_data for Ogg will not work if PHP is running in Safe + Mode + » There is now a wrapper class available, written by Allan Hansen, + which should simplify extracting most common basic information + (such as format, bitrate, comments). + New file: audioinfo.class.php + » OggWrite() in getid3.ogginfo.php has been replaced with a new + version that uses vorbiscomment to write the comments, because + of a reported bug that can corrupt OggVorbis files such they + cannot be played. + NOTE: Ogg comment writing now requires the use of vorbiscomment + which must be downloaded from http://www.vorbis.com/download.psp + and placed in the getID3() directory. + NOTE: Ogg comment writing will not work if PHP is running in + Safe Mode + Ø New root key ['tags'] is now always returned for all formats. + It is an array that may contain any of: + * Native format tags: 'vqf', 'riff', 'vorbiscomment', 'asf', + 'nsv', 'real', 'midi', 'zip', 'quicktime' + * Appended data tags: 'ape', 'lyrics3', 'id3v2', 'id3v1' + Ø New root key ['audio'] is an array containing any or all of: + codec, channels, channelmode, bitrate, bits_per_sample, + dataformat, bitrate_mode, sample_rate, encoder + Note: This replaces several root keys, including: + bitrate_audio, bits_per_sample, frequency, channels + Ø New root key ['video'] is an array containing any or all of: + bitrate_mode, bitrate, codec, resolution_x, resolution_y, + resolution_y, frame_rate, encoder + Note: This replaces several root keys, including: + bitrate_video, resolution_x, resolution_y, frame_rate + Ø ['id3']['id3v1'] has moved to ['id3v1'] + Ø ['id3']['id3v2'] has moved to ['id3v2'] + Ø ['audiodataoffset'] and ['audiodataend'] have been renamed to + ['avdataoffset'] and ['avdataend'] respectively + Ø GetAllMP3info() has been changed to GetAllFileInfo() with a + different parameter list ($allowedFormats is no longer a + parameter). Check your code where you're calling + GetAllMP3Info() - you will need to change both the function + name and the parameter list if you pass more than 2 parameters + Ø All formats now return ['audio']['dataformat'] and/or + ['video']['dataformat'] where appropriate - this goes along with + ['fileformat'] - ['fileformat'] will return the actual structure + of the file, whereas ['dataformat'] will return the format of + the data inside that structure. For example, an Ogg file can + contain Vobis data (normal), or it can contain FLAC data in the + Ogg container format. In that case, ['fileformat'] would be + 'ogg', but ['dataformat'] would be 'flac'. + Note: this means that WAV and AVI files now return a + ['fileformat'] of 'riff' rather than 'wav' or 'avi'. + Ø ['filesize'] is no longer returned for files larger than 2GB + because PHP does not support large file access. Attempting to + parse a file larger than 2GB will result in a message stored in + ['error'] and ['filesize'] not set. + Ø APEtag, ID3v1, and ID3v2 are now supported on ALL multimedia + files - even if illegal by format. Ogg will return warning if + ID3/APE tags are present. (thanks ah@artemis.dk) + Ø All files: non-critical errors are now returned in the root key + ['warning'] rather than ['error'] (only critical errors that + prevent getID3() from correctly parsing the file are returned in + ['error'] (thanks ah@artemis.dk) + Ø Renamed all references to $MP3fileInfo to $ThisFileInfo + Ø Joliet now supported for ISO-9660. + ['iso']['supplementary_volume_descriptor'] is now returned, if + available, and ['iso']['files'] will contain ASCII equivalents + of the Unicode directory structure & filenames stored. + Ø Moved Monkey's Audio code from getid3.ape.php to seperate file. + New file: getid3.monkey.php + Ø Added new keys for ISO-9660: ['name_ascii'] for directories, + ['file_identifier_ascii'] for files + Ø Added root key ['track'] for CD-audio files + Ø Ogg/Vorbis-comment files now have comments returned inside + ['ogg']['comments_common'] as an array of strings, rather than + simple strings in ['ogg'] + Ø Quicktime files now have comments returned inside + ['quicktime']['comments'] as an array of strings, rather than + simple strings in ['quicktime'] + Ø ['mime_type'] is a new root key returned for all supported + formats (thanks ah@artemis.dk) + Ø ['fileformat'] now returns 'mp1' instead of 'mp3' for MPEG-1 + layer-I audio files (thanks ah@artemis.dk) + Ø ['mpeg']['audio']['bitratemode'] now returns lowercase + Ø MPEG-4 audio files which consist of MP3 data wrapped in a + Quicktime fileformat will now return the usual data in + ['mpeg']['audio'] + Ø Type-1 DV AVIs are now supported + Ø DV AVIs will return 1 or 2 in ['RIFF']['video'][x]['dv_type'] + Ø Changed ['fileformat'] from 'mpg' to 'mpeg' for MPEG video files + Ø ASF comments are now stored in ['asf']['comments'] instead of + ['asf'] + Ø RealMedia chunk data is now returned inside ['real']['chunks'] + instead of ['real'] + Ø ['replay_gain'] now properly populated from APE tags + Ø Added support for ASF_Old_ASF_Index_Object in ASF files + (thanks ah@artemis.dk) + Ø AAC-ADTS files now return ['aac']['bitrate_distribution'] + Ø ParseVorbisComments() has been replaced with + ParseVorbisCommentsFilepointer() (with different parameters) + Ø All references to any key ['frequency'] are now ['sample_rate'] + Ø Moved ID3v2 comments from ['id3v2'] into common root + ['comments'] structure, and now returns more values than before + * Bugfix: ['iso']['files'] and ['zip']['files'] could potentially + contain duplicate entries (in a numeric-indexed array) for files + if the directory structure specifies files multiple times. + Entries are now guaranteed unique, with the last entry for the + file overwriting any former ones. + * Bugfix: RIFF parsing had numerous issues, including: + - large AVIs would take a very very long time to parse + - chunks with odd (not even) sizes would cause the parser fail + - video and/or audio codecs not always identified + The ParseRIFF() function has been completely rewritten and fixes + all known issues with RIFF parsing. Users are, however, + encouraged to double-check output of any parsed (AVI/WAV/CDDA) + files. + * Bugfix: Modified getid3.riff.php to return correct total + bitrates for AVIs with multiple audio streams + * Bugfix: GetFileFormat() was not creating array structure + correctly (thanks ah@artemis.dk) + * Bugfix: LAME tag for MP3s can only specify up to 255kbps, so any + files with actual CBR bitrate of >=256 were reported incorrectly + * Bugfix: Lyrics3 synched lyrics were not being correctly returned + * Bugfix: CreateDeepArray() was broken for non-nested cases, which + meant ZIP and ISO ['files'] structures were broken + * Bugfix: Incorrect pattern matching for ZIP files meant no zip + files were being detected as such + * Bugfix: AAC-ADIF was returning an incorrect number of channels + (too few) in some cases (thanks ah@artemis.dk) + * Bugfix: Vorbis comments were returning an incorrect value for + ['dataoffset'] in some cases + * Bugfix: MPEG video ['marker_bit'] and ['vbv_buffer_size'] were + incorrect + * Bugfix: ['playtime_string'] could potentially have a value of + x minutes and 60 seconds (ie 3:60 instead of 4:00) + Added support for FLAC cuesheets (FLAC 1.1.0+) + (thanks ah@artemis.dk) + Improved parsing speed in MP3, MP2 and AAC (thanks ah@artemis.dk) + Extra error-checking added to try and identify corrupt files for + most audio formats (thanks ah@artemis.dk) + More accurate playtime calculation for RealMedia + (thanks ah@artemis.dk) + Changed all relevant files to use ['audiodataoffset'] and + ['audiodataend'] rather than ['filesize'] where appropriate + (thanks ah@artemis.dk) + Added text encoding type 255 as a duplicate of UTF-16BE but with + Big-Endian rather than Little-Endian byte order + Added many RIFF-AVI audio types and fourcc video types to the + lookup functions in getid3.riff.php + Added numerous new known GUIDs to getid3.asf.php + Added PoweredBygetID3() function to easily get a "powered by" + string with the current getID3() version. + Added "Morgan Multimedia Motion JPEG2000" (MJ2C), "DivX v5" (DX50) + and "XviD" (XVID) codecs to list of known codecs in + getid3.riff.php + Changed GETID3_INCLUDEPATH path seperators to forced / + (from \ for Windows) + Modified getid3.check.php to only change \ directory seperators to + / on Windows operating systems + Modified getid3.check.php to handle larger-than-2GB files (which + now do not return a filesize) + Modified getid3.check.php to handle ['dataformat_audio'] and + ['dataformat_video'] + Modified getid3.check.php to show a list of present tags in one + column rather than one column for each of ID3v1, ID3v2, etc + Modified getid3.check.php to show MD5 values. Initially disabled + but can be enabled for a directory with a click. md5_file is + always calculated when displaying detailed info about a single + file; md5_data is calculated if the file is < 50MB + Modified getid3.check.php to show errors and warnings. Details are + visible with a mouseover or a click. + Changed getid3.check.php to use SafeStripSlashes instead of a + manual conditional directory name replacement for special + characters + Added sample recursive scanning sample code to getid3.readme.txt + (thanks lipisin@mail.ru for the idea) + +1.5.7: [Jan-10-2003] + » Added support for ISO 9660 (CD-ROM image) format. Most-useful + data is directory structure returned under ['iso']['files'] + Note: Only ISO-9660 supported, not (yet) Joliet extension + (thanks nebula_dj@softhome.net for the idea) + New file: getid3.iso.php + Ø ZIP files are now parsed by getID3() itself without relying on + built-in PHP functions and/or ZZipLib support. + (thanks Vince for the idea) + Ø ZIP files now return a simple directory listing with filename + and filesize info only under ['zip']['files']. + Note: empty subdirectories will note appear in here, only files + and non-empty subdirectories. Information for all entries, + including empty subdirectories, is available under + ['zip']['central_directory'] (or under ['zip']['entries'] if the + Central Directory cannot be located (usually due to a trucated + file). + Ø RIFF-WAV files with MP3 data (or MP3s with RIFF headers, if you + want to think of it that way) now have the MPEG audio portion + scanned and the usual data returned in ['mpeg']['audio'] if the + RIFF audio codec has wFormatTag of "85" (identified by getID3() + as "Microsoft ACM: LAME MP3 encoder (ACM)") + (thanks ah@artemis.dk for the idea) + Ø EXIF data (if present) is returned for JPEG files under + ['jpg']['exif'] (thanks nebula_dj@softhome.net) + Ø ['filepath'] now returned for all files with the directory part + of the full filename. + Ø ['filenamepath'] is now returned for all files (equivalent to + ['filepath'].'/'.['filename']) + * Bugfix: ['id3']['id3v2'][]['dataoffset'] was wrong + * Bugfix: MP3s tagged with iTunes have an invalid comment field + frame name ('COM ' - should be 'COMM') but the data is valid + otherwise; the frame is now renamed to 'COMM' and parsed + normally (with the error noted in ['error']) + (thanks kheller2@mac.com for the sample file) + * Bugfix: Some ASF/WMA audio files were not being identified as + any format (thanks ah@artemis.dk) + * Bugfix: Warning now generated and ASCII format assumed for + invalid text encoding values in ID3v2 + * Bugfix: Changed ZIP detection pattern from 'PK' to 'PK\x04\x03' + * Bugfix: Ogg/FLAC files with large Vorbis comments were dying in + an infinite loop with lots of error messages due to missing $fd + parameter on ParseVorbisComments() (thanks ah@artemis.dk) + * Bugfix: ['data'] and ['image_mime'] were being returned for all + Ogg comments even if they were not images for versions of PHP + that have image_type_to_mime_type() built in (ie PHP 4.3.0+) + +1.5.6: [Dec-31-2002] + » Added support for NSV (Nullsoft Streaming Video) + (www.nullsoft.com/nsv/) + (thanks demon@soundplanet.com for the idea) + New file: getid3.nsv.php + » Added support for CD-audio track files (track01.cda etc) + Ø Added standard ['frame_rate'] root value when known (AVI, NSV, + MPEG-video) + Ø ASF files now report ['fileformat'] of: + 'wmv' when Windows Media Video codec v7/v8/v9 is used; + 'wma' when any 'Windows Media Audio' named audio codec is used + and no video stream is present; + 'asf' in all other cases (audio-only, video-only, or both) + Ø Removed support for ZIP functions (will be rewritten to not + require ZZIPlib support in future versions) + Ø Added function SafeStripSlashes() as a drop-in replacement for + stripslashes(), but that only strips slashes if magic_quotes_gpc + is set + Ø Removed support for remote file scanning (HTTP / FTP) + Ø Added ['aac']['frames'] (number of AAC frames in file) + Ø Added ['mpeg']['audio']['frame_count'] when a bitrate histogram + is created + Ø Average bitrate for VBR MP3/MP2 is calculated from actual counts + of frames of various bitrates (rather than relying on the header + values or filesize) when a bitrate histogram is created + Ø RecursiveFrameScanning() split out into seperate function + (getid3.mp3.php) + Ø Removed old function getMP3header() from getid3.mp3.php + Ø Changed default MPEG_VALID_CHECK_FRAMES (number of mp3 frames + scanned to ensure a valid audio sequence has been located) from + 10 to 25. This means scanning will be slightly slower, but more + reliable/accurate + * Bugfix: ID3v2.2 - valid frame names not correctly detected + (thanks maecker@web.de for the sample file) + * Bugfix: ID3v2.2 - valid padding not correctly detected + (thanks maecker@web.de for the sample file) + * Bugfix: MIDI files with flat key signatures were not being + correctly reported (thanks alexleeis@shaw.ca for sample file) + * Bugfix: now returns message in ['error'] if file does not exist + * Bugfix: ['RIFF']['video'][x]['codec'] wasn't always being + correctly populated + * Bugfix: ['bitrate'] was incorrect for multi-stream RealMedia + * Bugfix: ['playtime_seconds'] was sometimes null or incorrect + for multi-stream RealMedia + * Bugfix: ChannelTypeID was incorrect in RVA2 ID3v2.4 frames + * Bugfix: Fixed potential divide-by-zero error for corrupt FLAC + files (thanks ah@artemis.dk) + * Bugfix: AAC-ADTS was not returning ['bitrate_mode'] unless + $ReturnExtendedInfo was TRUE (thanks ah@artemis.dk) + * Bugfix: LAME-encoded CBR MP3s now properly identified as CBR + with correct bitrate (thanks ah@artemis.dk) + * Bugfix: VBR MP2 (or headerless MP3) is now identified as VBR + rather than CBR. Note: to obtain VBR bitrate for headerless + files, the entire file is scanned and a histogram distribution + of bitrates is created, and the average bitrate calculated from + that. (thanks ah@artemis.dk for sample file) + Added support for DSIZ chunks in VQF, and checks to make sure size + of audio data matches DSIZ value, if present + (thanks ah@artemis.dk for sample file) + Rewrote GetAllMP3info() - removed some unneccesary code, changed + format-detection routine from ParseAsThisFormat() to + GetFileFormat() to allow for more flexible format parsing + (needed for ISO CD-ROM images, helpful for Quicktime and others) + Changed references in all files from string-cast indexes: ["$i"] + to non-cast indexes: [$i] where appropriate + Put a sans-serif 9pt style on all text in getid3.check.php + getAACADTSheaderFilepointer() now return TRUE if synch is lost + after the first frame has been successfully parsed (previously + it would return FALSE if synch was lost at any time, meaning the + file is most likely MP3, which was incorrect) + (thanks ah@artemis.dk for sample file) + Speed improvement code changes to getid3.mp3.php (up to 24% faster + in some cases) (thanks ah@artemis.dk for the code) + Changed all include_once() to require_once() + + +1.5.5: [Nov-25-2002] + » Added support for La (Lossless Audio - www.lossless-audio.com) + (thanks ah@artemis.dk for the idea) + New file: getid3.la.php + Ø Moved lookup functions from getid3.lookup.php to the files where + they are used. + New file: getid3.id3.php + New file: getid3.rgad.php + Removed file: getid3.lookup.php + Ø getID3v1Filepointer() returns FALSE if ID3v1 tag not found + Ø Added new paramter "ReturnExtendedInfo" to the function + getAACADTSheaderFilepointer() in getid3.aac.php which now + defaults to FALSE - if TRUE then the data for every frame is + returned (containing aac_frame_length, adts_buffer_fullness and + num_raw_data_blocks, which aren't usually very useful). Speed + improvement with FALSE is about 35%. + Ø Now returns fopen() errors in ['error'], for example if a remote + file is not accessible. + Ø Changed default number of MP3 audio frames to scan to determine + if a valid stream has been found from 5 to 10, now also defined + as a constant at the top of getid3.mp3.php This will result in + slightly slower MP3 parsing, but greater reliability in + detecting false/invalid/corrupted VBR headers. + Ø fopen() errors now displayed in getid3.putid3.php + (thanks miguel.dieckmann@hamburg.de) + Ø Added 4th parameter to decodeMPEGaudioHeader() $ScanAsCBR which + will force an MP3 audio frame sequence to be force-scanned in + CBR mode. You should never need to call this directly, it's only + used internally to scan for MP3 files that have an illegal VBR + header with CBR data. (thanks fletch@pobox.com) + * Bugfix: ASF_Marker_Object in getid3.asf.php was always returning + an error in non-existant "reserved_1" and failing + * Bugfix: VBR bitrate calculations in getid3.mp3.php only occur if + ['mpeg']['audio']['VBR_frames'] is defined. + (thanks fletch@pobox.com) + * Bugfix: getid3.putid3.php no longer deletes original MP3 if + ID3v2 tag writing fails (thanks miguel.dieckmann@hamburg.de) + * Bugfix: incorrect order of if-statement error messages in + getid3.putid3.php (thanks miguel.dieckmann@hamburg.de) + getid3.asf.php now notes the error and continues parsing rather + than failing when it encounters an error parsing a chunk + Now actually scan 1000 frames for AAC ADTS as reported in the + v1.5.4 changelog, rather than 100. (thanks ah@artemis.dk) + Improved scanning speed in getAACADTSheaderFilepointer() by ~30% + (thanks ah@artemis.dk for the fix) + Added FileSizeNiceDisplay() function to getid3.functions.php for + formatting filesize output in kB, MB, GB, etc. + +1.5.4: [Oct-07-2002] + » Added support for Quicktime. + New file: getid3.quicktime.php + » Added support for AAC files, both ADTS and ADIF header formats. + ADIF format is a pain because it's very similar to standard MP3 + header format, and it's hard to distinguish between the two. I + have tried to make the detection accurate, but I have a limited + number of AAC test files to play with so if you have an AAC file + that gets detected as MP3/MP2 (or vice-versa), please send me + the details via email at getid3@silisoftware.com + ADTS format is very slow to parse because to get the bitrate of + VBR files the whole file has to be stepped through frame by + frame (getID3() scans up to the first 1000 frames and assumes + that to be close enough). + Note: I would suggest commenting out support for AAC (see top of + GetAllMP3info() function in getid3.php) unless you need it. + (thanks jfaul@gmx.de for the idea and sample Delphi source code) + New file: getid3.aac.php + » Added bitrate distribution analysis option for MP3 VBR files. A + new boolean parameter for getOnlyMPEGaudioInfo() enabled this + feature which steps through the MP3 file frame by frame and + counts how many frames of each bitrate exist. This information + is returned in ['mpeg']['audio']['bitrate_distribution'] + Caution: this feature is very inefficient for large files and + takes a very long time and does lots of disk I/O. Use with care. + Ø Changed layout of allowedFormats in GetAllMP3info() function in + getid3.php to allow easy removal of support for any of the + supported format. As stated above, I recommend commenting out + AAC unless needed. + Ø Added ['flac']['compressed_audio_bytes'], + ['flac']['uncompressed_audio_bytes'], and + ['flac']['compression_ratio'] + Ø Replaced FXPT2DOT30toFloat() function with FixedPoint2_30() + * Bugfix: getid3.mpc.php was slightly miscalculating the number of + samples, therefore also bitrate and playtime + (thanks ah@artemis.dk for the fix) + * Bugfix: MonkeyCompressionLevelNameLookup() didn't know about + 'insane' compression (thanks ah@artemis.dk for the fix) + * Bugfix: MonkeySamplesPerFrame() was incorrect for MAC v3.95+ + (thanks ah@artemis.dk for the fix) + * Bugfix: getid3.check.php wasn't processing the assumeFormat + directive when (register_globals == off) + * Bugfix: detecting of synch pattern for MP3 files with invalid + data at the beginning wasn't always correct, also meant possible + incorrect bitrate/duration/etc info for such corrupt files. + getid3.functions.php now includes a replacement utf8_decode() + function for those PHP installations that are not configured + with the --with-xml option. (thanks stephane@tekartists.com) + +1.5.3: [Sep-30-2002] + » Added support for VQF. (thanks mt@mansonthomas.com for the idea) + New file: getid3.vqf.php + » Added support for FLAC. Comments, if present, are returned under + ['ogg'] because they follow the Ogg Vorbis structure standard. + New file: getid3.flac.php + Ø OS/2-format bitmaps are now correctly interpreted. The format of + the bitmap is now returned in ['bmp']['type_os'] and + ['bmp']['type_version']. OS/2 bitmaps can be v1 or v2, Windows + can be v1, v4 or v5 + +1.5.2: [Sep-25-2002] + + » Support for RealMedia (audio & video) added + Note: only tested on G2 and v5 audio and video files - if anyone + has older and/or newer sample files, please test it and/or send + me the sample files. + (thanks stephane@tekartists.com for idea) + New file: getid3.real.php + » Support for BMP added. Palette and pixel data can optionally be + extracted as well - this is slow and generally unneccesary, but + the option is there if you need it. Also includes PlotBMP() + which will take the extracted pixel data and output it as a true + color PNG. This function requires GD v2.0+ + Note: Untested on 16-bit and 32-bit BMPs because I couldn't find + any sample files - if you know of a program that can create such + files, please email getid3@silisoftware.com + Note: Support for RGB (uncompressed), RLE8 and RLE4 is included + and tested. BITFIELDS support is also included for 16- & 32-bit + formats, but it's untested, so if anybody has any test files + please send them to getid3@silisoftware.com + Note: Support currently only for Windows-format BMPs, and trying + to parse an OS/2-format bitmap leads to unpredictable/invalid + results. + New file: getid3.bmp.php + » PNG now fully parsed, including all information chunks + New file: getid3.png.php + Ø Support for GIF/JPG/PNG moved to seperate files and expanded, + including standard ['resolution_x'] and ['resolution_y'] as well + as more thorough parsing of header information + New file: getid3.gif.php + New file: getid3.jpg.php + table_var_dump() simplified and now outputs {-style character + entities for characters outside the normal alphanumeric range + CleanOggCommentName() changed to a regular expression + (thanks chris-getid3@bolt.cx for rewriting the function) + +1.5.1: [Sep-20-2002] + » Added support for MPEGplus/Musepack SV7. ['fileformat'] is 'SV7' + for version 7 files (versions 4, 5 ,6 and 8 are not supported + yet, but will be of ['fileformat'] SV4, SV5, SV6 and SV8) when + they are supported (thanks Christian Fritz for the idea) + New file: getid3.mpc.php + Ø ['bitrate_audio'], ['bitrate_video'], ['bitrate_mode'], + ['channels'], ['resolution_x'], and ['resolution_y'] keys added + for all appropriate formats + Ø Ogg files with a COVERART comment now save and display the + attached image the same way as is done with ID3v2 APICs + Ø ['ogg']['comments'][n]['data'] and + ['ogg']['comments'][n]['dataoffset'] is now returned for all + comments. ['ogg']['comments'][n]['data'] is only useful if + the field is supposed to contain binary data. It is a + base64_decode()'d version of ['value']. + ['ogg']['comments'][n]['dataoffset'] is the byte offset in the + file at which the 'COMMENTNAME=value string' starts, not the + start of just 'value' + Ø ['ogg']['comments'][n]['image_mime'] is now returned if + ['ogg']['comments'][n]['data'] contains valid image data. + Ø More than 3 Ogg pages may now be read in, if the comment data + is longer than 1 page (usually about 4kB) + Ø ['fileformat'] is now 'mp2' rather than 'mp3' if it's MPEG-1, + Layer-II audio + Ø ASF bitrates now calculated even if stream_bitrate_properties + object not present + Ø ['asf']['stream_properties_object'] is now a numeric-key array + with one entry for each stream - the key being the stream number + Ø ['replay_gain'] is returned for all audio formats that support + it (MP3-LAME, ID3v2, Ogg) (thanks Christian Fritz for the idea) + Ø ['mpeg']['audio']['LAME']['RGAD']['radio_replay_gain'] is now + ['mpeg']['audio']['LAME']['RGAD']['radio'] (same for audiophile) + Ø ASF/WMA files now use WM/Track to get track number from if + WM/TrackNumber is not available (thanks stephane@tekartists.com) + Ø ASF/WMV files now returns ['year'] and ['asf']['year'] + Ø ASV/WMV files now use ['content_description']['description'] for + the ['comment'] field (thanks stephane@tekartists.com) + Ø ['track'] is now always returned as an integer + * Bugfix: Ogg comments that are larger than one data page (usually + about 4kB) are now correctly parsed (thanks Christian Fritz) + * Bugfix: Ogg comment data is now UTF8-decoded + * Bugfix: Ogg comment writing now UTF8-encodes the data + * Bugfix: playtime for ASF files was off by (usually + between 3 and 12 seconds) + * Bugfix: ['asf']['stream_properties_objects']['flags'] data was + possibly incorrect + * Bugfix: ASF Padding Object was overwriting + Stream Bitrate Properties Object data (now returned correctly in + ['asf']['padding_object'] + * Bugfix: ASF Marker Object Reserved_2 field was incorrect + * Bugfix: ASF Bitrate Mutual Exclusion Object had incorrect stream + numbers + Warning displayed if incorrectly-formatted Ogg comment is present + (known to be an issue with CDex v1.40, but fixed by v1.50b7) + (thanks Christian Fritz) + Ogg comment writing now checks for valid comment names + Added bitrate column in getid3.check.php, and added some formatting + (font, colour) + Performance tweaks using bitwise math instead of binary string + operations + +1.5.0: [Sep-18-2002] + » Ogg comment writing support added. getid3.write.php has been + updated to allow for writing comment tags to both MP3 and Ogg. + Big thanks to Chris Bolt for writing the + OggWrite() function and offering it for inclusion in getID3() + New file: getid3.ogginfo.php + » Support for Monkey's Audio and APE tag added. + (thanks Christian Fritz for the idea) + New file: getid3.ape.php + ['fileformat'] now returns 'mac' for Monkey's Audio files, or + 'ape' for files with an APE tag (Monkey's Audio or other format) + » getid3.thumbnail.php has been removed from the distribution and + the table_var_dump() function now outputs APICs as seperate + files in the same directory as the analyzed file. This should + make the image-displaying more reliable as well as reduce + complexity. The naming convention for the images is + filename.ext.[byte offset of APIC data].[jpg|gif|png] + If anybody still has any problems with corrupted images please + let me know at getid3@silisoftware.com + » Support for extended Xing/LAME tag + (see http://users.belgacom.net/gc247244/extra/tag.html) + Data is returned in ['mpeg']['audio']['LAME'] + Ø ['ogg']['tracknumber'] has been renamed to ['ogg']['track'] and + ['track'] is now returned in the root of the array + Ø ['ogg']['pageheader'][n]['flag'] has been renamed to + ['ogg']['pageheader'][n]['flags'] and the unprocessed flag byte + is available in ['ogg']['pageheader'][n]['flags_raw'] + Ø ['frequency'] is now returned for WAVE files in the root of the + array (thanks daniel@electroteque.org) + Ø ASF files now return codec, bitrate, resolution, etc information + under ['asf']['video_media'] or ['asf']['audio_media'] + * Bugfix: RVA2 and EQU2 writing in getid3.putid3.php were + incorrectly writing Volume Adjustment field + * Bugfix: EQU2 in getid3.frames.php was reading Volume Adjustment + as unsigned integer instead of signed integer + * Bugfix: handling of remote files over HTTP & FTP was broken + (thanks Vince) + * Bugfix: incorrect handling of some ASF packets + ASF/Windows Media format now more fully parsed, including Index + Objects + Added several new fourCC video codecs + + +1.4.3: [Sep-15-2002] + » Now parses ASF / WMV / WMA files + Ø New file: getid3.asf.php + * Bugfix: RoughTranslateUnicodeToASCII() would return nothing + if didn't find a terminator it was expecting + Added FILETIMEtoUNIXtime() function (for converting 64-bit + Microsoft FILETIME timestamps, used in ASF files and elsewhere, + to UNIX Epoch timestamps) + Added GUIDtoBytestring() and BytestringToGUID() functions + +1.4.2: [Sep-12-2002] + » getID3() now requires PHP v4.1.0 or higher because it now is + designed to work with register_globals = off and the new auto- + globals ($_GET, $_SERVER, etc). + * Bugfix: VBR MP3 files with Fraunhofer-style VBR header were not + being correctly detected in most cases + (thanks dkushner@oddcast.com and mike@ftl.com for sample files) + * Bugfix: IsValidTextEncoding() was broken + * Bugfix: Add stripslashes($EditorFilename) to getid3.write.php + (writing was broken for files with ' or " in the filename) + (thanks mike@ftl.com and kthejoker) + * Bugfix: If there is garbage data between a valid VBR header + frame and a sequence of valid MPEG-audio frames the VBR data is + no longer discarded. (thanks to mike@ftl.com for sample + Fraunhofer-style VBR file produced with MusicMatch v7.2) + Ø Changed variable system to work with (register_globals = off) + Ø Moved relevant code into seperate PlaytimeString() function + Ø Added nl2br() to table_var_dump() for cleaner output + Ø Now returns the following keys from Fraunhofer-VBR files: + ['VBR_seek_offsets'], ['VBR_seek_offsets_stride'], + ['VBR_offsets_relative'] and ['VBR_offsets_absolute'] + Ø Added ID3v1matchesID3v2() function and implemented in + getid3.check.php (thanks to "Guest" in the forums for the idea) + Changed amount of data read in getid3.getimagesize.php from 10kB + to entire file. (thanks mike@ftl.com) + Wrapped function_exists() checks around function definitions in + getid3.functions.php + Fixed a lot of E_WARNING and E_NOTICE situations, especially in + ID3-writing code (getid3.putid3.php, etc) + Added checks to make sure all needed data is available for writing + ID3v2 tags + +1.4.1b5: [May-30-2002] + * Bugfix: Unsynchronise() was broken, now fixed + (thanks mike@ftl.com) + * Bugfix: GenerateID3v2Tag() now correctly uses non-synchsafe + integers for frame size descriptors in ID3v2.3 and ID3v2.2 + (thanks mike@ftl.com) + Ø Added ['artist'], ['title'], etc keys to root of returned + array to provide a common place to access any returned info + from any file type. Currently gets info from ID3v1, ID3v2, + Ogg, and RIFF/WAVE. Possible returned keys are: + title, artist, album, year, genre, comment, track + Ø Modified LookupGenre() function to search for either genre based + on numeric ID, or now reverse lookup as well + Ø Added ['artist'], ['title'], etc keys to ['RIFF'] information + if info tags are present + Added functionality to attach a picture to the ID3v2 tag in + getid3.write.php + Sorted genres into alphabetical order (special 3 at end of list) + in getid3.write.php + Changed the comment-edit field in getid3.write.php to a multi-line + '; + if ($OldThisfileInfo['fileformat'] == 'mp3') { + echo 'Picture'; + echo ''; + echo ' Write Delete'; + echo ' ID3v1 ID3v2'; + } elseif ($OldThisfileInfo['fileformat'] == 'ogg') { + echo ''; + } + echo ' '; + } else { + echo 'Error'.FixTextFields($EditorFilename).' does not exist'; + echo ''; + } +} else { + echo ''; + echo ''; +} +echo ''; + +?> \ No newline at end of file diff --git a/livesupport/modules/getid3/var/getid3.zip.php b/livesupport/modules/getid3/var/getid3.zip.php new file mode 100644 index 000000000..4f8409227 --- /dev/null +++ b/livesupport/modules/getid3/var/getid3.zip.php @@ -0,0 +1,389 @@ + // +// available at http://getid3.sourceforge.net /// +///////////////////////////////////////////////////////////////// +// // +// getid3.zip.php - part of getID3() // +// See getid3.readme.txt for more details // +// // +///////////////////////////////////////////////////////////////// + +function getZIPHeaderFilepointer(&$fd, &$ThisFileInfo) { + + $ThisFileInfo['fileformat'] = 'zip'; + $ThisFileInfo['zip']['files'] = array(); + + $ThisFileInfo['zip']['compressed_size'] = 0; + $ThisFileInfo['zip']['uncompressed_size'] = 0; + $ThisFileInfo['zip']['entries_count'] = 0; + + $EOCDsearchData = ''; + $EOCDsearchCounter = 0; + while ($EOCDsearchCounter++ < 512) { + + fseek($fd, -128 * $EOCDsearchCounter, SEEK_END); + $EOCDsearchData = fread($fd, 128).$EOCDsearchData; + + if (strstr($EOCDsearchData, 'PK'.chr(5).chr(6))) { + + $EOCDposition = strpos($EOCDsearchData, 'PK'.chr(5).chr(6)); + fseek($fd, (-128 * $EOCDsearchCounter) + $EOCDposition, SEEK_END); + $ThisFileInfo['zip']['end_central_directory'] = ZIPparseEndOfCentralDirectory($fd); + + fseek($fd, $ThisFileInfo['zip']['end_central_directory']['directory_offset'], SEEK_SET); + $ThisFileInfo['zip']['entries_count'] = 0; + while ($centraldirectoryentry = ZIPparseCentralDirectory($fd)) { + $ThisFileInfo['zip']['central_directory'][] = $centraldirectoryentry; + $ThisFileInfo['zip']['entries_count']++; + $ThisFileInfo['zip']['compressed_size'] += $centraldirectoryentry['compressed_size']; + $ThisFileInfo['zip']['uncompressed_size'] += $centraldirectoryentry['uncompressed_size']; + + if ($centraldirectoryentry['uncompressed_size'] > 0) { + $ThisFileInfo['zip']['files'] = array_merge_clobber($ThisFileInfo['zip']['files'], CreateDeepArray($centraldirectoryentry['filename'], '/', $centraldirectoryentry['uncompressed_size'])); + } + } + + if ($ThisFileInfo['zip']['entries_count'] == 0) { + $ThisFileInfo['error'] .= "\n".'No Central Directory entries found (truncated file?)'; + return false; + } + + if (isset($ThisFileInfo['zip']['end_central_directory']['comment'])) { + $ThisFileInfo['zip']['comments']['comment'] = $ThisFileInfo['zip']['end_central_directory']['comment']; + + // ZIP tags have highest priority + if (!empty($ThisFileInfo['zip']['comments'])) { + CopyFormatCommentsToRootComments($ThisFileInfo['zip']['comments'], $ThisFileInfo, true, true, true); + } + // add tag to array of tags + $ThisFileInfo['tags'][] = 'zip'; + } + + if (isset($ThisFileInfo['zip']['central_directory'][0]['compression_method'])) { + $ThisFileInfo['zip']['compression_method'] = $ThisFileInfo['zip']['central_directory'][0]['compression_method']; + } + if (isset($ThisFileInfo['zip']['central_directory'][0]['flags']['compression_speed'])) { + $ThisFileInfo['zip']['compression_speed'] = $ThisFileInfo['zip']['central_directory'][0]['flags']['compression_speed']; + } + if (isset($ThisFileInfo['zip']['compression_method']) && ($ThisFileInfo['zip']['compression_method'] == 'store') && !isset($ThisFileInfo['zip']['compression_speed'])) { + $ThisFileInfo['zip']['compression_speed'] = 'store'; + } + + return true; + + } + + } + + if (getZIPentriesFilepointer($fd, $ThisFileInfo)) { + + // central directory couldn't be found and/or parsed + // scan through actual file data entries, recover as much as possible from probable trucated file + if ($ThisFileInfo['zip']['compressed_size'] > ($ThisFileInfo['filesize'] - 46 - 22)) { + $ThisFileInfo['error'] .= "\n".'Warning: Truncated file! - Total compressed file sizes ('.$ThisFileInfo['zip']['compressed_size'].' bytes) is greater than filesize minus Central Directory and End Of Central Directory structures ('.($ThisFileInfo['filesize'] - 46 - 22).' bytes)'; + } + $ThisFileInfo['error'] .= "\n".'Cannot find End Of Central Directory - returned list of files in [zip][entries] array may not be complete'; + return true; + + } else { + + unset($ThisFileInfo['zip']); + $ThisFileInfo['fileformat'] = ''; + $ThisFileInfo['error'] .= "\n".'Cannot find End Of Central Directory (truncated file?)'; + return false; + + } +} + + +function getZIPHeaderFilepointerTopDown(&$fd, &$ThisFileInfo) { + $ThisFileInfo['fileformat'] = 'zip'; + + $ThisFileInfo['zip']['compressed_size'] = 0; + $ThisFileInfo['zip']['uncompressed_size'] = 0; + $ThisFileInfo['zip']['entries_count'] = 0; + + rewind($fd); + while ($fileentry = ZIPparseLocalFileHeader($fd)) { + $ThisFileInfo['zip']['entries'][] = $fileentry; + $ThisFileInfo['zip']['entries_count']++; + } + if ($ThisFileInfo['zip']['entries_count'] == 0) { + $ThisFileInfo['error'] .= "\n".'No Local File Header entries found'; + return false; + } + + $ThisFileInfo['zip']['entries_count'] = 0; + while ($centraldirectoryentry = ZIPparseCentralDirectory($fd)) { + $ThisFileInfo['zip']['central_directory'][] = $centraldirectoryentry; + $ThisFileInfo['zip']['entries_count']++; + $ThisFileInfo['zip']['compressed_size'] += $centraldirectoryentry['compressed_size']; + $ThisFileInfo['zip']['uncompressed_size'] += $centraldirectoryentry['uncompressed_size']; + } + if ($ThisFileInfo['zip']['entries_count'] == 0) { + $ThisFileInfo['error'] .= "\n".'No Central Directory entries found (truncated file?)'; + return false; + } + + if ($EOCD = ZIPparseEndOfCentralDirectory($fd)) { + $ThisFileInfo['zip']['end_central_directory'] = $EOCD; + } else { + $ThisFileInfo['error'] .= "\n".'No End Of Central Directory entry found (truncated file?)'; + return false; + } + + if (isset($ThisFileInfo['zip']['end_central_directory']['comment'])) { + $ThisFileInfo['zip']['comments']['comment'] = $ThisFileInfo['zip']['end_central_directory']['comment']; + + // ZIP tags have highest priority + if (!empty($ThisFileInfo['zip']['comments'])) { + CopyFormatCommentsToRootComments($ThisFileInfo['zip']['comments'], $ThisFileInfo, true, true, true); + } + // add tag to array of tags + $ThisFileInfo['tags'][] = 'zip'; + } + + return true; +} + + +function getZIPentriesFilepointer(&$fd, &$ThisFileInfo) { + $ThisFileInfo['zip']['compressed_size'] = 0; + $ThisFileInfo['zip']['uncompressed_size'] = 0; + $ThisFileInfo['zip']['entries_count'] = 0; + + rewind($fd); + while ($fileentry = ZIPparseLocalFileHeader($fd)) { + $ThisFileInfo['zip']['entries'][] = $fileentry; + $ThisFileInfo['zip']['entries_count']++; + $ThisFileInfo['zip']['compressed_size'] += $fileentry['compressed_size']; + $ThisFileInfo['zip']['uncompressed_size'] += $fileentry['uncompressed_size']; + } + if ($ThisFileInfo['zip']['entries_count'] == 0) { + $ThisFileInfo['error'] .= "\n".'No Local File Header entries found'; + return false; + } + + return true; +} + + +function ZIPparseLocalFileHeader(&$fd) { + $LocalFileHeader['offset'] = ftell($fd); + + $ZIPlocalFileHeader = fread($fd, 30); + + $LocalFileHeader['raw']['signature'] = LittleEndian2Int(substr($ZIPlocalFileHeader, 0, 4)); + if ($LocalFileHeader['raw']['signature'] != 0x04034B50) { + // invalid Local File Header Signature + fseek($fd, $LocalFileHeader['offset'], SEEK_SET); // seek back to where filepointer originally was so it can be handled properly + return false; + } + $LocalFileHeader['raw']['extract_version'] = LittleEndian2Int(substr($ZIPlocalFileHeader, 4, 2)); + $LocalFileHeader['raw']['general_flags'] = LittleEndian2Int(substr($ZIPlocalFileHeader, 6, 2)); + $LocalFileHeader['raw']['compression_method'] = LittleEndian2Int(substr($ZIPlocalFileHeader, 8, 2)); + $LocalFileHeader['raw']['last_mod_file_time'] = LittleEndian2Int(substr($ZIPlocalFileHeader, 10, 2)); + $LocalFileHeader['raw']['last_mod_file_date'] = LittleEndian2Int(substr($ZIPlocalFileHeader, 12, 2)); + $LocalFileHeader['raw']['crc_32'] = LittleEndian2Int(substr($ZIPlocalFileHeader, 14, 4)); + $LocalFileHeader['raw']['compressed_size'] = LittleEndian2Int(substr($ZIPlocalFileHeader, 18, 4)); + $LocalFileHeader['raw']['uncompressed_size'] = LittleEndian2Int(substr($ZIPlocalFileHeader, 22, 4)); + $LocalFileHeader['raw']['filename_length'] = LittleEndian2Int(substr($ZIPlocalFileHeader, 26, 2)); + $LocalFileHeader['raw']['extra_field_length'] = LittleEndian2Int(substr($ZIPlocalFileHeader, 28, 2)); + + $LocalFileHeader['extract_version'] = sprintf('%1.1f', $LocalFileHeader['raw']['extract_version'] / 10); + $LocalFileHeader['host_os'] = ZIPversionOSLookup(($LocalFileHeader['raw']['extract_version'] & 0xFF00) >> 8); + $LocalFileHeader['compression_method'] = ZIPcompressionMethodLookup($LocalFileHeader['raw']['compression_method']); + $LocalFileHeader['compressed_size'] = $LocalFileHeader['raw']['compressed_size']; + $LocalFileHeader['uncompressed_size'] = $LocalFileHeader['raw']['uncompressed_size']; + $LocalFileHeader['flags'] = ZIPparseGeneralPurposeFlags($LocalFileHeader['raw']['general_flags'], $LocalFileHeader['raw']['compression_method']); + $LocalFileHeader['last_modified_timestamp'] = DOStime2UNIXtime($LocalFileHeader['raw']['last_mod_file_date'], $LocalFileHeader['raw']['last_mod_file_time']); + + $FilenameExtrafieldLength = $LocalFileHeader['raw']['filename_length'] + $LocalFileHeader['raw']['extra_field_length']; + if ($FilenameExtrafieldLength > 0) { + $ZIPlocalFileHeader .= fread($fd, $FilenameExtrafieldLength); + + if ($LocalFileHeader['raw']['filename_length'] > 0) { + $LocalFileHeader['filename'] = substr($ZIPlocalFileHeader, 30, $LocalFileHeader['raw']['filename_length']); + } + if ($LocalFileHeader['raw']['extra_field_length'] > 0) { + $LocalFileHeader['raw']['extra_field_data'] = substr($ZIPlocalFileHeader, 30 + $LocalFileHeader['raw']['filename_length'], $LocalFileHeader['raw']['extra_field_length']); + } + } + + //$LocalFileHeader['compressed_data'] = fread($fd, $LocalFileHeader['raw']['compressed_size']); + fseek($fd, $LocalFileHeader['raw']['compressed_size'], SEEK_CUR); + + if ($LocalFileHeader['flags']['data_descriptor_used']) { + $DataDescriptor = fread($fd, 12); + $LocalFileHeader['data_descriptor']['crc_32'] = LittleEndian2Int(substr($DataDescriptor, 0, 4)); + $LocalFileHeader['data_descriptor']['compressed_size'] = LittleEndian2Int(substr($DataDescriptor, 4, 4)); + $LocalFileHeader['data_descriptor']['uncompressed_size'] = LittleEndian2Int(substr($DataDescriptor, 8, 4)); + } + + return $LocalFileHeader; +} + + +function ZIPparseCentralDirectory(&$fd) { + $CentralDirectory['offset'] = ftell($fd); + + $ZIPcentralDirectory = fread($fd, 46); + + $CentralDirectory['raw']['signature'] = LittleEndian2Int(substr($ZIPcentralDirectory, 0, 4)); + if ($CentralDirectory['raw']['signature'] != 0x02014B50) { + // invalid Central Directory Signature + fseek($fd, $CentralDirectory['offset'], SEEK_SET); // seek back to where filepointer originally was so it can be handled properly + return false; + } + $CentralDirectory['raw']['create_version'] = LittleEndian2Int(substr($ZIPcentralDirectory, 4, 2)); + $CentralDirectory['raw']['extract_version'] = LittleEndian2Int(substr($ZIPcentralDirectory, 6, 2)); + $CentralDirectory['raw']['general_flags'] = LittleEndian2Int(substr($ZIPcentralDirectory, 8, 2)); + $CentralDirectory['raw']['compression_method'] = LittleEndian2Int(substr($ZIPcentralDirectory, 10, 2)); + $CentralDirectory['raw']['last_mod_file_time'] = LittleEndian2Int(substr($ZIPcentralDirectory, 12, 2)); + $CentralDirectory['raw']['last_mod_file_date'] = LittleEndian2Int(substr($ZIPcentralDirectory, 14, 2)); + $CentralDirectory['raw']['crc_32'] = LittleEndian2Int(substr($ZIPcentralDirectory, 16, 4)); + $CentralDirectory['raw']['compressed_size'] = LittleEndian2Int(substr($ZIPcentralDirectory, 20, 4)); + $CentralDirectory['raw']['uncompressed_size'] = LittleEndian2Int(substr($ZIPcentralDirectory, 24, 4)); + $CentralDirectory['raw']['filename_length'] = LittleEndian2Int(substr($ZIPcentralDirectory, 28, 2)); + $CentralDirectory['raw']['extra_field_length'] = LittleEndian2Int(substr($ZIPcentralDirectory, 30, 2)); + $CentralDirectory['raw']['file_comment_length'] = LittleEndian2Int(substr($ZIPcentralDirectory, 32, 2)); + $CentralDirectory['raw']['disk_number_start'] = LittleEndian2Int(substr($ZIPcentralDirectory, 34, 2)); + $CentralDirectory['raw']['internal_file_attrib'] = LittleEndian2Int(substr($ZIPcentralDirectory, 36, 2)); + $CentralDirectory['raw']['external_file_attrib'] = LittleEndian2Int(substr($ZIPcentralDirectory, 38, 4)); + $CentralDirectory['raw']['local_header_offset'] = LittleEndian2Int(substr($ZIPcentralDirectory, 42, 4)); + + $CentralDirectory['entry_offset'] = $CentralDirectory['raw']['local_header_offset']; + $CentralDirectory['create_version'] = sprintf('%1.1f', $CentralDirectory['raw']['create_version'] / 10); + $CentralDirectory['extract_version'] = sprintf('%1.1f', $CentralDirectory['raw']['extract_version'] / 10); + $CentralDirectory['host_os'] = ZIPversionOSLookup(($CentralDirectory['raw']['extract_version'] & 0xFF00) >> 8); + $CentralDirectory['compression_method'] = ZIPcompressionMethodLookup($CentralDirectory['raw']['compression_method']); + $CentralDirectory['compressed_size'] = $CentralDirectory['raw']['compressed_size']; + $CentralDirectory['uncompressed_size'] = $CentralDirectory['raw']['uncompressed_size']; + $CentralDirectory['flags'] = ZIPparseGeneralPurposeFlags($CentralDirectory['raw']['general_flags'], $CentralDirectory['raw']['compression_method']); + $CentralDirectory['last_modified_timestamp'] = DOStime2UNIXtime($CentralDirectory['raw']['last_mod_file_date'], $CentralDirectory['raw']['last_mod_file_time']); + + $FilenameExtrafieldCommentLength = $CentralDirectory['raw']['filename_length'] + $CentralDirectory['raw']['extra_field_length'] + $CentralDirectory['raw']['file_comment_length']; + if ($FilenameExtrafieldCommentLength > 0) { + $FilenameExtrafieldComment = fread($fd, $FilenameExtrafieldCommentLength); + + if ($CentralDirectory['raw']['filename_length'] > 0) { + $CentralDirectory['filename'] = substr($FilenameExtrafieldComment, 0, $CentralDirectory['raw']['filename_length']); + } + if ($CentralDirectory['raw']['extra_field_length'] > 0) { + $CentralDirectory['raw']['extra_field_data'] = substr($FilenameExtrafieldComment, $CentralDirectory['raw']['filename_length'], $CentralDirectory['raw']['extra_field_length']); + } + if ($CentralDirectory['raw']['file_comment_length'] > 0) { + $CentralDirectory['file_comment'] = substr($FilenameExtrafieldComment, $CentralDirectory['raw']['filename_length'] + $CentralDirectory['raw']['extra_field_length'], $CentralDirectory['raw']['file_comment_length']); + } + } + + return $CentralDirectory; +} + +function ZIPparseEndOfCentralDirectory(&$fd) { + $EndOfCentralDirectory['offset'] = ftell($fd); + + $ZIPendOfCentralDirectory = fread($fd, 22); + + $EndOfCentralDirectory['signature'] = LittleEndian2Int(substr($ZIPendOfCentralDirectory, 0, 4)); + if ($EndOfCentralDirectory['signature'] != 0x06054B50) { + // invalid End Of Central Directory Signature + fseek($fd, $EndOfCentralDirectory['offset'], SEEK_SET); // seek back to where filepointer originally was so it can be handled properly + return false; + } + $EndOfCentralDirectory['disk_number_current'] = LittleEndian2Int(substr($ZIPendOfCentralDirectory, 4, 2)); + $EndOfCentralDirectory['disk_number_start_directory'] = LittleEndian2Int(substr($ZIPendOfCentralDirectory, 6, 2)); + $EndOfCentralDirectory['directory_entries_this_disk'] = LittleEndian2Int(substr($ZIPendOfCentralDirectory, 8, 2)); + $EndOfCentralDirectory['directory_entries_total'] = LittleEndian2Int(substr($ZIPendOfCentralDirectory, 10, 2)); + $EndOfCentralDirectory['directory_size'] = LittleEndian2Int(substr($ZIPendOfCentralDirectory, 12, 4)); + $EndOfCentralDirectory['directory_offset'] = LittleEndian2Int(substr($ZIPendOfCentralDirectory, 16, 4)); + $EndOfCentralDirectory['comment_length'] = LittleEndian2Int(substr($ZIPendOfCentralDirectory, 20, 2)); + + if ($EndOfCentralDirectory['comment_length'] > 0) { + $EndOfCentralDirectory['comment'] = fread($fd, $EndOfCentralDirectory['comment_length']); + } + + return $EndOfCentralDirectory; +} + + +function ZIPparseGeneralPurposeFlags($flagbytes, $compressionmethod) { + $ParsedFlags['encrypted'] = (bool) ($flagbytes & 0x0001); + + switch ($compressionmethod) { + case 6: + $ParsedFlags['dictionary_size'] = (($flagbytes & 0x0002) ? 8192 : 4096); + $ParsedFlags['shannon_fano_trees'] = (($flagbytes & 0x0004) ? 3 : 2); + break; + + case 8: + case 9: + switch (($flagbytes & 0x0006) >> 1) { + case 0: + $ParsedFlags['compression_speed'] = 'normal'; + break; + case 1: + $ParsedFlags['compression_speed'] = 'maximum'; + break; + case 2: + $ParsedFlags['compression_speed'] = 'fast'; + break; + case 3: + $ParsedFlags['compression_speed'] = 'superfast'; + break; + } + break; + } + $ParsedFlags['data_descriptor_used'] = (bool) ($flagbytes & 0x0008); + + return $ParsedFlags; +} + + +function ZIPversionOSLookup($index) { + static $ZIPversionOSLookup = array(); + if (empty($ZIPversionOSLookup)) { + $ZIPversionOSLookup[0] = 'MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)'; + $ZIPversionOSLookup[1] = 'Amiga'; + $ZIPversionOSLookup[2] = 'OpenVMS'; + $ZIPversionOSLookup[3] = 'Unix'; + $ZIPversionOSLookup[4] = 'VM/CMS'; + $ZIPversionOSLookup[5] = 'Atari ST'; + $ZIPversionOSLookup[6] = 'OS/2 H.P.F.S.'; + $ZIPversionOSLookup[7] = 'Macintosh'; + $ZIPversionOSLookup[8] = 'Z-System'; + $ZIPversionOSLookup[9] = 'CP/M'; + $ZIPversionOSLookup[10] = 'Windows NTFS'; + $ZIPversionOSLookup[11] = 'MVS'; + $ZIPversionOSLookup[12] = 'VSE'; + $ZIPversionOSLookup[13] = 'Acorn Risc'; + $ZIPversionOSLookup[14] = 'VFAT'; + $ZIPversionOSLookup[15] = 'Alternate MVS'; + $ZIPversionOSLookup[16] = 'BeOS'; + $ZIPversionOSLookup[17] = 'Tandem'; + } + + return (isset($ZIPversionOSLookup[$index]) ? $ZIPversionOSLookup[$index] : '[unknown]'); +} + +function ZIPcompressionMethodLookup($index) { + static $ZIPcompressionMethodLookup = array(); + if (empty($ZIPcompressionMethodLookup)) { + $ZIPcompressionMethodLookup[0] = 'store'; + $ZIPcompressionMethodLookup[1] = 'shrink'; + $ZIPcompressionMethodLookup[2] = 'reduce-1'; + $ZIPcompressionMethodLookup[3] = 'reduce-2'; + $ZIPcompressionMethodLookup[4] = 'reduce-3'; + $ZIPcompressionMethodLookup[5] = 'reduce-4'; + $ZIPcompressionMethodLookup[6] = 'implode'; + $ZIPcompressionMethodLookup[7] = 'tokenize'; + $ZIPcompressionMethodLookup[8] = 'deflate'; + $ZIPcompressionMethodLookup[9] = 'deflate64'; + $ZIPcompressionMethodLookup[10] = 'PKWARE Date Compression Library Imploding'; + } + + return (isset($ZIPcompressionMethodLookup[$index]) ? $ZIPcompressionMethodLookup[$index] : '[unknown]'); +} + +?> \ No newline at end of file