CC-1428 Packaged version: campcaster-import must be run as root. Checked to see if the storage directory was writable, if not the program prints an error message and then exits. Updated module getid3 to latest stable version and fixed some deprecations.

This commit is contained in:
naomiaro 2010-08-18 15:43:27 -07:00
parent ee4ddf27a8
commit b75eab5516
48 changed files with 11190 additions and 1076 deletions

135
src/modules/getid3/Makefile Normal file
View File

@ -0,0 +1,135 @@
#-------------------------------------------------------------------------------
# getID3 - read and writes tags in media files - see getid3.readme.txt
# getID3 by James Heinrich <getid3@users.sourceforge.net>
#
# This file is part of the Campcaster project.
# Copyright (c) 2010 Sourcefabric O.P.S.
#
# Campcaster 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.
#
# Campcaster 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 Campcaster; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ../Makefile. Generated from Makefile.in by configure.
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# General command definitions
#-------------------------------------------------------------------------------
SHELL = /bin/bash
MKDIR = mkdir -p
RM = rm -f
RMDIR = rm -rf
DOXYGEN = doxygen
CP = cp -f
#-------------------------------------------------------------------------------
# Misc
#-------------------------------------------------------------------------------
MODULE_NAME = getid3
TAR_C = tar -cj --exclude .svn --exclude '*~' -C ${BASE_DIR} -f
DIST_EXT = .tgz
DATE = `date +%y%m%d`
#-------------------------------------------------------------------------------
# Basic directory and file definitions
#-------------------------------------------------------------------------------
#BASE_DIR = .
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
VAR_DIR = ${BASE_DIR}/var
prefix = /home/naomiaro/dev-campcaster/campcaster/usr
USR_DIR = ${prefix}
USR_INCLUDE_DIR = ${USR_DIR}/include
USR_VAR_DIR = ${USR_DIR}/var
DOXYGEN_CONFIG = ${ETC_DIR}/doxygen.config
PHP_DIR = ${VAR_DIR}
#TEST_RUNNER = ${PHP_DIR}/tests/index.php
#-------------------------------------------------------------------------------
# Configuration parameters
#-------------------------------------------------------------------------------
#CPPFLAGS = @CPPFLAGS@
#CXXFLAGS = @CXXFLAGS@ -DPACKAGE_NAME=\"GetId3\" -DPACKAGE_TARNAME=\"getid3\" -DPACKAGE_VERSION=\"1.4.0\" -DPACKAGE_STRING=\"GetId3\ 0.0\" -DPACKAGE_BUGREPORT=\"bugs@campware.org\" -DPACKAGE_URL=\"\" -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 install
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
install:
${MKDIR} ${USR_VAR_DIR}/Campcaster/getid3/var
${CP} ${VAR_DIR}/*.php ${USR_VAR_DIR}/Campcaster/getid3/var
#-------------------------------------------------------------------------------
# Specific targets
#-------------------------------------------------------------------------------
${DOXYGEN_DIR}:
${MKDIR} ${DOXYGEN_DIR}
#${TEST_RUNNER}:
#-------------------------------------------------------------------------------
# Pattern rules
#-------------------------------------------------------------------------------
#${TMP_DIR}/%.o : ${SRC_DIR}/%.cxx
# ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c -o $@ $<

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
# This file was generated by Autom4te Tue Dec 22 07:01:21 UTC 2009.
# It contains the lists of macros which have been traced.
# It can be safely removed.
@request = (
bless( [
'0',
1,
[
'/usr/share/autoconf',
'/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/tmp'
],
[
'/usr/share/autoconf/autoconf/autoconf.m4f',
'/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac'
],
{
'_LT_AC_TAGCONFIG' => 1,
'AM_PROG_F77_C_O' => 1,
'AC_INIT' => 1,
'm4_pattern_forbid' => 1,
'_AM_COND_IF' => 1,
'AC_CANONICAL_TARGET' => 1,
'AC_SUBST' => 1,
'AC_CONFIG_LIBOBJ_DIR' => 1,
'AC_FC_SRCEXT' => 1,
'AC_CANONICAL_HOST' => 1,
'AC_PROG_LIBTOOL' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AC_CONFIG_SUBDIRS' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'LT_CONFIG_LTDL_DIR' => 1,
'AC_REQUIRE_AUX_FILE' => 1,
'AC_CONFIG_LINKS' => 1,
'm4_sinclude' => 1,
'LT_SUPPORTED_TAG' => 1,
'AM_MAINTAINER_MODE' => 1,
'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
'_m4_warn' => 1,
'AM_PROG_CXX_C_O' => 1,
'_AM_COND_ENDIF' => 1,
'AM_ENABLE_MULTILIB' => 1,
'AM_SILENT_RULES' => 1,
'AC_CONFIG_FILES' => 1,
'include' => 1,
'LT_INIT' => 1,
'AM_GNU_GETTEXT' => 1,
'AC_LIBSOURCE' => 1,
'AM_PROG_FC_C_O' => 1,
'AC_CANONICAL_BUILD' => 1,
'AC_FC_FREEFORM' => 1,
'AH_OUTPUT' => 1,
'_AM_SUBST_NOTMAKE' => 1,
'AC_CONFIG_AUX_DIR' => 1,
'sinclude' => 1,
'm4_pattern_allow' => 1,
'AM_PROG_CC_C_O' => 1,
'AC_CANONICAL_SYSTEM' => 1,
'AM_CONDITIONAL' => 1,
'AC_CONFIG_HEADERS' => 1,
'AC_DEFINE_TRACE_LITERAL' => 1,
'm4_include' => 1,
'_AM_COND_ELSE' => 1,
'AC_SUBST_TRACE' => 1
}
], 'Autom4te::Request' )
);

View File

@ -0,0 +1,164 @@
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_INIT([GetId3], [0.0], [bugs@campware.org])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_forbid([^_?A[CHUM]_])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_forbid([_AC_])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^AS_FLAGS$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_forbid([^_?m4_])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_forbid([^dnl$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_forbid([^_?AS_])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([SHELL])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([SHELL])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^SHELL$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([PATH_SEPARATOR])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([PATH_SEPARATOR])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PATH_SEPARATOR$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([PACKAGE_NAME])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_NAME$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([PACKAGE_TARNAME])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_TARNAME$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([PACKAGE_VERSION])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_VERSION$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([PACKAGE_STRING])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_STRING$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([PACKAGE_BUGREPORT])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([PACKAGE_URL], [m4_ifdef([AC_PACKAGE_URL], ['AC_PACKAGE_URL'])])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([PACKAGE_URL])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_URL$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([exec_prefix], [NONE])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([exec_prefix])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^exec_prefix$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([prefix], [NONE])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([prefix])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^prefix$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([program_transform_name], [s,x,x,])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([program_transform_name])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^program_transform_name$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([bindir], ['${exec_prefix}/bin'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([bindir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^bindir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([sbindir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^sbindir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([libexecdir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^libexecdir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([datarootdir], ['${prefix}/share'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([datarootdir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^datarootdir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([datadir], ['${datarootdir}'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([datadir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^datadir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([sysconfdir], ['${prefix}/etc'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([sysconfdir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^sysconfdir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([sharedstatedir], ['${prefix}/com'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([sharedstatedir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^sharedstatedir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([localstatedir], ['${prefix}/var'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([localstatedir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^localstatedir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([includedir], ['${prefix}/include'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([includedir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^includedir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([oldincludedir], ['/usr/include'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([oldincludedir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^oldincludedir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME],
['${datarootdir}/doc/${PACKAGE_TARNAME}'],
['${datarootdir}/doc/${PACKAGE}'])])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([docdir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^docdir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([infodir], ['${datarootdir}/info'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([infodir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^infodir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([htmldir], ['${docdir}'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([htmldir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^htmldir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([dvidir], ['${docdir}'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([dvidir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^dvidir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([pdfdir], ['${docdir}'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([pdfdir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^pdfdir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([psdir], ['${docdir}'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([psdir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^psdir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([libdir], ['${exec_prefix}/lib'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([libdir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^libdir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([localedir], ['${datarootdir}/locale'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([localedir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^localedir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([mandir], ['${datarootdir}/man'])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([mandir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^mandir$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_NAME$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */
@%:@undef PACKAGE_NAME])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_TARNAME$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */
@%:@undef PACKAGE_TARNAME])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_VERSION$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */
@%:@undef PACKAGE_VERSION])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_STRING$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */
@%:@undef PACKAGE_STRING])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */
@%:@undef PACKAGE_BUGREPORT])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_URL])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^PACKAGE_URL$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AH_OUTPUT([PACKAGE_URL], [/* Define to the home page for this package. */
@%:@undef PACKAGE_URL])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([DEFS])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([DEFS])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^DEFS$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([ECHO_C])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([ECHO_C])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^ECHO_C$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([ECHO_N])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([ECHO_N])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^ECHO_N$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([ECHO_T])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([ECHO_T])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^ECHO_T$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([LIBS])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([LIBS])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^LIBS$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([build_alias])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([build_alias])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^build_alias$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([host_alias])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([host_alias])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^host_alias$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST([target_alias])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- AC_SUBST_TRACE([target_alias])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:30: -1- m4_pattern_allow([^target_alias$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:38: -1- AC_CONFIG_FILES([../Makefile:../etc/Makefile.in])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST_TRACE([LIB@&t@OBJS])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- m4_pattern_allow([^LIB@&t@OBJS$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST_TRACE([LTLIBOBJS])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- m4_pattern_allow([^LTLIBOBJS$])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST_TRACE([top_builddir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST_TRACE([top_build_prefix])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST_TRACE([srcdir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST_TRACE([abs_srcdir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST_TRACE([top_srcdir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST_TRACE([abs_top_srcdir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST_TRACE([builddir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST_TRACE([abs_builddir])
m4trace:/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/etc/configure.ac:40: -1- AC_SUBST_TRACE([abs_top_builddir])

View File

@ -0,0 +1,132 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by GetId3 configure 0.0, which was
generated by GNU Autoconf 2.65. Invocation command line was
$ /home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/tmp/configure --prefix=/home/naomiaro/dev-campcaster/campcaster/usr PACKAGE_VERSION=1.4.0
## --------- ##
## Platform. ##
## --------- ##
hostname = naomiaro-ubuntu
uname -m = i686
uname -r = 2.6.32-21-generic
uname -s = Linux
uname -v = #32-Ubuntu SMP Fri Apr 16 08:10:02 UTC 2010
/usr/bin/uname -p = unknown
/bin/uname -X = unknown
/bin/arch = unknown
/usr/bin/arch -k = unknown
/usr/convex/getsysinfo = unknown
/usr/bin/hostinfo = unknown
/bin/machine = unknown
/usr/bin/oslevel = unknown
/bin/universe = unknown
PATH: /home/naomiaro/bin
PATH: /home/naomiaro/bin
PATH: /usr/local/sbin
PATH: /usr/local/bin
PATH: /usr/sbin
PATH: /usr/bin
PATH: /sbin
PATH: /bin
PATH: /usr/games
## ----------- ##
## Core tests. ##
## ----------- ##
configure:1793: creating ./config.status
## ---------------------- ##
## Running config.status. ##
## ---------------------- ##
This file was extended by GetId3 config.status 0.0, which was
generated by GNU Autoconf 2.65. Invocation command line was
CONFIG_FILES =
CONFIG_HEADERS =
CONFIG_LINKS =
CONFIG_COMMANDS =
$ ./config.status
on naomiaro-ubuntu
config.status:715: creating ../Makefile
## ---------------- ##
## Cache variables. ##
## ---------------- ##
ac_cv_env_build_alias_set=
ac_cv_env_build_alias_value=
ac_cv_env_host_alias_set=
ac_cv_env_host_alias_value=
ac_cv_env_target_alias_set=
ac_cv_env_target_alias_value=
## ----------------- ##
## Output variables. ##
## ----------------- ##
DEFS='-DPACKAGE_NAME=\"GetId3\" -DPACKAGE_TARNAME=\"getid3\" -DPACKAGE_VERSION=\"1.4.0\" -DPACKAGE_STRING=\"GetId3\ 0.0\" -DPACKAGE_BUGREPORT=\"bugs@campware.org\" -DPACKAGE_URL=\"\"'
ECHO_C=''
ECHO_N='-n'
ECHO_T=''
LIBOBJS=''
LIBS=''
LTLIBOBJS=''
PACKAGE_BUGREPORT='bugs@campware.org'
PACKAGE_NAME='GetId3'
PACKAGE_STRING='GetId3 0.0'
PACKAGE_TARNAME='getid3'
PACKAGE_URL=''
PACKAGE_VERSION='1.4.0'
PATH_SEPARATOR=':'
SHELL='/bin/bash'
bindir='${exec_prefix}/bin'
build_alias=''
datadir='${datarootdir}'
datarootdir='${prefix}/share'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
dvidir='${docdir}'
exec_prefix='${prefix}'
host_alias=''
htmldir='${docdir}'
includedir='${prefix}/include'
infodir='${datarootdir}/info'
libdir='${exec_prefix}/lib'
libexecdir='${exec_prefix}/libexec'
localedir='${datarootdir}/locale'
localstatedir='${prefix}/var'
mandir='${datarootdir}/man'
oldincludedir='/usr/include'
pdfdir='${docdir}'
prefix='/home/naomiaro/dev-campcaster/campcaster/usr'
program_transform_name='s,x,x,'
psdir='${docdir}'
sbindir='${exec_prefix}/sbin'
sharedstatedir='${prefix}/com'
sysconfdir='${prefix}/etc'
target_alias=''
## ----------- ##
## confdefs.h. ##
## ----------- ##
/* confdefs.h */
#define PACKAGE_NAME "GetId3"
#define PACKAGE_TARNAME "getid3"
#define PACKAGE_VERSION "1.4.0"
#define PACKAGE_STRING "GetId3 0.0"
#define PACKAGE_BUGREPORT "bugs@campware.org"
#define PACKAGE_URL ""
configure: exit 0

View File

@ -0,0 +1,873 @@
#! /bin/bash
# Generated by configure.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.
debug=false
ac_cs_recheck=false
ac_cs_silent=false
SHELL=${CONFIG_SHELL-/bin/bash}
export SHELL
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##
# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
# Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
else
case `(set -o) 2>/dev/null` in #(
*posix*) :
set -o posix ;; #(
*) :
;;
esac
fi
as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
&& (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
as_echo='print -r --'
as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
as_echo='printf %s\n'
as_echo_n='printf %s'
else
if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
as_echo_n='/usr/ucb/echo -n'
else
as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
as_echo_n_body='eval
arg=$1;
case $arg in #(
*"$as_nl"*)
expr "X$arg" : "X\\(.*\\)$as_nl";
arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
esac;
expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
'
export as_echo_n_body
as_echo_n='sh -c $as_echo_n_body as_echo'
fi
export as_echo_body
as_echo='sh -c $as_echo_body as_echo'
fi
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
(PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
PATH_SEPARATOR=';'
}
fi
# IFS
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" "" $as_nl"
# Find who we are. Look in the path if we contain no directory separator.
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
IFS=$as_save_IFS
;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
$as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
exit 1
fi
# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there. '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
&& ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '
# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
# as_fn_error ERROR [LINENO LOG_FD]
# ---------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with status $?, using 1 if that was 0.
as_fn_error ()
{
as_status=$?; test $as_status -eq 0 && as_status=1
if test "$3"; then
as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
$as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
fi
$as_echo "$as_me: error: $1" >&2
as_fn_exit $as_status
} # as_fn_error
# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
return $1
} # as_fn_set_status
# as_fn_exit STATUS
# -----------------
# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
as_fn_exit ()
{
set +e
as_fn_set_status $1
exit $1
} # as_fn_exit
# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
{ eval $1=; unset $1;}
}
as_unset=as_fn_unset
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
eval 'as_fn_append ()
{
eval $1+=\$2
}'
else
as_fn_append ()
{
eval $1=\$$1\$2
}
fi # as_fn_append
# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
eval 'as_fn_arith ()
{
as_val=$(( $* ))
}'
else
as_fn_arith ()
{
as_val=`expr "$@" || test $? -eq 1`
}
fi # as_fn_arith
if expr a : '\(a\)' >/dev/null 2>&1 &&
test "X`expr 00001 : '.*\(...\)'`" = X001; then
as_expr=expr
else
as_expr=false
fi
if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
as_dirname=dirname
else
as_dirname=false
fi
as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{
s//\1/
q
}
/^X\/\(\/\/\)$/{
s//\1/
q
}
/^X\/\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
case `echo 'xy\c'` in
*c*) ECHO_T=' ';; # ECHO_T is single tab character.
xy) ECHO_C='\c';;
*) echo `echo ksh88 bug on AIX 6.1` > /dev/null
ECHO_T=' ';;
esac;;
*)
ECHO_N='-n';;
esac
rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
rm -f conf$$.dir/conf$$.file
else
rm -f conf$$.dir
mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
if ln -s conf$$.file conf$$ 2>/dev/null; then
as_ln_s='ln -s'
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
# In both cases, we have to default to `cp -p'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
as_ln_s='cp -p'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -p'
fi
else
as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
# as_fn_mkdir_p
# -------------
# Create "$as_dir" as a directory, including parents if necessary.
as_fn_mkdir_p ()
{
case $as_dir in #(
-*) as_dir=./$as_dir;;
esac
test -d "$as_dir" || eval $as_mkdir_p || {
as_dirs=
while :; do
case $as_dir in #(
*\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
*) as_qdir=$as_dir;;
esac
as_dirs="'$as_qdir' $as_dirs"
as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
} || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
} # as_fn_mkdir_p
if mkdir -p . 2>/dev/null; then
as_mkdir_p='mkdir -p "$as_dir"'
else
test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
if test -x / >/dev/null 2>&1; then
as_test_x='test -x'
else
if ls -dL / >/dev/null 2>&1; then
as_ls_L_option=L
else
as_ls_L_option=
fi
as_test_x='
eval sh -c '\''
if test -d "$1"; then
test -d "$1/.";
else
case $1 in #(
-*)set "./$1";;
esac;
case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
???[sx]*):;;*)false;;esac;fi
'\'' sh
'
fi
as_executable_p=$as_test_x
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
exec 6>&1
## ----------------------------------- ##
## Main body of $CONFIG_STATUS script. ##
## ----------------------------------- ##
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by GetId3 $as_me 0.0, which was
generated by GNU Autoconf 2.65. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
CONFIG_LINKS = $CONFIG_LINKS
CONFIG_COMMANDS = $CONFIG_COMMANDS
$ $0 $@
on `(hostname || uname -n) 2>/dev/null | sed 1q`
"
# Files that config.status was made for.
config_files=" ../Makefile:../etc/Makefile.in"
ac_cs_usage="\
\`$as_me' instantiates files and other configuration actions
from templates according to the current configuration. Unless the files
and actions are specified as TAGs, all are instantiated by default.
Usage: $0 [OPTION]... [TAG]...
-h, --help print this help, then exit
-V, --version print version number and configuration settings, then exit
--config print configuration, then exit
-q, --quiet, --silent
do not print progress messages
-d, --debug don't remove temporary files
--recheck update $as_me by reconfiguring in the same conditions
--file=FILE[:TEMPLATE]
instantiate the configuration file FILE
Configuration files:
$config_files
Report bugs to <bugs@campware.org>."
ac_cs_config="'--prefix=/home/naomiaro/dev-campcaster/campcaster/usr' 'PACKAGE_VERSION=1.4.0'"
ac_cs_version="\
GetId3 config.status 0.0
configured by /home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/tmp/configure, generated by GNU Autoconf 2.65,
with options \"$ac_cs_config\"
Copyright (C) 2009 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
ac_pwd='/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/tmp'
srcdir='.'
test -n "$AWK" || AWK=awk
# The default lists apply if the user does not specify any file.
ac_need_defaults=:
while test $# != 0
do
case $1 in
--*=*)
ac_option=`expr "X$1" : 'X\([^=]*\)='`
ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
ac_shift=:
;;
*)
ac_option=$1
ac_optarg=$2
ac_shift=shift
;;
esac
case $ac_option in
# Handling of the options.
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
ac_cs_recheck=: ;;
--version | --versio | --versi | --vers | --ver | --ve | --v | -V )
$as_echo "$ac_cs_version"; exit ;;
--config | --confi | --conf | --con | --co | --c )
$as_echo "$ac_cs_config"; exit ;;
--debug | --debu | --deb | --de | --d | -d )
debug=: ;;
--file | --fil | --fi | --f )
$ac_shift
case $ac_optarg in
*\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
esac
as_fn_append CONFIG_FILES " '$ac_optarg'"
ac_need_defaults=false;;
--he | --h | --help | --hel | -h )
$as_echo "$ac_cs_usage"; exit ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil | --si | --s)
ac_cs_silent=: ;;
# This is an error.
-*) as_fn_error "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;
*) as_fn_append ac_config_targets " $1"
ac_need_defaults=false ;;
esac
shift
done
ac_configure_extra_args=
if $ac_cs_silent; then
exec 6>/dev/null
ac_configure_extra_args="$ac_configure_extra_args --silent"
fi
if $ac_cs_recheck; then
set X '/bin/bash' '/home/naomiaro/dev-campcaster/campcaster/src/modules/getid3/tmp/configure' '--prefix=/home/naomiaro/dev-campcaster/campcaster/usr' 'PACKAGE_VERSION=1.4.0' $ac_configure_extra_args --no-create --no-recursion
shift
$as_echo "running CONFIG_SHELL=/bin/bash $*" >&6
CONFIG_SHELL='/bin/bash'
export CONFIG_SHELL
exec "$@"
fi
exec 5>>config.log
{
echo
sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
$as_echo "$ac_log"
} >&5
# Handling of arguments.
for ac_config_target in $ac_config_targets
do
case $ac_config_target in
"../Makefile") CONFIG_FILES="$CONFIG_FILES ../Makefile:../etc/Makefile.in" ;;
*) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used. Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
fi
# Have a temporary directory for convenience. Make it in the build tree
# simply because there is no reason against having it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Note that there is a small window in which the directory will not be cleaned:
# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
tmp=
trap 'exit_status=$?
{ test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
' 0
trap 'as_fn_exit 1' 1 2 13 15
}
# Create a (secure) tmp directory for tmp files.
{
tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
test -n "$tmp" && test -d "$tmp"
} ||
{
tmp=./conf$$-$RANDOM
(umask 077 && mkdir "$tmp")
} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
# This happens for instance with `./config.status config.h'.
if test -n "$CONFIG_FILES"; then
ac_cr=`echo X | tr X '\015'`
# On cygwin, bash can eat \r inside `` if the user requested igncr.
# But we know of no other shell where ac_cr would be empty at this
# point, so we can use a bashism as a fallback.
if test "x$ac_cr" = x; then
eval ac_cr=\$\'\\r\'
fi
ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
ac_cs_awk_cr='\r'
else
ac_cs_awk_cr=$ac_cr
fi
echo 'BEGIN {' >"$tmp/subs1.awk" &&
cat >>"$tmp/subs1.awk" <<\_ACAWK &&
S["LTLIBOBJS"]=""
S["LIBOBJS"]=""
S["target_alias"]=""
S["host_alias"]=""
S["build_alias"]=""
S["LIBS"]=""
S["ECHO_T"]=""
S["ECHO_N"]="-n"
S["ECHO_C"]=""
S["DEFS"]="-DPACKAGE_NAME=\\\"GetId3\\\" -DPACKAGE_TARNAME=\\\"getid3\\\" -DPACKAGE_VERSION=\\\"1.4.0\\\" -DPACKAGE_STRING=\\\"GetId3\\ 0.0\\\" -DPACKAGE_BUGREPORT=\\\"bugs@campw"\
"are.org\\\" -DPACKAGE_URL=\\\"\\\""
S["mandir"]="${datarootdir}/man"
S["localedir"]="${datarootdir}/locale"
S["libdir"]="${exec_prefix}/lib"
S["psdir"]="${docdir}"
S["pdfdir"]="${docdir}"
S["dvidir"]="${docdir}"
S["htmldir"]="${docdir}"
S["infodir"]="${datarootdir}/info"
S["docdir"]="${datarootdir}/doc/${PACKAGE_TARNAME}"
S["oldincludedir"]="/usr/include"
S["includedir"]="${prefix}/include"
S["localstatedir"]="${prefix}/var"
S["sharedstatedir"]="${prefix}/com"
S["sysconfdir"]="${prefix}/etc"
S["datadir"]="${datarootdir}"
S["datarootdir"]="${prefix}/share"
S["libexecdir"]="${exec_prefix}/libexec"
S["sbindir"]="${exec_prefix}/sbin"
S["bindir"]="${exec_prefix}/bin"
S["program_transform_name"]="s,x,x,"
S["prefix"]="/home/naomiaro/dev-campcaster/campcaster/usr"
S["exec_prefix"]="${prefix}"
S["PACKAGE_URL"]=""
S["PACKAGE_BUGREPORT"]="bugs@campware.org"
S["PACKAGE_STRING"]="GetId3 0.0"
S["PACKAGE_VERSION"]="1.4.0"
S["PACKAGE_TARNAME"]="getid3"
S["PACKAGE_NAME"]="GetId3"
S["PATH_SEPARATOR"]=":"
S["SHELL"]="/bin/bash"
_ACAWK
cat >>"$tmp/subs1.awk" <<_ACAWK &&
for (key in S) S_is_set[key] = 1
FS = ""
}
{
line = $ 0
nfields = split(line, field, "@")
substed = 0
len = length(field[1])
for (i = 2; i < nfields; i++) {
key = field[i]
keylen = length(key)
if (S_is_set[key]) {
value = S[key]
line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
len += length(value) + length(field[++i])
substed = 1
} else
len += 1 + keylen
}
print line
}
_ACAWK
if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
else
cat
fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
|| as_fn_error "could not setup config files machinery" "$LINENO" 5
fi # test -n "$CONFIG_FILES"
eval set X " :F $CONFIG_FILES "
shift
for ac_tag
do
case $ac_tag in
:[FHLC]) ac_mode=$ac_tag; continue;;
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
:L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
ac_save_IFS=$IFS
IFS=:
set x $ac_tag
IFS=$ac_save_IFS
shift
ac_file=$1
shift
case $ac_mode in
:L) ac_source=$1;;
:[FH])
ac_file_inputs=
for ac_f
do
case $ac_f in
-) ac_f="$tmp/stdin";;
*) # Look for the file first in the build tree, then in the source tree
# (if the path is not absolute). The absolute path cannot be DOS-style,
# because $ac_f cannot contain `:'.
test -f "$ac_f" ||
case $ac_f in
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
done
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
configure_input='Generated from '`
$as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
`' by configure.'
if test x"$ac_file" != x-; then
configure_input="$ac_file. $configure_input"
{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
$as_echo "$as_me: creating $ac_file" >&6;}
fi
# Neutralize special characters interpreted by sed in replacement strings.
case $configure_input in #(
*\&* | *\|* | *\\* )
ac_sed_conf_input=`$as_echo "$configure_input" |
sed 's/[\\\\&|]/\\\\&/g'`;; #(
*) ac_sed_conf_input=$configure_input;;
esac
case $ac_tag in
*:-:* | *:-) cat >"$tmp/stdin" \
|| as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
ac_dir=`$as_dirname -- "$ac_file" ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
as_dir="$ac_dir"; as_fn_mkdir_p
ac_builddir=.
case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
# A ".." for each directory in $ac_dir_suffix.
ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
case $ac_top_builddir_sub in
"") ac_top_builddir_sub=. ac_top_build_prefix= ;;
*) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix
case $srcdir in
.) # We are building in place.
ac_srcdir=.
ac_top_srcdir=$ac_top_builddir_sub
ac_abs_top_srcdir=$ac_pwd ;;
[\\/]* | ?:[\\/]* ) # Absolute name.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir
ac_abs_top_srcdir=$srcdir ;;
*) # Relative name.
ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_build_prefix$srcdir
ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
case $ac_mode in
:F)
#
# CONFIG_FILE
#
# If the template does not know about datarootdir, expand it.
# FIXME: This hack should be removed a few years after 2.60.
ac_datarootdir_hack=; ac_datarootdir_seen=
ac_sed_dataroot='
/datarootdir/ {
p
q
}
/@datadir@/p
/@docdir@/p
/@infodir@/p
/@localedir@/p
/@mandir@/p'
case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
*datarootdir*) ac_datarootdir_seen=yes;;
*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
ac_datarootdir_hack='
s&@datadir@&${datarootdir}&g
s&@docdir@&${datarootdir}/doc/${PACKAGE_TARNAME}&g
s&@infodir@&${datarootdir}/info&g
s&@localedir@&${datarootdir}/locale&g
s&@mandir@&${datarootdir}/man&g
s&\${datarootdir}&${prefix}/share&g' ;;
esac
ac_sed_extra="/^[ ]*VPATH[ ]*=/{
s/:*\$(srcdir):*/:/
s/:*\${srcdir}:*/:/
s/:*@srcdir@:*/:/
s/^\([^=]*=[ ]*\):*/\1/
s/:*$//
s/^[^=]*=[ ]*$//
}
:t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
s|@configure_input@|$ac_sed_conf_input|;t t
s&@top_builddir@&$ac_top_builddir_sub&;t t
s&@top_build_prefix@&$ac_top_build_prefix&;t t
s&@srcdir@&$ac_srcdir&;t t
s&@abs_srcdir@&$ac_abs_srcdir&;t t
s&@top_srcdir@&$ac_top_srcdir&;t t
s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
s&@builddir@&$ac_builddir&;t t
s&@abs_builddir@&$ac_abs_builddir&;t t
s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
$ac_datarootdir_hack
"
eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
|| as_fn_error "could not create $ac_file" "$LINENO" 5
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
{ ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
{ ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined." >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined." >&2;}
rm -f "$tmp/stdin"
case $ac_file in
-) cat "$tmp/out" && rm -f "$tmp/out";;
*) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
esac \
|| as_fn_error "could not create $ac_file" "$LINENO" 5
;;
esac
done # for ac_tag
as_fn_exit 0

2791
src/modules/getid3/tmp/configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -64,7 +64,7 @@ class getid3_lib
// convert a float to type int, only if possible // convert a float to type int, only if possible
if (getid3_lib::trunc($floatnum) == $floatnum) { if (getid3_lib::trunc($floatnum) == $floatnum) {
// it's not floating point // it's not floating point
if ($floatnum <= 1073741824) { // 2^30 if ($floatnum <= 2147483647) { // 2^31
// it's within int range // it's within int range
$floatnum = (int) $floatnum; $floatnum = (int) $floatnum;
} }
@ -162,6 +162,9 @@ class getid3_lib
// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html
$bitword = getid3_lib::BigEndian2Bin($byteword); $bitword = getid3_lib::BigEndian2Bin($byteword);
if (!$bitword) {
return 0;
}
$signbit = $bitword{0}; $signbit = $bitword{0};
switch (strlen($byteword) * 8) { switch (strlen($byteword) * 8) {
@ -406,13 +409,15 @@ class getid3_lib
function PlaytimeString($playtimeseconds) { function PlaytimeString($playtimeseconds) {
$sign = (($playtimeseconds < 0) ? '-' : '');
$playtimeseconds = abs($playtimeseconds);
$contentseconds = round((($playtimeseconds / 60) - floor($playtimeseconds / 60)) * 60); $contentseconds = round((($playtimeseconds / 60) - floor($playtimeseconds / 60)) * 60);
$contentminutes = floor($playtimeseconds / 60); $contentminutes = floor($playtimeseconds / 60);
if ($contentseconds >= 60) { if ($contentseconds >= 60) {
$contentseconds -= 60; $contentseconds -= 60;
$contentminutes++; $contentminutes++;
} }
return intval($contentminutes).':'.str_pad($contentseconds, 2, 0, STR_PAD_LEFT); return $sign.intval($contentminutes).':'.str_pad($contentseconds, 2, 0, STR_PAD_LEFT);
} }
@ -580,6 +585,9 @@ class getid3_lib
// Allan Hansen <ahØartemis*dk> // Allan Hansen <ahØartemis*dk>
// getid3_lib::md5_data() - returns md5sum for a file from startuing position to absolute end position // getid3_lib::md5_data() - returns md5sum for a file from startuing position to absolute end position
function hash_data($file, $offset, $end, $algorithm) { function hash_data($file, $offset, $end, $algorithm) {
if ($end >= pow(2, 31)) {
return false;
}
switch ($algorithm) { switch ($algorithm) {
case 'md5': case 'md5':
@ -954,69 +962,47 @@ class getid3_lib
return $string; return $string;
} }
static $iconv_broken_or_unavailable = array(); // iconv() availble
if (is_null(@$iconv_broken_or_unavailable[$in_charset.'_'.$out_charset])) { if (function_exists('iconv')) {
$GETID3_ICONV_TEST_STRING = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~<><7F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><>ウЖ<E382A6><D096><EFBFBD>渦慨偽係杭纂従神疎団兎波品北洋椀冫嘖孛忤掣桀毳烙痰邃繙艾蜉謖邇關髓齡<E9AB93><E9BDA1>巐鄕<E5B790><E98495>';
// Check iconv() if ($converted_string = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) {
if (function_exists('iconv')) { switch ($out_charset) {
if (@iconv($in_charset, 'ISO-8859-1', @iconv('ISO-8859-1', $in_charset, $GETID3_ICONV_TEST_STRING)) == $GETID3_ICONV_TEST_STRING) { case 'ISO-8859-1':
if (@iconv($out_charset, 'ISO-8859-1', @iconv('ISO-8859-1', $out_charset, $GETID3_ICONV_TEST_STRING)) == $GETID3_ICONV_TEST_STRING) { $converted_string = rtrim($converted_string, "\x00");
// everything works, use iconv() break;
$iconv_broken_or_unavailable[$in_charset.'_'.$out_charset] = false; }
} else { return $converted_string;
// iconv() available, but broken. Use getID3()'s iconv_fallback() conversions instead }
// known issue in PHP v4.1.x
$iconv_broken_or_unavailable[$in_charset.'_'.$out_charset] = true; // iconv() may sometimes fail with "illegal character in input string" error message
} // and return an empty string, but returning the unconverted string is more useful
} else { return $string;
// iconv() available, but broken. Use getID3()'s iconv_fallback() conversions instead }
// known issue in PHP v4.1.x
$iconv_broken_or_unavailable[$in_charset.'_'.$out_charset] = true;
} // iconv() not available
} else { static $ConversionFunctionList = array();
// iconv() unavailable, use getID3()'s iconv_fallback() conversions if (empty($ConversionFunctionList)) {
$iconv_broken_or_unavailable[$in_charset.'_'.$out_charset] = true; $ConversionFunctionList['ISO-8859-1']['UTF-8'] = 'iconv_fallback_iso88591_utf8';
} $ConversionFunctionList['ISO-8859-1']['UTF-16'] = 'iconv_fallback_iso88591_utf16';
$ConversionFunctionList['ISO-8859-1']['UTF-16BE'] = 'iconv_fallback_iso88591_utf16be';
$ConversionFunctionList['ISO-8859-1']['UTF-16LE'] = 'iconv_fallback_iso88591_utf16le';
$ConversionFunctionList['UTF-8']['ISO-8859-1'] = 'iconv_fallback_utf8_iso88591';
$ConversionFunctionList['UTF-8']['UTF-16'] = 'iconv_fallback_utf8_utf16';
$ConversionFunctionList['UTF-8']['UTF-16BE'] = 'iconv_fallback_utf8_utf16be';
$ConversionFunctionList['UTF-8']['UTF-16LE'] = 'iconv_fallback_utf8_utf16le';
$ConversionFunctionList['UTF-16']['ISO-8859-1'] = 'iconv_fallback_utf16_iso88591';
$ConversionFunctionList['UTF-16']['UTF-8'] = 'iconv_fallback_utf16_utf8';
$ConversionFunctionList['UTF-16LE']['ISO-8859-1'] = 'iconv_fallback_utf16le_iso88591';
$ConversionFunctionList['UTF-16LE']['UTF-8'] = 'iconv_fallback_utf16le_utf8';
$ConversionFunctionList['UTF-16BE']['ISO-8859-1'] = 'iconv_fallback_utf16be_iso88591';
$ConversionFunctionList['UTF-16BE']['UTF-8'] = 'iconv_fallback_utf16be_utf8';
} }
if (isset($ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)])) {
if ($iconv_broken_or_unavailable[$in_charset.'_'.$out_charset]) { $ConversionFunction = $ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)];
static $ConversionFunctionList = array(); return getid3_lib::$ConversionFunction($string);
if (empty($ConversionFunctionList)) {
$ConversionFunctionList['ISO-8859-1']['UTF-8'] = 'iconv_fallback_iso88591_utf8';
$ConversionFunctionList['ISO-8859-1']['UTF-16'] = 'iconv_fallback_iso88591_utf16';
$ConversionFunctionList['ISO-8859-1']['UTF-16BE'] = 'iconv_fallback_iso88591_utf16be';
$ConversionFunctionList['ISO-8859-1']['UTF-16LE'] = 'iconv_fallback_iso88591_utf16le';
$ConversionFunctionList['UTF-8']['ISO-8859-1'] = 'iconv_fallback_utf8_iso88591';
$ConversionFunctionList['UTF-8']['UTF-16'] = 'iconv_fallback_utf8_utf16';
$ConversionFunctionList['UTF-8']['UTF-16BE'] = 'iconv_fallback_utf8_utf16be';
$ConversionFunctionList['UTF-8']['UTF-16LE'] = 'iconv_fallback_utf8_utf16le';
$ConversionFunctionList['UTF-16']['ISO-8859-1'] = 'iconv_fallback_utf16_iso88591';
$ConversionFunctionList['UTF-16']['UTF-8'] = 'iconv_fallback_utf16_utf8';
$ConversionFunctionList['UTF-16LE']['ISO-8859-1'] = 'iconv_fallback_utf16le_iso88591';
$ConversionFunctionList['UTF-16LE']['UTF-8'] = 'iconv_fallback_utf16le_utf8';
$ConversionFunctionList['UTF-16BE']['ISO-8859-1'] = 'iconv_fallback_utf16be_iso88591';
$ConversionFunctionList['UTF-16BE']['UTF-8'] = 'iconv_fallback_utf16be_utf8';
}
if (isset($ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)])) {
$ConversionFunction = $ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)];
return getid3_lib::$ConversionFunction($string);
}
die('PHP does not have iconv() support - cannot convert from '.$in_charset.' to '.$out_charset);
} }
die('PHP does not have iconv() support - cannot convert from '.$in_charset.' to '.$out_charset);
if ($converted_string = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) {
switch ($out_charset) {
case 'ISO-8859-1':
$converted_string = rtrim($converted_string, "\x00");
break;
}
return $converted_string;
}
// iconv() may sometimes fail with "illegal character in input string" error message
// and return an empty string, but returning the unconverted string is more useful
return $string;
} }
@ -1061,21 +1047,21 @@ class getid3_lib
$charval = 0; $charval = 0;
if ($char_ord_val < 0x80) { if ($char_ord_val < 0x80) {
$charval = $char_ord_val; $charval = $char_ord_val;
} elseif ((($char_ord_val & 0xF0) >> 4) == 0x0F) { } elseif ((($char_ord_val & 0xF0) >> 4) == 0x0F && $i+3 < $strlen) {
$charval = (($char_ord_val & 0x07) << 18); $charval = (($char_ord_val & 0x07) << 18);
$charval += ((ord($string{++$i}) & 0x3F) << 12); $charval += ((ord($string{++$i}) & 0x3F) << 12);
$charval += ((ord($string{++$i}) & 0x3F) << 6); $charval += ((ord($string{++$i}) & 0x3F) << 6);
$charval += (ord($string{++$i}) & 0x3F); $charval += (ord($string{++$i}) & 0x3F);
} elseif ((($char_ord_val & 0xE0) >> 5) == 0x07) { } elseif ((($char_ord_val & 0xE0) >> 5) == 0x07 && $i+2 < $strlen) {
$charval = (($char_ord_val & 0x0F) << 12); $charval = (($char_ord_val & 0x0F) << 12);
$charval += ((ord($string{++$i}) & 0x3F) << 6); $charval += ((ord($string{++$i}) & 0x3F) << 6);
$charval += (ord($string{++$i}) & 0x3F); $charval += (ord($string{++$i}) & 0x3F);
} elseif ((($char_ord_val & 0xC0) >> 6) == 0x03) { } elseif ((($char_ord_val & 0xC0) >> 6) == 0x03 && $i+1 < $strlen) {
$charval = (($char_ord_val & 0x1F) << 6); $charval = (($char_ord_val & 0x1F) << 6);
$charval += (ord($string{++$i}) & 0x3F); $charval += (ord($string{++$i}) & 0x3F);
} }
if (($charval >= 32) && ($charval <= 127)) { if (($charval >= 32) && ($charval <= 127)) {
$HTMLstring .= chr($charval); $HTMLstring .= htmlentities(chr($charval));
} else { } else {
$HTMLstring .= '&#'.$charval.';'; $HTMLstring .= '&#'.$charval.';';
} }
@ -1167,13 +1153,13 @@ class getid3_lib
} }
function GetDataImageSize($imgData) { function GetDataImageSize($imgData, &$imageinfo) {
$GetDataImageSize = false; $GetDataImageSize = false;
if ($tempfilename = tempnam('*', 'getID3')) { if ($tempfilename = tempnam('*', 'getID3')) {
if ($tmp = @fopen($tempfilename, 'wb')) { if ($tmp = @fopen($tempfilename, 'wb')) {
fwrite($tmp, $imgData); fwrite($tmp, $imgData);
fclose($tmp); fclose($tmp);
$GetDataImageSize = @GetImageSize($tempfilename); $GetDataImageSize = @GetImageSize($tempfilename, $imageinfo);
} }
unlink($tempfilename); unlink($tempfilename);
} }
@ -1203,7 +1189,7 @@ class getid3_lib
function CopyTagsToComments(&$ThisFileInfo) { function CopyTagsToComments(&$ThisFileInfo) {
// Copy all entries from ['tags'] into common ['comments'] // Copy all entries from ['tags'] into common ['comments']
if (!empty($ThisFileInfo['tags'])) { if (!empty($ThisFileInfo['tags'])) {
foreach ($ThisFileInfo['tags'] as $tagtype => $tagarray) { foreach ($ThisFileInfo['tags'] as $tagtype => $tagarray) {
foreach ($tagarray as $tagname => $tagdata) { foreach ($tagarray as $tagname => $tagdata) {
@ -1243,8 +1229,8 @@ class getid3_lib
} }
} }
} }
// Copy to ['comments_html'] // Copy to ['comments_html']
foreach ($ThisFileInfo['comments'] as $field => $values) { foreach ($ThisFileInfo['comments'] as $field => $values) {
foreach ($values as $index => $value) { foreach ($values as $index => $value) {
$ThisFileInfo['comments_html'][$field][$index] = str_replace('&#0;', '', getid3_lib::MultiByteCharString2HTML($value, $ThisFileInfo['encoding'])); $ThisFileInfo['comments_html'][$field][$index] = str_replace('&#0;', '', getid3_lib::MultiByteCharString2HTML($value, $ThisFileInfo['encoding']));

View File

@ -10,7 +10,7 @@
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Defines // Defines
define('GETID3_VERSION', '1.7.7'); define('GETID3_VERSION', '1.7.9-20090308');
define('GETID3_FREAD_BUFFER_SIZE', 16384); // read buffer size in bytes define('GETID3_FREAD_BUFFER_SIZE', 16384); // read buffer size in bytes
@ -53,14 +53,15 @@ class getID3
$this->startup_error = ''; $this->startup_error = '';
$this->startup_warning = ''; $this->startup_warning = '';
// Check for PHP version >= 4.1.0 // Check for PHP version >= 4.2.0
if (phpversion() < '4.1.0') { if (phpversion() < '4.2.0') {
$this->startup_error .= 'getID3() requires PHP v4.1.0 or higher - you are running v'.phpversion(); $this->startup_error .= 'getID3() requires PHP v4.2.0 or higher - you are running v'.phpversion();
} }
// Check memory // Check memory
$memory_limit = ini_get('memory_limit'); $memory_limit = ini_get('memory_limit');
if (eregi('([0-9]+)M', $memory_limit, $matches)) { #if (eregi('([0-9]+)M', $memory_limit, $matches)) {
if (preg_match('/([0-9]+)M/', $memory_limit, $matches)) {
// could be stored as "16M" rather than 16777216 for example // could be stored as "16M" rather than 16777216 for example
$memory_limit = $matches[1] * 1048576; $memory_limit = $matches[1] * 1048576;
} }
@ -110,40 +111,26 @@ class getID3
// ie for "C:/Program Files/Apache/" put "C:/PROGRA~1/APACHE/" // ie for "C:/Program Files/Apache/" put "C:/PROGRA~1/APACHE/"
// IMPORTANT: This path must include the trailing slash // IMPORTANT: This path must include the trailing slash
if (GETID3_OS_ISWINDOWS && !defined('GETID3_HELPERAPPSDIR')) { if (GETID3_OS_ISWINDOWS && !defined('GETID3_HELPERAPPSDIR')) {
$helperappsdir = GETID3_INCLUDEPATH.'..'.DIRECTORY_SEPARATOR.'helperapps'; // must not have any space in this path $helperappsdir = GETID3_INCLUDEPATH.'..'.DIRECTORY_SEPARATOR.'helperapps'; // must not have any space in this path
if (!is_dir($helperappsdir)) { if (!is_dir($helperappsdir)) {
$this->startup_error .= '"'.$helperappsdir.'" cannot be defined as GETID3_HELPERAPPSDIR because it does not exist'; $this->startup_error .= '"'.$helperappsdir.'" cannot be defined as GETID3_HELPERAPPSDIR because it does not exist';
} elseif (strpos(realpath($helperappsdir), ' ') !== false) { } elseif (strpos(realpath($helperappsdir), ' ') !== false) {
$DirPieces = explode(DIRECTORY_SEPARATOR, realpath($helperappsdir)); $DirPieces = explode(DIRECTORY_SEPARATOR, realpath($helperappsdir));
$DirPieces8 = $DirPieces; foreach ($DirPieces as $key => $value) {
if ((strpos($value, '.') !== false) && (strpos($value, ' ') === false)) {
$CLIdir = $DirPieces[0].' && cd \\'; if (strpos($value, '.') > 8) {
for ($i = 1; $i < count($DirPieces); $i++) { $value = substr($value, 0, 6).'~1';
if (strpos($DirPieces[$i], ' ') === false) { }
$CLIdir .= ' && cd '.$DirPieces[$i]; } elseif ((strpos($value, ' ') !== false) || strlen($value) > 8) {
} else { $value = substr($value, 0, 6).'~1';
ob_start(); }
system($CLIdir.' && dir /ad /x'); $DirPieces[$key] = strtoupper($value);
$subdirsraw = explode("\n", ob_get_contents());
ob_end_clean();
foreach ($subdirsraw as $dummy => $line) {
if (eregi('^[0-9]{4}/[0-9]{2}/[0-9]{2} [0-9]{2}:[0-9]{2} [AP]M <DIR> ([^ ]{8}) '.preg_quote($DirPieces[$i]).'$', trim($line), $matches)) {
$CLIdir .= ' && cd '.$matches[1];
break;
}
}
$DirPieces8[$i] = $matches[1];
}
} }
$helperappsdir = implode(DIRECTORY_SEPARATOR, $DirPieces8); $this->startup_error .= 'GETID3_HELPERAPPSDIR must not have any spaces in it - use 8dot3 naming convention if neccesary (on this server that would be something like "'.implode(DIRECTORY_SEPARATOR, $DirPieces).'" - NOTE: this may or may not be the actual 8.3 equivalent of "'.$helperappsdir.'", please double-check). You can run "dir /x" from the commandline to see the correct 8.3-style names.';
} }
define('GETID3_HELPERAPPSDIR', realpath($helperappsdir).DIRECTORY_SEPARATOR); define('GETID3_HELPERAPPSDIR', realpath($helperappsdir).DIRECTORY_SEPARATOR);
} }
} }
@ -155,7 +142,8 @@ class getID3
return false; return false;
} }
foreach ($optArray as $opt => $val) { foreach ($optArray as $opt => $val) {
if (isset($this, $opt) === false) { //if (isset($this, $opt) === false) {
if (isset($this->$opt) === false) {
continue; continue;
} }
$this->$opt = $val; $this->$opt = $val;
@ -192,7 +180,7 @@ class getID3
// Disable magic_quotes_runtime, if neccesary // Disable magic_quotes_runtime, if neccesary
$old_magic_quotes_runtime = get_magic_quotes_runtime(); // store current setting of magic_quotes_runtime $old_magic_quotes_runtime = get_magic_quotes_runtime(); // store current setting of magic_quotes_runtime
if ($old_magic_quotes_runtime) { if ($old_magic_quotes_runtime) {
set_magic_quotes_runtime(0); // turn off magic_quotes_runtime ini_set('magic_quotes_runtime', 0); // turn off magic_quotes_runtime
if (get_magic_quotes_runtime()) { if (get_magic_quotes_runtime()) {
return $this->error('Could not disable magic_quotes_runtime - getID3() cannot work properly with this setting enabled'); return $this->error('Could not disable magic_quotes_runtime - getID3() cannot work properly with this setting enabled');
} }
@ -203,8 +191,13 @@ class getID3
return $this->error('Remote files are not supported in this version of getID3() - please copy the file locally first'); return $this->error('Remote files are not supported in this version of getID3() - please copy the file locally first');
} }
$filename = str_replace('/', DIRECTORY_SEPARATOR, $filename);
$filename = preg_replace('#'.preg_quote(DIRECTORY_SEPARATOR).'{2,}#', DIRECTORY_SEPARATOR, $filename);
// open local file // open local file
if (!$fp = @fopen($filename, 'rb')) { if (file_exists($filename) && ($fp = @fopen($filename, 'rb'))) {
// great
} else {
return $this->error('Could not open file "'.$filename.'"'); return $this->error('Could not open file "'.$filename.'"');
} }
@ -220,9 +213,31 @@ class getID3
if ((($this->info['filesize'] != 0) && (ftell($fp) == 0)) || if ((($this->info['filesize'] != 0) && (ftell($fp) == 0)) ||
($this->info['filesize'] < 0) || ($this->info['filesize'] < 0) ||
(ftell($fp) < 0)) { (ftell($fp) < 0)) {
unset($this->info['filesize']); $real_filesize = false;
fclose($fp); if (GETID3_OS_ISWINDOWS) {
return $this->error('File is most likely larger than 2GB and is not supported by PHP'); $commandline = 'dir /-C "'.str_replace('/', DIRECTORY_SEPARATOR, $filename).'"';
$dir_output = `$commandline`;
if (eregi('1 File\(s\)[ ]+([0-9]+) bytes', $dir_output, $matches)) {
$real_filesize = (float) $matches[1];
}
} else {
$commandline = 'ls -o -g -G --time-style=long-iso '.escapeshellarg($filename);
$dir_output = `$commandline`;
if (eregi('([0-9]+) ([0-9]{4}-[0-9]{2}\-[0-9]{2} [0-9]{2}:[0-9]{2}) '.preg_quote($filename).'$', $dir_output, $matches)) {
$real_filesize = (float) $matches[1];
}
}
if ($real_filesize === false) {
unset($this->info['filesize']);
fclose($fp);
return $this->error('File is most likely larger than 2GB and is not supported by PHP');
} elseif ($real_filesize < pow(2, 31)) {
unset($this->info['filesize']);
fclose($fp);
return $this->error('PHP seems to think the file is larger than 2GB, but filesystem reports it as '.number_format($real_filesize, 3).'GB, please report to info@getid3.org');
}
$this->info['filesize'] = $real_filesize;
$this->error('File is larger than 2GB (filesystem reports it as '.number_format($real_filesize, 3).'GB) and is not properly supported by PHP.');
} }
} }
@ -251,13 +266,14 @@ class getID3
$GETID3_ERRORARRAY = &$this->info['warning']; $GETID3_ERRORARRAY = &$this->info['warning'];
if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, false)) { if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, false)) {
$tag = new getid3_id3v2($fp, $this->info); $tag = new getid3_id3v2($fp, $this->info);
unset($tag);
} }
} else { } else {
fseek($fp, 0, SEEK_SET); fseek($fp, 0, SEEK_SET);
$header = fread($fp, 10); $header = fread($fp, 10);
if (substr($header, 0, 3) == 'ID3') { if (substr($header, 0, 3) == 'ID3' && strlen($header) == 10) {
$this->info['id3v2']['header'] = true; $this->info['id3v2']['header'] = true;
$this->info['id3v2']['majorversion'] = ord($header{3}); $this->info['id3v2']['majorversion'] = ord($header{3});
$this->info['id3v2']['minorversion'] = ord($header{4}); $this->info['id3v2']['minorversion'] = ord($header{4});
@ -277,6 +293,7 @@ class getID3
return $this->error('module.tag.id3v1.php is missing - you may disable option_tag_id3v1.'); return $this->error('module.tag.id3v1.php is missing - you may disable option_tag_id3v1.');
} }
$tag = new getid3_id3v1($fp, $this->info); $tag = new getid3_id3v1($fp, $this->info);
unset($tag);
} }
// handle APE tag // handle APE tag
@ -285,6 +302,7 @@ class getID3
return $this->error('module.tag.apetag.php is missing - you may disable option_tag_apetag.'); return $this->error('module.tag.apetag.php is missing - you may disable option_tag_apetag.');
} }
$tag = new getid3_apetag($fp, $this->info); $tag = new getid3_apetag($fp, $this->info);
unset($tag);
} }
// handle lyrics3 tag // handle lyrics3 tag
@ -293,6 +311,7 @@ class getID3
return $this->error('module.tag.lyrics3.php is missing - you may disable option_tag_lyrics3.'); return $this->error('module.tag.lyrics3.php is missing - you may disable option_tag_lyrics3.');
} }
$tag = new getid3_lyrics3($fp, $this->info); $tag = new getid3_lyrics3($fp, $this->info);
unset($tag);
} }
// read 32 kb file data // read 32 kb file data
@ -334,7 +353,7 @@ class getID3
// supported format signature pattern detected, but module deleted // supported format signature pattern detected, but module deleted
if (!file_exists(GETID3_INCLUDEPATH.$determined_format['include'])) { if (!file_exists(GETID3_INCLUDEPATH.$determined_format['include'])) {
fclose($fp); fclose($fp);
return $this->error('Format not supported, module, '.$determined_format['include'].', was removed.'); return $this->error('Format not supported, module "'.$determined_format['include'].'" was removed.');
} }
// module requires iconv support // module requires iconv support
@ -348,13 +367,14 @@ class getID3
// instantiate module class // instantiate module class
$class_name = 'getid3_'.$determined_format['module']; $class_name = 'getid3_'.$determined_format['module'];
if (!class_exists($class_name)) { if (!class_exists($class_name)) {
return $this->error('Format not supported, module, '.$determined_format['include'].', is corrupt.'); return $this->error('Format not supported, module "'.$determined_format['include'].'" is corrupt.');
} }
if (isset($determined_format['option'])) { if (isset($determined_format['option'])) {
$class = new $class_name($fp, $this->info, $determined_format['option']); $class = new $class_name($fp, $this->info, $determined_format['option']);
} else { } else {
$class = new $class_name($fp, $this->info); $class = new $class_name($fp, $this->info);
} }
unset($class);
// close file // close file
fclose($fp); fclose($fp);
@ -389,8 +409,8 @@ class getID3
// remove undesired keys // remove undesired keys
$this->CleanUp(); $this->CleanUp();
// restore magic_quotes_runtime setting // restore magic_quotes_runtime setting
set_magic_quotes_runtime($old_magic_quotes_runtime); ini_set('magic_quotes_runtime', $old_magic_quotes_runtime);
// return info array // return info array
return $this->info; return $this->info;
@ -418,7 +438,7 @@ class getID3
function CleanUp() { function CleanUp() {
// remove possible empty keys // remove possible empty keys
$AVpossibleEmptyKeys = array('dataformat', 'bits_per_sample', 'encoder_options', 'streams'); $AVpossibleEmptyKeys = array('dataformat', 'bits_per_sample', 'encoder_options', 'streams', 'bitrate');
foreach ($AVpossibleEmptyKeys as $dummy => $key) { foreach ($AVpossibleEmptyKeys as $dummy => $key) {
if (empty($this->info['audio'][$key]) && isset($this->info['audio'][$key])) { if (empty($this->info['audio'][$key]) && isset($this->info['audio'][$key])) {
unset($this->info['audio'][$key]); unset($this->info['audio'][$key]);
@ -511,6 +531,22 @@ class getID3
'mime_type' => 'audio/xmms-bonk', 'mime_type' => 'audio/xmms-bonk',
), ),
// DSS - audio - Digital Speech Standard
'dss' => array(
'pattern' => '^[\x02]dss',
'group' => 'audio',
'module' => 'dss',
'mime_type' => 'application/octet-stream',
),
// DTS - audio - Dolby Theatre System
'dts' => array(
'pattern' => '^\x7F\xFE\x80\x01',
'group' => 'audio',
'module' => 'dts',
'mime_type' => 'audio/dts',
),
// FLAC - audio - Free Lossless Audio Codec // FLAC - audio - Free Lossless Audio Codec
'flac' => array( 'flac' => array(
'pattern' => '^fLaC', 'pattern' => '^fLaC',
@ -551,14 +587,15 @@ class getID3
'mime_type' => 'application/octet-stream', 'mime_type' => 'application/octet-stream',
), ),
// MOD - audio - MODule (assorted sub-formats) // has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available
'mod' => array( // // MOD - audio - MODule (assorted sub-formats)
'pattern' => '^.{1080}(M.K.|[5-9]CHN|[1-3][0-9]CH)', // 'mod' => array(
'group' => 'audio', // 'pattern' => '^.{1080}(M\\.K\\.|M!K!|FLT4|FLT8|[5-9]CHN|[1-3][0-9]CH)',
'module' => 'mod', // 'group' => 'audio',
'option' => 'mod', // 'module' => 'mod',
'mime_type' => 'audio/mod', // 'option' => 'mod',
), // 'mime_type' => 'audio/mod',
// ),
// MOD - audio - MODule (Impulse Tracker) // MOD - audio - MODule (Impulse Tracker)
'it' => array( 'it' => array(
@ -589,10 +626,10 @@ class getID3
// MPC - audio - Musepack / MPEGplus // MPC - audio - Musepack / MPEGplus
'mpc' => array( 'mpc' => array(
'pattern' => '^(MP\+|[\x00\x01\x10\x11\x40\x41\x50\x51\x80\x81\x90\x91\xC0\xC1\xD0\xD1][\x20-37][\x00\x20\x40\x60\x80\xA0\xC0\xE0])', 'pattern' => '^(MPCK|MP\+|[\x00\x01\x10\x11\x40\x41\x50\x51\x80\x81\x90\x91\xC0\xC1\xD0\xD1][\x20-37][\x00\x20\x40\x60\x80\xA0\xC0\xE0])',
'group' => 'audio', 'group' => 'audio',
'module' => 'mpc', 'module' => 'mpc',
'mime_type' => 'application/octet-stream', 'mime_type' => 'audio/x-musepack',
), ),
// MP3 - audio - MPEG-audio Layer 3 (very similar to AAC-ADTS) // MP3 - audio - MPEG-audio Layer 3 (very similar to AAC-ADTS)
@ -694,7 +731,7 @@ class getID3
'pattern' => '^\x1A\x45\xDF\xA3', 'pattern' => '^\x1A\x45\xDF\xA3',
'group' => 'audio-video', 'group' => 'audio-video',
'module' => 'matroska', 'module' => 'matroska',
'mime_type' => 'application/octet-stream', 'mime_type' => 'video/x-matroska', // may also be audio/x-matroska
), ),
// MPEG - audio/video - MPEG (Moving Pictures Experts Group) // MPEG - audio/video - MPEG (Moving Pictures Experts Group)
@ -742,7 +779,7 @@ class getID3
// Real - audio/video - RealAudio, RealVideo // Real - audio/video - RealAudio, RealVideo
'real' => array( 'real' => array(
'pattern' => '^(\.RMF|.ra)', 'pattern' => '^(\\.RMF|\\.ra)',
'group' => 'audio-video', 'group' => 'audio-video',
'module' => 'real', 'module' => 'real',
'mime_type' => 'audio/x-realaudio', 'mime_type' => 'audio/x-realaudio',
@ -811,6 +848,17 @@ class getID3
), ),
// SVG - still image - Scalable Vector Graphics (SVG)
'svg' => array(
'pattern' => '<!DOCTYPE svg PUBLIC ',
'group' => 'graphic',
'module' => 'svg',
'mime_type' => 'image/svg+xml',
'fail_id3' => 'ERROR',
'fail_ape' => 'ERROR',
),
// TIFF - still image - Tagged Information File Format (TIFF) // TIFF - still image - Tagged Information File Format (TIFF)
'tiff' => array( 'tiff' => array(
'pattern' => '^(II\x2A\x00|MM\x00\x2A)', 'pattern' => '^(II\x2A\x00|MM\x00\x2A)',
@ -888,7 +936,17 @@ class getID3
// Misc other formats // Misc other formats
// PDF - data - ZIP compressed data // PAR2 - data - Parity Volume Set Specification 2.0
'par2' => array (
'pattern' => '^PAR2\x00PKT',
'group' => 'misc',
'module' => 'par2',
'mime_type' => 'application/octet-stream',
'fail_id3' => 'ERROR',
'fail_ape' => 'ERROR',
),
// PDF - data - Portable Document Format
'pdf' => array( 'pdf' => array(
'pattern' => '^\x25PDF', 'pattern' => '^\x25PDF',
'group' => 'misc', 'group' => 'misc',
@ -898,7 +956,7 @@ class getID3
'fail_ape' => 'ERROR', 'fail_ape' => 'ERROR',
), ),
// MSOFFICE - data - ZIP compressed data // MSOFFICE - data - ZIP compressed data
'msoffice' => array( 'msoffice' => array(
'pattern' => '^\xD0\xCF\x11\xE0', // D0CF11E == DOCFILE == Microsoft Office Document 'pattern' => '^\xD0\xCF\x11\xE0', // D0CF11E == DOCFILE == Microsoft Office Document
'group' => 'misc', 'group' => 'misc',
@ -1187,10 +1245,45 @@ class getID3
// unset($this->info['bitrate']); // unset($this->info['bitrate']);
//} //}
if (!isset($this->info['playtime_seconds']) && !empty($this->info['bitrate'])) { // video bitrate undetermined, but calculable
if (isset($this->info['video']['dataformat']) && $this->info['video']['dataformat'] && (!isset($this->info['video']['bitrate']) || ($this->info['video']['bitrate'] == 0))) {
// if video bitrate not set
if (isset($this->info['audio']['bitrate']) && ($this->info['audio']['bitrate'] > 0) && ($this->info['audio']['bitrate'] == $this->info['bitrate'])) {
// AND if audio bitrate is set to same as overall bitrate
if (isset($this->info['playtime_seconds']) && ($this->info['playtime_seconds'] > 0)) {
// AND if playtime is set
if (isset($this->info['avdataend']) && isset($this->info['avdataoffset'])) {
// AND if AV data offset start/end is known
// THEN we can calculate the video bitrate
$this->info['bitrate'] = round((($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['playtime_seconds']);
$this->info['video']['bitrate'] = $this->info['bitrate'] - $this->info['audio']['bitrate'];
}
}
}
}
if ((!isset($this->info['playtime_seconds']) || ($this->info['playtime_seconds'] <= 0)) && !empty($this->info['bitrate'])) {
$this->info['playtime_seconds'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['bitrate']; $this->info['playtime_seconds'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['bitrate'];
} }
if (!isset($this->info['bitrate']) && !empty($this->info['playtime_seconds'])) {
$this->info['bitrate'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['playtime_seconds'];
}
//echo '<pre>';
//var_dump($this->info['bitrate']);
//var_dump($this->info['audio']['bitrate']);
//var_dump($this->info['video']['bitrate']);
//echo '</pre>';
if (isset($this->info['bitrate']) && empty($this->info['audio']['bitrate']) && empty($this->info['video']['bitrate'])) {
if (isset($this->info['audio']['dataformat']) && empty($this->info['video']['resolution_x'])) {
// audio only
$this->info['audio']['bitrate'] = $this->info['bitrate'];
} elseif (isset($this->info['video']['resolution_x']) && empty($this->info['audio']['dataformat'])) {
// video only
$this->info['video']['bitrate'] = $this->info['bitrate'];
}
}
// Set playtime string // Set playtime string
if (!empty($this->info['playtime_seconds']) && empty($this->info['playtime_string'])) { if (!empty($this->info['playtime_seconds']) && empty($this->info['playtime_string'])) {
$this->info['playtime_string'] = getid3_lib::PlaytimeString($this->info['playtime_seconds']); $this->info['playtime_string'] = getid3_lib::PlaytimeString($this->info['playtime_seconds']);

View File

@ -8,11 +8,16 @@
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// // // //
// module.archive.gzip.php // // module.archive.gzip.php //
// written by Mike Mozolin <teddybearØmail*ru> //
// module for analyzing GZIP files // // module for analyzing GZIP files //
// dependencies: NONE // // dependencies: NONE //
// /// // ///
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// //
// Module originally written by //
// Mike Mozolin <teddybearØmail*ru> //
// //
/////////////////////////////////////////////////////////////////
class getid3_gzip { class getid3_gzip {
@ -112,10 +117,10 @@ class getid3_gzip {
$si1 = ord(substr($buff, $fpointer + $idx++, 1)); $si1 = ord(substr($buff, $fpointer + $idx++, 1));
$si2 = ord(substr($buff, $fpointer + $idx++, 1)); $si2 = ord(substr($buff, $fpointer + $idx++, 1));
if (($si1 == 0x41) && ($si2 == 0x70)) { if (($si1 == 0x41) && ($si2 == 0x70)) {
$w_xsublen = substr($buff, $fpointer+$idx, 2); $w_xsublen = substr($buff, $fpointer + $idx, 2);
$xsublen = getid3_lib::LittleEndian2Int($w_xsublen); $xsublen = getid3_lib::LittleEndian2Int($w_xsublen);
$idx += 2; $idx += 2;
$arr_xsubfield[] = substr($buff, $fpointer+$idx, $xsublen); $arr_xsubfield[] = substr($buff, $fpointer + $idx, $xsublen);
$idx += $xsublen; $idx += $xsublen;
} else { } else {
break; break;
@ -198,7 +203,24 @@ class getid3_gzip {
case 'tar': case 'tar':
// view TAR-file info // view TAR-file info
if (file_exists(GETID3_INCLUDEPATH.$determined_format['include']) && @include_once(GETID3_INCLUDEPATH.$determined_format['include'])) { if (file_exists(GETID3_INCLUDEPATH.$determined_format['include']) && @include_once(GETID3_INCLUDEPATH.$determined_format['include'])) {
getid3_tar::read_tar($inflated, $ThisFileInfo['gzip']['member_header'][$idx]); if (($temp_tar_filename = tempnam('*', 'getID3')) === false) {
// can't find anywhere to create a temp file, abort
$ThisFileInfo['error'][] = 'Unable to create temp file to parse TAR inside GZIP file';
break;
}
if ($fp_temp_tar = fopen($temp_tar_filename, 'w+b')) {
fwrite($fp_temp_tar, $inflated);
rewind($fp_temp_tar);
$getid3_tar = new getid3_tar($fp_temp_tar, $dummy);
$ThisFileInfo['gzip']['member_header'][$idx]['tar'] = $dummy['tar'];
unset($dummy);
unset($getid3_tar);
fclose($fp_temp_tar);
unlink($temp_tar_filename);
} else {
$ThisFileInfo['error'][] = 'Unable to fopen() temp file to parse TAR inside GZIP file';
break;
}
} }
break; break;

View File

@ -17,11 +17,31 @@
class getid3_rar class getid3_rar
{ {
var $option_use_rar_extension = false;
function getid3_rar(&$fd, &$ThisFileInfo) { function getid3_rar(&$fd, &$ThisFileInfo) {
$ThisFileInfo['fileformat'] = 'rar'; $ThisFileInfo['fileformat'] = 'rar';
$ThisFileInfo['error'][] = 'RAR parsing not enabled in this version of getID3()'; if ($this->option_use_rar_extension === true) {
if (function_exists('rar_open')) {
if ($rp = rar_open($ThisFileInfo['filename'])) {
$ThisFileInfo['rar']['files'] = array();
$entries = rar_list($rp);
foreach ($entries as $entry) {
$ThisFileInfo['rar']['files'] = getid3_lib::array_merge_clobber($ThisFileInfo['rar']['files'], getid3_lib::CreateDeepArray($entry->getName(), '/', $entry->getUnpackedSize()));
}
rar_close($rp);
return true;
} else {
$ThisFileInfo['error'][] = 'failed to rar_open('.$ThisFileInfo['filename'].')';
}
} else {
$ThisFileInfo['error'][] = 'RAR support does not appear to be available in this PHP installation';
}
} else {
$ThisFileInfo['error'][] = 'PHP-RAR processing has been disabled (set $getid3_rar->option_use_rar_extension=true to enable)';
}
return false; return false;
} }

View File

@ -8,11 +8,16 @@
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// // // //
// module.archive.tar.php // // module.archive.tar.php //
// written by Mike Mozolin <teddybearØmail*ru> //
// module for analyzing TAR files // // module for analyzing TAR files //
// dependencies: NONE // // dependencies: NONE //
// /// // ///
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// //
// Module originally written by //
// Mike Mozolin <teddybearØmail*ru> //
// //
/////////////////////////////////////////////////////////////////
class getid3_tar { class getid3_tar {
@ -20,12 +25,15 @@ class getid3_tar {
$ThisFileInfo['fileformat'] = 'tar'; $ThisFileInfo['fileformat'] = 'tar';
$ThisFileInfo['tar']['files'] = array(); $ThisFileInfo['tar']['files'] = array();
$unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155/prefix'; $unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155prefix';
$null_512k = str_repeat("\0", 512); // end-of-file marker $null_512k = str_repeat("\x00", 512); // end-of-file marker
@fseek($fd, 0); @fseek($fd, 0);
while (!feof($fd)) { while (!feof($fd)) {
$buffer = fread($fd, 512); $buffer = fread($fd, 512);
if (strlen($buffer) < 512) {
break;
}
// check the block // check the block
$checksum = 0; $checksum = 0;

View File

@ -27,55 +27,56 @@ class getid3_zip
$ThisFileInfo['zip']['uncompressed_size'] = 0; $ThisFileInfo['zip']['uncompressed_size'] = 0;
$ThisFileInfo['zip']['entries_count'] = 0; $ThisFileInfo['zip']['entries_count'] = 0;
$EOCDsearchData = ''; if ($ThisFileInfo['filesize'] < pow(2, 31)) {
$EOCDsearchCounter = 0; $EOCDsearchData = '';
while ($EOCDsearchCounter++ < 512) { $EOCDsearchCounter = 0;
while ($EOCDsearchCounter++ < 512) {
fseek($fd, -128 * $EOCDsearchCounter, SEEK_END); fseek($fd, -128 * $EOCDsearchCounter, SEEK_END);
$EOCDsearchData = fread($fd, 128).$EOCDsearchData; $EOCDsearchData = fread($fd, 128).$EOCDsearchData;
if (strstr($EOCDsearchData, 'PK'."\x05\x06")) { if (strstr($EOCDsearchData, 'PK'."\x05\x06")) {
$EOCDposition = strpos($EOCDsearchData, 'PK'."\x05\x06"); $EOCDposition = strpos($EOCDsearchData, 'PK'."\x05\x06");
fseek($fd, (-128 * $EOCDsearchCounter) + $EOCDposition, SEEK_END); fseek($fd, (-128 * $EOCDsearchCounter) + $EOCDposition, SEEK_END);
$ThisFileInfo['zip']['end_central_directory'] = $this->ZIPparseEndOfCentralDirectory($fd); $ThisFileInfo['zip']['end_central_directory'] = $this->ZIPparseEndOfCentralDirectory($fd);
fseek($fd, $ThisFileInfo['zip']['end_central_directory']['directory_offset'], SEEK_SET); fseek($fd, $ThisFileInfo['zip']['end_central_directory']['directory_offset'], SEEK_SET);
$ThisFileInfo['zip']['entries_count'] = 0; $ThisFileInfo['zip']['entries_count'] = 0;
while ($centraldirectoryentry = $this->ZIPparseCentralDirectory($fd)) { while ($centraldirectoryentry = $this->ZIPparseCentralDirectory($fd)) {
$ThisFileInfo['zip']['central_directory'][] = $centraldirectoryentry; $ThisFileInfo['zip']['central_directory'][] = $centraldirectoryentry;
$ThisFileInfo['zip']['entries_count']++; $ThisFileInfo['zip']['entries_count']++;
$ThisFileInfo['zip']['compressed_size'] += $centraldirectoryentry['compressed_size']; $ThisFileInfo['zip']['compressed_size'] += $centraldirectoryentry['compressed_size'];
$ThisFileInfo['zip']['uncompressed_size'] += $centraldirectoryentry['uncompressed_size']; $ThisFileInfo['zip']['uncompressed_size'] += $centraldirectoryentry['uncompressed_size'];
if ($centraldirectoryentry['uncompressed_size'] > 0) { if ($centraldirectoryentry['uncompressed_size'] > 0) {
$ThisFileInfo['zip']['files'] = getid3_lib::array_merge_clobber($ThisFileInfo['zip']['files'], getid3_lib::CreateDeepArray($centraldirectoryentry['filename'], '/', $centraldirectoryentry['uncompressed_size'])); $ThisFileInfo['zip']['files'] = getid3_lib::array_merge_clobber($ThisFileInfo['zip']['files'], getid3_lib::CreateDeepArray($centraldirectoryentry['filename'], '/', $centraldirectoryentry['uncompressed_size']));
}
} }
}
if ($ThisFileInfo['zip']['entries_count'] == 0) { if ($ThisFileInfo['zip']['entries_count'] == 0) {
$ThisFileInfo['error'][] = 'No Central Directory entries found (truncated file?)'; $ThisFileInfo['error'][] = 'No Central Directory entries found (truncated file?)';
return false; return false;
} }
if (!empty($ThisFileInfo['zip']['end_central_directory']['comment'])) { if (!empty($ThisFileInfo['zip']['end_central_directory']['comment'])) {
$ThisFileInfo['zip']['comments']['comment'][] = $ThisFileInfo['zip']['end_central_directory']['comment']; $ThisFileInfo['zip']['comments']['comment'][] = $ThisFileInfo['zip']['end_central_directory']['comment'];
} }
if (isset($ThisFileInfo['zip']['central_directory'][0]['compression_method'])) { if (isset($ThisFileInfo['zip']['central_directory'][0]['compression_method'])) {
$ThisFileInfo['zip']['compression_method'] = $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'])) { if (isset($ThisFileInfo['zip']['central_directory'][0]['flags']['compression_speed'])) {
$ThisFileInfo['zip']['compression_speed'] = $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'])) { if (isset($ThisFileInfo['zip']['compression_method']) && ($ThisFileInfo['zip']['compression_method'] == 'store') && !isset($ThisFileInfo['zip']['compression_speed'])) {
$ThisFileInfo['zip']['compression_speed'] = 'store'; $ThisFileInfo['zip']['compression_speed'] = 'store';
} }
return true; return true;
}
} }
} }
if ($this->getZIPentriesFilepointer($fd, $ThisFileInfo)) { if ($this->getZIPentriesFilepointer($fd, $ThisFileInfo)) {

View File

@ -78,9 +78,7 @@ class getid3_asf
$thisfile_asf_headerobject['reserved1'] = getid3_lib::LittleEndian2Int(substr($HeaderObjectData, 28, 1)); $thisfile_asf_headerobject['reserved1'] = getid3_lib::LittleEndian2Int(substr($HeaderObjectData, 28, 1));
$thisfile_asf_headerobject['reserved2'] = getid3_lib::LittleEndian2Int(substr($HeaderObjectData, 29, 1)); $thisfile_asf_headerobject['reserved2'] = getid3_lib::LittleEndian2Int(substr($HeaderObjectData, 29, 1));
//$ASFHeaderData = $HeaderObjectData;
$ASFHeaderData = fread($fd, $thisfile_asf_headerobject['objectsize'] - 30); $ASFHeaderData = fread($fd, $thisfile_asf_headerobject['objectsize'] - 30);
//$offset = 30;
$offset = 0; $offset = 0;
for ($HeaderObjectsCounter = 0; $HeaderObjectsCounter < $thisfile_asf_headerobject['headerobjects']; $HeaderObjectsCounter++) { for ($HeaderObjectsCounter = 0; $HeaderObjectsCounter < $thisfile_asf_headerobject['headerobjects']; $HeaderObjectsCounter++) {
@ -134,7 +132,6 @@ class getid3_asf
$offset += 8; $offset += 8;
$thisfile_asf_filepropertiesobject['preroll'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8)); $thisfile_asf_filepropertiesobject['preroll'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
$offset += 8; $offset += 8;
$ThisFileInfo['playtime_seconds'] = ($thisfile_asf_filepropertiesobject['play_duration'] / 10000000) - ($thisfile_asf_filepropertiesobject['preroll'] / 1000);
$thisfile_asf_filepropertiesobject['flags_raw'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4)); $thisfile_asf_filepropertiesobject['flags_raw'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
$offset += 4; $offset += 4;
$thisfile_asf_filepropertiesobject['flags']['broadcast'] = (bool) ($thisfile_asf_filepropertiesobject['flags_raw'] & 0x0001); $thisfile_asf_filepropertiesobject['flags']['broadcast'] = (bool) ($thisfile_asf_filepropertiesobject['flags_raw'] & 0x0001);
@ -146,8 +143,25 @@ class getid3_asf
$offset += 4; $offset += 4;
$thisfile_asf_filepropertiesobject['max_bitrate'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4)); $thisfile_asf_filepropertiesobject['max_bitrate'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
$offset += 4; $offset += 4;
//$ThisFileInfo['bitrate'] = $thisfile_asf_filepropertiesobject['max_bitrate'];
$ThisFileInfo['bitrate'] = ($thisfile_asf_filepropertiesobject['filesize'] * 8) / $ThisFileInfo['playtime_seconds']; if ($thisfile_asf_filepropertiesobject['flags']['broadcast']) {
// broadcast flag is set, some values invalid
unset($thisfile_asf_filepropertiesobject['filesize']);
unset($thisfile_asf_filepropertiesobject['data_packets']);
unset($thisfile_asf_filepropertiesobject['play_duration']);
unset($thisfile_asf_filepropertiesobject['send_duration']);
unset($thisfile_asf_filepropertiesobject['min_packet_size']);
unset($thisfile_asf_filepropertiesobject['max_packet_size']);
} else {
// broadcast flag NOT set, perform calculations
$ThisFileInfo['playtime_seconds'] = ($thisfile_asf_filepropertiesobject['play_duration'] / 10000000) - ($thisfile_asf_filepropertiesobject['preroll'] / 1000);
//$ThisFileInfo['bitrate'] = $thisfile_asf_filepropertiesobject['max_bitrate'];
$ThisFileInfo['bitrate'] = ((isset($thisfile_asf_filepropertiesobject['filesize']) ? $thisfile_asf_filepropertiesobject['filesize'] : $ThisFileInfo['filesize']) * 8) / $ThisFileInfo['playtime_seconds'];
}
break; break;
case GETID3_ASF_Stream_Properties_Object: case GETID3_ASF_Stream_Properties_Object:
@ -387,7 +401,6 @@ class getid3_asf
default: default:
$ThisFileInfo['warning'][] = 'unknown frequency: "'.$AudioCodecFrequency.'" ('.$this->TrimConvert($thisfile_asf_codeclistobject_codecentries_current['description']).')'; $ThisFileInfo['warning'][] = 'unknown frequency: "'.$AudioCodecFrequency.'" ('.$this->TrimConvert($thisfile_asf_codeclistobject_codecentries_current['description']).')';
// return false;
break; break;
} }
@ -789,10 +802,12 @@ class getid3_asf
$tempfilehandle = fopen($tempfile, "rb"); $tempfilehandle = fopen($tempfile, "rb");
$id3 = new getid3_id3v2($tempfilehandle, $tempThisfileInfo); $id3 = new getid3_id3v2($tempfilehandle, $tempThisfileInfo);
unset($id3);
fclose($tempfilehandle); fclose($tempfilehandle);
unlink($tempfile); unlink($tempfile);
$ThisFileInfo['id3v2'] = $tempThisfileInfo['id3v2']; $ThisFileInfo['id3v2'] = $tempThisfileInfo['id3v2'];
unset($tempThisfileInfo);
} }
break; break;
@ -900,6 +915,7 @@ class getid3_asf
$thisfile_asf_paddingobject['objectsize'] = $NextObjectSize; $thisfile_asf_paddingobject['objectsize'] = $NextObjectSize;
$thisfile_asf_paddingobject['padding_length'] = $thisfile_asf_paddingobject['objectsize'] - 16 - 8; $thisfile_asf_paddingobject['padding_length'] = $thisfile_asf_paddingobject['objectsize'] - 16 - 8;
$thisfile_asf_paddingobject['padding'] = substr($ASFHeaderData, $offset, $thisfile_asf_paddingobject['padding_length']); $thisfile_asf_paddingobject['padding'] = substr($ASFHeaderData, $offset, $thisfile_asf_paddingobject['padding_length']);
$offset += ($NextObjectSize - 16 - 8);
break; break;
case GETID3_ASF_Extended_Content_Encryption_Object: case GETID3_ASF_Extended_Content_Encryption_Object:
@ -1001,6 +1017,7 @@ class getid3_asf
$thisfile_audio['streams'][$streamnumber]['wformattag'] = $thisfile_asf_audiomedia_currentstream['raw']['wFormatTag']; $thisfile_audio['streams'][$streamnumber]['wformattag'] = $thisfile_asf_audiomedia_currentstream['raw']['wFormatTag'];
$thisfile_audio['streams'][$streamnumber]['lossless'] = $thisfile_audio['lossless']; $thisfile_audio['streams'][$streamnumber]['lossless'] = $thisfile_audio['lossless'];
$thisfile_audio['streams'][$streamnumber]['bitrate'] = $thisfile_audio['bitrate']; $thisfile_audio['streams'][$streamnumber]['bitrate'] = $thisfile_audio['bitrate'];
$thisfile_audio['streams'][$streamnumber]['dataformat'] = 'wma';
unset($thisfile_audio['streams'][$streamnumber]['raw']); unset($thisfile_audio['streams'][$streamnumber]['raw']);
$thisfile_asf_audiomedia_currentstream['codec_data_size'] = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $audiomediaoffset, 2)); $thisfile_asf_audiomedia_currentstream['codec_data_size'] = getid3_lib::LittleEndian2Int(substr($streamdata['type_specific_data'], $audiomediaoffset, 2));
@ -1071,7 +1088,7 @@ class getid3_asf
foreach ($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'] as $dummy => $dataarray) { foreach ($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'] as $dummy => $dataarray) {
if (@$dataarray['flags']['stream_number'] == $streamnumber) { if (@$dataarray['flags']['stream_number'] == $streamnumber) {
$thisfile_asf_videomedia_currentstream['bitrate'] = $dataarray['bitrate']; $thisfile_asf_videomedia_currentstream['bitrate'] = $dataarray['bitrate'];
$thisfile_video['streams'][$streamnumber]['bitrate'] = $dataarray['bitrate']; $thisfile_video['streams'][$streamnumber]['bitrate'] = $dataarray['bitrate'];
$thisfile_video['bitrate'] += $dataarray['bitrate']; $thisfile_video['bitrate'] += $dataarray['bitrate'];
break; break;
} }
@ -1282,6 +1299,12 @@ class getid3_asf
case 'WMV1': case 'WMV1':
case 'WMV2': case 'WMV2':
case 'WMV3': case 'WMV3':
case 'MSS1':
case 'MSS2':
case 'WMVA':
case 'WVC1':
case 'WMVP':
case 'WVP2':
$thisfile_video['dataformat'] = 'wmv'; $thisfile_video['dataformat'] = 'wmv';
$ThisFileInfo['mime_type'] = 'video/x-ms-wmv'; $ThisFileInfo['mime_type'] = 'video/x-ms-wmv';
break; break;
@ -1363,7 +1386,22 @@ class getid3_asf
$thisfile_video['pixel_aspect_ratio'] = (isset($thisfile_audio['pixel_aspect_ratio']) ? $thisfile_audio['pixel_aspect_ratio'] : (float) 1); $thisfile_video['pixel_aspect_ratio'] = (isset($thisfile_audio['pixel_aspect_ratio']) ? $thisfile_audio['pixel_aspect_ratio'] : (float) 1);
$thisfile_video['dataformat'] = (!empty($thisfile_video['dataformat']) ? $thisfile_video['dataformat'] : 'asf'); $thisfile_video['dataformat'] = (!empty($thisfile_video['dataformat']) ? $thisfile_video['dataformat'] : 'asf');
} }
if (!empty($thisfile_video['streams'])) {
$thisfile_video['streams']['resolution_x'] = 0;
$thisfile_video['streams']['resolution_y'] = 0;
foreach ($thisfile_video['streams'] as $key => $valuearray) {
if (($valuearray['resolution_x'] > $thisfile_video['streams']['resolution_x']) || ($valuearray['resolution_y'] > $thisfile_video['streams']['resolution_y'])) {
$thisfile_video['resolution_x'] = $valuearray['resolution_x'];
$thisfile_video['resolution_y'] = $valuearray['resolution_y'];
}
}
}
$ThisFileInfo['bitrate'] = @$thisfile_audio['bitrate'] + @$thisfile_video['bitrate']; $ThisFileInfo['bitrate'] = @$thisfile_audio['bitrate'] + @$thisfile_video['bitrate'];
if ((!isset($ThisFileInfo['playtime_seconds']) || ($ThisFileInfo['playtime_seconds'] <= 0)) && ($ThisFileInfo['bitrate'] > 0)) {
$ThisFileInfo['playtime_seconds'] = ($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset']) / ($ThisFileInfo['bitrate'] / 8);
}
return true; return true;
} }

View File

@ -11,14 +11,19 @@
// minor modifications by James Heinrich <info@getid3.org> // // minor modifications by James Heinrich <info@getid3.org> //
// * version 0.1.1 (15 July 2005) // // * version 0.1.1 (15 July 2005) //
// // // //
// Support for On2 VP6 codec and meta information by // // Support for On2 VP6 codec and meta information //
// Steve Webster <steve.webster@featurecreep.com> // // by Steve Webster <steve.webster@featurecreep.com> //
// * version 0.2 (22 February 2006) // // * version 0.2 (22 February 2006) //
// // // //
// Modified to not read entire file into memory // // Modified to not read entire file into memory //
// by James Heinrich <info@getid3.org> // // by James Heinrich <info@getid3.org> //
// * version 0.3 (15 June 2006) // // * version 0.3 (15 June 2006) //
// // // //
// Bugfixes for incorrectly parsed FLV dimensions //
// and incorrect parsing of onMetaTag //
// by Evgeny Moysevich <moysevich@gmail.com> //
// * version 0.4 (07 December 2007) //
// //
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// // // //
// module.audio-video.flv.php // // module.audio-video.flv.php //
@ -39,6 +44,7 @@ class getid3_flv
{ {
function getid3_flv(&$fd, &$ThisFileInfo, $ReturnAllTagData=false) { function getid3_flv(&$fd, &$ThisFileInfo, $ReturnAllTagData=false) {
//$start_time = microtime(true);
fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET); fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
$FLVdataLength = $ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']; $FLVdataLength = $ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'];
@ -64,15 +70,13 @@ class getid3_flv
if ($FrameSizeDataLength > $FLVheaderFrameLength) { if ($FrameSizeDataLength > $FLVheaderFrameLength) {
fseek($fd, $FrameSizeDataLength - $FLVheaderFrameLength, SEEK_CUR); fseek($fd, $FrameSizeDataLength - $FLVheaderFrameLength, SEEK_CUR);
} }
//echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
$Duration = 0; $Duration = 0;
while ((ftell($fd) + 1) < $ThisFileInfo['avdataend']) { $found_video = false;
//if (!$ThisFileInfo['flv']['header']['hasAudio'] || isset($ThisFileInfo['flv']['audio']['audioFormat'])) { $found_audio = false;
// if (!$ThisFileInfo['flv']['header']['hasVideo'] || isset($ThisFileInfo['flv']['video']['videoCodec'])) { $found_meta = false;
// break; while ((ftell($fd) + 16) < $ThisFileInfo['avdataend']) {
// }
//}
$ThisTagHeader = fread($fd, 16); $ThisTagHeader = fread($fd, 16);
$PreviousTagLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 0, 4)); $PreviousTagLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 0, 4));
@ -81,10 +85,16 @@ class getid3_flv
$Timestamp = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 8, 3)); $Timestamp = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 8, 3));
$LastHeaderByte = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 15, 1)); $LastHeaderByte = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 15, 1));
$NextOffset = ftell($fd) - 1 + $DataLength; $NextOffset = ftell($fd) - 1 + $DataLength;
if ($Timestamp > $Duration) {
$Duration = $Timestamp;
}
//echo __LINE__.'['.ftell($fd).']=('.$TagType.')='.number_format(microtime(true) - $start_time, 3).'<br>';
switch ($TagType) { switch ($TagType) {
case GETID3_FLV_TAG_AUDIO: case GETID3_FLV_TAG_AUDIO:
if (!isset($ThisFileInfo['flv']['audio']['audioFormat'])) { if (!$found_audio) {
$found_audio = true;
$ThisFileInfo['flv']['audio']['audioFormat'] = $LastHeaderByte & 0x07; $ThisFileInfo['flv']['audio']['audioFormat'] = $LastHeaderByte & 0x07;
$ThisFileInfo['flv']['audio']['audioRate'] = ($LastHeaderByte & 0x30) / 0x10; $ThisFileInfo['flv']['audio']['audioRate'] = ($LastHeaderByte & 0x30) / 0x10;
$ThisFileInfo['flv']['audio']['audioSampleSize'] = ($LastHeaderByte & 0x40) / 0x40; $ThisFileInfo['flv']['audio']['audioSampleSize'] = ($LastHeaderByte & 0x40) / 0x40;
@ -93,7 +103,8 @@ class getid3_flv
break; break;
case GETID3_FLV_TAG_VIDEO: case GETID3_FLV_TAG_VIDEO:
if (!isset($ThisFileInfo['flv']['video']['videoCodec'])) { if (!$found_video) {
$found_video = true;
$ThisFileInfo['flv']['video']['videoCodec'] = $LastHeaderByte & 0x07; $ThisFileInfo['flv']['video']['videoCodec'] = $LastHeaderByte & 0x07;
$FLVvideoHeader = fread($fd, 11); $FLVvideoHeader = fread($fd, 11);
@ -105,22 +116,28 @@ class getid3_flv
$ThisFileInfo['flv']['header']['videoSizeType'] = $PictureSizeType; $ThisFileInfo['flv']['header']['videoSizeType'] = $PictureSizeType;
switch ($PictureSizeType) { switch ($PictureSizeType) {
case 0: case 0:
$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2)); //$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2));
$PictureSizeEnc <<= 1; //$PictureSizeEnc <<= 1;
$ThisFileInfo['video']['resolution_x'] = ($PictureSizeEnc & 0xFF00) >> 8; //$ThisFileInfo['video']['resolution_x'] = ($PictureSizeEnc & 0xFF00) >> 8;
$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 2)); //$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 2));
$PictureSizeEnc <<= 1; //$PictureSizeEnc <<= 1;
$ThisFileInfo['video']['resolution_y'] = ($PictureSizeEnc & 0xFF00) >> 8; //$ThisFileInfo['video']['resolution_y'] = ($PictureSizeEnc & 0xFF00) >> 8;
$PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 2));
$PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2));
$PictureSizeEnc['x'] >>= 7;
$PictureSizeEnc['y'] >>= 7;
$ThisFileInfo['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xFF;
$ThisFileInfo['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xFF;
break; break;
case 1: case 1:
$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 4)); $PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 3));
$PictureSizeEnc <<= 1; $PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 3));
$ThisFileInfo['video']['resolution_x'] = ($PictureSizeEnc & 0xFFFF0000) >> 16; $PictureSizeEnc['x'] >>= 7;
$PictureSizeEnc['y'] >>= 7;
$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 7, 4)); $ThisFileInfo['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xFFFF;
$PictureSizeEnc <<= 1; $ThisFileInfo['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xFFFF;
$ThisFileInfo['video']['resolution_y'] = ($PictureSizeEnc & 0xFFFF0000) >> 16;
break; break;
case 2: case 2:
@ -160,16 +177,18 @@ class getid3_flv
// Meta tag // Meta tag
case GETID3_FLV_TAG_META: case GETID3_FLV_TAG_META:
if (!$found_meta) {
$found_meta = true;
fseek($fd, -1, SEEK_CUR);
$reader = new AMFReader(new AMFStream(fread($fd, $DataLength)));
$eventName = $reader->readData();
$ThisFileInfo['meta'][$eventName] = $reader->readData();
unset($reader);
fseek($fd, -1, SEEK_CUR); $ThisFileInfo['video']['frame_rate'] = @$ThisFileInfo['meta']['onMetaData']['framerate'];
$reader = new AMFReader(new AMFStream(fread($fd, $DataLength))); $ThisFileInfo['video']['resolution_x'] = @$ThisFileInfo['meta']['onMetaData']['width'];
$eventName = $reader->readData(); $ThisFileInfo['video']['resolution_y'] = @$ThisFileInfo['meta']['onMetaData']['height'];
$ThisFileInfo['meta'][$eventName] = $reader->readData(); }
unset($reader);
$ThisFileInfo['video']['frame_rate'] = $ThisFileInfo['meta']['onMetaData']['framerate'];
$ThisFileInfo['video']['resolution_x'] = $ThisFileInfo['meta']['onMetaData']['width'];
$ThisFileInfo['video']['resolution_y'] = $ThisFileInfo['meta']['onMetaData']['height'];
break; break;
default: default:
@ -177,15 +196,12 @@ class getid3_flv
break; break;
} }
if ($Timestamp > $Duration) {
$Duration = $Timestamp;
}
fseek($fd, $NextOffset, SEEK_SET); fseek($fd, $NextOffset, SEEK_SET);
} }
$ThisFileInfo['playtime_seconds'] = $Duration / 1000; if ($ThisFileInfo['playtime_seconds'] = $Duration / 1000) {
$ThisFileInfo['bitrate'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $ThisFileInfo['playtime_seconds']; $ThisFileInfo['bitrate'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $ThisFileInfo['playtime_seconds'];
}
if ($ThisFileInfo['flv']['header']['hasAudio']) { if ($ThisFileInfo['flv']['header']['hasAudio']) {
$ThisFileInfo['audio']['codec'] = $this->FLVaudioFormat($ThisFileInfo['flv']['audio']['audioFormat']); $ThisFileInfo['audio']['codec'] = $this->FLVaudioFormat($ThisFileInfo['flv']['audio']['audioFormat']);
@ -340,8 +356,8 @@ class AMFReader {
$value = null; $value = null;
$type = $this->stream->readByte(); $type = $this->stream->readByte();
switch ($type) {
switch($type) {
// Double // Double
case 0: case 0:
$value = $this->readDouble(); $value = $this->readDouble();
@ -420,21 +436,18 @@ class AMFReader {
function readObject() { function readObject() {
// Get highest numerical index - ignored // Get highest numerical index - ignored
$highestIndex = $this->stream->readLong(); // $highestIndex = $this->stream->readLong();
$data = array(); $data = array();
while ($key = $this->stream->readUTF()) { while ($key = $this->stream->readUTF()) {
// Mixed array record ends with empty string (0x00 0x00) and 0x09
if (($key == '') && ($this->stream->peekByte() == 0x09)) {
// Consume byte
$this->stream->readByte();
break;
}
$data[$key] = $this->readData(); $data[$key] = $this->readData();
} }
// Mixed array record ends with empty string (0x00 0x00) and 0x09
if (($key == '') && ($this->stream->peekByte() == 0x09)) {
// Consume byte
$this->stream->readByte();
}
return $data; return $data;
} }
@ -445,32 +458,27 @@ class AMFReader {
$data = array(); $data = array();
while ($key = $this->stream->readUTF()) { while ($key = $this->stream->readUTF()) {
// Mixed array record ends with empty string (0x00 0x00) and 0x09
if (($key == '') && ($this->stream->peekByte() == 0x09)) {
// Consume byte
$this->stream->readByte();
break;
}
if (is_numeric($key)) { if (is_numeric($key)) {
$key = (float) $key; $key = (float) $key;
} }
$data[$key] = $this->readData(); $data[$key] = $this->readData();
} }
// Mixed array record ends with empty string (0x00 0x00) and 0x09
if (($key == '') && ($this->stream->peekByte() == 0x09)) {
// Consume byte
$this->stream->readByte();
}
return $data; return $data;
} }
function readArray() { function readArray() {
$length = $this->stream->readLong(); $length = $this->stream->readLong();
$data = array(); $data = array();
for ($i = 0; $i < count($length); $i++) { for ($i = 0; $i < $length; $i++) {
$data[] = $this->readData(); $data[] = $this->readData();
} }
return $data; return $data;
} }

File diff suppressed because it is too large Load Diff

View File

@ -29,11 +29,21 @@ class getid3_quicktime
$atomcounter = 0; $atomcounter = 0;
while ($offset < $ThisFileInfo['avdataend']) { while ($offset < $ThisFileInfo['avdataend']) {
if ($offset >= pow(2, 31)) {
$ThisFileInfo['error'][] = 'Unable to parse atom at offset '.$offset.' because beyond 2GB limit of PHP filesystem functions';
break;
}
fseek($fd, $offset, SEEK_SET); fseek($fd, $offset, SEEK_SET);
$AtomHeader = fread($fd, 8); $AtomHeader = fread($fd, 8);
$atomsize = getid3_lib::BigEndian2Int(substr($AtomHeader, 0, 4)); $atomsize = getid3_lib::BigEndian2Int(substr($AtomHeader, 0, 4));
$atomname = substr($AtomHeader, 4, 4); $atomname = substr($AtomHeader, 4, 4);
// 64-bit MOV patch by jlegateØktnc*com
if ($atomsize == 1) {
$atomsize = getid3_lib::BigEndian2Int(fread($fd, 8));
}
$ThisFileInfo['quicktime'][$atomname]['name'] = $atomname; $ThisFileInfo['quicktime'][$atomname]['name'] = $atomname;
$ThisFileInfo['quicktime'][$atomname]['size'] = $atomsize; $ThisFileInfo['quicktime'][$atomname]['size'] = $atomsize;
$ThisFileInfo['quicktime'][$atomname]['offset'] = $offset; $ThisFileInfo['quicktime'][$atomname]['offset'] = $offset;
@ -105,7 +115,17 @@ class getid3_quicktime
if (isset($ThisFileInfo['bitrate']) && !isset($ThisFileInfo['audio']['bitrate']) && !isset($ThisFileInfo['quicktime']['video'])) { if (isset($ThisFileInfo['bitrate']) && !isset($ThisFileInfo['audio']['bitrate']) && !isset($ThisFileInfo['quicktime']['video'])) {
$ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['bitrate']; $ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['bitrate'];
} }
if (@$ThisFileInfo['playtime_seconds'] && !isset($ThisFileInfo['video']['frame_rate']) && !empty($ThisFileInfo['quicktime']['stts_framecount'])) {
foreach ($ThisFileInfo['quicktime']['stts_framecount'] as $key => $samples_count) {
$samples_per_second = $samples_count / $ThisFileInfo['playtime_seconds'];
if ($samples_per_second > 240) {
// has to be audio samples
} else {
$ThisFileInfo['video']['frame_rate'] = $samples_per_second;
break;
}
}
}
if (($ThisFileInfo['audio']['dataformat'] == 'mp4') && empty($ThisFileInfo['video']['resolution_x'])) { if (($ThisFileInfo['audio']['dataformat'] == 'mp4') && empty($ThisFileInfo['video']['resolution_x'])) {
$ThisFileInfo['fileformat'] = 'mp4'; $ThisFileInfo['fileformat'] = 'mp4';
$ThisFileInfo['mime_type'] = 'audio/mp4'; $ThisFileInfo['mime_type'] = 'audio/mp4';
@ -146,7 +166,6 @@ class getid3_quicktime
case 'minf': // Media INFormation container atom case 'minf': // Media INFormation container atom
case 'dinf': // Data INFormation container atom case 'dinf': // Data INFormation container atom
case 'udta': // User DaTA container atom case 'udta': // User DaTA container atom
case 'stbl': // Sample TaBLe container atom
case 'cmov': // Compressed MOVie container atom case 'cmov': // Compressed MOVie container atom
case 'rmra': // Reference Movie Record Atom case 'rmra': // Reference Movie Record Atom
case 'rmda': // Reference Movie Descriptor Atom case 'rmda': // Reference Movie Descriptor Atom
@ -154,6 +173,45 @@ class getid3_quicktime
$atomstructure['subatoms'] = $this->QuicktimeParseContainerAtom($atomdata, $ThisFileInfo, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms); $atomstructure['subatoms'] = $this->QuicktimeParseContainerAtom($atomdata, $ThisFileInfo, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
break; break;
case 'stbl': // Sample TaBLe container atom
$atomstructure['subatoms'] = $this->QuicktimeParseContainerAtom($atomdata, $ThisFileInfo, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
$isVideo = false;
$framerate = 0;
$framecount = 0;
foreach ($atomstructure['subatoms'] as $key => $value_array) {
if (isset($value_array['sample_description_table'])) {
foreach ($value_array['sample_description_table'] as $key2 => $value_array2) {
if (isset($value_array2['data_format'])) {
switch ($value_array2['data_format']) {
case 'avc1':
case 'mp4v':
// video data
$isVideo = true;
break;
case 'mp4a':
// audio data
break;
}
}
}
} elseif (isset($value_array['time_to_sample_table'])) {
foreach ($value_array['time_to_sample_table'] as $key2 => $value_array2) {
if (isset($value_array2['sample_count']) && isset($value_array2['sample_duration'])) {
$framerate = round($ThisFileInfo['quicktime']['time_scale'] / $value_array2['sample_duration'], 3);
$framecount = $value_array2['sample_count'];
}
}
}
}
if ($isVideo && $framerate) {
$ThisFileInfo['quicktime']['video']['frame_rate'] = $framerate;
$ThisFileInfo['video']['frame_rate'] = $ThisFileInfo['quicktime']['video']['frame_rate'];
}
if ($isVideo && $framecount) {
$ThisFileInfo['quicktime']['video']['frame_count'] = $framecount;
}
break;
case '©cpy': case '©cpy':
case '©day': case '©day':
@ -396,9 +454,11 @@ class getid3_quicktime
$atomstructure['sample_description_table'][$i]['audio_sample_rate'] = getid3_lib::FixedPoint16_16(substr($atomstructure['sample_description_table'][$i]['data'], 16, 4)); $atomstructure['sample_description_table'][$i]['audio_sample_rate'] = getid3_lib::FixedPoint16_16(substr($atomstructure['sample_description_table'][$i]['data'], 16, 4));
switch ($atomstructure['sample_description_table'][$i]['data_format']) { switch ($atomstructure['sample_description_table'][$i]['data_format']) {
case 'avc1':
case 'mp4v': case 'mp4v':
$ThisFileInfo['fileformat'] = 'mp4'; $ThisFileInfo['fileformat'] = 'mp4';
$ThisFileInfo['error'][] = 'This version ('.GETID3_VERSION.') of getID3() does not fully support MPEG-4 audio/video streams'; $ThisFileInfo['video']['fourcc'] = $atomstructure['sample_description_table'][$i]['data_format'];
$ThisFileInfo['warning'][] = 'This version ('.GETID3_VERSION.') of getID3() does not fully support MPEG-4 audio/video streams';
break; break;
case 'qtvr': case 'qtvr':
@ -508,44 +568,48 @@ class getid3_quicktime
case 'stts': // Sample Table Time-to-Sample atom case 'stts': // Sample Table Time-to-Sample atom
//if ($ParseAllPossibleAtoms) { $atomstructure['version'] = getid3_lib::BigEndian2Int(substr($atomdata, 0, 1));
$atomstructure['version'] = getid3_lib::BigEndian2Int(substr($atomdata, 0, 1)); $atomstructure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atomdata, 1, 3)); // hardcoded: 0x0000
$atomstructure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atomdata, 1, 3)); // hardcoded: 0x0000 $atomstructure['number_entries'] = getid3_lib::BigEndian2Int(substr($atomdata, 4, 4));
$atomstructure['number_entries'] = getid3_lib::BigEndian2Int(substr($atomdata, 4, 4)); $sttsEntriesDataOffset = 8;
$sttsEntriesDataOffset = 8; //$FrameRateCalculatorArray = array();
$FrameRateCalculatorArray = array(); $frames_count = 0;
for ($i = 0; $i < $atomstructure['number_entries']; $i++) { for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
$atomstructure['time_to_sample_table'][$i]['sample_count'] = getid3_lib::BigEndian2Int(substr($atomdata, $sttsEntriesDataOffset, 4)); $atomstructure['time_to_sample_table'][$i]['sample_count'] = getid3_lib::BigEndian2Int(substr($atomdata, $sttsEntriesDataOffset, 4));
$sttsEntriesDataOffset += 4; $sttsEntriesDataOffset += 4;
$atomstructure['time_to_sample_table'][$i]['sample_duration'] = getid3_lib::BigEndian2Int(substr($atomdata, $sttsEntriesDataOffset, 4)); $atomstructure['time_to_sample_table'][$i]['sample_duration'] = getid3_lib::BigEndian2Int(substr($atomdata, $sttsEntriesDataOffset, 4));
$sttsEntriesDataOffset += 4; $sttsEntriesDataOffset += 4;
if (!empty($ThisFileInfo['quicktime']['time_scale']) && (@$atomstructure['time_to_sample_table'][$i]['sample_duration'] > 0)) { $frames_count += $atomstructure['time_to_sample_table'][$i]['sample_count'];
$stts_new_framerate = $ThisFileInfo['quicktime']['time_scale'] / $atomstructure['time_to_sample_table'][$i]['sample_duration'];
if ($stts_new_framerate <= 60) { // THIS SECTION REPLACED WITH CODE IN "stbl" ATOM
// some atoms have durations of "1" giving a very large framerate, which probably is not right //if (!empty($ThisFileInfo['quicktime']['time_scale']) && (@$atomstructure['time_to_sample_table'][$i]['sample_duration'] > 0)) {
$ThisFileInfo['video']['frame_rate'] = max(@$ThisFileInfo['video']['frame_rate'], $stts_new_framerate); // $stts_new_framerate = $ThisFileInfo['quicktime']['time_scale'] / $atomstructure['time_to_sample_table'][$i]['sample_duration'];
} // if ($stts_new_framerate <= 60) {
} // // some atoms have durations of "1" giving a very large framerate, which probably is not right
//@$FrameRateCalculatorArray[($ThisFileInfo['quicktime']['time_scale'] / $atomstructure['time_to_sample_table'][$i]['sample_duration'])] += $atomstructure['time_to_sample_table'][$i]['sample_count']; // $ThisFileInfo['video']['frame_rate'] = max(@$ThisFileInfo['video']['frame_rate'], $stts_new_framerate);
}
//$sttsFramesTotal = 0;
//$sttsSecondsTotal = 0;
//foreach ($FrameRateCalculatorArray as $frames_per_second => $frame_count) {
// if (($frames_per_second > 60) || ($frames_per_second < 1)) {
// // not video FPS information, probably audio information
// $sttsFramesTotal = 0;
// $sttsSecondsTotal = 0;
// break;
// }
// $sttsFramesTotal += $frame_count;
// $sttsSecondsTotal += $frame_count / $frames_per_second;
//}
//if (($sttsFramesTotal > 0) && ($sttsSecondsTotal > 0)) {
// if (($sttsFramesTotal / $sttsSecondsTotal) > @$ThisFileInfo['video']['frame_rate']) {
// $ThisFileInfo['video']['frame_rate'] = $sttsFramesTotal / $sttsSecondsTotal;
// } // }
//} //}
//
//@$FrameRateCalculatorArray[($ThisFileInfo['quicktime']['time_scale'] / $atomstructure['time_to_sample_table'][$i]['sample_duration'])] += $atomstructure['time_to_sample_table'][$i]['sample_count'];
}
$ThisFileInfo['quicktime']['stts_framecount'][] = $frames_count;
//$sttsFramesTotal = 0;
//$sttsSecondsTotal = 0;
//foreach ($FrameRateCalculatorArray as $frames_per_second => $frame_count) {
// if (($frames_per_second > 60) || ($frames_per_second < 1)) {
// // not video FPS information, probably audio information
// $sttsFramesTotal = 0;
// $sttsSecondsTotal = 0;
// break;
// }
// $sttsFramesTotal += $frame_count;
// $sttsSecondsTotal += $frame_count / $frames_per_second;
//}
//if (($sttsFramesTotal > 0) && ($sttsSecondsTotal > 0)) {
// if (($sttsFramesTotal / $sttsSecondsTotal) > @$ThisFileInfo['video']['frame_rate']) {
// $ThisFileInfo['video']['frame_rate'] = $sttsFramesTotal / $sttsSecondsTotal;
// }
//} //}
break; break;
@ -613,6 +677,20 @@ class getid3_quicktime
break; break;
case 'co64': // Chunk Offset 64-bit (version of "stco" that supports > 2GB files)
if ($ParseAllPossibleAtoms) {
$atomstructure['version'] = getid3_lib::BigEndian2Int(substr($atomdata, 0, 1));
$atomstructure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atomdata, 1, 3)); // hardcoded: 0x0000
$atomstructure['number_entries'] = getid3_lib::BigEndian2Int(substr($atomdata, 4, 4));
$stcoEntriesDataOffset = 8;
for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
$atomstructure['chunk_offset_table'][$i] = getid3_lib::BigEndian2Int(substr($atomdata, $stcoEntriesDataOffset, 8));
$stcoEntriesDataOffset += 8;
}
}
break;
case 'dref': // Data REFerence atom case 'dref': // Data REFerence atom
$atomstructure['version'] = getid3_lib::BigEndian2Int(substr($atomdata, 0, 1)); $atomstructure['version'] = getid3_lib::BigEndian2Int(substr($atomdata, 0, 1));
$atomstructure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atomdata, 1, 3)); // hardcoded: 0x0000 $atomstructure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atomdata, 1, 3)); // hardcoded: 0x0000
@ -697,6 +775,8 @@ class getid3_quicktime
$ThisFileInfo['error'][] = 'Corrupt Quicktime file: mdhd.time_scale == zero'; $ThisFileInfo['error'][] = 'Corrupt Quicktime file: mdhd.time_scale == zero';
return false; return false;
} }
$ThisFileInfo['quicktime']['time_scale'] = max(@$ThisFileInfo['quicktime']['time_scale'], $atomstructure['time_scale']);
$atomstructure['creation_time_unix'] = getid3_lib::DateMac2Unix($atomstructure['creation_time']); $atomstructure['creation_time_unix'] = getid3_lib::DateMac2Unix($atomstructure['creation_time']);
$atomstructure['modify_time_unix'] = getid3_lib::DateMac2Unix($atomstructure['modify_time']); $atomstructure['modify_time_unix'] = getid3_lib::DateMac2Unix($atomstructure['modify_time']);
$atomstructure['playtime_seconds'] = $atomstructure['duration'] / $atomstructure['time_scale']; $atomstructure['playtime_seconds'] = $atomstructure['duration'] / $atomstructure['time_scale'];
@ -811,7 +891,7 @@ class getid3_quicktime
} }
$atomstructure['creation_time_unix'] = getid3_lib::DateMac2Unix($atomstructure['creation_time']); $atomstructure['creation_time_unix'] = getid3_lib::DateMac2Unix($atomstructure['creation_time']);
$atomstructure['modify_time_unix'] = getid3_lib::DateMac2Unix($atomstructure['modify_time']); $atomstructure['modify_time_unix'] = getid3_lib::DateMac2Unix($atomstructure['modify_time']);
$ThisFileInfo['quicktime']['time_scale'] = $atomstructure['time_scale']; $ThisFileInfo['quicktime']['time_scale'] = max(@$ThisFileInfo['quicktime']['time_scale'], $atomstructure['time_scale']);
$ThisFileInfo['quicktime']['display_scale'] = $atomstructure['matrix_a']; $ThisFileInfo['quicktime']['display_scale'] = $atomstructure['matrix_a'];
$ThisFileInfo['playtime_seconds'] = $atomstructure['duration'] / $atomstructure['time_scale']; $ThisFileInfo['playtime_seconds'] = $atomstructure['duration'] / $atomstructure['time_scale'];
break; break;
@ -834,8 +914,8 @@ class getid3_quicktime
$atomstructure['matrix_b'] = getid3_lib::FixedPoint16_16(substr($atomdata, 44, 4)); $atomstructure['matrix_b'] = getid3_lib::FixedPoint16_16(substr($atomdata, 44, 4));
$atomstructure['matrix_u'] = getid3_lib::FixedPoint16_16(substr($atomdata, 48, 4)); $atomstructure['matrix_u'] = getid3_lib::FixedPoint16_16(substr($atomdata, 48, 4));
$atomstructure['matrix_c'] = getid3_lib::FixedPoint16_16(substr($atomdata, 52, 4)); $atomstructure['matrix_c'] = getid3_lib::FixedPoint16_16(substr($atomdata, 52, 4));
$atomstructure['matrix_v'] = getid3_lib::FixedPoint16_16(substr($atomdata, 56, 4)); $atomstructure['matrix_d'] = getid3_lib::FixedPoint16_16(substr($atomdata, 56, 4));
$atomstructure['matrix_d'] = getid3_lib::FixedPoint16_16(substr($atomdata, 60, 4)); $atomstructure['matrix_v'] = getid3_lib::FixedPoint16_16(substr($atomdata, 60, 4));
$atomstructure['matrix_x'] = getid3_lib::FixedPoint2_30(substr($atomdata, 64, 4)); $atomstructure['matrix_x'] = getid3_lib::FixedPoint2_30(substr($atomdata, 64, 4));
$atomstructure['matrix_y'] = getid3_lib::FixedPoint2_30(substr($atomdata, 68, 4)); $atomstructure['matrix_y'] = getid3_lib::FixedPoint2_30(substr($atomdata, 68, 4));
$atomstructure['matrix_w'] = getid3_lib::FixedPoint2_30(substr($atomdata, 72, 4)); $atomstructure['matrix_w'] = getid3_lib::FixedPoint2_30(substr($atomdata, 72, 4));

View File

@ -73,8 +73,8 @@ class getid3_real
$ChunkData .= fread($fd, GETID3_FREAD_BUFFER_SIZE - 8); $ChunkData .= fread($fd, GETID3_FREAD_BUFFER_SIZE - 8);
fseek($fd, $thisfile_real_chunks_currentchunk['offset'] + $ChunkSize, SEEK_SET); fseek($fd, $thisfile_real_chunks_currentchunk['offset'] + $ChunkSize, SEEK_SET);
} else { } elseif(($ChunkSize - 8) > 0) {
$ChunkData .= fread($fd, $ChunkSize - 8); $ChunkData .= fread($fd, $ChunkSize - 8);
} }

View File

@ -13,6 +13,7 @@
// Wave, AVI, AIFF/AIFC, (MP3,AC3)/RIFF, Wavpack v3, 8SVX // // Wave, AVI, AIFF/AIFC, (MP3,AC3)/RIFF, Wavpack v3, 8SVX //
// dependencies: module.audio.mp3.php // // dependencies: module.audio.mp3.php //
// module.audio.ac3.php (optional) // // module.audio.ac3.php (optional) //
// module.audio.dts.php (optional) //
// /// // ///
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
@ -63,8 +64,21 @@ class getid3_riff
$ThisFileInfo['fileformat'] = 'riff'; $ThisFileInfo['fileformat'] = 'riff';
$RIFFheaderSize = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($RIFFheader, 4, 4)); $RIFFheaderSize = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($RIFFheader, 4, 4));
$thisfile_riff[$RIFFsubtype] = getid3_riff::ParseRIFF($fd, $thisfile_avdataoffset + 12, $thisfile_avdataoffset + $RIFFheaderSize, $ThisFileInfo);
$thisfile_riff['header_size'] = $RIFFheaderSize; $thisfile_riff['header_size'] = $RIFFheaderSize;
$thisfile_riff[$RIFFsubtype] = getid3_riff::ParseRIFF($fd, $thisfile_avdataoffset + 12, $thisfile_avdataoffset + $RIFFheaderSize, $ThisFileInfo);
fseek($fd, $thisfile_avdataoffset + $RIFFheaderSize);
$nextRIFFheader = fread($fd, 20);
if (substr($nextRIFFheader, 8, 4) == 'RIFF') {
$nextRIFFsize = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($nextRIFFheader, 12, 4));
$nextRIFFtype = substr($nextRIFFheader, 16, 4).'<br>';
$thisfile_riff[$nextRIFFtype]['offset'] = ftell($fd) - 4;
$thisfile_riff[$nextRIFFtype]['size'] = $nextRIFFsize;
$ThisFileInfo['avdataend'] = $thisfile_riff[$nextRIFFtype]['offset'] + $thisfile_riff[$nextRIFFtype]['size'];
$ThisFileInfo['error'][] = 'AVI extends beyond 2GB and PHP filesystem functions cannot read that far, playtime is probably wrong';
$ThisFileInfo['warning'][] = '[avdataend] value may be incorrect, multiple AVIX chunks may be present';
$thisfile_riff[$nextRIFFtype] = getid3_riff::ParseRIFF($fd, $thisfile_riff[$nextRIFFtype]['offset'] + 4, $thisfile_riff[$nextRIFFtype]['offset'] + $thisfile_riff[$nextRIFFtype]['size'], $ThisFileInfo);
}
if ($RIFFsubtype == 'WAVE') { if ($RIFFsubtype == 'WAVE') {
$thisfile_riff_WAVE = &$thisfile_riff['WAVE']; $thisfile_riff_WAVE = &$thisfile_riff['WAVE'];
} }
@ -412,6 +426,33 @@ class getid3_riff
} }
} }
if (isset($thisfile_riff['AVI ']['hdrl']['strl']['indx'])) {
//$bIndexType = array(
// 0x00 => 'AVI_INDEX_OF_INDEXES',
// 0x01 => 'AVI_INDEX_OF_CHUNKS',
// 0x80 => 'AVI_INDEX_IS_DATA',
//);
//$bIndexSubtype = array(
// 0x01 => array(
// 0x01 => 'AVI_INDEX_2FIELD',
// ),
//);
foreach ($thisfile_riff['AVI ']['hdrl']['strl']['indx'] as $streamnumber => $steamdataarray) {
$thisfile_riff_avi_hdrl_strl_indx_stream_data = &$thisfile_riff['AVI ']['hdrl']['strl']['indx'][$streamnumber]['data'];
$thisfile_riff_raw['indx'][$streamnumber]['wLongsPerEntry'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 0, 2));
$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 2, 1));
$thisfile_riff_raw['indx'][$streamnumber]['bIndexType'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 3, 1));
$thisfile_riff_raw['indx'][$streamnumber]['nEntriesInUse'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 4, 4));
$thisfile_riff_raw['indx'][$streamnumber]['dwChunkId'] = substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 8, 4);
$thisfile_riff_raw['indx'][$streamnumber]['dwReserved'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 12, 4));
//$thisfile_riff_raw['indx'][$streamnumber]['bIndexType_name'] = @$bIndexType[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']];
//$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType_name'] = @$bIndexSubtype[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']][$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType']];
unset($thisfile_riff_avi_hdrl_strl_indx_stream_data);
}
}
if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) { if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) {
$avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data']; $avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'];
@ -591,17 +632,18 @@ class getid3_riff
switch ($strhfccType) { switch ($strhfccType) {
case 'vids': case 'vids':
$thisfile_riff_raw_strf_strhfccType_streamindex['biSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 0, 4)); // number of bytes required by the BITMAPINFOHEADER structure $thisfile_riff_raw_strf_strhfccType_streamindex = getid3_riff::ParseBITMAPINFOHEADER(substr($strfData, 0, 40), ($ThisFileInfo['fileformat'] == 'riff'));
$thisfile_riff_raw_strf_strhfccType_streamindex['biWidth'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 4, 4)); // width of the bitmap in pixels //$thisfile_riff_raw_strf_strhfccType_streamindex['biSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 0, 4)); // number of bytes required by the BITMAPINFOHEADER structure
$thisfile_riff_raw_strf_strhfccType_streamindex['biHeight'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 8, 4)); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner //$thisfile_riff_raw_strf_strhfccType_streamindex['biWidth'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 4, 4)); // width of the bitmap in pixels
$thisfile_riff_raw_strf_strhfccType_streamindex['biPlanes'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 12, 2)); // number of color planes on the target device. In most cases this value must be set to 1 //$thisfile_riff_raw_strf_strhfccType_streamindex['biHeight'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 8, 4)); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner
$thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 14, 2)); // Specifies the number of bits per pixels //$thisfile_riff_raw_strf_strhfccType_streamindex['biPlanes'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 12, 2)); // number of color planes on the target device. In most cases this value must be set to 1
$thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'] = substr($strfData, 16, 4); // //$thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 14, 2)); // Specifies the number of bits per pixels
$thisfile_riff_raw_strf_strhfccType_streamindex['biSizeImage'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 20, 4)); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures) //$thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'] = substr($strfData, 16, 4); //
$thisfile_riff_raw_strf_strhfccType_streamindex['biXPelsPerMeter'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 24, 4)); // horizontal resolution, in pixels per metre, of the target device //$thisfile_riff_raw_strf_strhfccType_streamindex['biSizeImage'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 20, 4)); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures)
$thisfile_riff_raw_strf_strhfccType_streamindex['biYPelsPerMeter'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 28, 4)); // vertical resolution, in pixels per metre, of the target device //$thisfile_riff_raw_strf_strhfccType_streamindex['biXPelsPerMeter'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 24, 4)); // horizontal resolution, in pixels per metre, of the target device
$thisfile_riff_raw_strf_strhfccType_streamindex['biClrUsed'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 32, 4)); // actual number of color indices in the color table used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression //$thisfile_riff_raw_strf_strhfccType_streamindex['biYPelsPerMeter'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 28, 4)); // vertical resolution, in pixels per metre, of the target device
$thisfile_riff_raw_strf_strhfccType_streamindex['biClrImportant'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 36, 4)); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important //$thisfile_riff_raw_strf_strhfccType_streamindex['biClrUsed'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 32, 4)); // actual number of color indices in the color table used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression
//$thisfile_riff_raw_strf_strhfccType_streamindex['biClrImportant'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 36, 4)); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important
$thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount']; $thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'];
@ -885,6 +927,7 @@ class getid3_riff
$ThisFileInfo['mpeg'] = $dummy['mpeg']; $ThisFileInfo['mpeg'] = $dummy['mpeg'];
$ThisFileInfo['warning'] = $dummy['warning']; $ThisFileInfo['warning'] = $dummy['warning'];
} }
unset($mpeg_scanner);
} }
} }
break; break;
@ -896,6 +939,20 @@ class getid3_riff
break; break;
} }
if (@$thisfile_riff_raw['fmt ']['wFormatTag'] == 1) {
// http://www.mega-nerd.com/erikd/Blog/Windiots/dts.html
fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
$FirstFourBytes = fread($fd, 4);
if (preg_match('/^\xFF\x1F\x00\xE8/s', $FirstFourBytes)) {
// DTSWAV
$thisfile_audio_dataformat = 'dts';
} elseif (preg_match('/^\x7F\xFF\x80\x01/s', $FirstFourBytes)) {
// DTS, but this probably shouldn't happen
$thisfile_audio_dataformat = 'dts';
}
}
if (isset($thisfile_riff_WAVE['DISP']) && is_array($thisfile_riff_WAVE['DISP'])) { if (isset($thisfile_riff_WAVE['DISP']) && is_array($thisfile_riff_WAVE['DISP'])) {
$thisfile_riff['comments']['title'][] = trim(substr($thisfile_riff_WAVE['DISP'][count($thisfile_riff_WAVE['DISP']) - 1]['data'], 4)); $thisfile_riff['comments']['title'][] = trim(substr($thisfile_riff_WAVE['DISP'][count($thisfile_riff_WAVE['DISP']) - 1]['data'], 4));
} }
@ -1060,11 +1117,15 @@ class getid3_riff
} }
function ParseRIFF(&$fd, $startoffset, $maxoffset, &$ThisFileInfo) { function ParseRIFF(&$fd, $startoffset, $maxoffset, &$ThisFileInfo) {
$maxoffset = min($maxoffset, $ThisFileInfo['avdataend']); $maxoffset = min($maxoffset, $ThisFileInfo['avdataend']);
$RIFFchunk = false; $RIFFchunk = false;
$FoundAllChunksWeNeed = false;
if (($startoffset < 0) || ($startoffset >= pow(2, 31))) {
$ThisFileInfo['warning'][] = 'Unable to ParseRIFF() at '.$startoffset.' because beyond 2GB limit of PHP filesystem functions';
return false;
}
fseek($fd, $startoffset, SEEK_SET); fseek($fd, $startoffset, SEEK_SET);
while (ftell($fd) < $maxoffset) { while (ftell($fd) < $maxoffset) {
@ -1076,8 +1137,8 @@ class getid3_riff
$chunksize = getid3_riff::EitherEndian2Int($ThisFileInfo, fread($fd, 4)); $chunksize = getid3_riff::EitherEndian2Int($ThisFileInfo, fread($fd, 4));
if ($chunksize == 0) { if ($chunksize == 0) {
$ThisFileInfo['error'][] = 'Chunk size at offset '.(ftell($fd) - 4).' is zero. Aborting RIFF parsing.'; $ThisFileInfo['warning'][] = 'Chunk size at offset '.(ftell($fd) - 4).' is zero. Aborting RIFF parsing.';
break; continue;
} }
if (($chunksize % 2) != 0) { if (($chunksize % 2) != 0) {
// all structures are packed on word boundaries // all structures are packed on word boundaries
@ -1087,90 +1148,101 @@ class getid3_riff
switch ($chunkname) { switch ($chunkname) {
case 'LIST': case 'LIST':
$listname = fread($fd, 4); $listname = fread($fd, 4);
switch ($listname) { if (eregi('^(movi|rec )$', $listname)) {
case 'movi': $RIFFchunk[$listname]['offset'] = ftell($fd) - 4;
case 'rec ': $RIFFchunk[$listname]['size'] = $chunksize;
$RIFFchunk[$listname]['offset'] = ftell($fd) - 4;
$RIFFchunk[$listname]['size'] = $chunksize;
static $ParsedAudioStream = false; if ($FoundAllChunksWeNeed) {
if ($ParsedAudioStream) {
// skip over // skip over
} else { } else {
$WhereWeWere = ftell($fd); $WhereWeWere = ftell($fd);
$AudioChunkHeader = fread($fd, 12); $AudioChunkHeader = fread($fd, 12);
$AudioChunkStreamNum = substr($AudioChunkHeader, 0, 2); $AudioChunkStreamNum = substr($AudioChunkHeader, 0, 2);
$AudioChunkStreamType = substr($AudioChunkHeader, 2, 2); $AudioChunkStreamType = substr($AudioChunkHeader, 2, 2);
$AudioChunkSize = getid3_lib::LittleEndian2Int(substr($AudioChunkHeader, 4, 4)); $AudioChunkSize = getid3_lib::LittleEndian2Int(substr($AudioChunkHeader, 4, 4));
if ($AudioChunkStreamType == 'wb') { if ($AudioChunkStreamType == 'wb') {
$FirstFourBytes = substr($AudioChunkHeader, 8, 4); $FirstFourBytes = substr($AudioChunkHeader, 8, 4);
if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) { if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
// MP3
// MP3 if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) { $dummy = $ThisFileInfo;
$dummy = $ThisFileInfo; $dummy['avdataoffset'] = ftell($fd) - 4;
$dummy['avdataoffset'] = ftell($fd) - 4; $dummy['avdataend'] = ftell($fd) + $AudioChunkSize;
$dummy['avdataend'] = ftell($fd) + $AudioChunkSize; getid3_mp3::getOnlyMPEGaudioInfo($fd, $dummy, $dummy['avdataoffset'], false);
getid3_mp3::getOnlyMPEGaudioInfo($fd, $dummy, $dummy['avdataoffset'], false); if (isset($dummy['mpeg']['audio'])) {
if (isset($dummy['mpeg']['audio'])) { $ThisFileInfo = $dummy;
$ThisFileInfo = $dummy; $ThisFileInfo['audio']['dataformat'] = 'mp'.$ThisFileInfo['mpeg']['audio']['layer'];
$ThisFileInfo['audio']['dataformat'] = 'mp'.$ThisFileInfo['mpeg']['audio']['layer']; $ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['mpeg']['audio']['sample_rate'];
$ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['mpeg']['audio']['sample_rate']; $ThisFileInfo['audio']['channels'] = $ThisFileInfo['mpeg']['audio']['channels'];
$ThisFileInfo['audio']['channels'] = $ThisFileInfo['mpeg']['audio']['channels']; $ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['bitrate'];
$ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['bitrate']; $ThisFileInfo['bitrate'] = $ThisFileInfo['audio']['bitrate'];
$ThisFileInfo['bitrate'] = $ThisFileInfo['audio']['bitrate']; $ThisFileInfo['audio']['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']);
$ThisFileInfo['audio']['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']);
}
} }
unset($dummy);
}
} elseif (preg_match('/^\x0B\x77/s', $FirstFourBytes)) { } elseif (preg_match('/^\x0B\x77/s', $FirstFourBytes)) {
// AC3 // AC3
$GETID3_ERRORARRAY = &$ThisFileInfo['warning']; $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) { if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
$dummy = $ThisFileInfo;
$dummy['avdataoffset'] = ftell($fd) - 4;
$dummy['avdataend'] = ftell($fd) + $AudioChunkSize;
$dummy['error'] = array();
$ac3_tag = new getid3_ac3($fd, $dummy);
if (empty($dummy['error'])) {
$ThisFileInfo['audio'] = $dummy['audio'];
$ThisFileInfo['ac3'] = $dummy['ac3'];
$ThisFileInfo['warning'] = $dummy['warning'];
}
$dummy = $ThisFileInfo;
$dummy['avdataoffset'] = ftell($fd) - 4;
$dummy['avdataend'] = ftell($fd) + $AudioChunkSize;
$dummy['error'] = array();
$ac3_tag = new getid3_ac3($fd, $dummy);
if (empty($dummy['error'])) {
$ThisFileInfo['audio'] = $dummy['audio'];
$ThisFileInfo['ac3'] = $dummy['ac3'];
$ThisFileInfo['warning'] = $dummy['warning'];
} }
unset($ac3_tag);
} }
} }
$ParsedAudioStream = true; }
fseek($fd, $WhereWeWere, SEEK_SET);
} $FoundAllChunksWeNeed = true;
fseek($fd, $chunksize - 4, SEEK_CUR); fseek($fd, $WhereWeWere, SEEK_SET);
break;
}
fseek($fd, $chunksize - 4, SEEK_CUR);
//} elseif (ereg('^[0-9]{2}(wb|pc|dc|db)$', $listname)) {
//
// // data chunk, ignore
//
} else {
if (!isset($RIFFchunk[$listname])) {
$RIFFchunk[$listname] = array();
}
$LISTchunkParent = $listname;
$LISTchunkMaxOffset = ftell($fd) - 4 + $chunksize;
if ($parsedChunk = getid3_riff::ParseRIFF($fd, ftell($fd), ftell($fd) + $chunksize - 4, $ThisFileInfo)) {
$RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk);
}
default:
if (!isset($RIFFchunk[$listname])) {
$RIFFchunk[$listname] = array();
}
$LISTchunkParent = $listname;
$LISTchunkMaxOffset = ftell($fd) - 4 + $chunksize;
if ($parsedChunk = getid3_riff::ParseRIFF($fd, ftell($fd), ftell($fd) + $chunksize - 4, $ThisFileInfo)) {
$RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk);
}
break;
} }
break; break;
default: default:
if (eregi('^[0-9]{2}(wb|pc|dc|db)$', $chunkname)) {
$nextoffset = ftell($fd) + $chunksize;
if (($nextoffset < 0) || ($nextoffset >= pow(2, 31))) {
$ThisFileInfo['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond 2GB limit of PHP filesystem functions';
break 2;
}
fseek($fd, $nextoffset, SEEK_SET);
break;
}
$thisindex = 0; $thisindex = 0;
if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) { if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) {
$thisindex = count($RIFFchunk[$chunkname]); $thisindex = count($RIFFchunk[$chunkname]);
@ -1188,7 +1260,16 @@ class getid3_riff
// Probably is MP3 data // Probably is MP3 data
if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($RIFFdataChunkContentsTest, 0, 4))) { if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($RIFFdataChunkContentsTest, 0, 4))) {
getid3_mp3::getOnlyMPEGaudioInfo($fd, $ThisFileInfo, $RIFFchunk[$chunkname][$thisindex]['offset'], false);
// copy info array
$dummy = $ThisFileInfo;
getid3_mp3::getOnlyMPEGaudioInfo($fd, $dummy, $RIFFchunk[$chunkname][$thisindex]['offset'], false);
// use dummy array unless error
if (empty($dummy['error'])) {
$ThisFileInfo = $dummy;
}
} }
} elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 2) == "\x0B\x77")) { } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 2) == "\x0B\x77")) {
@ -1208,6 +1289,7 @@ class getid3_riff
$ThisFileInfo['ac3'] = $dummy['ac3']; $ThisFileInfo['ac3'] = $dummy['ac3'];
$ThisFileInfo['warning'] = $dummy['warning']; $ThisFileInfo['warning'] = $dummy['warning'];
} }
unset($ac3_tag);
} }
@ -1242,6 +1324,7 @@ class getid3_riff
} else { } else {
$ThisFileInfo['error'][] = 'Errors parsing DolbyDigital WAV: '.explode(';', $dummy['error']); $ThisFileInfo['error'][] = 'Errors parsing DolbyDigital WAV: '.explode(';', $dummy['error']);
} }
unset($ac3_tag);
} else { } else {
@ -1264,12 +1347,20 @@ class getid3_riff
// do nothing special, just skip it // do nothing special, just skip it
} }
$nextoffset = $RIFFchunk[$chunkname][$thisindex]['offset'] + 8 + $chunksize;
if (($nextoffset < 0) || ($nextoffset >= pow(2, 31))) {
$ThisFileInfo['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond 2GB limit of PHP filesystem functions';
break 3;
}
fseek($fd, $RIFFchunk[$chunkname][$thisindex]['offset'] + 8 + $chunksize, SEEK_SET); fseek($fd, $RIFFchunk[$chunkname][$thisindex]['offset'] + 8 + $chunksize, SEEK_SET);
break; break;
case 'bext': case 'bext':
case 'cart': case 'cart':
case 'fmt ': case 'fmt ':
case 'strh':
case 'strf':
case 'indx':
case 'MEXT': case 'MEXT':
case 'DISP': case 'DISP':
// always read data in // always read data in
@ -1277,7 +1368,7 @@ class getid3_riff
break; break;
default: default:
if (!empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) { if (!ereg('^[0-9]{2}(wb|pc|dc|db)$', $chunkname) && !empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) {
$RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset']; $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
$RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size'] = $RIFFchunk[$chunkname][$thisindex]['size']; $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size'] = $RIFFchunk[$chunkname][$thisindex]['size'];
unset($RIFFchunk[$chunkname][$thisindex]['offset']); unset($RIFFchunk[$chunkname][$thisindex]['offset']);
@ -1293,7 +1384,12 @@ class getid3_riff
// only read data in if smaller than 2kB // only read data in if smaller than 2kB
$RIFFchunk[$chunkname][$thisindex]['data'] = fread($fd, $chunksize); $RIFFchunk[$chunkname][$thisindex]['data'] = fread($fd, $chunksize);
} else { } else {
fseek($fd, $chunksize, SEEK_CUR); $nextoffset = ftell($fd) + $chunksize;
if (($nextoffset < 0) || ($nextoffset >= pow(2, 31))) {
$ThisFileInfo['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond 2GB limit of PHP filesystem functions';
break 3;
}
fseek($fd, $nextoffset, SEEK_SET);
} }
break; break;
} }
@ -1328,6 +1424,7 @@ class getid3_riff
$ThisFileInfo['error'] = $dummy['error']; $ThisFileInfo['error'] = $dummy['error'];
$ThisFileInfo['tags'] = $dummy['tags']; $ThisFileInfo['tags'] = $dummy['tags'];
$ThisFileInfo['comments'] = $dummy['comments']; $ThisFileInfo['comments'] = $dummy['comments'];
unset($riff);
fclose($fp_temp); fclose($fp_temp);
unlink($tempfile); unlink($tempfile);
return true; return true;
@ -1421,6 +1518,24 @@ class getid3_riff
return true; return true;
} }
function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
// yes it's ugly to instantiate a getid3_lib object here, suggested alternative please?
$getid3_lib = new getid3_lib();
$functionname = ($littleEndian ? 'LittleEndian2Int' : 'BigEndian2Int');
$parsed['biSize'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 0, 4)); // number of bytes required by the BITMAPINFOHEADER structure
$parsed['biWidth'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 4, 4)); // width of the bitmap in pixels
$parsed['biHeight'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 8, 4)); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner
$parsed['biPlanes'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 12, 2)); // number of color planes on the target device. In most cases this value must be set to 1
$parsed['biBitCount'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 14, 2)); // Specifies the number of bits per pixels
$parsed['fourcc'] = substr($BITMAPINFOHEADER, 16, 4); // compression identifier
$parsed['biSizeImage'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 20, 4)); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures)
$parsed['biXPelsPerMeter'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 24, 4)); // horizontal resolution, in pixels per metre, of the target device
$parsed['biYPelsPerMeter'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 28, 4)); // vertical resolution, in pixels per metre, of the target device
$parsed['biClrUsed'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 32, 4)); // actual number of color indices in the color table used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression
$parsed['biClrImportant'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 36, 4)); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important
return $parsed;
}
function RIFFwFormatTagLookup($wFormatTag) { function RIFFwFormatTagLookup($wFormatTag) {
$begin = __LINE__; $begin = __LINE__;

View File

@ -18,6 +18,7 @@ class getid3_swf
{ {
function getid3_swf(&$fd, &$ThisFileInfo, $ReturnAllTagData=false) { function getid3_swf(&$fd, &$ThisFileInfo, $ReturnAllTagData=false) {
//$start_time = microtime(true);
$ThisFileInfo['fileformat'] = 'swf'; $ThisFileInfo['fileformat'] = 'swf';
$ThisFileInfo['video']['dataformat'] = 'swf'; $ThisFileInfo['video']['dataformat'] = 'swf';
@ -25,7 +26,6 @@ class getid3_swf
fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET); fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
//echo 'reading '.($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']).' bytes<br>';
$SWFfileData = fread($fd, $ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']); // 8 + 2 + 2 + max(9) bytes NOT including Frame_Size RECT data $SWFfileData = fread($fd, $ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']); // 8 + 2 + 2 + max(9) bytes NOT including Frame_Size RECT data
$ThisFileInfo['swf']['header']['signature'] = substr($SWFfileData, 0, 3); $ThisFileInfo['swf']['header']['signature'] = substr($SWFfileData, 0, 3);
@ -48,31 +48,25 @@ class getid3_swf
$ThisFileInfo['swf']['header']['version'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 3, 1)); $ThisFileInfo['swf']['header']['version'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 3, 1));
$ThisFileInfo['swf']['header']['length'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 4, 4)); $ThisFileInfo['swf']['header']['length'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 4, 4));
//echo '1<br>'; //echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
if ($ThisFileInfo['swf']['header']['compressed']) { if ($ThisFileInfo['swf']['header']['compressed']) {
//echo '2<br>'; $SWFHead = substr($SWFfileData, 0, 8);
// $foo = substr($SWFfileData, 8, 4096); $SWFfileData = substr($SWFfileData, 8);
// echo '['.strlen($foo).']<br>'; if ($decompressed = @gzuncompress($SWFfileData)) {
// $fee = gzuncompress($foo);
// echo '('.strlen($fee).')<br>';
//return false;
//echo '<br>time: '.time().'<br>';
//return false;
if ($UncompressedFileData = gzuncompress(substr($SWFfileData, 8))) {
//echo '3<br>'; $SWFfileData = $SWFHead.$decompressed;
$SWFfileData = substr($SWFfileData, 0, 8).$UncompressedFileData;
} else { } else {
//echo '4<br>'; $ThisFileInfo['error'][] = 'Error decompressing compressed SWF data ('.strlen($SWFfileData).' bytes compressed, should be '.($ThisFileInfo['swf']['header']['length'] - 8).' bytes uncompressed)';
$ThisFileInfo['error'][] = 'Error decompressing compressed SWF data';
return false; return false;
} }
} }
//echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
$FrameSizeBitsPerValue = (ord(substr($SWFfileData, 8, 1)) & 0xF8) >> 3; $FrameSizeBitsPerValue = (ord(substr($SWFfileData, 8, 1)) & 0xF8) >> 3;
$FrameSizeDataLength = ceil((5 + (4 * $FrameSizeBitsPerValue)) / 8); $FrameSizeDataLength = ceil((5 + (4 * $FrameSizeBitsPerValue)) / 8);
@ -102,6 +96,7 @@ class getid3_swf
if (($ThisFileInfo['swf']['header']['frame_count'] > 0) && ($ThisFileInfo['swf']['header']['frame_rate'] > 0)) { if (($ThisFileInfo['swf']['header']['frame_count'] > 0) && ($ThisFileInfo['swf']['header']['frame_rate'] > 0)) {
$ThisFileInfo['playtime_seconds'] = $ThisFileInfo['swf']['header']['frame_count'] / $ThisFileInfo['swf']['header']['frame_rate']; $ThisFileInfo['playtime_seconds'] = $ThisFileInfo['swf']['header']['frame_count'] / $ThisFileInfo['swf']['header']['frame_rate'];
} }
//echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
// SWF tags // SWF tags
@ -110,6 +105,7 @@ class getid3_swf
$SWFdataLength = strlen($SWFfileData); $SWFdataLength = strlen($SWFfileData);
while ($CurrentOffset < $SWFdataLength) { while ($CurrentOffset < $SWFdataLength) {
//echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
$TagIDTagLength = getid3_lib::LittleEndian2Int(substr($SWFfileData, $CurrentOffset, 2)); $TagIDTagLength = getid3_lib::LittleEndian2Int(substr($SWFfileData, $CurrentOffset, 2));
$TagID = ($TagIDTagLength & 0xFFFC) >> 6; $TagID = ($TagIDTagLength & 0xFFFC) >> 6;

View File

@ -306,6 +306,10 @@ class getid3_aac
// breaks out when end-of-file encountered, or invalid data found, // breaks out when end-of-file encountered, or invalid data found,
// or MaxFramesToScan frames have been scanned // or MaxFramesToScan frames have been scanned
if ($byteoffset >= pow(2, 31)) {
$ThisFileInfo['warning'][] = 'Unable to parse AAC file beyond '.ftell($fd).' (PHP does not support file operations beyond 2GB)';
return false;
}
fseek($fd, $byteoffset, SEEK_SET); fseek($fd, $byteoffset, SEEK_SET);
// First get substring // First get substring

View File

@ -25,32 +25,40 @@ class getid3_bonk
$thisfile_bonk['dataoffset'] = $ThisFileInfo['avdataoffset']; $thisfile_bonk['dataoffset'] = $ThisFileInfo['avdataoffset'];
$thisfile_bonk['dataend'] = $ThisFileInfo['avdataend']; $thisfile_bonk['dataend'] = $ThisFileInfo['avdataend'];
// scan-from-end method, for v0.6 and higher if ($thisfile_bonk['dataend'] >= pow(2, 31)) {
fseek($fd, $thisfile_bonk['dataend'] - 8, SEEK_SET);
$PossibleBonkTag = fread($fd, 8);
while ($this->BonkIsValidTagName(substr($PossibleBonkTag, 4, 4), true)) {
$BonkTagSize = getid3_lib::LittleEndian2Int(substr($PossibleBonkTag, 0, 4));
fseek($fd, 0 - $BonkTagSize, SEEK_CUR);
$BonkTagOffset = ftell($fd);
$TagHeaderTest = fread($fd, 5);
if (($TagHeaderTest{0} != "\x00") || (substr($PossibleBonkTag, 4, 4) != strtolower(substr($PossibleBonkTag, 4, 4)))) {
$ThisFileInfo['error'][] = 'Expecting "Ø'.strtoupper(substr($PossibleBonkTag, 4, 4)).'" at offset '.$BonkTagOffset.', found "'.$TagHeaderTest.'"';
return false;
}
$BonkTagName = substr($TagHeaderTest, 1, 4);
$thisfile_bonk[$BonkTagName]['size'] = $BonkTagSize; $ThisFileInfo['warning'][] = 'Unable to parse BONK file from end (v0.6+ preferred method) because PHP filesystem functions only support up to 2GB';
$thisfile_bonk[$BonkTagName]['offset'] = $BonkTagOffset;
$this->HandleBonkTags($fd, $BonkTagName, $ThisFileInfo); } else {
$NextTagEndOffset = $BonkTagOffset - 8;
if ($NextTagEndOffset < $thisfile_bonk['dataoffset']) { // scan-from-end method, for v0.6 and higher
if (empty($ThisFileInfo['audio']['encoder'])) { fseek($fd, $thisfile_bonk['dataend'] - 8, SEEK_SET);
$ThisFileInfo['audio']['encoder'] = 'Extended BONK v0.9+';
}
return true;
}
fseek($fd, $NextTagEndOffset, SEEK_SET);
$PossibleBonkTag = fread($fd, 8); $PossibleBonkTag = fread($fd, 8);
while ($this->BonkIsValidTagName(substr($PossibleBonkTag, 4, 4), true)) {
$BonkTagSize = getid3_lib::LittleEndian2Int(substr($PossibleBonkTag, 0, 4));
fseek($fd, 0 - $BonkTagSize, SEEK_CUR);
$BonkTagOffset = ftell($fd);
$TagHeaderTest = fread($fd, 5);
if (($TagHeaderTest{0} != "\x00") || (substr($PossibleBonkTag, 4, 4) != strtolower(substr($PossibleBonkTag, 4, 4)))) {
$ThisFileInfo['error'][] = 'Expecting "Ø'.strtoupper(substr($PossibleBonkTag, 4, 4)).'" at offset '.$BonkTagOffset.', found "'.$TagHeaderTest.'"';
return false;
}
$BonkTagName = substr($TagHeaderTest, 1, 4);
$thisfile_bonk[$BonkTagName]['size'] = $BonkTagSize;
$thisfile_bonk[$BonkTagName]['offset'] = $BonkTagOffset;
$this->HandleBonkTags($fd, $BonkTagName, $ThisFileInfo);
$NextTagEndOffset = $BonkTagOffset - 8;
if ($NextTagEndOffset < $thisfile_bonk['dataoffset']) {
if (empty($ThisFileInfo['audio']['encoder'])) {
$ThisFileInfo['audio']['encoder'] = 'Extended BONK v0.9+';
}
return true;
}
fseek($fd, $NextTagEndOffset, SEEK_SET);
$PossibleBonkTag = fread($fd, 8);
}
} }
// seek-from-beginning method for v0.4 and v0.5 // seek-from-beginning method for v0.4 and v0.5

View File

@ -0,0 +1,72 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.audio.au.php //
// module for analyzing Digital Speech Standard (DSS) files //
// dependencies: NONE //
// ///
/////////////////////////////////////////////////////////////////
class getid3_dss
{
function getid3_dss(&$fd, &$ThisFileInfo) {
fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
$DSSheader = fread($fd, 1256);
if (substr($DSSheader, 0, 4) != "\x02".'dss') {
$ThisFileInfo['error'][] = 'Expecting "[x02]dss" at offset '.$ThisFileInfo['avdataoffset'].', found "'.substr($DSSheader, 0, 4).'"';
return false;
}
// some structure information taken from http://cpansearch.perl.org/src/RGIBSON/Audio-DSS-0.02/lib/Audio/DSS.pm
// shortcut
$ThisFileInfo['dss'] = array();
$thisfile_dss = &$ThisFileInfo['dss'];
$ThisFileInfo['fileformat'] = 'dss';
$ThisFileInfo['audio']['dataformat'] = 'dss';
$ThisFileInfo['audio']['bitrate_mode'] = 'cbr';
//$thisfile_dss['encoding'] = 'ISO-8859-1';
$thisfile_dss['date_create'] = $this->DSSdateStringToUnixDate(substr($DSSheader, 38, 12));
$thisfile_dss['date_complete'] = $this->DSSdateStringToUnixDate(substr($DSSheader, 50, 12));
$thisfile_dss['length'] = intval(substr($DSSheader, 62, 6));
$thisfile_dss['priority'] = ord(substr($DSSheader, 793, 1));
$thisfile_dss['comments'] = trim(substr($DSSheader, 798, 100));
//$ThisFileInfo['audio']['bits_per_sample'] = ?;
//$ThisFileInfo['audio']['sample_rate'] = ?;
$ThisFileInfo['audio']['channels'] = 1;
$ThisFileInfo['playtime_seconds'] = $thisfile_dss['length'];
$ThisFileInfo['audio']['bitrate'] = ($ThisFileInfo['filesize'] * 8) / $ThisFileInfo['playtime_seconds'];
return true;
}
function DSSdateStringToUnixDate($datestring) {
$y = substr($datestring, 0, 2);
$m = substr($datestring, 2, 2);
$d = substr($datestring, 4, 2);
$h = substr($datestring, 6, 2);
$i = substr($datestring, 8, 2);
$s = substr($datestring, 10, 2);
$y += (($y < 95) ? 2000 : 1900);
return mktime($h, $i, $s, $m, $d, $y);
}
}
?>

View File

@ -0,0 +1,239 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.audio.dts.php //
// module for analyzing DTS Audio files //
// dependencies: NONE //
// //
/////////////////////////////////////////////////////////////////
class getid3_dts
{
function getid3_dts(&$fd, &$ThisFileInfo) {
// Specs taken from "DTS Coherent Acoustics;Core and Extensions, ETSI TS 102 114 V1.2.1 (2002-12)"
// (http://pda.etsi.org/pda/queryform.asp)
// With thanks to Gambit <macteam@users.sourceforge.net> http://mac.sourceforge.net/atl/
$ThisFileInfo['fileformat'] = 'dts';
fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
$DTSheader = fread($fd, 16);
$ThisFileInfo['dts']['raw']['magic'] = getid3_lib::BigEndian2Int(substr($DTSheader, 0, 4));
if ($ThisFileInfo['dts']['raw']['magic'] != 0x7FFE8001) {
$ThisFileInfo['error'][] = 'Expecting "0x7FFE8001" at offset '.$ThisFileInfo['avdataoffset'].', found "0x'.str_pad(strtoupper(dechex($ThisFileInfo['dts']['raw']['magic'])), 8, '0', STR_PAD_LEFT).'"';
unset($ThisFileInfo['fileformat']);
unset($ThisFileInfo['dts']);
return false;
}
$fhBS = getid3_lib::BigEndian2Bin(substr($DTSheader, 4, 12));
$bsOffset = 0;
$ThisFileInfo['dts']['raw']['frame_type'] = bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['raw']['deficit_samples'] = bindec(substr($fhBS, $bsOffset, 5)); $bsOffset += 5;
$ThisFileInfo['dts']['flags']['crc_present'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['raw']['pcm_sample_blocks'] = bindec(substr($fhBS, $bsOffset, 7)); $bsOffset += 7;
$ThisFileInfo['dts']['raw']['frame_byte_size'] = bindec(substr($fhBS, $bsOffset, 14)); $bsOffset += 14;
$ThisFileInfo['dts']['raw']['channel_arrangement'] = bindec(substr($fhBS, $bsOffset, 6)); $bsOffset += 6;
$ThisFileInfo['dts']['raw']['sample_frequency'] = bindec(substr($fhBS, $bsOffset, 4)); $bsOffset += 4;
$ThisFileInfo['dts']['raw']['bitrate'] = bindec(substr($fhBS, $bsOffset, 5)); $bsOffset += 5;
$ThisFileInfo['dts']['flags']['embedded_downmix'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['flags']['dynamicrange'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['flags']['timestamp'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['flags']['auxdata'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['flags']['hdcd'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['raw']['extension_audio'] = bindec(substr($fhBS, $bsOffset, 3)); $bsOffset += 3;
$ThisFileInfo['dts']['flags']['extended_coding'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['flags']['audio_sync_insertion'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['raw']['lfe_effects'] = bindec(substr($fhBS, $bsOffset, 2)); $bsOffset += 2;
$ThisFileInfo['dts']['flags']['predictor_history'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
if ($ThisFileInfo['dts']['flags']['crc_present']) {
$ThisFileInfo['dts']['raw']['crc16'] = bindec(substr($fhBS, $bsOffset, 16)); $bsOffset += 16;
}
$ThisFileInfo['dts']['flags']['mri_perfect_reconst'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['raw']['encoder_soft_version'] = bindec(substr($fhBS, $bsOffset, 4)); $bsOffset += 4;
$ThisFileInfo['dts']['raw']['copy_history'] = bindec(substr($fhBS, $bsOffset, 2)); $bsOffset += 2;
$ThisFileInfo['dts']['raw']['bits_per_sample'] = bindec(substr($fhBS, $bsOffset, 2)); $bsOffset += 2;
$ThisFileInfo['dts']['flags']['surround_es'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['flags']['front_sum_diff'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['flags']['surround_sum_diff'] = (bool) bindec(substr($fhBS, $bsOffset, 1)); $bsOffset += 1;
$ThisFileInfo['dts']['raw']['dialog_normalization'] = bindec(substr($fhBS, $bsOffset, 4)); $bsOffset += 4;
$ThisFileInfo['dts']['bitrate'] = $this->DTSbitrateLookup($ThisFileInfo['dts']['raw']['bitrate']);
$ThisFileInfo['dts']['bits_per_sample'] = $this->DTSbitPerSampleLookup($ThisFileInfo['dts']['raw']['bits_per_sample']);
$ThisFileInfo['dts']['sample_rate'] = $this->DTSsampleRateLookup($ThisFileInfo['dts']['raw']['sample_frequency']);
$ThisFileInfo['dts']['dialog_normalization'] = $this->DTSdialogNormalization($ThisFileInfo['dts']['raw']['dialog_normalization'], $ThisFileInfo['dts']['raw']['encoder_soft_version']);
$ThisFileInfo['dts']['flags']['lossless'] = (($ThisFileInfo['dts']['raw']['bitrate'] == 31) ? true : false);
$ThisFileInfo['dts']['bitrate_mode'] = (($ThisFileInfo['dts']['raw']['bitrate'] == 30) ? 'vbr' : 'cbr');
$ThisFileInfo['dts']['channels'] = $this->DTSnumChannelsLookup($ThisFileInfo['dts']['raw']['channel_arrangement']);
$ThisFileInfo['dts']['channel_arrangement'] = $this->DTSchannelArrangementLookup($ThisFileInfo['dts']['raw']['channel_arrangement']);
$ThisFileInfo['audio']['dataformat'] = 'dts';
$ThisFileInfo['audio']['lossless'] = $ThisFileInfo['dts']['flags']['lossless'];
$ThisFileInfo['audio']['bitrate_mode'] = $ThisFileInfo['dts']['bitrate_mode'];
$ThisFileInfo['audio']['bits_per_sample'] = $ThisFileInfo['dts']['bits_per_sample'];
$ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['dts']['sample_rate'];
$ThisFileInfo['audio']['channels'] = $ThisFileInfo['dts']['channels'];
$ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['dts']['bitrate'];
if (isset($ThisFileInfo['avdataend'])) {
$ThisFileInfo['playtime_seconds'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / ($ThisFileInfo['dts']['bitrate'] / 8);
}
return true;
}
function DTSbitrateLookup($index) {
$DTSbitrateLookup = array(
0 => 32000,
1 => 56000,
2 => 64000,
3 => 96000,
4 => 112000,
5 => 128000,
6 => 192000,
7 => 224000,
8 => 256000,
9 => 320000,
10 => 384000,
11 => 448000,
12 => 512000,
13 => 576000,
14 => 640000,
15 => 768000,
16 => 960000,
17 => 1024000,
18 => 1152000,
19 => 1280000,
20 => 1344000,
21 => 1408000,
22 => 1411200,
23 => 1472000,
24 => 1536000,
25 => 1920000,
26 => 2048000,
27 => 3072000,
28 => 3840000,
29 => 'open',
30 => 'variable',
31 => 'lossless'
);
return @$DTSbitrateLookup[$index];
}
function DTSsampleRateLookup($index) {
$DTSsampleRateLookup = array(
0 => 'invalid',
1 => 8000,
2 => 16000,
3 => 32000,
4 => 'invalid',
5 => 'invalid',
6 => 11025,
7 => 22050,
8 => 44100,
9 => 'invalid',
10 => 'invalid',
11 => 12000,
12 => 24000,
13 => 48000,
14 => 'invalid',
15 => 'invalid'
);
return @$DTSsampleRateLookup[$index];
}
function DTSbitPerSampleLookup($index) {
$DTSbitPerSampleLookup = array(
0 => 16,
1 => 20,
2 => 24,
3 => 24,
);
return @$DTSbitPerSampleLookup[$index];
}
function DTSnumChannelsLookup($index) {
switch ($index) {
case 0:
return 1;
break;
case 1:
case 2:
case 3:
case 4:
return 2;
break;
case 5:
case 6:
return 3;
break;
case 7:
case 8:
return 4;
break;
case 9:
return 5;
break;
case 10:
case 11:
case 12:
return 6;
break;
case 13:
return 7;
break;
case 14:
case 15:
return 8;
break;
}
return false;
}
function DTSchannelArrangementLookup($index) {
$DTSchannelArrangementLookup = array(
0 => 'A',
1 => 'A + B (dual mono)',
2 => 'L + R (stereo)',
3 => '(L+R) + (L-R) (sum-difference)',
4 => 'LT + RT (left and right total)',
5 => 'C + L + R',
6 => 'L + R + S',
7 => 'C + L + R + S',
8 => 'L + R + SL + SR',
9 => 'C + L + R + SL + SR',
10 => 'CL + CR + L + R + SL + SR',
11 => 'C + L + R+ LR + RR + OV',
12 => 'CF + CR + LF + RF + LR + RR',
13 => 'CL + C + CR + L + R + SL + SR',
14 => 'CL + CR + L + R + SL1 + SL2 + SR1 + SR2',
15 => 'CL + C+ CR + L + R + SL + S + SR',
);
return (@$DTSchannelArrangementLookup[$index] ? @$DTSchannelArrangementLookup[$index] : 'user-defined');
}
function DTSdialogNormalization($index, $version) {
switch ($version) {
case 7:
return 0 - $index;
break;
case 6:
return 0 - 16 - $index;
break;
}
return false;
}
}
?>

View File

@ -100,6 +100,12 @@ class getid3_flac
} }
break; break;
case 'PICTURE':
if (!$this->FLACparsePICTURE($ThisFileInfo_flac_METAdataBlockTypeText_raw['block_data'], $ThisFileInfo)) {
return false;
}
break;
default: default:
$ThisFileInfo['warning'][] = 'Unhandled METADATA_BLOCK_HEADER.BLOCK_TYPE ('.$METAdataBlockType.') at offset '.$METAdataBlockOffset; $ThisFileInfo['warning'][] = 'Unhandled METADATA_BLOCK_HEADER.BLOCK_TYPE ('.$METAdataBlockType.') at offset '.$METAdataBlockOffset;
break; break;
@ -163,6 +169,7 @@ class getid3_flac
$FLACmetaBlockTypeLookup[3] = 'SEEKTABLE'; $FLACmetaBlockTypeLookup[3] = 'SEEKTABLE';
$FLACmetaBlockTypeLookup[4] = 'VORBIS_COMMENT'; $FLACmetaBlockTypeLookup[4] = 'VORBIS_COMMENT';
$FLACmetaBlockTypeLookup[5] = 'CUESHEET'; $FLACmetaBlockTypeLookup[5] = 'CUESHEET';
$FLACmetaBlockTypeLookup[6] = 'PICTURE';
} }
return (isset($FLACmetaBlockTypeLookup[$blocktype]) ? $FLACmetaBlockTypeLookup[$blocktype] : 'reserved'); return (isset($FLACmetaBlockTypeLookup[$blocktype]) ? $FLACmetaBlockTypeLookup[$blocktype] : 'reserved');
} }
@ -177,6 +184,33 @@ class getid3_flac
return (isset($FLACapplicationIDLookup[$applicationid]) ? $FLACapplicationIDLookup[$applicationid] : 'reserved'); return (isset($FLACapplicationIDLookup[$applicationid]) ? $FLACapplicationIDLookup[$applicationid] : 'reserved');
} }
function FLACpictureTypeLookup($type_id) {
static $lookup = array (
0 => 'Other',
1 => '32x32 pixels \'file icon\' (PNG only)',
2 => 'Other file icon',
3 => 'Cover (front)',
4 => 'Cover (back)',
5 => 'Leaflet page',
6 => 'Media (e.g. label side of CD)',
7 => 'Lead artist/lead performer/soloist',
8 => 'Artist/performer',
9 => 'Conductor',
10 => 'Band/Orchestra',
11 => 'Composer',
12 => 'Lyricist/text writer',
13 => 'Recording Location',
14 => 'During recording',
15 => 'During performance',
16 => 'Movie/video screen capture',
17 => 'A bright coloured fish',
18 => 'Illustration',
19 => 'Band/artist logotype',
20 => 'Publisher/Studio logotype',
);
return (isset($lookup[$type_id]) ? $lookup[$type_id] : 'reserved');
}
function FLACparseSTREAMINFO($METAdataBlockData, &$ThisFileInfo) { function FLACparseSTREAMINFO($METAdataBlockData, &$ThisFileInfo) {
$offset = 0; $offset = 0;
$ThisFileInfo['flac']['STREAMINFO']['min_block_size'] = getid3_lib::BigEndian2Int(substr($METAdataBlockData, $offset, 2)); $ThisFileInfo['flac']['STREAMINFO']['min_block_size'] = getid3_lib::BigEndian2Int(substr($METAdataBlockData, $offset, 2));
@ -213,6 +247,9 @@ class getid3_flac
return false; return false;
} }
unset($ThisFileInfo['flac']['STREAMINFO']['raw']);
return true; return true;
} }
@ -225,6 +262,8 @@ class getid3_flac
$ThisFileInfo['flac']['APPLICATION'][$ApplicationID]['data'] = substr($METAdataBlockData, $offset); $ThisFileInfo['flac']['APPLICATION'][$ApplicationID]['data'] = substr($METAdataBlockData, $offset);
$offset = $METAdataBlockLength; $offset = $METAdataBlockLength;
unset($ThisFileInfo['flac']['APPLICATION']['raw']);
return true; return true;
} }
@ -252,6 +291,9 @@ class getid3_flac
} }
} }
unset($ThisFileInfo['flac']['SEEKTABLE']['raw']);
return true; return true;
} }
@ -301,9 +343,55 @@ class getid3_flac
$ThisFileInfo['flac']['CUESHEET']['tracks'][$TrackNumber]['indexes'][$IndexNumber] = $IndexSampleOffset; $ThisFileInfo['flac']['CUESHEET']['tracks'][$TrackNumber]['indexes'][$IndexNumber] = $IndexSampleOffset;
} }
} }
unset($ThisFileInfo['flac']['CUESHEET']['raw']);
return true; return true;
} }
function FLACparsePICTURE($meta_data_block_data, &$ThisFileInfo) {
$picture = &$ThisFileInfo['flac']['PICTURE'][sizeof($ThisFileInfo['flac']['PICTURE']) - 1];
$offset = 0;
$picture['type'] = $this->FLACpictureTypeLookup(getid3_lib::BigEndian2Int(substr($meta_data_block_data, $offset, 4)));
$offset += 4;
$length = getid3_lib::BigEndian2Int(substr($meta_data_block_data, $offset, 4));
$offset += 4;
$picture['mime_type'] = substr($meta_data_block_data, $offset, $length);
$offset += $length;
$length = getid3_lib::BigEndian2Int(substr($meta_data_block_data, $offset, 4));
$offset += 4;
$picture['description'] = substr($meta_data_block_data, $offset, $length);
$offset += $length;
$picture['width'] = getid3_lib::BigEndian2Int(substr($meta_data_block_data, $offset, 4));
$offset += 4;
$picture['height'] = getid3_lib::BigEndian2Int(substr($meta_data_block_data, $offset, 4));
$offset += 4;
$picture['color_depth'] = getid3_lib::BigEndian2Int(substr($meta_data_block_data, $offset, 4));
$offset += 4;
$picture['colors_indexed'] = getid3_lib::BigEndian2Int(substr($meta_data_block_data, $offset, 4));
$offset += 4;
$length = getid3_lib::BigEndian2Int(substr($meta_data_block_data, $offset, 4));
$offset += 4;
$picture['image_data'] = substr($meta_data_block_data, $offset, $length);
$offset += $length;
unset($ThisFileInfo['flac']['PICTURE']['raw']);
return true;
}
} }
?> ?>

View File

@ -180,6 +180,7 @@ class getid3_la
} else { } else {
$ThisFileInfo['warning'][] = 'Error parsing RIFF portion of La file: '.implode($dummy['error']); $ThisFileInfo['warning'][] = 'Error parsing RIFF portion of La file: '.implode($dummy['error']);
} }
unset($riff);
unset($dummy); unset($dummy);
fclose($RIFF_fp); fclose($RIFF_fp);
} }

View File

@ -76,6 +76,7 @@ class getid3_lpac
$dummy = $ThisFileInfo; $dummy = $ThisFileInfo;
$riff = new getid3_riff($fd, $dummy); $riff = new getid3_riff($fd, $dummy);
unset($riff);
$ThisFileInfo['avdataoffset'] = $dummy['avdataoffset']; $ThisFileInfo['avdataoffset'] = $dummy['avdataoffset'];
$ThisFileInfo['riff'] = $dummy['riff']; $ThisFileInfo['riff'] = $dummy['riff'];
$ThisFileInfo['error'] = $dummy['error']; $ThisFileInfo['error'] = $dummy['error'];

View File

@ -76,6 +76,7 @@ class getid3_midi
$ThisFileInfo['playtime_seconds'] = 0; $ThisFileInfo['playtime_seconds'] = 0;
$CurrentMicroSecondsPerBeat = 500000; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat $CurrentMicroSecondsPerBeat = 500000; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat
$CurrentBeatsPerMinute = 120; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat $CurrentBeatsPerMinute = 120; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat
$MicroSecondsPerQuarterNoteAfter = array ();
foreach ($trackdataarray as $tracknumber => $trackdata) { foreach ($trackdataarray as $tracknumber => $trackdata) {
@ -304,8 +305,9 @@ class getid3_midi
} }
} }
if ($ThisFileInfo['playtime_seconds'] > 0) { if (@$ThisFileInfo['playtime_seconds'] > 0) {
$ThisFileInfo['bitrate'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['playtime_seconds']; $ThisFileInfo['bitrate'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['playtime_seconds'];
} }

View File

@ -49,7 +49,7 @@ class getid3_mp3
$synchoffsetwarning .= '(should be at beginning of file, '; $synchoffsetwarning .= '(should be at beginning of file, ';
} }
$synchoffsetwarning .= 'synch detected at '.$ThisFileInfo['avdataoffset'].')'; $synchoffsetwarning .= 'synch detected at '.$ThisFileInfo['avdataoffset'].')';
if ($ThisFileInfo['audio']['bitrate_mode'] == 'cbr') { if (@$ThisFileInfo['audio']['bitrate_mode'] == 'cbr') {
if (!empty($ThisFileInfo['id3v2']['headerlength']) && (($ThisFileInfo['avdataoffset'] - $ThisFileInfo['id3v2']['headerlength']) == $ThisFileInfo['mpeg']['audio']['framelength'])) { if (!empty($ThisFileInfo['id3v2']['headerlength']) && (($ThisFileInfo['avdataoffset'] - $ThisFileInfo['id3v2']['headerlength']) == $ThisFileInfo['mpeg']['audio']['framelength'])) {
@ -119,7 +119,7 @@ class getid3_mp3
$ThisFileInfo['audio']['dataformat'] = 'mp'.$ThisFileInfo['mpeg']['audio']['layer']; $ThisFileInfo['audio']['dataformat'] = 'mp'.$ThisFileInfo['mpeg']['audio']['layer'];
break; break;
} }
if ($ThisFileInfo['fileformat'] == 'mp3') { if (@$ThisFileInfo['fileformat'] == 'mp3') {
switch ($ThisFileInfo['audio']['dataformat']) { switch ($ThisFileInfo['audio']['dataformat']) {
case 'mp1': case 'mp1':
case 'mp2': case 'mp2':
@ -718,10 +718,10 @@ class getid3_mp3
// byte $A5 Info Tag revision + VBR method // byte $A5 Info Tag revision + VBR method
$LAMEtagRevisionVBRmethod = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 1)); $LAMEtagRevisionVBRmethod = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 1));
$thisfile_mpeg_audio_lame['tag_revision'] = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4; $thisfile_mpeg_audio_lame['tag_revision'] = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4;
$thisfile_mpeg_audio_lame_raw['vbr_method'] = $LAMEtagRevisionVBRmethod & 0x0F; $thisfile_mpeg_audio_lame_raw['vbr_method'] = $LAMEtagRevisionVBRmethod & 0x0F;
$thisfile_mpeg_audio_lame['vbr_method'] = getid3_mp3::LAMEvbrMethodLookup($thisfile_mpeg_audio_lame_raw['vbr_method']); $thisfile_mpeg_audio_lame['vbr_method'] = getid3_mp3::LAMEvbrMethodLookup($thisfile_mpeg_audio_lame_raw['vbr_method']);
$thisfile_mpeg_audio['bitrate_mode'] = substr($thisfile_mpeg_audio_lame['vbr_method'], 0, 3); // usually either 'cbr' or 'vbr', but truncates 'vbr-old / vbr-rh' to 'vbr' $thisfile_mpeg_audio['bitrate_mode'] = substr($thisfile_mpeg_audio_lame['vbr_method'], 0, 3); // usually either 'cbr' or 'vbr', but truncates 'vbr-old / vbr-rh' to 'vbr'
// byte $A6 Lowpass filter value // byte $A6 Lowpass filter value
$thisfile_mpeg_audio_lame['lowpass_frequency'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100; $thisfile_mpeg_audio_lame['lowpass_frequency'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100;
@ -890,7 +890,9 @@ class getid3_mp3
if (($ExpectedNumberOfAudioBytes > 0) && ($ExpectedNumberOfAudioBytes != ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']))) { if (($ExpectedNumberOfAudioBytes > 0) && ($ExpectedNumberOfAudioBytes != ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']))) {
if ($ExpectedNumberOfAudioBytes > ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])) { if ($ExpectedNumberOfAudioBytes > ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])) {
if (($ExpectedNumberOfAudioBytes - ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])) == 1) { if (@$ThisFileInfo['fileformat'] == 'riff') {
// ignore, audio data is broken into chunks so will always be data "missing"
} elseif (($ExpectedNumberOfAudioBytes - ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])) == 1) {
$ThisFileInfo['warning'][] = 'Last byte of data truncated (this is a known bug in Meracl ID3 Tag Writer before v1.3.5)'; $ThisFileInfo['warning'][] = 'Last byte of data truncated (this is a known bug in Meracl ID3 Tag Writer before v1.3.5)';
} else { } else {
$ThisFileInfo['warning'][] = 'Probable truncated file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, only found '.($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']).' (short by '.($ExpectedNumberOfAudioBytes - ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])).' bytes)'; $ThisFileInfo['warning'][] = 'Probable truncated file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, only found '.($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']).' (short by '.($ExpectedNumberOfAudioBytes - ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])).' bytes)';
@ -931,16 +933,16 @@ class getid3_mp3
} }
} }
if (!empty($thisfile_mpeg_audio['VBR_frames'])) { if (@$thisfile_mpeg_audio['VBR_frames']) {
switch ($thisfile_mpeg_audio['bitrate_mode']) { switch ($thisfile_mpeg_audio['bitrate_mode']) {
case 'vbr': case 'vbr':
case 'abr': case 'abr':
if (($thisfile_mpeg_audio['version'] == '1') && ($thisfile_mpeg_audio['layer'] == 1)) { if (($thisfile_mpeg_audio['version'] == '1') && ($thisfile_mpeg_audio['layer'] == 1)) {
$thisfile_mpeg_audio['VBR_bitrate'] = (($thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 384); $thisfile_mpeg_audio['VBR_bitrate'] = ((@$thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 384);
} elseif ((($thisfile_mpeg_audio['version'] == '2') || ($thisfile_mpeg_audio['version'] == '2.5')) && ($thisfile_mpeg_audio['layer'] == 3)) { } elseif ((($thisfile_mpeg_audio['version'] == '2') || ($thisfile_mpeg_audio['version'] == '2.5')) && ($thisfile_mpeg_audio['layer'] == 3)) {
$thisfile_mpeg_audio['VBR_bitrate'] = (($thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 576); $thisfile_mpeg_audio['VBR_bitrate'] = ((@$thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 576);
} else { } else {
$thisfile_mpeg_audio['VBR_bitrate'] = (($thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 1152); $thisfile_mpeg_audio['VBR_bitrate'] = ((@$thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 1152);
} }
if ($thisfile_mpeg_audio['VBR_bitrate'] > 0) { if ($thisfile_mpeg_audio['VBR_bitrate'] > 0) {
$ThisFileInfo['audio']['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate']; $ThisFileInfo['audio']['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate'];
@ -1206,6 +1208,9 @@ class getid3_mp3
fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET); fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
$max_frames_scan = 5000;
$frames_scanned = 0;
$previousvalidframe = $ThisFileInfo['avdataoffset']; $previousvalidframe = $ThisFileInfo['avdataoffset'];
while (ftell($fd) < $ThisFileInfo['avdataend']) { while (ftell($fd) < $ThisFileInfo['avdataend']) {
set_time_limit(30); set_time_limit(30);
@ -1262,6 +1267,16 @@ class getid3_mp3
@$Distribution['version'][$LongMPEGversionLookup[$head4]]++; @$Distribution['version'][$LongMPEGversionLookup[$head4]]++;
@$Distribution['padding'][intval($LongMPEGpaddingLookup[$head4])]++; @$Distribution['padding'][intval($LongMPEGpaddingLookup[$head4])]++;
@$Distribution['frequency'][$LongMPEGfrequencyLookup[$head4]]++; @$Distribution['frequency'][$LongMPEGfrequencyLookup[$head4]]++;
if ($max_frames_scan && (++$frames_scanned >= $max_frames_scan)) {
$pct_data_scanned = (ftell($fd) - $ThisFileInfo['avdataoffset']) / ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']);
$ThisFileInfo['warning'][] = 'too many MPEG audio frames to scan, only scanned first '.$max_frames_scan.' frames ('.number_format($pct_data_scanned * 100, 1).'% of file) and extrapolated distribution, playtime and bitrate may be incorrect.';
foreach ($Distribution as $key1 => $value1) {
foreach ($value1 as $key2 => $value2) {
$Distribution[$key1][$key2] = round($value2 / $pct_data_scanned);
}
}
break;
}
continue; continue;
} }
} }
@ -1317,30 +1332,35 @@ class getid3_mp3
function getOnlyMPEGaudioInfo($fd, &$ThisFileInfo, $avdataoffset, $BitrateHistogram=false) { function getOnlyMPEGaudioInfo($fd, &$ThisFileInfo, $avdataoffset, $BitrateHistogram=false) {
// looks for synch, decodes MPEG audio header
fseek($fd, $avdataoffset, SEEK_SET); // looks for synch, decodes MPEG audio header
$header = '';
$SynchSeekOffset = 0;
static $MPEGaudioVersionLookup; static $MPEGaudioVersionLookup;
static $MPEGaudioLayerLookup; static $MPEGaudioLayerLookup;
static $MPEGaudioBitrateLookup; static $MPEGaudioBitrateLookup;
if (empty($MPEGaudioVersionLookup)) { if (empty($MPEGaudioVersionLookup)) {
$MPEGaudioVersionLookup = getid3_mp3::MPEGaudioVersionArray(); $MPEGaudioVersionLookup = getid3_mp3::MPEGaudioVersionArray();
$MPEGaudioLayerLookup = getid3_mp3::MPEGaudioLayerArray(); $MPEGaudioLayerLookup = getid3_mp3::MPEGaudioLayerArray();
$MPEGaudioBitrateLookup = getid3_mp3::MPEGaudioBitrateArray(); $MPEGaudioBitrateLookup = getid3_mp3::MPEGaudioBitrateArray();
} }
$header_len = strlen($header) - intval(round(GETID3_FREAD_BUFFER_SIZE / 2)); fseek($fd, $avdataoffset, SEEK_SET);
while (true) { $sync_seek_buffer_size = min(128 * 1024, $ThisFileInfo['avdataend'] - $avdataoffset);
if ($sync_seek_buffer_size <= 0) {
$ThisFileInfo['error'][] = 'Invalid $sync_seek_buffer_size at offset '.$avdataoffset;
return false;
}
$header = fread($fd, $sync_seek_buffer_size);
$sync_seek_buffer_size = strlen($header);
$SynchSeekOffset = 0;
while ($SynchSeekOffset < $sync_seek_buffer_size) {
if (($SynchSeekOffset > $header_len) && (($avdataoffset + $SynchSeekOffset) < $ThisFileInfo['avdataend']) && !feof($fd)) { if ((($avdataoffset + $SynchSeekOffset) < $ThisFileInfo['avdataend']) && !feof($fd)) {
if ($SynchSeekOffset > 131072) { if ($SynchSeekOffset > $sync_seek_buffer_size) {
// if a synch's not found within the first 128k bytes, then give up // if a synch's not found within the first 128k bytes, then give up
$ThisFileInfo['error'][] = 'could not find valid MPEG audio synch within the first 128k bytes'; $ThisFileInfo['error'][] = 'Could not find valid MPEG audio synch within the first '.round($sync_seek_buffer_size / 1024).'kB';
if (isset($ThisFileInfo['audio']['bitrate'])) { if (isset($ThisFileInfo['audio']['bitrate'])) {
unset($ThisFileInfo['audio']['bitrate']); unset($ThisFileInfo['audio']['bitrate']);
} }
@ -1352,14 +1372,9 @@ class getid3_mp3
} }
return false; return false;
} elseif ($header .= fread($fd, GETID3_FREAD_BUFFER_SIZE)) { } elseif (feof($fd)) {
// great $ThisFileInfo['error'][] = 'Could not find valid MPEG audio synch before end of file';
$header_len = strlen($header) - intval(round(GETID3_FREAD_BUFFER_SIZE / 2));
} else {
$ThisFileInfo['error'][] = 'could not find valid MPEG audio synch before end of file';
if (isset($ThisFileInfo['audio']['bitrate'])) { if (isset($ThisFileInfo['audio']['bitrate'])) {
unset($ThisFileInfo['audio']['bitrate']); unset($ThisFileInfo['audio']['bitrate']);
} }
@ -1370,12 +1385,11 @@ class getid3_mp3
unset($ThisFileInfo['mpeg']); unset($ThisFileInfo['mpeg']);
} }
return false; return false;
} }
} }
if (($SynchSeekOffset + 1) >= strlen($header)) { if (($SynchSeekOffset + 1) >= strlen($header)) {
$ThisFileInfo['error'][] = 'could not find valid MPEG synch before end of file'; $ThisFileInfo['error'][] = 'Could not find valid MPEG synch before end of file';
return false; return false;
} }
@ -1395,7 +1409,7 @@ class getid3_mp3
if (getid3_mp3::decodeMPEGaudioHeader($fd, $avdataoffset + $SynchSeekOffset, $dummy, true)) { if (getid3_mp3::decodeMPEGaudioHeader($fd, $avdataoffset + $SynchSeekOffset, $dummy, true)) {
$ThisFileInfo = $dummy; $ThisFileInfo = $dummy;
$ThisFileInfo['avdataoffset'] = $avdataoffset + $SynchSeekOffset; $ThisFileInfo['avdataoffset'] = $avdataoffset + $SynchSeekOffset;
switch ($ThisFileInfo['fileformat']) { switch (@$ThisFileInfo['fileformat']) {
case '': case '':
case 'id3': case 'id3':
case 'ape': case 'ape':
@ -1455,23 +1469,94 @@ class getid3_mp3
$dummy = array('error'=>$ThisFileInfo['error'], 'warning'=>$ThisFileInfo['warning'], 'avdataend'=>$ThisFileInfo['avdataend'], 'avdataoffset'=>$ThisFileInfo['avdataoffset']); $dummy = array('error'=>$ThisFileInfo['error'], 'warning'=>$ThisFileInfo['warning'], 'avdataend'=>$ThisFileInfo['avdataend'], 'avdataoffset'=>$ThisFileInfo['avdataoffset']);
$synchstartoffset = $ThisFileInfo['avdataoffset']; $synchstartoffset = $ThisFileInfo['avdataoffset'];
fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
// you can play with these numbers:
$max_frames_scan = 50000;
$max_scan_segments = 10;
// don't play with these numbers:
$FastMode = false; $FastMode = false;
$SynchErrorsFound = 0; $SynchErrorsFound = 0;
while (getid3_mp3::decodeMPEGaudioHeader($fd, $synchstartoffset, $dummy, false, false, $FastMode)) { $frames_scanned = 0;
$FastMode = true; $this_scan_segment = 0;
$thisframebitrate = $MPEGaudioBitrateLookup[$MPEGaudioVersionLookup[$dummy['mpeg']['audio']['raw']['version']]][$MPEGaudioLayerLookup[$dummy['mpeg']['audio']['raw']['layer']]][$dummy['mpeg']['audio']['raw']['bitrate']]; $frames_scan_per_segment = ceil($max_frames_scan / $max_scan_segments);
$pct_data_scanned = 0;
for ($current_segment = 0; $current_segment < $max_scan_segments; $current_segment++) {
//echo 'was at '.ftell($fd).'<br>';
$frames_scanned_this_segment = 0;
if (ftell($fd) >= $ThisFileInfo['avdataend']) {
//echo 'breaking because current position ('.ftell($fd).') is >= $ThisFileInfo[avdataend] ('.$ThisFileInfo['avdataend'].')<br>';
break;
}
$scan_start_offset[$current_segment] = max(ftell($fd), $ThisFileInfo['avdataoffset'] + round($current_segment * (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $max_scan_segments)));
//echo 'start at '.$scan_start_offset[$current_segment].'<br>';
if ($current_segment > 0) {
fseek($fd, $scan_start_offset[$current_segment], SEEK_SET);
$buffer_4k = fread($fd, 4096);
for ($j = 0; $j < (strlen($buffer_4k) - 4); $j++) {
if (($buffer_4k{$j} == "\xFF") && ($buffer_4k{($j + 1)} > "\xE0")) { // synch detected
if (getid3_mp3::decodeMPEGaudioHeader($fd, $scan_start_offset[$current_segment] + $j, $dummy, false, false, $FastMode)) {
$calculated_next_offset = $scan_start_offset[$current_segment] + $j + $dummy['mpeg']['audio']['framelength'];
if (getid3_mp3::decodeMPEGaudioHeader($fd, $calculated_next_offset, $dummy, false, false, $FastMode)) {
$scan_start_offset[$current_segment] += $j;
break;
} else {
//echo 'header['.__LINE__.'] at '.($calculated_next_offset).' invalid<br>';
}
} else {
//echo 'header['.__LINE__.'] at '.($scan_start_offset[$current_segment] + $j).' invalid<br>';
}
}
}
}
//echo 'actually start at '.$scan_start_offset[$current_segment].'<br>';
$synchstartoffset = $scan_start_offset[$current_segment];
while (getid3_mp3::decodeMPEGaudioHeader($fd, $synchstartoffset, $dummy, false, false, $FastMode)) {
$FastMode = true;
$thisframebitrate = $MPEGaudioBitrateLookup[$MPEGaudioVersionLookup[$dummy['mpeg']['audio']['raw']['version']]][$MPEGaudioLayerLookup[$dummy['mpeg']['audio']['raw']['layer']]][$dummy['mpeg']['audio']['raw']['bitrate']];
if (empty($dummy['mpeg']['audio']['framelength'])) { if (empty($dummy['mpeg']['audio']['framelength'])) {
$SynchErrorsFound++; $SynchErrorsFound++;
} else { $synchstartoffset++;
$ThisFileInfo['mpeg']['audio']['bitrate_distribution'][$thisframebitrate]++; //echo ' [Ø] ';
$ThisFileInfo['mpeg']['audio']['stereo_distribution'][$dummy['mpeg']['audio']['channelmode']]++; } else {
$ThisFileInfo['mpeg']['audio']['version_distribution'][$dummy['mpeg']['audio']['version']]++; //echo ' . ';
@$ThisFileInfo['mpeg']['audio']['bitrate_distribution'][$thisframebitrate]++;
@$ThisFileInfo['mpeg']['audio']['stereo_distribution'][$dummy['mpeg']['audio']['channelmode']]++;
@$ThisFileInfo['mpeg']['audio']['version_distribution'][$dummy['mpeg']['audio']['version']]++;
$synchstartoffset += $dummy['mpeg']['audio']['framelength']; $synchstartoffset += $dummy['mpeg']['audio']['framelength'];
}
$frames_scanned++;
if ($frames_scan_per_segment && (++$frames_scanned_this_segment >= $frames_scan_per_segment)) {
$this_pct_scanned = (ftell($fd) - $scan_start_offset[$current_segment]) / ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']);
if (($current_segment == 0) && (($this_pct_scanned * $max_scan_segments) >= 1)) {
// file likely contains < $max_frames_scan, just scan as one segment
$max_scan_segments = 1;
$frames_scan_per_segment = $max_frames_scan;
} else {
$pct_data_scanned += $this_pct_scanned;
//var_dump($pct_data_scanned);
//exit;
break;
}
}
}
//echo '<hr>';
}
if ($pct_data_scanned > 0) {
$ThisFileInfo['warning'][] = 'too many MPEG audio frames to scan, only scanned '.$frames_scanned.' frames in '.$max_scan_segments.' segments ('.number_format($pct_data_scanned * 100, 1).'% of file) and extrapolated distribution, playtime and bitrate may be incorrect.';
foreach ($ThisFileInfo['mpeg']['audio'] as $key1 => $value1) {
if (!eregi('_distribution$', $key1)) {
continue;
}
foreach ($value1 as $key2 => $value2) {
$ThisFileInfo['mpeg']['audio'][$key1][$key2] = round($value2 / $pct_data_scanned);
}
} }
} }
if ($SynchErrorsFound > 0) { if ($SynchErrorsFound > 0) {
$ThisFileInfo['warning'][] = 'Found '.$SynchErrorsFound.' synch errors in histogram analysis'; $ThisFileInfo['warning'][] = 'Found '.$SynchErrorsFound.' synch errors in histogram analysis';
//return false; //return false;
@ -1489,7 +1574,7 @@ class getid3_mp3
$ThisFileInfo['error'][] = 'Corrupt MP3 file: framecounter == zero'; $ThisFileInfo['error'][] = 'Corrupt MP3 file: framecounter == zero';
return false; return false;
} }
$ThisFileInfo['mpeg']['audio']['frame_count'] = $framecounter; $ThisFileInfo['mpeg']['audio']['frame_count'] = getid3_lib::CastAsInt($framecounter);
$ThisFileInfo['mpeg']['audio']['bitrate'] = ($bittotal / $framecounter); $ThisFileInfo['mpeg']['audio']['bitrate'] = ($bittotal / $framecounter);
$ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['bitrate']; $ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['bitrate'];
@ -1558,15 +1643,15 @@ class getid3_mp3
function MPEGaudioBitrateArray() { function MPEGaudioBitrateArray() {
static $MPEGaudioBitrate; static $MPEGaudioBitrate;
if (empty($MPEGaudioBitrate)) { if (empty($MPEGaudioBitrate)) {
$MPEGaudioBitrate = array ( $MPEGaudioBitrate = array (
'1' => array (1 => array('free', 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000), '1' => array (1 => array('free', 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000),
2 => array('free', 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000), 2 => array('free', 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000),
3 => array('free', 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000) 3 => array('free', 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000)
), ),
'2' => array (1 => array('free', 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 176000, 192000, 224000, 256000), '2' => array (1 => array('free', 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 176000, 192000, 224000, 256000),
2 => array('free', 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000), 2 => array('free', 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000),
) )
); );
$MPEGaudioBitrate['2'][3] = $MPEGaudioBitrate['2'][2]; $MPEGaudioBitrate['2'][3] = $MPEGaudioBitrate['2'][2];
$MPEGaudioBitrate['2.5'] = $MPEGaudioBitrate['2']; $MPEGaudioBitrate['2.5'] = $MPEGaudioBitrate['2'];
@ -1577,10 +1662,10 @@ class getid3_mp3
function MPEGaudioFrequencyArray() { function MPEGaudioFrequencyArray() {
static $MPEGaudioFrequency; static $MPEGaudioFrequency;
if (empty($MPEGaudioFrequency)) { if (empty($MPEGaudioFrequency)) {
$MPEGaudioFrequency = array ( $MPEGaudioFrequency = array (
'1' => array(44100, 48000, 32000), '1' => array(44100, 48000, 32000),
'2' => array(22050, 24000, 16000), '2' => array(22050, 24000, 16000),
'2.5' => array(11025, 12000, 8000) '2.5' => array(11025, 12000, 8000)
); );
} }
return $MPEGaudioFrequency; return $MPEGaudioFrequency;
@ -1594,10 +1679,10 @@ class getid3_mp3
function MPEGaudioModeExtensionArray() { function MPEGaudioModeExtensionArray() {
static $MPEGaudioModeExtension; static $MPEGaudioModeExtension;
if (empty($MPEGaudioModeExtension)) { if (empty($MPEGaudioModeExtension)) {
$MPEGaudioModeExtension = array ( $MPEGaudioModeExtension = array (
1 => array('4-31', '8-31', '12-31', '16-31'), 1 => array('4-31', '8-31', '12-31', '16-31'),
2 => array('4-31', '8-31', '12-31', '16-31'), 2 => array('4-31', '8-31', '12-31', '16-31'),
3 => array('', 'IS', 'MS', 'IS+MS') 3 => array('', 'IS', 'MS', 'IS+MS')
); );
} }
return $MPEGaudioModeExtension; return $MPEGaudioModeExtension;
@ -1807,24 +1892,24 @@ class getid3_mp3
static $XingVBRidOffsetCache = array(); static $XingVBRidOffsetCache = array();
if (empty($XingVBRidOffset)) { if (empty($XingVBRidOffset)) {
$XingVBRidOffset = array ( $XingVBRidOffset = array (
'1' => array ('mono' => 0x15, // 4 + 17 = 21 '1' => array ('mono' => 0x15, // 4 + 17 = 21
'stereo' => 0x24, // 4 + 32 = 36 'stereo' => 0x24, // 4 + 32 = 36
'joint stereo' => 0x24, 'joint stereo' => 0x24,
'dual channel' => 0x24 'dual channel' => 0x24
), ),
'2' => array ('mono' => 0x0D, // 4 + 9 = 13 '2' => array ('mono' => 0x0D, // 4 + 9 = 13
'stereo' => 0x15, // 4 + 17 = 21 'stereo' => 0x15, // 4 + 17 = 21
'joint stereo' => 0x15, 'joint stereo' => 0x15,
'dual channel' => 0x15 'dual channel' => 0x15
), ),
'2.5' => array ('mono' => 0x15, '2.5' => array ('mono' => 0x15,
'stereo' => 0x15, 'stereo' => 0x15,
'joint stereo' => 0x15, 'joint stereo' => 0x15,
'dual channel' => 0x15 'dual channel' => 0x15
) )
); );
} }
return $XingVBRidOffset[$version][$channelmode]; return $XingVBRidOffset[$version][$channelmode];
} }
@ -1837,9 +1922,9 @@ class getid3_mp3
0x03 => 'vbr-old / vbr-rh', 0x03 => 'vbr-old / vbr-rh',
0x04 => 'vbr-new / vbr-mtrh', 0x04 => 'vbr-new / vbr-mtrh',
0x05 => 'vbr-mt', 0x05 => 'vbr-mt',
0x06 => 'Full VBR Method 4', 0x06 => 'vbr (full vbr method 4)',
0x08 => 'constant bitrate 2 pass', 0x08 => 'cbr (constant bitrate 2 pass)',
0x09 => 'abr 2 pass', 0x09 => 'abr (2 pass)',
0x0F => 'reserved' 0x0F => 'reserved'
); );
return (isset($LAMEvbrMethodLookup[$VBRmethodID]) ? $LAMEvbrMethodLookup[$VBRmethodID] : ''); return (isset($LAMEvbrMethodLookup[$VBRmethodID]) ? $LAMEvbrMethodLookup[$VBRmethodID] : '');
@ -1881,56 +1966,56 @@ class getid3_mp3
function LAMEpresetUsedLookup($LAMEtag) { function LAMEpresetUsedLookup($LAMEtag) {
if ($LAMEtag['preset_used_id'] == 0) { if ($LAMEtag['preset_used_id'] == 0) {
// no preset used (LAME >=3.93) // no preset used (LAME >=3.93)
// no preset recorded (LAME <3.93) // no preset recorded (LAME <3.93)
return ''; return '';
} }
$LAMEpresetUsedLookup = array(); $LAMEpresetUsedLookup = array();
///// THIS PART CANNOT BE STATIC . ///// THIS PART CANNOT BE STATIC .
for ($i = 8; $i <= 320; $i++) { for ($i = 8; $i <= 320; $i++) {
switch ($LAMEtag['vbr_method']) { switch ($LAMEtag['vbr_method']) {
case 'cbr': case 'cbr':
$LAMEpresetUsedLookup[$i] = '--alt-preset '.$LAMEtag['vbr_method'].' '.$i; $LAMEpresetUsedLookup[$i] = '--alt-preset '.$LAMEtag['vbr_method'].' '.$i;
break; break;
case 'abr': case 'abr':
default: // other VBR modes shouldn't be here(?) default: // other VBR modes shouldn't be here(?)
$LAMEpresetUsedLookup[$i] = '--alt-preset '.$i; $LAMEpresetUsedLookup[$i] = '--alt-preset '.$i;
break; break;
} }
} }
// named old-style presets (studio, phone, voice, etc) are handled in GuessEncoderOptions() // named old-style presets (studio, phone, voice, etc) are handled in GuessEncoderOptions()
// named alt-presets // named alt-presets
$LAMEpresetUsedLookup[1000] = '--r3mix'; $LAMEpresetUsedLookup[1000] = '--r3mix';
$LAMEpresetUsedLookup[1001] = '--alt-preset standard'; $LAMEpresetUsedLookup[1001] = '--alt-preset standard';
$LAMEpresetUsedLookup[1002] = '--alt-preset extreme'; $LAMEpresetUsedLookup[1002] = '--alt-preset extreme';
$LAMEpresetUsedLookup[1003] = '--alt-preset insane'; $LAMEpresetUsedLookup[1003] = '--alt-preset insane';
$LAMEpresetUsedLookup[1004] = '--alt-preset fast standard'; $LAMEpresetUsedLookup[1004] = '--alt-preset fast standard';
$LAMEpresetUsedLookup[1005] = '--alt-preset fast extreme'; $LAMEpresetUsedLookup[1005] = '--alt-preset fast extreme';
$LAMEpresetUsedLookup[1006] = '--alt-preset medium'; $LAMEpresetUsedLookup[1006] = '--alt-preset medium';
$LAMEpresetUsedLookup[1007] = '--alt-preset fast medium'; $LAMEpresetUsedLookup[1007] = '--alt-preset fast medium';
// LAME 3.94 additions/changes // LAME 3.94 additions/changes
$LAMEpresetUsedLookup[1010] = '--preset portable'; // 3.94a15 Oct 21 2003 $LAMEpresetUsedLookup[1010] = '--preset portable'; // 3.94a15 Oct 21 2003
$LAMEpresetUsedLookup[1015] = '--preset radio'; // 3.94a15 Oct 21 2003 $LAMEpresetUsedLookup[1015] = '--preset radio'; // 3.94a15 Oct 21 2003
$LAMEpresetUsedLookup[320] = '--preset insane'; // 3.94a15 Nov 12 2003 $LAMEpresetUsedLookup[320] = '--preset insane'; // 3.94a15 Nov 12 2003
$LAMEpresetUsedLookup[410] = '-V9'; $LAMEpresetUsedLookup[410] = '-V9';
$LAMEpresetUsedLookup[420] = '-V8'; $LAMEpresetUsedLookup[420] = '-V8';
$LAMEpresetUsedLookup[440] = '-V6'; $LAMEpresetUsedLookup[440] = '-V6';
$LAMEpresetUsedLookup[430] = '--preset radio'; // 3.94a15 Nov 12 2003 $LAMEpresetUsedLookup[430] = '--preset radio'; // 3.94a15 Nov 12 2003
$LAMEpresetUsedLookup[450] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'portable'; // 3.94a15 Nov 12 2003 $LAMEpresetUsedLookup[450] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'portable'; // 3.94a15 Nov 12 2003
$LAMEpresetUsedLookup[460] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'medium'; // 3.94a15 Nov 12 2003 $LAMEpresetUsedLookup[460] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'medium'; // 3.94a15 Nov 12 2003
$LAMEpresetUsedLookup[470] = '--r3mix'; // 3.94b1 Dec 18 2003 $LAMEpresetUsedLookup[470] = '--r3mix'; // 3.94b1 Dec 18 2003
$LAMEpresetUsedLookup[480] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'standard'; // 3.94a15 Nov 12 2003 $LAMEpresetUsedLookup[480] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'standard'; // 3.94a15 Nov 12 2003
$LAMEpresetUsedLookup[490] = '-V1'; $LAMEpresetUsedLookup[490] = '-V1';
$LAMEpresetUsedLookup[500] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'extreme'; // 3.94a15 Nov 12 2003 $LAMEpresetUsedLookup[500] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'extreme'; // 3.94a15 Nov 12 2003
return (isset($LAMEpresetUsedLookup[$LAMEtag['preset_used_id']]) ? $LAMEpresetUsedLookup[$LAMEtag['preset_used_id']] : 'new/unknown preset: '.$LAMEtag['preset_used_id'].' - report to info@getid3.org'); return (isset($LAMEpresetUsedLookup[$LAMEtag['preset_used_id']]) ? $LAMEpresetUsedLookup[$LAMEtag['preset_used_id']] : 'new/unknown preset: '.$LAMEtag['preset_used_id'].' - report to info@getid3.org');
} }
} }

View File

@ -18,122 +18,213 @@ class getid3_mpc
{ {
function getid3_mpc(&$fd, &$ThisFileInfo) { function getid3_mpc(&$fd, &$ThisFileInfo) {
// http://www.uni-jena.de/~pfk/mpp/sv8/header.html
$ThisFileInfo['mpc']['header'] = array(); $ThisFileInfo['mpc']['header'] = array();
$thisfile_mpc_header = &$ThisFileInfo['mpc']['header']; $thisfile_mpc_header = &$ThisFileInfo['mpc']['header'];
$ThisFileInfo['fileformat'] = 'mpc'; $ThisFileInfo['fileformat'] = 'mpc';
$ThisFileInfo['audio']['dataformat'] = 'mpc'; $ThisFileInfo['audio']['dataformat'] = 'mpc';
$ThisFileInfo['audio']['bitrate_mode'] = 'vbr'; $ThisFileInfo['audio']['bitrate_mode'] = 'vbr';
$ThisFileInfo['audio']['channels'] = 2; // the format appears to be hardcoded for stereo only $ThisFileInfo['audio']['channels'] = 2; // up to SV7 the format appears to have been hardcoded for stereo only
$ThisFileInfo['audio']['lossless'] = false; $ThisFileInfo['audio']['lossless'] = false;
fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET); fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
$MPCheaderData = fread($fd, 4);
$ThisFileInfo['mpc']['header']['preamble'] = substr($MPCheaderData, 0, 4); // should be 'MPCK' (SV8) or 'MP+' (SV7), otherwise possible stream data (SV4-SV6)
if (ereg('^MPCK', $ThisFileInfo['mpc']['header']['preamble'])) {
$thisfile_mpc_header['size'] = 28; // this is SV8
$MPCheaderData = fread($fd, $thisfile_mpc_header['size']); return $this->ParseMPCsv8($fd, $ThisFileInfo);
$offset = 0;
if (substr($MPCheaderData, $offset, 3) == 'MP+') { } elseif (ereg('^MP\+', $ThisFileInfo['mpc']['header']['preamble'])) {
// great, this is SV7+ // this is SV7
$thisfile_mpc_header['raw']['preamble'] = substr($MPCheaderData, $offset, 3); // should be 'MP+' return $this->ParseMPCsv7($fd, $ThisFileInfo);
$offset += 3;
} elseif (preg_match('/^[\x00\x01\x10\x11\x40\x41\x50\x51\x80\x81\x90\x91\xC0\xC1\xD0\xD1][\x20-37][\x00\x20\x40\x60\x80\xA0\xC0\xE0]/s', substr($MPCheaderData, 0, 4))) { } elseif (preg_match('/^[\x00\x01\x10\x11\x40\x41\x50\x51\x80\x81\x90\x91\xC0\xC1\xD0\xD1][\x20-37][\x00\x20\x40\x60\x80\xA0\xC0\xE0]/s', $MPCheaderData)) {
// this is SV4 - SV6, handle seperately // this is SV4 - SV6, handle seperately
$thisfile_mpc_header['size'] = 8; return $this->ParseMPCsv6($fd, $ThisFileInfo);
// add size of file header to avdataoffset - calc bitrate correctly + MD5 data
$ThisFileInfo['avdataoffset'] += $thisfile_mpc_header['size'];
// Most of this code adapted from Jurgen Faul's MPEGplus source code - thanks Jurgen! :)
$HeaderDWORD[0] = getid3_lib::LittleEndian2Int(substr($MPCheaderData, 0, 4));
$HeaderDWORD[1] = getid3_lib::LittleEndian2Int(substr($MPCheaderData, 4, 4));
// DDDD DDDD CCCC CCCC BBBB BBBB AAAA AAAA
// aaaa aaaa abcd dddd dddd deee eeff ffff
//
// a = bitrate = anything
// b = IS = anything
// c = MS = anything
// d = streamversion = 0000000004 or 0000000005 or 0000000006
// e = maxband = anything
// f = blocksize = 000001 for SV5+, anything(?) for SV4
$thisfile_mpc_header['target_bitrate'] = (($HeaderDWORD[0] & 0xFF800000) >> 23);
$thisfile_mpc_header['intensity_stereo'] = (bool) (($HeaderDWORD[0] & 0x00400000) >> 22);
$thisfile_mpc_header['mid-side_stereo'] = (bool) (($HeaderDWORD[0] & 0x00200000) >> 21);
$thisfile_mpc_header['stream_major_version'] = ($HeaderDWORD[0] & 0x001FF800) >> 11;
$thisfile_mpc_header['stream_minor_version'] = 0; // no sub-version numbers before SV7
$thisfile_mpc_header['max_band'] = ($HeaderDWORD[0] & 0x000007C0) >> 6; // related to lowpass frequency, not sure how it translates exactly
$thisfile_mpc_header['block_size'] = ($HeaderDWORD[0] & 0x0000003F);
switch ($thisfile_mpc_header['stream_major_version']) {
case 4:
$thisfile_mpc_header['frame_count'] = ($HeaderDWORD[1] >> 16);
break;
case 5:
case 6:
$thisfile_mpc_header['frame_count'] = $HeaderDWORD[1];
break;
default:
$ThisFileInfo['error'] = 'Expecting 4, 5 or 6 in version field, found '.$thisfile_mpc_header['stream_major_version'].' instead';
unset($ThisFileInfo['mpc']);
return false;
break;
}
if (($thisfile_mpc_header['stream_major_version'] > 4) && ($thisfile_mpc_header['block_size'] != 1)) {
$ThisFileInfo['warning'][] = 'Block size expected to be 1, actual value found: '.$thisfile_mpc_header['block_size'];
}
$thisfile_mpc_header['sample_rate'] = 44100; // AB: used by all files up to SV7
$ThisFileInfo['audio']['sample_rate'] = $thisfile_mpc_header['sample_rate'];
$thisfile_mpc_header['samples'] = $thisfile_mpc_header['frame_count'] * 1152 * $ThisFileInfo['audio']['channels'];
if ($thisfile_mpc_header['target_bitrate'] == 0) {
$ThisFileInfo['audio']['bitrate_mode'] = 'vbr';
} else {
$ThisFileInfo['audio']['bitrate_mode'] = 'cbr';
}
$ThisFileInfo['mpc']['bitrate'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8 * 44100 / $thisfile_mpc_header['frame_count'] / 1152;
$ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['mpc']['bitrate'];
$ThisFileInfo['audio']['encoder'] = 'SV'.$thisfile_mpc_header['stream_major_version'];
return true;
} else { } else {
$ThisFileInfo['error'][] = 'Expecting "MP+" at offset '.$ThisFileInfo['avdataoffset'].', found "'.substr($MPCheaderData, $offset, 3).'"'; $ThisFileInfo['error'][] = 'Expecting "MP+" or "MPCK" at offset '.$ThisFileInfo['avdataoffset'].', found "'.substr($MPCheaderData, 0, 4).'"';
unset($ThisFileInfo['fileformat']); unset($ThisFileInfo['fileformat']);
unset($ThisFileInfo['mpc']); unset($ThisFileInfo['mpc']);
return false; return false;
} }
return false;
}
function ParseMPCsv8(&$fd, &$ThisFileInfo) {
// this is SV8
// http://trac.musepack.net/trac/wiki/SV8Specification
$thisfile_mpc_header = &$ThisFileInfo['mpc']['header'];
$keyNameSize = 2;
$maxHandledPacketLength = 9; // specs say: "n*8; 0 < n < 10"
$offset = ftell($fd);
while ($offset < $ThisFileInfo['avdataend']) {
$thisPacket = array();
$thisPacket['offset'] = $offset;
$packet_offset = 0;
// Size is a variable-size field, could be 1-4 bytes (possibly more?)
// read enough data in and figure out the exact size later
$MPCheaderData = fread($fd, $keyNameSize + $maxHandledPacketLength);
$packet_offset += $keyNameSize;
$thisPacket['key'] = substr($MPCheaderData, 0, $keyNameSize);
$thisPacket['key_name'] = $this->MPCsv8PacketName($thisPacket['key']);
if ($thisPacket['key'] == $thisPacket['key_name']) {
$ThisFileInfo['error'][] = 'Found unexpected key value "'.$thisPacket['key'].'" at offset '.$thisPacket['offset'];
return false;
}
$packetLength = 0;
$thisPacket['packet_size'] = $this->SV8variableLengthInteger(substr($MPCheaderData, $keyNameSize), $packetLength); // includes keyname and packet_size field
if ($thisPacket['packet_size'] === false) {
$ThisFileInfo['error'][] = 'Did not find expected packet length within '.$maxHandledPacketLength.' bytes at offset '.($thisPacket['offset'] + $keyNameSize);
return false;
}
$packet_offset += $packetLength;
$offset += $thisPacket['packet_size'];
switch ($thisPacket['key']) {
case 'SH': // Stream Header
$moreBytesToRead = $thisPacket['packet_size'] - $keyNameSize - $maxHandledPacketLength;
if ($moreBytesToRead > 0) {
$MPCheaderData .= fread($fd, $moreBytesToRead);
}
$thisPacket['crc'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 4));
$packet_offset += 4;
$thisPacket['stream_version'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
$packet_offset += 1;
$packetLength = 0;
$thisPacket['sample_count'] = $this->SV8variableLengthInteger(substr($MPCheaderData, $packet_offset, $maxHandledPacketLength), $packetLength);
$packet_offset += $packetLength;
$packetLength = 0;
$thisPacket['beginning_silence'] = $this->SV8variableLengthInteger(substr($MPCheaderData, $packet_offset, $maxHandledPacketLength), $packetLength);
$packet_offset += $packetLength;
$otherUsefulData = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 2));
$packet_offset += 2;
$thisPacket['sample_frequency_raw'] = (($otherUsefulData & 0xE000) >> 13);
$thisPacket['max_bands_used'] = (($otherUsefulData & 0x1F00) >> 8);
$thisPacket['channels'] = (($otherUsefulData & 0x00F0) >> 4) + 1;
$thisPacket['ms_used'] = (bool) (($otherUsefulData & 0x0008) >> 3);
$thisPacket['audio_block_frames'] = (($otherUsefulData & 0x0007) >> 0);
$thisPacket['sample_frequency'] = $this->MPCfrequencyLookup($thisPacket['sample_frequency_raw']);
$thisfile_mpc_header['mid_side_stereo'] = $thisPacket['ms_used'];
$thisfile_mpc_header['sample_rate'] = $thisPacket['sample_frequency'];
$thisfile_mpc_header['samples'] = $thisPacket['sample_count'];
$thisfile_mpc_header['stream_version_major'] = $thisPacket['stream_version'];
$ThisFileInfo['audio']['channels'] = $thisPacket['channels'];
$ThisFileInfo['audio']['sample_rate'] = $thisPacket['sample_frequency'];
$ThisFileInfo['playtime_seconds'] = $thisPacket['sample_count'] / $thisPacket['sample_frequency'];
$ThisFileInfo['audio']['bitrate'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['playtime_seconds'];
break;
case 'RG': // Replay Gain
$moreBytesToRead = $thisPacket['packet_size'] - $keyNameSize - $maxHandledPacketLength;
if ($moreBytesToRead > 0) {
$MPCheaderData .= fread($fd, $moreBytesToRead);
}
$thisPacket['replaygain_version'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
$packet_offset += 1;
$thisPacket['replaygain_title_gain'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 2));
$packet_offset += 2;
$thisPacket['replaygain_title_peak'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 2));
$packet_offset += 2;
$thisPacket['replaygain_album_gain'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 2));
$packet_offset += 2;
$thisPacket['replaygain_album_peak'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 2));
$packet_offset += 2;
if ($thisPacket['replaygain_title_gain']) { $ThisFileInfo['replay_gain']['title']['gain'] = $thisPacket['replaygain_title_gain']; }
if ($thisPacket['replaygain_title_peak']) { $ThisFileInfo['replay_gain']['title']['peak'] = $thisPacket['replaygain_title_peak']; }
if ($thisPacket['replaygain_album_gain']) { $ThisFileInfo['replay_gain']['album']['gain'] = $thisPacket['replaygain_album_gain']; }
if ($thisPacket['replaygain_album_peak']) { $ThisFileInfo['replay_gain']['album']['peak'] = $thisPacket['replaygain_album_peak']; }
break;
case 'EI': // Encoder Info
$moreBytesToRead = $thisPacket['packet_size'] - $keyNameSize - $maxHandledPacketLength;
if ($moreBytesToRead > 0) {
$MPCheaderData .= fread($fd, $moreBytesToRead);
}
$profile_pns = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
$packet_offset += 1;
$quality_int = (($profile_pns & 0xF0) >> 4);
$quality_dec = (($profile_pns & 0x0E) >> 3);
$thisPacket['quality'] = (float) $quality_int + ($quality_dec / 8);
$thisPacket['pns_tool'] = (bool) (($profile_pns & 0x01) >> 0);
$thisPacket['version_major'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
$packet_offset += 1;
$thisPacket['version_minor'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
$packet_offset += 1;
$thisPacket['version_build'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
$packet_offset += 1;
$thisPacket['version'] = $thisPacket['version_major'].'.'.$thisPacket['version_minor'].'.'.$thisPacket['version_build'];
$ThisFileInfo['audio']['encoder'] = 'MPC v'.$thisPacket['version'].' ('.(($thisPacket['version_minor'] % 2) ? 'unstable' : 'stable').')';
$thisfile_mpc_header['encoder_version'] = $ThisFileInfo['audio']['encoder'];
//$thisfile_mpc_header['quality'] = (float) ($thisPacket['quality'] / 1.5875); // values can range from 0.000 to 15.875, mapped to qualities of 0.0 to 10.0
$thisfile_mpc_header['quality'] = (float) ($thisPacket['quality'] - 5); // values can range from 0.000 to 15.875, of which 0..4 are "reserved/experimental", and 5..15 are mapped to qualities of 0.0 to 10.0
break;
case 'SO': // Seek Table Offset
$packetLength = 0;
$thisPacket['seek_table_offset'] = $thisPacket['offset'] + $this->SV8variableLengthInteger(substr($MPCheaderData, $packet_offset, $maxHandledPacketLength), $packetLength);
$packet_offset += $packetLength;
break;
case 'ST': // Seek Table
case 'SE': // Stream End
case 'AP': // Audio Data
// nothing useful here, just skip this packet
$thisPacket = array();
break;
default:
$ThisFileInfo['error'][] = 'Found unhandled key type "'.$thisPacket['key'].'" at offset '.$thisPacket['offset'];
return false;
break;
}
if (!empty($thisPacket)) {
$ThisFileInfo['mpc']['packets'][] = $thisPacket;
}
fseek($fd, $offset);
}
$thisfile_mpc_header['size'] = $offset;
return true;
}
function ParseMPCsv7(&$fd, &$ThisFileInfo) {
// this is SV7
// http://www.uni-jena.de/~pfk/mpp/sv8/header.html
$thisfile_mpc_header = &$ThisFileInfo['mpc']['header'];
$offset = 0;
$thisfile_mpc_header['size'] = 28;
$MPCheaderData = $ThisFileInfo['mpc']['header']['preamble'];
$MPCheaderData .= fread($fd, $thisfile_mpc_header['size'] - strlen($ThisFileInfo['mpc']['header']['preamble']));
$offset = strlen('MP+');
// Continue with SV7+ handling
$StreamVersionByte = getid3_lib::LittleEndian2Int(substr($MPCheaderData, $offset, 1)); $StreamVersionByte = getid3_lib::LittleEndian2Int(substr($MPCheaderData, $offset, 1));
$offset += 1; $offset += 1;
$thisfile_mpc_header['stream_major_version'] = ($StreamVersionByte & 0x0F); $thisfile_mpc_header['stream_version_major'] = ($StreamVersionByte & 0x0F) >> 0;
$thisfile_mpc_header['stream_minor_version'] = ($StreamVersionByte & 0xF0) >> 4; $thisfile_mpc_header['stream_version_minor'] = ($StreamVersionByte & 0xF0) >> 4; // should always be 0, subversions no longer exist in SV8
$thisfile_mpc_header['frame_count'] = getid3_lib::LittleEndian2Int(substr($MPCheaderData, $offset, 4)); $thisfile_mpc_header['frame_count'] = getid3_lib::LittleEndian2Int(substr($MPCheaderData, $offset, 4));
$offset += 4; $offset += 4;
switch ($thisfile_mpc_header['stream_major_version']) { if ($thisfile_mpc_header['stream_version_major'] != 7) {
case 7: $ThisFileInfo['error'][] = 'Only Musepack SV7 supported (this file claims to be v'.$thisfile_mpc_header['stream_version_major'].')';
//$ThisFileInfo['fileformat'] = 'SV7'; return false;
break;
default:
$ThisFileInfo['error'][] = 'Only Musepack SV7 supported';
return false;
} }
$FlagsDWORD1 = getid3_lib::LittleEndian2Int(substr($MPCheaderData, $offset, 4)); $FlagsDWORD1 = getid3_lib::LittleEndian2Int(substr($MPCheaderData, $offset, 4));
@ -217,13 +308,88 @@ class getid3_mpc
$ThisFileInfo['replay_gain']['album']['peak'] = $thisfile_mpc_header['album_peak']; $ThisFileInfo['replay_gain']['album']['peak'] = $thisfile_mpc_header['album_peak'];
} }
//$ThisFileInfo['audio']['encoder'] = 'SV'.$thisfile_mpc_header['stream_major_version'].'.'.$thisfile_mpc_header['stream_minor_version'].', '.$thisfile_mpc_header['encoder_version']; //$ThisFileInfo['audio']['encoder'] = 'SV'.$thisfile_mpc_header['stream_version_major'].'.'.$thisfile_mpc_header['stream_version_minor'].', '.$thisfile_mpc_header['encoder_version'];
$ThisFileInfo['audio']['encoder'] = $thisfile_mpc_header['encoder_version']; $ThisFileInfo['audio']['encoder'] = $thisfile_mpc_header['encoder_version'];
$ThisFileInfo['audio']['encoder_options'] = $thisfile_mpc_header['profile']; $ThisFileInfo['audio']['encoder_options'] = $thisfile_mpc_header['profile'];
$thisfile_mpc_header['quality'] = (float) ($thisfile_mpc_header['raw']['profile'] - 5); // values can range from 0 to 15, of which 0..4 are "reserved/experimental", and 5..15 are mapped to qualities of 0.0 to 10.0
return true; return true;
} }
function ParseMPCsv6(&$fd, &$ThisFileInfo) {
// this is SV4 - SV6
$thisfile_mpc_header = &$ThisFileInfo['mpc']['header'];
$offset = 0;
$thisfile_mpc_header['size'] = 8;
fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
$MPCheaderData = fread($fd, $thisfile_mpc_header['size']);
// add size of file header to avdataoffset - calc bitrate correctly + MD5 data
$ThisFileInfo['avdataoffset'] += $thisfile_mpc_header['size'];
// Most of this code adapted from Jurgen Faul's MPEGplus source code - thanks Jurgen! :)
$HeaderDWORD[0] = getid3_lib::LittleEndian2Int(substr($MPCheaderData, 0, 4));
$HeaderDWORD[1] = getid3_lib::LittleEndian2Int(substr($MPCheaderData, 4, 4));
// DDDD DDDD CCCC CCCC BBBB BBBB AAAA AAAA
// aaaa aaaa abcd dddd dddd deee eeff ffff
//
// a = bitrate = anything
// b = IS = anything
// c = MS = anything
// d = streamversion = 0000000004 or 0000000005 or 0000000006
// e = maxband = anything
// f = blocksize = 000001 for SV5+, anything(?) for SV4
$thisfile_mpc_header['target_bitrate'] = (($HeaderDWORD[0] & 0xFF800000) >> 23);
$thisfile_mpc_header['intensity_stereo'] = (bool) (($HeaderDWORD[0] & 0x00400000) >> 22);
$thisfile_mpc_header['mid_side_stereo'] = (bool) (($HeaderDWORD[0] & 0x00200000) >> 21);
$thisfile_mpc_header['stream_version_major'] = ($HeaderDWORD[0] & 0x001FF800) >> 11;
$thisfile_mpc_header['stream_version_minor'] = 0; // no sub-version numbers before SV7
$thisfile_mpc_header['max_band'] = ($HeaderDWORD[0] & 0x000007C0) >> 6; // related to lowpass frequency, not sure how it translates exactly
$thisfile_mpc_header['block_size'] = ($HeaderDWORD[0] & 0x0000003F);
switch ($thisfile_mpc_header['stream_version_major']) {
case 4:
$thisfile_mpc_header['frame_count'] = ($HeaderDWORD[1] >> 16);
break;
case 5:
case 6:
$thisfile_mpc_header['frame_count'] = $HeaderDWORD[1];
break;
default:
$ThisFileInfo['error'] = 'Expecting 4, 5 or 6 in version field, found '.$thisfile_mpc_header['stream_version_major'].' instead';
unset($ThisFileInfo['mpc']);
return false;
break;
}
if (($thisfile_mpc_header['stream_version_major'] > 4) && ($thisfile_mpc_header['block_size'] != 1)) {
$ThisFileInfo['warning'][] = 'Block size expected to be 1, actual value found: '.$thisfile_mpc_header['block_size'];
}
$thisfile_mpc_header['sample_rate'] = 44100; // AB: used by all files up to SV7
$ThisFileInfo['audio']['sample_rate'] = $thisfile_mpc_header['sample_rate'];
$thisfile_mpc_header['samples'] = $thisfile_mpc_header['frame_count'] * 1152 * $ThisFileInfo['audio']['channels'];
if ($thisfile_mpc_header['target_bitrate'] == 0) {
$ThisFileInfo['audio']['bitrate_mode'] = 'vbr';
} else {
$ThisFileInfo['audio']['bitrate_mode'] = 'cbr';
}
$ThisFileInfo['mpc']['bitrate'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8 * 44100 / $thisfile_mpc_header['frame_count'] / 1152;
$ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['mpc']['bitrate'];
$ThisFileInfo['audio']['encoder'] = 'SV'.$thisfile_mpc_header['stream_version_major'];
return true;
}
function MPCprofileNameLookup($profileid) { function MPCprofileNameLookup($profileid) {
static $MPCprofileNameLookup = array( static $MPCprofileNameLookup = array(
0 => 'no profile', 0 => 'no profile',
@ -290,6 +456,46 @@ class getid3_mpc
return number_format($encoderversion / 100, 2).' alpha'; return number_format($encoderversion / 100, 2).' alpha';
} }
function SV8variableLengthInteger($data, &$packetLength, $maxHandledPacketLength=9) {
$packet_size = 0;
for ($packetLength = 1; $packetLength <= $maxHandledPacketLength; $packetLength++) {
// variable-length size field:
// bits, big-endian
// 0xxx xxxx - value 0 to 2^7-1
// 1xxx xxxx 0xxx xxxx - value 0 to 2^14-1
// 1xxx xxxx 1xxx xxxx 0xxx xxxx - value 0 to 2^21-1
// 1xxx xxxx 1xxx xxxx 1xxx xxxx 0xxx xxxx - value 0 to 2^28-1
// ...
$thisbyte = ord(substr($data, ($packetLength - 1), 1));
// look through bytes until find a byte with MSB==0
$packet_size = ($packet_size << 7);
$packet_size = ($packet_size | ($thisbyte & 0x7F));
if (($thisbyte & 0x80) === 0) {
break;
}
if ($packetLength >= $maxHandledPacketLength) {
return false;
}
}
return $packet_size;
}
function MPCsv8PacketName($packetKey) {
static $MPCsv8PacketName = array();
if (empty($MPCsv8PacketName)) {
$MPCsv8PacketName = array(
'AP' => 'Audio Packet',
'CT' => 'Chapter Tag',
'EI' => 'Encoder Info',
'RG' => 'Replay Gain',
'SE' => 'Stream End',
'SH' => 'Stream Header',
'SO' => 'Seek Table Offset',
'ST' => 'Seek Table',
);
}
return (isset($MPCsv8PacketName[$packetKey]) ? $MPCsv8PacketName[$packetKey] : $packetKey);
}
} }

View File

@ -59,49 +59,7 @@ class getid3_ogg
} elseif (substr($filedata, 1, 6) == 'vorbis') { } elseif (substr($filedata, 1, 6) == 'vorbis') {
$ThisFileInfo['audio']['dataformat'] = 'vorbis'; $this->ParseVorbisPageHeader($filedata, $filedataoffset, $ThisFileInfo, $oggpageinfo);
$ThisFileInfo['audio']['lossless'] = false;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['packet_type'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
$filedataoffset += 1;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type'] = substr($filedata, $filedataoffset, 6); // hard-coded to 'vorbis'
$filedataoffset += 6;
$ThisFileInfo['ogg']['bitstreamversion'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['numberofchannels'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
$filedataoffset += 1;
$ThisFileInfo['audio']['channels'] = $ThisFileInfo['ogg']['numberofchannels'];
$ThisFileInfo['ogg']['samplerate'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
if ($ThisFileInfo['ogg']['samplerate'] == 0) {
$ThisFileInfo['error'][] = 'Corrupt Ogg file: sample rate == zero';
return false;
}
$ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['ogg']['samplerate'];
$ThisFileInfo['ogg']['samples'] = 0; // filled in later
$ThisFileInfo['ogg']['bitrate_average'] = 0; // filled in later
$ThisFileInfo['ogg']['bitrate_max'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['bitrate_nominal'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['bitrate_min'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['blocksize_small'] = pow(2, getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)) & 0x0F);
$ThisFileInfo['ogg']['blocksize_large'] = pow(2, (getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)) & 0xF0) >> 4);
$ThisFileInfo['ogg']['stop_bit'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)); // must be 1, marks end of packet
$ThisFileInfo['audio']['bitrate_mode'] = 'vbr'; // overridden if actually abr
if ($ThisFileInfo['ogg']['bitrate_max'] == 0xFFFFFFFF) {
unset($ThisFileInfo['ogg']['bitrate_max']);
$ThisFileInfo['audio']['bitrate_mode'] = 'abr';
}
if ($ThisFileInfo['ogg']['bitrate_nominal'] == 0xFFFFFFFF) {
unset($ThisFileInfo['ogg']['bitrate_nominal']);
}
if ($ThisFileInfo['ogg']['bitrate_min'] == 0xFFFFFFFF) {
unset($ThisFileInfo['ogg']['bitrate_min']);
$ThisFileInfo['audio']['bitrate_mode'] = 'abr';
}
} elseif (substr($filedata, 0, 8) == 'Speex ') { } elseif (substr($filedata, 0, 8) == 'Speex ') {
@ -112,9 +70,9 @@ class getid3_ogg
$ThisFileInfo['audio']['bitrate_mode'] = 'abr'; $ThisFileInfo['audio']['bitrate_mode'] = 'abr';
$ThisFileInfo['audio']['lossless'] = false; $ThisFileInfo['audio']['lossless'] = false;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_string'] = substr($filedata, $filedataoffset, 8); // hard-coded to 'Speex ' $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_string'] = substr($filedata, $filedataoffset, 8); // hard-coded to 'Speex '
$filedataoffset += 8; $filedataoffset += 8;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version'] = substr($filedata, $filedataoffset, 20); $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version'] = substr($filedata, $filedataoffset, 20);
$filedataoffset += 20; $filedataoffset += 20;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version_id'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version_id'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4; $filedataoffset += 4;
@ -175,7 +133,7 @@ class getid3_ogg
case 'vorbis': case 'vorbis':
$filedata = fread($fd, $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']); $filedata = fread($fd, $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['packet_type'] = getid3_lib::LittleEndian2Int(substr($filedata, 0, 1)); $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['packet_type'] = getid3_lib::LittleEndian2Int(substr($filedata, 0, 1));
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type'] = substr($filedata, 1, 6); // hard-coded to 'vorbis' $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type'] = substr($filedata, 1, 6); // hard-coded to 'vorbis'
getid3_ogg::ParseVorbisCommentsFilepointer($fd, $ThisFileInfo); getid3_ogg::ParseVorbisCommentsFilepointer($fd, $ThisFileInfo);
break; break;
@ -198,18 +156,26 @@ class getid3_ogg
// Last Page - Number of Samples // Last Page - Number of Samples
fseek($fd, max($ThisFileInfo['avdataend'] - GETID3_FREAD_BUFFER_SIZE, 0), SEEK_SET); if ($ThisFileInfo['avdataend'] >= pow(2, 31)) {
$LastChunkOfOgg = strrev(fread($fd, GETID3_FREAD_BUFFER_SIZE));
if ($LastOggSpostion = strpos($LastChunkOfOgg, 'SggO')) { $ThisFileInfo['warning'][] = 'Unable to parse Ogg end chunk file (PHP does not support file operations beyond 2GB)';
fseek($fd, $ThisFileInfo['avdataend'] - ($LastOggSpostion + strlen('SggO')), SEEK_SET);
$ThisFileInfo['avdataend'] = ftell($fd); } else {
$ThisFileInfo['ogg']['pageheader']['eos'] = getid3_ogg::ParseOggPageHeader($fd);
$ThisFileInfo['ogg']['samples'] = $ThisFileInfo['ogg']['pageheader']['eos']['pcm_abs_position']; fseek($fd, max($ThisFileInfo['avdataend'] - GETID3_FREAD_BUFFER_SIZE, 0), SEEK_SET);
if ($ThisFileInfo['ogg']['samples'] == 0) { $LastChunkOfOgg = strrev(fread($fd, GETID3_FREAD_BUFFER_SIZE));
$ThisFileInfo['error'][] = 'Corrupt Ogg file: eos.number of samples == zero'; if ($LastOggSpostion = strpos($LastChunkOfOgg, 'SggO')) {
return false; fseek($fd, $ThisFileInfo['avdataend'] - ($LastOggSpostion + strlen('SggO')), SEEK_SET);
$ThisFileInfo['avdataend'] = ftell($fd);
$ThisFileInfo['ogg']['pageheader']['eos'] = getid3_ogg::ParseOggPageHeader($fd);
$ThisFileInfo['ogg']['samples'] = $ThisFileInfo['ogg']['pageheader']['eos']['pcm_abs_position'];
if ($ThisFileInfo['ogg']['samples'] == 0) {
$ThisFileInfo['error'][] = 'Corrupt Ogg file: eos.number of samples == zero';
return false;
}
$ThisFileInfo['ogg']['bitrate_average'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / ($ThisFileInfo['ogg']['samples'] / $ThisFileInfo['audio']['sample_rate']);
} }
$ThisFileInfo['ogg']['bitrate_average'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / ($ThisFileInfo['ogg']['samples'] / $ThisFileInfo['audio']['sample_rate']);
} }
if (!empty($ThisFileInfo['ogg']['bitrate_average'])) { if (!empty($ThisFileInfo['ogg']['bitrate_average'])) {
@ -257,6 +223,52 @@ class getid3_ogg
return true; return true;
} }
function ParseVorbisPageHeader(&$filedata, &$filedataoffset, &$ThisFileInfo, &$oggpageinfo) {
$ThisFileInfo['audio']['dataformat'] = 'vorbis';
$ThisFileInfo['audio']['lossless'] = false;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['packet_type'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
$filedataoffset += 1;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type'] = substr($filedata, $filedataoffset, 6); // hard-coded to 'vorbis'
$filedataoffset += 6;
$ThisFileInfo['ogg']['bitstreamversion'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['numberofchannels'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
$filedataoffset += 1;
$ThisFileInfo['audio']['channels'] = $ThisFileInfo['ogg']['numberofchannels'];
$ThisFileInfo['ogg']['samplerate'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
if ($ThisFileInfo['ogg']['samplerate'] == 0) {
$ThisFileInfo['error'][] = 'Corrupt Ogg file: sample rate == zero';
return false;
}
$ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['ogg']['samplerate'];
$ThisFileInfo['ogg']['samples'] = 0; // filled in later
$ThisFileInfo['ogg']['bitrate_average'] = 0; // filled in later
$ThisFileInfo['ogg']['bitrate_max'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['bitrate_nominal'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['bitrate_min'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['blocksize_small'] = pow(2, getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)) & 0x0F);
$ThisFileInfo['ogg']['blocksize_large'] = pow(2, (getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)) & 0xF0) >> 4);
$ThisFileInfo['ogg']['stop_bit'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)); // must be 1, marks end of packet
$ThisFileInfo['audio']['bitrate_mode'] = 'vbr'; // overridden if actually abr
if ($ThisFileInfo['ogg']['bitrate_max'] == 0xFFFFFFFF) {
unset($ThisFileInfo['ogg']['bitrate_max']);
$ThisFileInfo['audio']['bitrate_mode'] = 'abr';
}
if ($ThisFileInfo['ogg']['bitrate_nominal'] == 0xFFFFFFFF) {
unset($ThisFileInfo['ogg']['bitrate_nominal']);
}
if ($ThisFileInfo['ogg']['bitrate_min'] == 0xFFFFFFFF) {
unset($ThisFileInfo['ogg']['bitrate_min']);
$ThisFileInfo['audio']['bitrate_mode'] = 'abr';
}
return true;
}
function ParseOggPageHeader(&$fd) { function ParseOggPageHeader(&$fd) {
// http://xiph.org/ogg/vorbis/doc/framing.html // http://xiph.org/ogg/vorbis/doc/framing.html
@ -434,7 +446,8 @@ class getid3_ogg
$ThisFileInfo['ogg']['comments'][strtolower($ThisFileInfo['ogg']['comments_raw'][$i]['key'])][] = $ThisFileInfo['ogg']['comments_raw'][$i]['value']; $ThisFileInfo['ogg']['comments'][strtolower($ThisFileInfo['ogg']['comments_raw'][$i]['key'])][] = $ThisFileInfo['ogg']['comments_raw'][$i]['value'];
$imagechunkcheck = getid3_lib::GetDataImageSize($ThisFileInfo['ogg']['comments_raw'][$i]['data']); $imageinfo = array();
$imagechunkcheck = getid3_lib::GetDataImageSize($ThisFileInfo['ogg']['comments_raw'][$i]['data'], $imageinfo);
$ThisFileInfo['ogg']['comments_raw'][$i]['image_mime'] = getid3_lib::image_type_to_mime_type($imagechunkcheck[2]); $ThisFileInfo['ogg']['comments_raw'][$i]['image_mime'] = getid3_lib::image_type_to_mime_type($imagechunkcheck[2]);
if (!$ThisFileInfo['ogg']['comments_raw'][$i]['image_mime'] || ($ThisFileInfo['ogg']['comments_raw'][$i]['image_mime'] == 'application/octet-stream')) { if (!$ThisFileInfo['ogg']['comments_raw'][$i]['image_mime'] || ($ThisFileInfo['ogg']['comments_raw'][$i]['image_mime'] == 'application/octet-stream')) {
unset($ThisFileInfo['ogg']['comments_raw'][$i]['image_mime']); unset($ThisFileInfo['ogg']['comments_raw'][$i]['image_mime']);

View File

@ -123,7 +123,7 @@ class getid3_shorten
return false; return false;
} }
} }
$commandline = GETID3_HELPERAPPSDIR.'shorten.exe -x "'.$ThisFileInfo['filenamepath'].'" - | '.GETID3_HELPERAPPSDIR.'head.exe -c 44'; $commandline = GETID3_HELPERAPPSDIR.'shorten.exe -x "'.$ThisFileInfo['filenamepath'].'" - | '.GETID3_HELPERAPPSDIR.'head.exe -c 64';
$commandline = str_replace('/', '\\', $commandline); $commandline = str_replace('/', '\\', $commandline);
} else { } else {
@ -136,7 +136,7 @@ class getid3_shorten
$ThisFileInfo['error'][] = 'shorten binary was not found in path or /usr/local/bin'; $ThisFileInfo['error'][] = 'shorten binary was not found in path or /usr/local/bin';
return false; return false;
} }
$commandline = (file_exists('/usr/local/bin/shorten') ? '/usr/local/bin/' : '' ) . 'shorten -x '.escapeshellarg($ThisFileInfo['filenamepath']).' - | head -c 44'; $commandline = (file_exists('/usr/local/bin/shorten') ? '/usr/local/bin/' : '' ) . 'shorten -x '.escapeshellarg($ThisFileInfo['filenamepath']).' - | head -c 64';
} }
@ -146,14 +146,15 @@ class getid3_shorten
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true); getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
$DecodedWAVFORMATEX = getid3_riff::RIFFparseWAVEFORMATex(substr($output, 20, 16)); $fmt_size = getid3_lib::LittleEndian2Int(substr($output, 16, 4));
$DecodedWAVFORMATEX = getid3_riff::RIFFparseWAVEFORMATex(substr($output, 20, $fmt_size));
$ThisFileInfo['audio']['channels'] = $DecodedWAVFORMATEX['channels']; $ThisFileInfo['audio']['channels'] = $DecodedWAVFORMATEX['channels'];
$ThisFileInfo['audio']['bits_per_sample'] = $DecodedWAVFORMATEX['bits_per_sample']; $ThisFileInfo['audio']['bits_per_sample'] = $DecodedWAVFORMATEX['bits_per_sample'];
$ThisFileInfo['audio']['sample_rate'] = $DecodedWAVFORMATEX['sample_rate']; $ThisFileInfo['audio']['sample_rate'] = $DecodedWAVFORMATEX['sample_rate'];
if (substr($output, 36, 4) == 'data') { if (substr($output, 20 + $fmt_size, 4) == 'data') {
$ThisFileInfo['playtime_seconds'] = getid3_lib::LittleEndian2Int(substr($output, 40, 4)) / $DecodedWAVFORMATEX['raw']['nAvgBytesPerSec']; $ThisFileInfo['playtime_seconds'] = getid3_lib::LittleEndian2Int(substr($output, 20 + 4 + $fmt_size, 4)) / $DecodedWAVFORMATEX['raw']['nAvgBytesPerSec'];
} else { } else {

View File

@ -185,6 +185,8 @@ class getid3_bmp
// DWORD biClrUsed; // DWORD biClrUsed;
// DWORD biClrImportant; // DWORD biClrImportant;
// possibly integrate this section and module.audio-video.riff.php::ParseBITMAPINFOHEADER() ?
$thisfile_bmp_header_raw['width'] = getid3_lib::LittleEndian2Int(substr($BMPheader, $offset, 4), true); $thisfile_bmp_header_raw['width'] = getid3_lib::LittleEndian2Int(substr($BMPheader, $offset, 4), true);
$offset += 4; $offset += 4;
$thisfile_bmp_header_raw['height'] = getid3_lib::LittleEndian2Int(substr($BMPheader, $offset, 4), true); $thisfile_bmp_header_raw['height'] = getid3_lib::LittleEndian2Int(substr($BMPheader, $offset, 4), true);

View File

@ -27,45 +27,222 @@ class getid3_jpg
fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET); fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
list($width, $height, $type) = getid3_lib::GetDataImageSize(fread($fd, $ThisFileInfo['filesize'])); $imageinfo = array();
if ($type == 2) { list($width, $height, $type) = getid3_lib::GetDataImageSize(fread($fd, $ThisFileInfo['filesize']), $imageinfo);
$ThisFileInfo['video']['resolution_x'] = $width; if (isset($imageinfo['APP13'])) {
$ThisFileInfo['video']['resolution_y'] = $height; // http://php.net/iptcparse
// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/IPTC.html
$iptc_parsed = iptcparse($imageinfo['APP13']);
if (is_array($iptc_parsed)) {
foreach ($iptc_parsed as $iptc_key_raw => $iptc_values) {
list($iptc_record, $iptc_tagkey) = explode('#', $iptc_key_raw);
$iptc_tagkey = intval(ltrim($iptc_tagkey, '0'));
foreach ($iptc_values as $key => $value) {
@$ThisFileInfo['iptc'][$this->IPTCrecordName($iptc_record)][$this->IPTCrecordTagName($iptc_record, $iptc_tagkey)][] = $value;
}
}
}
//echo '<pre>'.htmlentities(print_r($iptc_parsed, true)).'</pre>';
}
if (version_compare(phpversion(), '4.2.0', '>=')) { switch ($type) {
case 2: // JPEG
$ThisFileInfo['video']['resolution_x'] = $width;
$ThisFileInfo['video']['resolution_y'] = $height;
if (function_exists('exif_read_data')) { if (version_compare(phpversion(), '4.2.0', '>=')) {
if (function_exists('exif_read_data')) {
ob_start();
$ThisFileInfo['jpg']['exif'] = exif_read_data($ThisFileInfo['filenamepath'], '', true, false);
$errors = ob_get_contents();
if ($errors) {
$ThisFileInfo['warning'][] = strip_tags($errors);
unset($ThisFileInfo['jpg']['exif']);
}
ob_end_clean();
} else {
$ThisFileInfo['warning'][] = 'EXIF parsing only available when '.(GETID3_OS_ISWINDOWS ? 'php_exif.dll enabled' : 'compiled with --enable-exif');
ob_start();
$ThisFileInfo['jpg']['exif'] = exif_read_data($ThisFileInfo['filenamepath'], '', true, false);
$errors = ob_get_contents();
if ($errors) {
$ThisFileInfo['error'][] = strip_tags($errors);
unset($ThisFileInfo['jpg']['exif']);
} }
ob_end_clean();
} else { } else {
$ThisFileInfo['warning'][] = 'EXIF parsing only available when '.(GETID3_OS_ISWINDOWS ? 'php_exif.dll enabled' : 'compiled with --enable-exif'); $ThisFileInfo['warning'][] = 'EXIF parsing only available in PHP v4.2.0 and higher compiled with --enable-exif (or php_exif.dll enabled for Windows). You are using PHP v'.phpversion();
} }
} else { return true;
break;
$ThisFileInfo['warning'][] = 'EXIF parsing only available in PHP v4.2.0 and higher compiled with --enable-exif (or php_exif.dll enabled for Windows). You are using PHP v'.phpversion();
}
return true;
default:
break;
} }
unset($ThisFileInfo['fileformat']); unset($ThisFileInfo['fileformat']);
return false; return false;
} }
function IPTCrecordName($iptc_record) {
// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/IPTC.html
static $IPTCrecordName = array();
if (empty($IPTCrecordName)) {
$IPTCrecordName = array(
1 => 'IPTCEnvelope',
2 => 'IPTCApplication',
3 => 'IPTCNewsPhoto',
7 => 'IPTCPreObjectData',
8 => 'IPTCObjectData',
9 => 'IPTCPostObjectData',
);
}
return (isset($IPTCrecordName[$iptc_record]) ? $IPTCrecordName[$iptc_record] : '');
}
function IPTCrecordTagName($iptc_record, $iptc_tagkey) {
// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/IPTC.html
static $IPTCrecordTagName = array();
if (empty($IPTCrecordTagName)) {
$IPTCrecordTagName = array(
1 => array( // IPTC EnvelopeRecord Tags
0 => 'EnvelopeRecordVersion',
5 => 'Destination',
20 => 'FileFormat',
22 => 'FileVersion',
30 => 'ServiceIdentifier',
40 => 'EnvelopeNumber',
50 => 'ProductID',
60 => 'EnvelopePriority',
70 => 'DateSent',
80 => 'TimeSent',
90 => 'CodedCharacterSet',
100 => 'UniqueObjectName',
120 => 'ARMIdentifier',
122 => 'ARMVersion',
),
2 => array( // IPTC ApplicationRecord Tags
0 => 'ApplicationRecordVersion',
3 => 'ObjectTypeReference',
4 => 'ObjectAttributeReference',
5 => 'ObjectName',
7 => 'EditStatus',
8 => 'EditorialUpdate',
10 => 'Urgency',
12 => 'SubjectReference',
15 => 'Category',
20 => 'SupplementalCategories',
22 => 'FixtureIdentifier',
25 => 'Keywords',
26 => 'ContentLocationCode',
27 => 'ContentLocationName',
30 => 'ReleaseDate',
35 => 'ReleaseTime',
37 => 'ExpirationDate',
38 => 'ExpirationTime',
40 => 'SpecialInstructions',
42 => 'ActionAdvised',
45 => 'ReferenceService',
47 => 'ReferenceDate',
50 => 'ReferenceNumber',
55 => 'DateCreated',
60 => 'TimeCreated',
62 => 'DigitalCreationDate',
63 => 'DigitalCreationTime',
65 => 'OriginatingProgram',
70 => 'ProgramVersion',
75 => 'ObjectCycle',
80 => 'By-line',
85 => 'By-lineTitle',
90 => 'City',
92 => 'Sub-location',
95 => 'Province-State',
100 => 'Country-PrimaryLocationCode',
101 => 'Country-PrimaryLocationName',
103 => 'OriginalTransmissionReference',
105 => 'Headline',
110 => 'Credit',
115 => 'Source',
116 => 'CopyrightNotice',
118 => 'Contact',
120 => 'Caption-Abstract',
121 => 'LocalCaption',
122 => 'Writer-Editor',
125 => 'RasterizedCaption',
130 => 'ImageType',
131 => 'ImageOrientation',
135 => 'LanguageIdentifier',
150 => 'AudioType',
151 => 'AudioSamplingRate',
152 => 'AudioSamplingResolution',
153 => 'AudioDuration',
154 => 'AudioOutcue',
184 => 'JobID',
185 => 'MasterDocumentID',
186 => 'ShortDocumentID',
187 => 'UniqueDocumentID',
188 => 'OwnerID',
200 => 'ObjectPreviewFileFormat',
201 => 'ObjectPreviewFileVersion',
202 => 'ObjectPreviewData',
221 => 'Prefs',
225 => 'ClassifyState',
228 => 'SimilarityIndex',
230 => 'DocumentNotes',
231 => 'DocumentHistory',
232 => 'ExifCameraInfo',
),
3 => array( // IPTC NewsPhoto Tags
0 => 'NewsPhotoVersion',
10 => 'IPTCPictureNumber',
20 => 'IPTCImageWidth',
30 => 'IPTCImageHeight',
40 => 'IPTCPixelWidth',
50 => 'IPTCPixelHeight',
55 => 'SupplementalType',
60 => 'ColorRepresentation',
64 => 'InterchangeColorSpace',
65 => 'ColorSequence',
66 => 'ICC_Profile',
70 => 'ColorCalibrationMatrix',
80 => 'LookupTable',
84 => 'NumIndexEntries',
85 => 'ColorPalette',
86 => 'IPTCBitsPerSample',
90 => 'SampleStructure',
100 => 'ScanningDirection',
102 => 'IPTCImageRotation',
110 => 'DataCompressionMethod',
120 => 'QuantizationMethod',
125 => 'EndPoints',
130 => 'ExcursionTolerance',
135 => 'BitsPerComponent',
140 => 'MaximumDensityRange',
145 => 'GammaCompensatedValue',
),
7 => array( // IPTC PreObjectData Tags
10 => 'SizeMode',
20 => 'MaxSubfileSize',
90 => 'ObjectSizeAnnounced',
95 => 'MaximumObjectSize',
),
8 => array( // IPTC ObjectData Tags
10 => 'SubFile',
),
9 => array( // IPTC PostObjectData Tags
10 => 'ConfirmedObjectSize',
),
);
}
return (isset($IPTCrecordTagName[$iptc_record][$iptc_tagkey]) ? $IPTCrecordTagName[$iptc_record][$iptc_tagkey] : $iptc_tagkey);
}
} }

View File

@ -67,13 +67,13 @@ class getid3_png
case 'IHDR': // Image Header case 'IHDR': // Image Header
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
$thisfile_png_chunk_type_text['width'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 4)); $thisfile_png_chunk_type_text['width'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 4));
$thisfile_png_chunk_type_text['height'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 4, 4)); $thisfile_png_chunk_type_text['height'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 4, 4));
$thisfile_png_chunk_type_text['raw']['bit_depth'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 8, 1)); $thisfile_png_chunk_type_text['raw']['bit_depth'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 8, 1));
$thisfile_png_chunk_type_text['raw']['color_type'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 9, 1)); $thisfile_png_chunk_type_text['raw']['color_type'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 9, 1));
$thisfile_png_chunk_type_text['raw']['compression_method'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 10, 1)); $thisfile_png_chunk_type_text['raw']['compression_method'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 10, 1));
$thisfile_png_chunk_type_text['raw']['filter_method'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 11, 1)); $thisfile_png_chunk_type_text['raw']['filter_method'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 11, 1));
$thisfile_png_chunk_type_text['raw']['interlace_method'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 12, 1)); $thisfile_png_chunk_type_text['raw']['interlace_method'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 12, 1));
$thisfile_png_chunk_type_text['compression_method_text'] = $this->PNGcompressionMethodLookup($thisfile_png_chunk_type_text['raw']['compression_method']); $thisfile_png_chunk_type_text['compression_method_text'] = $this->PNGcompressionMethodLookup($thisfile_png_chunk_type_text['raw']['compression_method']);
$thisfile_png_chunk_type_text['color_type']['palette'] = (bool) ($thisfile_png_chunk_type_text['raw']['color_type'] & 0x01); $thisfile_png_chunk_type_text['color_type']['palette'] = (bool) ($thisfile_png_chunk_type_text['raw']['color_type'] & 0x01);
@ -91,12 +91,12 @@ class getid3_png
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
$paletteoffset = 0; $paletteoffset = 0;
for ($i = 0; $i <= 255; $i++) { for ($i = 0; $i <= 255; $i++) {
//$thisfile_png_chunk_type_text['red'][$i] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $paletteoffset++, 1)); //$thisfile_png_chunk_type_text['red'][$i] = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
//$thisfile_png_chunk_type_text['green'][$i] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $paletteoffset++, 1)); //$thisfile_png_chunk_type_text['green'][$i] = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
//$thisfile_png_chunk_type_text['blue'][$i] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $paletteoffset++, 1)); //$thisfile_png_chunk_type_text['blue'][$i] = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
$red = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $paletteoffset++, 1)); $red = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
$green = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $paletteoffset++, 1)); $green = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
$blue = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $paletteoffset++, 1)); $blue = getid3_lib::BigEndian2Int(substr($chunk['data'], $paletteoffset++, 1));
$thisfile_png_chunk_type_text[$i] = (($red << 16) | ($green << 8) | ($blue)); $thisfile_png_chunk_type_text[$i] = (($red << 16) | ($green << 8) | ($blue));
} }
break; break;
@ -106,18 +106,18 @@ class getid3_png
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
switch ($thisfile_png['IHDR']['raw']['color_type']) { switch ($thisfile_png['IHDR']['raw']['color_type']) {
case 0: case 0:
$thisfile_png_chunk_type_text['transparent_color_gray'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 2)); $thisfile_png_chunk_type_text['transparent_color_gray'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 2));
break; break;
case 2: case 2:
$thisfile_png_chunk_type_text['transparent_color_red'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 2)); $thisfile_png_chunk_type_text['transparent_color_red'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 2));
$thisfile_png_chunk_type_text['transparent_color_green'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 2, 2)); $thisfile_png_chunk_type_text['transparent_color_green'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 2, 2));
$thisfile_png_chunk_type_text['transparent_color_blue'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 4, 2)); $thisfile_png_chunk_type_text['transparent_color_blue'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 4, 2));
break; break;
case 3: case 3:
for ($i = 0; $i < strlen($thisfile_png_chunk_type_text['header']['data']); $i++) { for ($i = 0; $i < strlen($chunk['data']); $i++) {
$thisfile_png_chunk_type_text['palette_opacity'][$i] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $i, 1)); $thisfile_png_chunk_type_text['palette_opacity'][$i] = getid3_lib::BigEndian2Int(substr($chunk['data'], $i, 1));
} }
break; break;
@ -134,33 +134,33 @@ class getid3_png
case 'gAMA': // Image Gamma case 'gAMA': // Image Gamma
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
$thisfile_png_chunk_type_text['gamma'] = getid3_lib::BigEndian2Int($thisfile_png_chunk_type_text['header']['data']) / 100000; $thisfile_png_chunk_type_text['gamma'] = getid3_lib::BigEndian2Int($chunk['data']) / 100000;
break; break;
case 'cHRM': // Primary Chromaticities case 'cHRM': // Primary Chromaticities
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
$thisfile_png_chunk_type_text['white_x'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 4)) / 100000; $thisfile_png_chunk_type_text['white_x'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 4)) / 100000;
$thisfile_png_chunk_type_text['white_y'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 4, 4)) / 100000; $thisfile_png_chunk_type_text['white_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 4, 4)) / 100000;
$thisfile_png_chunk_type_text['red_y'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 8, 4)) / 100000; $thisfile_png_chunk_type_text['red_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 8, 4)) / 100000;
$thisfile_png_chunk_type_text['red_y'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 12, 4)) / 100000; $thisfile_png_chunk_type_text['red_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 12, 4)) / 100000;
$thisfile_png_chunk_type_text['green_y'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 16, 4)) / 100000; $thisfile_png_chunk_type_text['green_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 16, 4)) / 100000;
$thisfile_png_chunk_type_text['green_y'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 20, 4)) / 100000; $thisfile_png_chunk_type_text['green_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 20, 4)) / 100000;
$thisfile_png_chunk_type_text['blue_y'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 24, 4)) / 100000; $thisfile_png_chunk_type_text['blue_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 24, 4)) / 100000;
$thisfile_png_chunk_type_text['blue_y'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 28, 4)) / 100000; $thisfile_png_chunk_type_text['blue_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 28, 4)) / 100000;
break; break;
case 'sRGB': // Standard RGB Color Space case 'sRGB': // Standard RGB Color Space
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
$thisfile_png_chunk_type_text['reindering_intent'] = getid3_lib::BigEndian2Int($thisfile_png_chunk_type_text['header']['data']); $thisfile_png_chunk_type_text['reindering_intent'] = getid3_lib::BigEndian2Int($chunk['data']);
$thisfile_png_chunk_type_text['reindering_intent_text'] = $this->PNGsRGBintentLookup($thisfile_png_chunk_type_text['reindering_intent']); $thisfile_png_chunk_type_text['reindering_intent_text'] = $this->PNGsRGBintentLookup($thisfile_png_chunk_type_text['reindering_intent']);
break; break;
case 'iCCP': // Embedded ICC Profile case 'iCCP': // Embedded ICC Profile
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
list($profilename, $compressiondata) = explode("\x00", $thisfile_png_chunk_type_text['header']['data'], 2); list($profilename, $compressiondata) = explode("\x00", $chunk['data'], 2);
$thisfile_png_chunk_type_text['profile_name'] = $profilename; $thisfile_png_chunk_type_text['profile_name'] = $profilename;
$thisfile_png_chunk_type_text['compression_method'] = getid3_lib::BigEndian2Int(substr($compressiondata, 0, 1)); $thisfile_png_chunk_type_text['compression_method'] = getid3_lib::BigEndian2Int(substr($compressiondata, 0, 1));
$thisfile_png_chunk_type_text['compression_profile'] = substr($compressiondata, 1); $thisfile_png_chunk_type_text['compression_profile'] = substr($compressiondata, 1);
@ -171,7 +171,7 @@ class getid3_png
case 'tEXt': // Textual Data case 'tEXt': // Textual Data
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
list($keyword, $text) = explode("\x00", $thisfile_png_chunk_type_text['header']['data'], 2); list($keyword, $text) = explode("\x00", $chunk['data'], 2);
$thisfile_png_chunk_type_text['keyword'] = $keyword; $thisfile_png_chunk_type_text['keyword'] = $keyword;
$thisfile_png_chunk_type_text['text'] = $text; $thisfile_png_chunk_type_text['text'] = $text;
@ -181,7 +181,7 @@ class getid3_png
case 'zTXt': // Compressed Textual Data case 'zTXt': // Compressed Textual Data
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
list($keyword, $otherdata) = explode("\x00", $thisfile_png_chunk_type_text['header']['data'], 2); list($keyword, $otherdata) = explode("\x00", $chunk['data'], 2);
$thisfile_png_chunk_type_text['keyword'] = $keyword; $thisfile_png_chunk_type_text['keyword'] = $keyword;
$thisfile_png_chunk_type_text['compression_method'] = getid3_lib::BigEndian2Int(substr($otherdata, 0, 1)); $thisfile_png_chunk_type_text['compression_method'] = getid3_lib::BigEndian2Int(substr($otherdata, 0, 1));
$thisfile_png_chunk_type_text['compressed_text'] = substr($otherdata, 1); $thisfile_png_chunk_type_text['compressed_text'] = substr($otherdata, 1);
@ -204,7 +204,7 @@ class getid3_png
case 'iTXt': // International Textual Data case 'iTXt': // International Textual Data
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
list($keyword, $otherdata) = explode("\x00", $thisfile_png_chunk_type_text['header']['data'], 2); list($keyword, $otherdata) = explode("\x00", $chunk['data'], 2);
$thisfile_png_chunk_type_text['keyword'] = $keyword; $thisfile_png_chunk_type_text['keyword'] = $keyword;
$thisfile_png_chunk_type_text['compression'] = (bool) getid3_lib::BigEndian2Int(substr($otherdata, 0, 1)); $thisfile_png_chunk_type_text['compression'] = (bool) getid3_lib::BigEndian2Int(substr($otherdata, 0, 1));
$thisfile_png_chunk_type_text['compression_method'] = getid3_lib::BigEndian2Int(substr($otherdata, 1, 1)); $thisfile_png_chunk_type_text['compression_method'] = getid3_lib::BigEndian2Int(substr($otherdata, 1, 1));
@ -242,18 +242,18 @@ class getid3_png
switch ($thisfile_png['IHDR']['raw']['color_type']) { switch ($thisfile_png['IHDR']['raw']['color_type']) {
case 0: case 0:
case 4: case 4:
$thisfile_png_chunk_type_text['background_gray'] = getid3_lib::BigEndian2Int($thisfile_png_chunk_type_text['header']['data']); $thisfile_png_chunk_type_text['background_gray'] = getid3_lib::BigEndian2Int($chunk['data']);
break; break;
case 2: case 2:
case 6: case 6:
$thisfile_png_chunk_type_text['background_red'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0 * $thisfile_png['IHDR']['raw']['bit_depth'], $thisfile_png['IHDR']['raw']['bit_depth'])); $thisfile_png_chunk_type_text['background_red'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0 * $thisfile_png['IHDR']['raw']['bit_depth'], $thisfile_png['IHDR']['raw']['bit_depth']));
$thisfile_png_chunk_type_text['background_green'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 1 * $thisfile_png['IHDR']['raw']['bit_depth'], $thisfile_png['IHDR']['raw']['bit_depth'])); $thisfile_png_chunk_type_text['background_green'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 1 * $thisfile_png['IHDR']['raw']['bit_depth'], $thisfile_png['IHDR']['raw']['bit_depth']));
$thisfile_png_chunk_type_text['background_blue'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 2 * $thisfile_png['IHDR']['raw']['bit_depth'], $thisfile_png['IHDR']['raw']['bit_depth'])); $thisfile_png_chunk_type_text['background_blue'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 2 * $thisfile_png['IHDR']['raw']['bit_depth'], $thisfile_png['IHDR']['raw']['bit_depth']));
break; break;
case 3: case 3:
$thisfile_png_chunk_type_text['background_index'] = getid3_lib::BigEndian2Int($thisfile_png_chunk_type_text['header']['data']); $thisfile_png_chunk_type_text['background_index'] = getid3_lib::BigEndian2Int($chunk['data']);
break; break;
default: default:
@ -264,9 +264,9 @@ class getid3_png
case 'pHYs': // Physical Pixel Dimensions case 'pHYs': // Physical Pixel Dimensions
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
$thisfile_png_chunk_type_text['pixels_per_unit_x'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 4)); $thisfile_png_chunk_type_text['pixels_per_unit_x'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 4));
$thisfile_png_chunk_type_text['pixels_per_unit_y'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 4, 4)); $thisfile_png_chunk_type_text['pixels_per_unit_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 4, 4));
$thisfile_png_chunk_type_text['unit_specifier'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 8, 1)); $thisfile_png_chunk_type_text['unit_specifier'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 8, 1));
$thisfile_png_chunk_type_text['unit'] = $this->PNGpHYsUnitLookup($thisfile_png_chunk_type_text['unit_specifier']); $thisfile_png_chunk_type_text['unit'] = $this->PNGpHYsUnitLookup($thisfile_png_chunk_type_text['unit_specifier']);
break; break;
@ -275,26 +275,26 @@ class getid3_png
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
switch ($thisfile_png['IHDR']['raw']['color_type']) { switch ($thisfile_png['IHDR']['raw']['color_type']) {
case 0: case 0:
$thisfile_png_chunk_type_text['significant_bits_gray'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 1)); $thisfile_png_chunk_type_text['significant_bits_gray'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
break; break;
case 2: case 2:
case 3: case 3:
$thisfile_png_chunk_type_text['significant_bits_red'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 1)); $thisfile_png_chunk_type_text['significant_bits_red'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
$thisfile_png_chunk_type_text['significant_bits_green'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 1, 1)); $thisfile_png_chunk_type_text['significant_bits_green'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 1, 1));
$thisfile_png_chunk_type_text['significant_bits_blue'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 2, 1)); $thisfile_png_chunk_type_text['significant_bits_blue'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 2, 1));
break; break;
case 4: case 4:
$thisfile_png_chunk_type_text['significant_bits_gray'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 1)); $thisfile_png_chunk_type_text['significant_bits_gray'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
$thisfile_png_chunk_type_text['significant_bits_alpha'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 1, 1)); $thisfile_png_chunk_type_text['significant_bits_alpha'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 1, 1));
break; break;
case 6: case 6:
$thisfile_png_chunk_type_text['significant_bits_red'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 1)); $thisfile_png_chunk_type_text['significant_bits_red'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
$thisfile_png_chunk_type_text['significant_bits_green'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 1, 1)); $thisfile_png_chunk_type_text['significant_bits_green'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 1, 1));
$thisfile_png_chunk_type_text['significant_bits_blue'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 2, 1)); $thisfile_png_chunk_type_text['significant_bits_blue'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 2, 1));
$thisfile_png_chunk_type_text['significant_bits_alpha'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 3, 1)); $thisfile_png_chunk_type_text['significant_bits_alpha'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 3, 1));
break; break;
default: default:
@ -305,7 +305,7 @@ class getid3_png
case 'sPLT': // Suggested Palette case 'sPLT': // Suggested Palette
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
list($palettename, $otherdata) = explode("\x00", $thisfile_png_chunk_type_text['header']['data'], 2); list($palettename, $otherdata) = explode("\x00", $chunk['data'], 2);
$thisfile_png_chunk_type_text['palette_name'] = $palettename; $thisfile_png_chunk_type_text['palette_name'] = $palettename;
$sPLToffset = 0; $sPLToffset = 0;
$thisfile_png_chunk_type_text['sample_depth_bits'] = getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, 1)); $thisfile_png_chunk_type_text['sample_depth_bits'] = getid3_lib::BigEndian2Int(substr($otherdata, $sPLToffset, 1));
@ -331,8 +331,8 @@ class getid3_png
case 'hIST': // Palette Histogram case 'hIST': // Palette Histogram
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
$hISTcounter = 0; $hISTcounter = 0;
while ($hISTcounter < strlen($thisfile_png_chunk_type_text['header']['data'])) { while ($hISTcounter < strlen($chunk['data'])) {
$thisfile_png_chunk_type_text[$hISTcounter] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $hISTcounter / 2, 2)); $thisfile_png_chunk_type_text[$hISTcounter] = getid3_lib::BigEndian2Int(substr($chunk['data'], $hISTcounter / 2, 2));
$hISTcounter += 2; $hISTcounter += 2;
} }
break; break;
@ -340,48 +340,48 @@ class getid3_png
case 'tIME': // Image Last-Modification Time case 'tIME': // Image Last-Modification Time
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
$thisfile_png_chunk_type_text['year'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 2)); $thisfile_png_chunk_type_text['year'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 2));
$thisfile_png_chunk_type_text['month'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 2, 1)); $thisfile_png_chunk_type_text['month'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 2, 1));
$thisfile_png_chunk_type_text['day'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 3, 1)); $thisfile_png_chunk_type_text['day'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 3, 1));
$thisfile_png_chunk_type_text['hour'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 4, 1)); $thisfile_png_chunk_type_text['hour'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 4, 1));
$thisfile_png_chunk_type_text['minute'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 5, 1)); $thisfile_png_chunk_type_text['minute'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 5, 1));
$thisfile_png_chunk_type_text['second'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 6, 1)); $thisfile_png_chunk_type_text['second'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 6, 1));
$thisfile_png_chunk_type_text['unix'] = gmmktime($thisfile_png_chunk_type_text['hour'], $thisfile_png_chunk_type_text['minute'], $thisfile_png_chunk_type_text['second'], $thisfile_png_chunk_type_text['month'], $thisfile_png_chunk_type_text['day'], $thisfile_png_chunk_type_text['year']); $thisfile_png_chunk_type_text['unix'] = gmmktime($thisfile_png_chunk_type_text['hour'], $thisfile_png_chunk_type_text['minute'], $thisfile_png_chunk_type_text['second'], $thisfile_png_chunk_type_text['month'], $thisfile_png_chunk_type_text['day'], $thisfile_png_chunk_type_text['year']);
break; break;
case 'oFFs': // Image Offset case 'oFFs': // Image Offset
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
$thisfile_png_chunk_type_text['position_x'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 4), false, true); $thisfile_png_chunk_type_text['position_x'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 4), false, true);
$thisfile_png_chunk_type_text['position_y'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 4, 4), false, true); $thisfile_png_chunk_type_text['position_y'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 4, 4), false, true);
$thisfile_png_chunk_type_text['unit_specifier'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 8, 1)); $thisfile_png_chunk_type_text['unit_specifier'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 8, 1));
$thisfile_png_chunk_type_text['unit'] = $this->PNGoFFsUnitLookup($thisfile_png_chunk_type_text['unit_specifier']); $thisfile_png_chunk_type_text['unit'] = $this->PNGoFFsUnitLookup($thisfile_png_chunk_type_text['unit_specifier']);
break; break;
case 'pCAL': // Calibration Of Pixel Values case 'pCAL': // Calibration Of Pixel Values
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
list($calibrationname, $otherdata) = explode("\x00", $thisfile_png_chunk_type_text['header']['data'], 2); list($calibrationname, $otherdata) = explode("\x00", $chunk['data'], 2);
$thisfile_png_chunk_type_text['calibration_name'] = $calibrationname; $thisfile_png_chunk_type_text['calibration_name'] = $calibrationname;
$pCALoffset = 0; $pCALoffset = 0;
$thisfile_png_chunk_type_text['original_zero'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $pCALoffset, 4), false, true); $thisfile_png_chunk_type_text['original_zero'] = getid3_lib::BigEndian2Int(substr($chunk['data'], $pCALoffset, 4), false, true);
$pCALoffset += 4; $pCALoffset += 4;
$thisfile_png_chunk_type_text['original_max'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $pCALoffset, 4), false, true); $thisfile_png_chunk_type_text['original_max'] = getid3_lib::BigEndian2Int(substr($chunk['data'], $pCALoffset, 4), false, true);
$pCALoffset += 4; $pCALoffset += 4;
$thisfile_png_chunk_type_text['equation_type'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $pCALoffset, 1)); $thisfile_png_chunk_type_text['equation_type'] = getid3_lib::BigEndian2Int(substr($chunk['data'], $pCALoffset, 1));
$pCALoffset += 1; $pCALoffset += 1;
$thisfile_png_chunk_type_text['equation_type_text'] = $this->PNGpCALequationTypeLookup($thisfile_png_chunk_type_text['equation_type']); $thisfile_png_chunk_type_text['equation_type_text'] = $this->PNGpCALequationTypeLookup($thisfile_png_chunk_type_text['equation_type']);
$thisfile_png_chunk_type_text['parameter_count'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], $pCALoffset, 1)); $thisfile_png_chunk_type_text['parameter_count'] = getid3_lib::BigEndian2Int(substr($chunk['data'], $pCALoffset, 1));
$pCALoffset += 1; $pCALoffset += 1;
$thisfile_png_chunk_type_text['parameters'] = explode("\x00", substr($thisfile_png_chunk_type_text['header']['data'], $pCALoffset)); $thisfile_png_chunk_type_text['parameters'] = explode("\x00", substr($chunk['data'], $pCALoffset));
break; break;
case 'sCAL': // Physical Scale Of Image Subject case 'sCAL': // Physical Scale Of Image Subject
$thisfile_png_chunk_type_text['header'] = $chunk; $thisfile_png_chunk_type_text['header'] = $chunk;
$thisfile_png_chunk_type_text['unit_specifier'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 1)); $thisfile_png_chunk_type_text['unit_specifier'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
$thisfile_png_chunk_type_text['unit'] = $this->PNGsCALUnitLookup($thisfile_png_chunk_type_text['unit_specifier']); $thisfile_png_chunk_type_text['unit'] = $this->PNGsCALUnitLookup($thisfile_png_chunk_type_text['unit_specifier']);
list($pixelwidth, $pixelheight) = explode("\x00", substr($thisfile_png_chunk_type_text['header']['data'], 1)); list($pixelwidth, $pixelheight) = explode("\x00", substr($chunk['data'], 1));
$thisfile_png_chunk_type_text['pixel_width'] = $pixelwidth; $thisfile_png_chunk_type_text['pixel_width'] = $pixelwidth;
$thisfile_png_chunk_type_text['pixel_height'] = $pixelheight; $thisfile_png_chunk_type_text['pixel_height'] = $pixelheight;
break; break;
@ -393,9 +393,9 @@ class getid3_png
$gIFgCounter = count($thisfile_png_chunk_type_text); $gIFgCounter = count($thisfile_png_chunk_type_text);
} }
$thisfile_png_chunk_type_text[$gIFgCounter]['header'] = $chunk; $thisfile_png_chunk_type_text[$gIFgCounter]['header'] = $chunk;
$thisfile_png_chunk_type_text[$gIFgCounter]['disposal_method'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 0, 1)); $thisfile_png_chunk_type_text[$gIFgCounter]['disposal_method'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 0, 1));
$thisfile_png_chunk_type_text[$gIFgCounter]['user_input_flag'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 1, 1)); $thisfile_png_chunk_type_text[$gIFgCounter]['user_input_flag'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 1, 1));
$thisfile_png_chunk_type_text[$gIFgCounter]['delay_time'] = getid3_lib::BigEndian2Int(substr($thisfile_png_chunk_type_text['header']['data'], 2, 2)); $thisfile_png_chunk_type_text[$gIFgCounter]['delay_time'] = getid3_lib::BigEndian2Int(substr($chunk['data'], 2, 2));
break; break;
@ -405,9 +405,9 @@ class getid3_png
$gIFxCounter = count($thisfile_png_chunk_type_text); $gIFxCounter = count($thisfile_png_chunk_type_text);
} }
$thisfile_png_chunk_type_text[$gIFxCounter]['header'] = $chunk; $thisfile_png_chunk_type_text[$gIFxCounter]['header'] = $chunk;
$thisfile_png_chunk_type_text[$gIFxCounter]['application_identifier'] = substr($thisfile_png_chunk_type_text['header']['data'], 0, 8); $thisfile_png_chunk_type_text[$gIFxCounter]['application_identifier'] = substr($chunk['data'], 0, 8);
$thisfile_png_chunk_type_text[$gIFxCounter]['authentication_code'] = substr($thisfile_png_chunk_type_text['header']['data'], 8, 3); $thisfile_png_chunk_type_text[$gIFxCounter]['authentication_code'] = substr($chunk['data'], 8, 3);
$thisfile_png_chunk_type_text[$gIFxCounter]['application_data'] = substr($thisfile_png_chunk_type_text['header']['data'], 11); $thisfile_png_chunk_type_text[$gIFxCounter]['application_data'] = substr($chunk['data'], 11);
break; break;

View File

@ -0,0 +1,32 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.archive.doc.php //
// module for analyzing MS Office (.doc, .xls, etc) files //
// dependencies: NONE //
// ///
/////////////////////////////////////////////////////////////////
class getid3_doc
{
function getid3_doc(&$fd, &$ThisFileInfo) {
$ThisFileInfo['fileformat'] = 'doc';
$ThisFileInfo['error'][] = 'MS Office (.doc, .xls, etc) parsing not enabled in this version of getID3()';
return false;
}
}
?>

View File

@ -0,0 +1,32 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.archive.doc.php //
// module for analyzing MS Office (.doc, .xls, etc) files //
// dependencies: NONE //
// ///
/////////////////////////////////////////////////////////////////
class getid3_doc
{
function getid3_doc(&$fd, &$ThisFileInfo) {
$ThisFileInfo['fileformat'] = 'doc';
$ThisFileInfo['error'][] = 'MS Office (.doc, .xls, etc) parsing not enabled in this version of getID3()';
return false;
}
}
?>

View File

@ -0,0 +1,32 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.misc.par2.php //
// module for analyzing PAR2 files //
// dependencies: NONE //
// ///
/////////////////////////////////////////////////////////////////
class getid3_par2
{
function getid3_par2(&$fd, &$ThisFileInfo) {
$ThisFileInfo['fileformat'] = 'par2';
$ThisFileInfo['error'][] = 'PAR2 parsing not enabled in this version of getID3()';
return false;
}
}
?>

View File

@ -0,0 +1,32 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.misc.pdf.php //
// module for analyzing PDF files //
// dependencies: NONE //
// ///
/////////////////////////////////////////////////////////////////
class getid3_pdf
{
function getid3_pdf(&$fd, &$ThisFileInfo) {
$ThisFileInfo['fileformat'] = 'pdf';
$ThisFileInfo['error'][] = 'PDF parsing not enabled in this version of getID3()';
return false;
}
}
?>

View File

@ -17,6 +17,12 @@ class getid3_apetag
{ {
function getid3_apetag(&$fd, &$ThisFileInfo, $overrideendoffset=0) { function getid3_apetag(&$fd, &$ThisFileInfo, $overrideendoffset=0) {
if ($ThisFileInfo['filesize'] >= pow(2, 31)) {
$ThisFileInfo['warning'][] = 'Unable to check for APEtags because file is larger than 2GB';
return false;
}
$id3v1tagsize = 128; $id3v1tagsize = 128;
$apetagheadersize = 32; $apetagheadersize = 32;
$lyrics3tagsize = 10; $lyrics3tagsize = 10;
@ -102,7 +108,7 @@ class getid3_apetag
// shortcut // shortcut
$ThisFileInfo['replay_gain'] = array(); $ThisFileInfo['replay_gain'] = array();
$thisfile_replaygain = &$ThisFileInfo['replay_gain']; $thisfile_replaygain = &$ThisFileInfo['replay_gain'];
for ($i = 0; $i < $thisfile_ape['footer']['raw']['tag_items']; $i++) { for ($i = 0; $i < $thisfile_ape['footer']['raw']['tag_items']; $i++) {
$value_size = getid3_lib::LittleEndian2Int(substr($APEtagData, $offset, 4)); $value_size = getid3_lib::LittleEndian2Int(substr($APEtagData, $offset, 4));
$offset += 4; $offset += 4;

View File

@ -19,6 +19,11 @@ class getid3_id3v1
function getid3_id3v1(&$fd, &$ThisFileInfo) { function getid3_id3v1(&$fd, &$ThisFileInfo) {
if ($ThisFileInfo['filesize'] >= pow(2, 31)) {
$ThisFileInfo['warning'][] = 'Unable to check for ID3v1 because file is larger than 2GB';
return false;
}
fseek($fd, -256, SEEK_END); fseek($fd, -256, SEEK_END);
$preid3v1 = fread($fd, 128); $preid3v1 = fread($fd, 128);
$id3v1tag = fread($fd, 128); $id3v1tag = fread($fd, 128);
@ -60,7 +65,7 @@ class getid3_id3v1
$ParsedID3v1['artist'], $ParsedID3v1['artist'],
$ParsedID3v1['album'], $ParsedID3v1['album'],
$ParsedID3v1['year'], $ParsedID3v1['year'],
$this->LookupGenreID(@$ParsedID3v1['genre']), (isset($ParsedID3v1['genre']) ? $this->LookupGenreID($ParsedID3v1['genre']) : false),
$ParsedID3v1['comment'], $ParsedID3v1['comment'],
@$ParsedID3v1['track']); @$ParsedID3v1['track']);
$ParsedID3v1['padding_valid'] = true; $ParsedID3v1['padding_valid'] = true;

View File

@ -50,7 +50,7 @@ class getid3_id3v2
fseek($fd, $StartingOffset, SEEK_SET); fseek($fd, $StartingOffset, SEEK_SET);
$header = fread($fd, 10); $header = fread($fd, 10);
if (substr($header, 0, 3) == 'ID3') { if (substr($header, 0, 3) == 'ID3' && strlen($header) == 10) {
$thisfile_id3v2['majorversion'] = ord($header{3}); $thisfile_id3v2['majorversion'] = ord($header{3});
$thisfile_id3v2['minorversion'] = ord($header{4}); $thisfile_id3v2['minorversion'] = ord($header{4});
@ -101,49 +101,6 @@ class getid3_id3v2
$thisfile_id3v2['tag_offset_start'] = $StartingOffset; $thisfile_id3v2['tag_offset_start'] = $StartingOffset;
$thisfile_id3v2['tag_offset_end'] = $thisfile_id3v2['tag_offset_start'] + $thisfile_id3v2['headerlength']; $thisfile_id3v2['tag_offset_end'] = $thisfile_id3v2['tag_offset_start'] + $thisfile_id3v2['headerlength'];
// Extended Header
if (isset($thisfile_id3v2_flags['exthead']) && $thisfile_id3v2_flags['exthead']) {
// Extended header size 4 * %0xxxxxxx
// Number of flag bytes $01
// Extended Flags $xx
// Where the 'Extended header size' is the size of the whole extended header, stored as a 32 bit synchsafe integer.
$thisfile_id3v2['exthead_length'] = getid3_lib::BigEndian2Int(fread($fd, 4), 1);
$thisfile_id3v2['exthead_flag_bytes'] = ord(fread($fd, 1));
if ($thisfile_id3v2['exthead_flag_bytes'] == 1) {
// The extended flags field, with its size described by 'number of flag bytes', is defined as:
// %0bcd0000
// b - Tag is an update
// Flag data length $00
// c - CRC data present
// Flag data length $05
// Total frame CRC 5 * %0xxxxxxx
// d - Tag restrictions
// Flag data length $01
$extheaderflags = fread($fd, $thisfile_id3v2['exthead_flag_bytes']);
$id3_exthead_flags = getid3_lib::BigEndian2Bin(substr($header, 5, 1));
$thisfile_id3v2['exthead_flags']['update'] = substr($id3_exthead_flags, 1, 1);
$thisfile_id3v2['exthead_flags']['CRC'] = substr($id3_exthead_flags, 2, 1);
if ($thisfile_id3v2['exthead_flags']['CRC']) {
$extheaderrawCRC = fread($fd, 5);
$thisfile_id3v2['exthead_flags']['CRC'] = getid3_lib::BigEndian2Int($extheaderrawCRC, 1);
}
$thisfile_id3v2['exthead_flags']['restrictions'] = substr($id3_exthead_flags, 3, 1);
if ($thisfile_id3v2['exthead_flags']['restrictions']) {
// Restrictions %ppqrrstt
$extheaderrawrestrictions = fread($fd, 1);
$thisfile_id3v2['exthead_flags']['restrictions_tagsize'] = (bindec('11000000') & ord($extheaderrawrestrictions)) >> 6; // p - Tag size restrictions
$thisfile_id3v2['exthead_flags']['restrictions_textenc'] = (bindec('00100000') & ord($extheaderrawrestrictions)) >> 5; // q - Text encoding restrictions
$thisfile_id3v2['exthead_flags']['restrictions_textsize'] = (bindec('00011000') & ord($extheaderrawrestrictions)) >> 3; // r - Text fields size restrictions
$thisfile_id3v2['exthead_flags']['restrictions_imgenc'] = (bindec('00000100') & ord($extheaderrawrestrictions)) >> 2; // s - Image encoding restrictions
$thisfile_id3v2['exthead_flags']['restrictions_imgsize'] = (bindec('00000011') & ord($extheaderrawrestrictions)) >> 0; // t - Image size restrictions
}
} else {
$ThisFileInfo['warning'][] = '$thisfile_id3v2[exthead_flag_bytes] = "'.$thisfile_id3v2['exthead_flag_bytes'].'" (expecting "1")';
fseek($fd, $thisfile_id3v2['exthead_length'] - 1, SEEK_CUR);
//return false;
}
} // end extended header
// create 'encoding' key - used by getid3::HandleAllTags() // create 'encoding' key - used by getid3::HandleAllTags()
@ -163,8 +120,8 @@ class getid3_id3v2
// Flags $xx xx // Flags $xx xx
$sizeofframes = $thisfile_id3v2['headerlength'] - 10; // not including 10-byte initial header $sizeofframes = $thisfile_id3v2['headerlength'] - 10; // not including 10-byte initial header
if (@$thisfile_id3v2['exthead_length']) { if (@$thisfile_id3v2['exthead']['length']) {
$sizeofframes -= ($thisfile_id3v2['exthead_length'] + 4); $sizeofframes -= ($thisfile_id3v2['exthead']['length'] + 4);
} }
if (@$thisfile_id3v2_flags['isfooter']) { if (@$thisfile_id3v2_flags['isfooter']) {
$sizeofframes -= 10; // footer takes last 10 bytes of ID3v2 header, after frame data, before audio $sizeofframes -= 10; // footer takes last 10 bytes of ID3v2 header, after frame data, before audio
@ -183,7 +140,89 @@ class getid3_id3v2
// there exists an unsynchronised frame, while the new unsynchronisation flag in // there exists an unsynchronised frame, while the new unsynchronisation flag in
// the frame header [S:4.1.2] indicates unsynchronisation. // the frame header [S:4.1.2] indicates unsynchronisation.
$framedataoffset = 10 + (@$thisfile_id3v2['exthead_length'] ? $thisfile_id3v2['exthead_length'] + 4 : 0); // how many bytes into the stream - start from after the 10-byte header (and extended header length+4, if present)
//$framedataoffset = 10 + (@$thisfile_id3v2['exthead']['length'] ? $thisfile_id3v2['exthead']['length'] + 4 : 0); // how many bytes into the stream - start from after the 10-byte header (and extended header length+4, if present)
$framedataoffset = 10; // how many bytes into the stream - start from after the 10-byte header
// Extended Header
if (@$thisfile_id3v2_flags['exthead']) {
$extended_header_offset = 0;
if ($id3v2_majorversion == 3) {
// v2.3 definition:
//Extended header size $xx xx xx xx // 32-bit integer
//Extended Flags $xx xx
// %x0000000 %00000000 // v2.3
// x - CRC data present
//Size of padding $xx xx xx xx
$thisfile_id3v2['exthead']['length'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 4), 0);
$extended_header_offset += 4;
$thisfile_id3v2['exthead']['flag_bytes'] = 2;
$thisfile_id3v2['exthead']['flag_raw'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, $thisfile_id3v2['exthead']['flag_bytes']));
$extended_header_offset += $thisfile_id3v2['exthead']['flag_bytes'];
$thisfile_id3v2['exthead']['flags']['crc'] = (bool) ($thisfile_id3v2['exthead']['flag_raw'] & 0x8000);
$thisfile_id3v2['exthead']['padding_size'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 4));
$extended_header_offset += 4;
if ($thisfile_id3v2['exthead']['flags']['crc']) {
$thisfile_id3v2['exthead']['flag_data']['crc'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 4));
$extended_header_offset += 4;
}
$extended_header_offset += $thisfile_id3v2['exthead']['padding_size'];
} elseif ($id3v2_majorversion == 4) {
// v2.4 definition:
//Extended header size 4 * %0xxxxxxx // 28-bit synchsafe integer
//Number of flag bytes $01
//Extended Flags $xx
// %0bcd0000 // v2.4
// b - Tag is an update
// Flag data length $00
// c - CRC data present
// Flag data length $05
// Total frame CRC 5 * %0xxxxxxx
// d - Tag restrictions
// Flag data length $01
$thisfile_id3v2['exthead']['length'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 4), 1);
$extended_header_offset += 4;
$thisfile_id3v2['exthead']['flag_bytes'] = 1;
$thisfile_id3v2['exthead']['flag_raw'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, $thisfile_id3v2['exthead']['flag_bytes']));
$extended_header_offset += $thisfile_id3v2['exthead']['flag_bytes'];
$thisfile_id3v2['exthead']['flags']['update'] = (bool) ($thisfile_id3v2['exthead']['flag_raw'] & 0x4000);
$thisfile_id3v2['exthead']['flags']['crc'] = (bool) ($thisfile_id3v2['exthead']['flag_raw'] & 0x2000);
$thisfile_id3v2['exthead']['flags']['restrictions'] = (bool) ($thisfile_id3v2['exthead']['flag_raw'] & 0x1000);
if ($thisfile_id3v2['exthead']['flags']['crc']) {
$thisfile_id3v2['exthead']['flag_data']['crc'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 5), 1);
$extended_header_offset += 5;
}
if ($thisfile_id3v2['exthead']['flags']['restrictions']) {
// %ppqrrstt
$restrictions_raw = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 1));
$extended_header_offset += 1;
$thisfile_id3v2['exthead']['flags']['restrictions']['tagsize'] = ($restrictions_raw && 0xC0) >> 6; // p - Tag size restrictions
$thisfile_id3v2['exthead']['flags']['restrictions']['textenc'] = ($restrictions_raw && 0x20) >> 5; // q - Text encoding restrictions
$thisfile_id3v2['exthead']['flags']['restrictions']['textsize'] = ($restrictions_raw && 0x18) >> 3; // r - Text fields size restrictions
$thisfile_id3v2['exthead']['flags']['restrictions']['imgenc'] = ($restrictions_raw && 0x04) >> 2; // s - Image encoding restrictions
$thisfile_id3v2['exthead']['flags']['restrictions']['imgsize'] = ($restrictions_raw && 0x03) >> 0; // t - Image size restrictions
}
}
$framedataoffset += $extended_header_offset;
$framedata = substr($framedata, $extended_header_offset);
} // end extended header
while (isset($framedata) && (strlen($framedata) > 0)) { // cycle through until no more frame data is left to parse while (isset($framedata) && (strlen($framedata) > 0)) { // cycle through until no more frame data is left to parse
if (strlen($framedata) <= $this->ID3v2HeaderLength($id3v2_majorversion)) { if (strlen($framedata) <= $this->ID3v2HeaderLength($id3v2_majorversion)) {
// insufficient room left in ID3v2 header for actual data - must be padding // insufficient room left in ID3v2 header for actual data - must be padding
@ -248,9 +287,11 @@ class getid3_id3v2
// padding encountered // padding encountered
$thisfile_id3v2['padding']['start'] = $framedataoffset; $thisfile_id3v2['padding']['start'] = $framedataoffset;
$thisfile_id3v2['padding']['length'] = strlen($framedata); $thisfile_id3v2['padding']['length'] = strlen($frame_header) + strlen($framedata);
$thisfile_id3v2['padding']['valid'] = true; $thisfile_id3v2['padding']['valid'] = true;
for ($i = 0; $i < $thisfile_id3v2['padding']['length']; $i++) {
$len = strlen($framedata);
for ($i = 0; $i < $len; $i++) {
if ($framedata{$i} != "\x00") { if ($framedata{$i} != "\x00") {
$thisfile_id3v2['padding']['valid'] = false; $thisfile_id3v2['padding']['valid'] = false;
$thisfile_id3v2['padding']['errorpos'] = $thisfile_id3v2['padding']['start'] + $i; $thisfile_id3v2['padding']['errorpos'] = $thisfile_id3v2['padding']['start'] + $i;
@ -329,7 +370,7 @@ class getid3_id3v2
break; break;
} }
} elseif ($frame_size > strlen($framedata)){ } elseif ($frame_size > strlen(@$framedata)){
$ThisFileInfo['error'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: $frame_size ('.$frame_size.') > strlen($framedata) ('.strlen($framedata).')).'; $ThisFileInfo['error'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: $frame_size ('.$frame_size.') > strlen($framedata) ('.strlen($framedata).')).';
@ -420,7 +461,10 @@ class getid3_id3v2
$unprocessed = substr($unprocessed, $endpos + 1); $unprocessed = substr($unprocessed, $endpos + 1);
} }
unset($unprocessed); unset($unprocessed);
} } elseif (eregi('^([0-9]+|CR|RX)$', $genrestring)) {
// some tagging program (including some that use TagLib) fail to include null byte after numeric genre
$genrestring = '('.$genrestring.')';
}
if (getid3_id3v1::LookupGenreID($genrestring)) { if (getid3_id3v1::LookupGenreID($genrestring)) {
$returnarray['genre'][] = $genrestring; $returnarray['genre'][] = $genrestring;
@ -561,9 +605,9 @@ class getid3_id3v2
if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
$ThisFileInfo['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; $ThisFileInfo['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
} }
$frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 $frame_terminatorpos++; // @strpos() fooled because 2nd byte of Unicode chars are often 0x00
} }
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_description) === 0) { if (ord($frame_description) === 0) {
@ -599,7 +643,14 @@ class getid3_id3v2
$parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding);
if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) {
$ThisFileInfo['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $ThisFileInfo['id3v2']['encoding'], $parsedFrame['data']);
// remove possible terminating \x00 (put by encoding id or software bug)
$string = getid3_lib::iconv_fallback($parsedFrame['encoding'], $ThisFileInfo['id3v2']['encoding'], $parsedFrame['data']);
if ($string[strlen($string) - 1] == "\x00") {
$string = substr($string, 0, strlen($string) - 1);
}
$ThisFileInfo['id3v2']['comments'][$parsedFrame['framenameshort']][] = $string;
unset($string);
} }
} elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'WXXX')) || // 4.3.2 WXXX User defined URL link frame } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'WXXX')) || // 4.3.2 WXXX User defined URL link frame
@ -616,9 +667,9 @@ class getid3_id3v2
if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
$ThisFileInfo['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; $ThisFileInfo['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
} }
$frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 $frame_terminatorpos++; // @strpos() fooled because 2nd byte of Unicode chars are often 0x00
} }
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
@ -798,9 +849,9 @@ class getid3_id3v2
} }
$frame_language = substr($parsedFrame['data'], $frame_offset, 3); $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
$frame_offset += 3; $frame_offset += 3;
$frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 $frame_terminatorpos++; // @strpos() fooled because 2nd byte of Unicode chars are often 0x00
} }
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_description) === 0) { if (ord($frame_description) === 0) {
@ -902,9 +953,9 @@ class getid3_id3v2
} }
$frame_language = substr($parsedFrame['data'], $frame_offset, 3); $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
$frame_offset += 3; $frame_offset += 3;
$frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 $frame_terminatorpos++; // @strpos() fooled because 2nd byte of Unicode chars are often 0x00
} }
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_description) === 0) { if (ord($frame_description) === 0) {
@ -1063,7 +1114,7 @@ class getid3_id3v2
$frame_offset = 0; $frame_offset = 0;
$frame_interpolationmethod = ord(substr($parsedFrame['data'], $frame_offset++, 1)); $frame_interpolationmethod = ord(substr($parsedFrame['data'], $frame_offset++, 1));
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_idstring = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_idstring = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_idstring) === 0) { if (ord($frame_idstring) === 0) {
$frame_idstring = ''; $frame_idstring = '';
@ -1160,12 +1211,12 @@ class getid3_id3v2
$ThisFileInfo['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; $ThisFileInfo['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
} }
if ($id3v2_majorversion == 2) { if ($id3v2_majorversion == 2 && strlen($parsedFrame['data']) > $frame_offset) {
$frame_imagetype = substr($parsedFrame['data'], $frame_offset, 3); $frame_imagetype = substr($parsedFrame['data'], $frame_offset, 3);
if (strtolower($frame_imagetype) == 'ima') { if (strtolower($frame_imagetype) == 'ima') {
// complete hack for mp3Rage (www.chaoticsoftware.com) that puts ID3v2.3-formatted // complete hack for mp3Rage (www.chaoticsoftware.com) that puts ID3v2.3-formatted
// MIME type instead of 3-char ID3v2.2-format image type (thanks xbhoffØpacbell*net) // MIME type instead of 3-char ID3v2.2-format image type (thanks xbhoff<EFBFBD>pacbell*net)
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_mimetype) === 0) { if (ord($frame_mimetype) === 0) {
$frame_mimetype = ''; $frame_mimetype = '';
@ -1179,8 +1230,8 @@ class getid3_id3v2
$frame_offset += 3; $frame_offset += 3;
} }
} }
if ($id3v2_majorversion > 2) { if ($id3v2_majorversion > 2 && strlen($parsedFrame['data']) > $frame_offset) {
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_mimetype) === 0) { if (ord($frame_mimetype) === 0) {
$frame_mimetype = ''; $frame_mimetype = '';
@ -1190,9 +1241,9 @@ class getid3_id3v2
$frame_picturetype = ord(substr($parsedFrame['data'], $frame_offset++, 1)); $frame_picturetype = ord(substr($parsedFrame['data'], $frame_offset++, 1));
$frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 $frame_terminatorpos++; // @strpos() fooled because 2nd byte of Unicode chars are often 0x00
} }
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_description) === 0) { if (ord($frame_description) === 0) {
@ -1211,7 +1262,8 @@ class getid3_id3v2
$parsedFrame['description'] = $frame_description; $parsedFrame['description'] = $frame_description;
$parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding))); $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)));
$imagechunkcheck = getid3_lib::GetDataImageSize($parsedFrame['data']); $imageinfo = array();
$imagechunkcheck = getid3_lib::GetDataImageSize($parsedFrame['data'], $imageinfo);
if (($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) { if (($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) {
$parsedFrame['image_mime'] = 'image/'.getid3_lib::ImageTypesLookup($imagechunkcheck[2]); $parsedFrame['image_mime'] = 'image/'.getid3_lib::ImageTypesLookup($imagechunkcheck[2]);
if ($imagechunkcheck[0]) { if ($imagechunkcheck[0]) {
@ -1240,16 +1292,16 @@ class getid3_id3v2
if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
$ThisFileInfo['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; $ThisFileInfo['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
} }
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_mimetype) === 0) { if (ord($frame_mimetype) === 0) {
$frame_mimetype = ''; $frame_mimetype = '';
} }
$frame_offset = $frame_terminatorpos + strlen("\x00"); $frame_offset = $frame_terminatorpos + strlen("\x00");
$frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 $frame_terminatorpos++; // @strpos() fooled because 2nd byte of Unicode chars are often 0x00
} }
$frame_filename = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_filename = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_filename) === 0) { if (ord($frame_filename) === 0) {
@ -1257,9 +1309,9 @@ class getid3_id3v2
} }
$frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)); $frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding));
$frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 $frame_terminatorpos++; // @strpos() fooled because 2nd byte of Unicode chars are often 0x00
} }
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_description) === 0) { if (ord($frame_description) === 0) {
@ -1298,7 +1350,7 @@ class getid3_id3v2
// Counter $xx xx xx xx (xx ...) // Counter $xx xx xx xx (xx ...)
$frame_offset = 0; $frame_offset = 0;
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_emailaddress = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_emailaddress = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_emailaddress) === 0) { if (ord($frame_emailaddress) === 0) {
$frame_emailaddress = ''; $frame_emailaddress = '';
@ -1338,11 +1390,11 @@ class getid3_id3v2
// Encrypted datablock <binary data> // Encrypted datablock <binary data>
$frame_offset = 0; $frame_offset = 0;
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
$frame_offset = $frame_terminatorpos + strlen("\x00"); $frame_offset = $frame_terminatorpos + strlen("\x00");
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_description) === 0) { if (ord($frame_description) === 0) {
$frame_description = ''; $frame_description = '';
@ -1366,7 +1418,7 @@ class getid3_id3v2
// Encryption info <binary data> // Encryption info <binary data>
$frame_offset = 0; $frame_offset = 0;
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_ownerid) === 0) { if (ord($frame_ownerid) === 0) {
$frame_ownerid == ''; $frame_ownerid == '';
@ -1400,7 +1452,7 @@ class getid3_id3v2
$frame_offset += 4; $frame_offset += 4;
} }
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_url = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_url = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_url) === 0) { if (ord($frame_url) === 0) {
$frame_url = ''; $frame_url = '';
@ -1410,7 +1462,7 @@ class getid3_id3v2
$parsedFrame['additionaldata'] = (string) substr($parsedFrame['data'], $frame_offset); $parsedFrame['additionaldata'] = (string) substr($parsedFrame['data'], $frame_offset);
if (!empty($parsedFrame['framenameshort']) && $parsedFrame['url']) { if (!empty($parsedFrame['framenameshort']) && $parsedFrame['url']) {
$ThisFileInfo['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $ThisFileInfo['id3v2']['encoding'], $parsedFrame['url']); $ThisFileInfo['id3v2']['comments'][$parsedFrame['framenameshort']][] = utf8_encode($parsedFrame['url']);
} }
unset($parsedFrame['data']); unset($parsedFrame['data']);
@ -1470,7 +1522,7 @@ class getid3_id3v2
$parsedFrame['encodingid'] = $frame_textencoding; $parsedFrame['encodingid'] = $frame_textencoding;
$parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding);
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_pricepaid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_pricepaid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
$frame_offset = $frame_terminatorpos + strlen("\x00"); $frame_offset = $frame_terminatorpos + strlen("\x00");
@ -1508,7 +1560,7 @@ class getid3_id3v2
$ThisFileInfo['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; $ThisFileInfo['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
} }
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_pricestring = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_pricestring = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
$frame_offset = $frame_terminatorpos + strlen("\x00"); $frame_offset = $frame_terminatorpos + strlen("\x00");
$frame_rawpricearray = explode('/', $frame_pricestring); $frame_rawpricearray = explode('/', $frame_pricestring);
@ -1521,15 +1573,15 @@ class getid3_id3v2
$frame_datestring = substr($parsedFrame['data'], $frame_offset, 8); $frame_datestring = substr($parsedFrame['data'], $frame_offset, 8);
$frame_offset += 8; $frame_offset += 8;
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_contacturl = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_contacturl = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
$frame_offset = $frame_terminatorpos + strlen("\x00"); $frame_offset = $frame_terminatorpos + strlen("\x00");
$frame_receivedasid = ord(substr($parsedFrame['data'], $frame_offset++, 1)); $frame_receivedasid = ord(substr($parsedFrame['data'], $frame_offset++, 1));
$frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 $frame_terminatorpos++; // @strpos() fooled because 2nd byte of Unicode chars are often 0x00
} }
$frame_sellername = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_sellername = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_sellername) === 0) { if (ord($frame_sellername) === 0) {
@ -1537,9 +1589,9 @@ class getid3_id3v2
} }
$frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)); $frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding));
$frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
$frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 $frame_terminatorpos++; // @strpos() fooled because 2nd byte of Unicode chars are often 0x00
} }
$frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_description) === 0) { if (ord($frame_description) === 0) {
@ -1547,7 +1599,7 @@ class getid3_id3v2
} }
$frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)); $frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding));
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
$frame_offset = $frame_terminatorpos + strlen("\x00"); $frame_offset = $frame_terminatorpos + strlen("\x00");
@ -1577,7 +1629,7 @@ class getid3_id3v2
// Encryption data <binary data> // Encryption data <binary data>
$frame_offset = 0; $frame_offset = 0;
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_ownerid) === 0) { if (ord($frame_ownerid) === 0) {
$frame_ownerid = ''; $frame_ownerid = '';
@ -1600,7 +1652,7 @@ class getid3_id3v2
// Group dependent data <binary data> // Group dependent data <binary data>
$frame_offset = 0; $frame_offset = 0;
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_ownerid) === 0) { if (ord($frame_ownerid) === 0) {
$frame_ownerid = ''; $frame_ownerid = '';
@ -1620,7 +1672,7 @@ class getid3_id3v2
// The private data <binary data> // The private data <binary data>
$frame_offset = 0; $frame_offset = 0;
$frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); $frame_terminatorpos = @strpos($parsedFrame['data'], "\x00", $frame_offset);
$frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); $frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
if (ord($frame_ownerid) === 0) { if (ord($frame_ownerid) === 0) {
$frame_ownerid = ''; $frame_ownerid = '';
@ -2078,7 +2130,7 @@ class getid3_id3v2
SOS Somalia SOS Somalia
SPL Seborga SPL Seborga
SRG Suriname SRG Suriname
STD São Tome and Principe STD S<EFBFBD>o Tome and Principe
SVC El Salvador SVC El Salvador
SYP Syria SYP Syria
SZL Swaziland SZL Swaziland
@ -2102,13 +2154,13 @@ class getid3_id3v2
VND Viet Nam VND Viet Nam
VUV Vanuatu VUV Vanuatu
WST Samoa WST Samoa
XAF Communauté Financière Africaine XAF Communaut<EFBFBD> Financi<EFBFBD>re Africaine
XAG Silver XAG Silver
XAU Gold XAU Gold
XCD East Caribbean XCD East Caribbean
XDR International Monetary Fund XDR International Monetary Fund
XPD Palladium XPD Palladium
XPF Comptoirs Français du Pacifique XPF Comptoirs Fran<EFBFBD>ais du Pacifique
XPT Platinum XPT Platinum
YER Yemen YER Yemen
YUM Yugoslavia YUM Yugoslavia
@ -2552,7 +2604,7 @@ class getid3_id3v2
vai Vai vai Vai
ven Venda ven Venda
vie Vietnamese vie Vietnamese
vol Volapük vol Volap<EFBFBD>k
vot Votic vot Votic
wak Wakashan Languages wak Wakashan Languages
wal Walamo wal Walamo
@ -2757,10 +2809,12 @@ class getid3_id3v2
TBP BPM (Beats Per Minute) TBP BPM (Beats Per Minute)
TBPM BPM (beats per minute) TBPM BPM (beats per minute)
TCM Composer TCM Composer
TCMP Part of a compilation
TCO Content type TCO Content type
TCOM Composer TCOM Composer
TCON Content type TCON Content type
TCOP Copyright message TCOP Copyright message
TCP Part of a compilation
TCR Copyright message TCR Copyright message
TDA Date TDA Date
TDAT Date TDAT Date
@ -2823,15 +2877,22 @@ class getid3_id3v2
TRK Track number/Position in set TRK Track number/Position in set
TRSN Internet radio station name TRSN Internet radio station name
TRSO Internet radio station owner TRSO Internet radio station owner
TS2 Album-Artist sort order
TSA Album sort order
TSC Composer sort order
TSI Size TSI Size
TSIZ Size TSIZ Size
TSO2 Album-Artist sort order
TSOA Album sort order TSOA Album sort order
TSOC Composer sort order
TSOP Performer sort order TSOP Performer sort order
TSOT Title sort order TSOT Title sort order
TSP Performer sort order
TSRC ISRC (international standard recording code) TSRC ISRC (international standard recording code)
TSS Software/hardware and settings used for encoding TSS Software/hardware and settings used for encoding
TSSE Software/Hardware and settings used for encoding TSSE Software/Hardware and settings used for encoding
TSST Set subtitle TSST Set subtitle
TST Title sort order
TT1 Content group description TT1 Content group description
TT2 Title/Songname/Content description TT2 Title/Songname/Content description
TT3 Subtitle/Description refinement TT3 Subtitle/Description refinement
@ -2879,168 +2940,177 @@ class getid3_id3v2
$begin = __LINE__; $begin = __LINE__;
/** This is not a comment! /** This is not a comment!
AENC audio_encryption AENC audio_encryption
APIC attached_picture APIC attached_picture
ASPI audio_seek_point_index ASPI audio_seek_point_index
BUF recommended_buffer_size BUF recommended_buffer_size
CNT play_counter CNT play_counter
COM comments COM comments
COMM comments COMM comments
COMR commercial_frame COMR commercial_frame
CRA audio_encryption CRA audio_encryption
CRM encrypted_meta_frame CRM encrypted_meta_frame
ENCR encryption_method_registration ENCR encryption_method_registration
EQU equalisation EQU equalisation
EQU2 equalisation EQU2 equalisation
EQUA equalisation EQUA equalisation
ETC event_timing_codes ETC event_timing_codes
ETCO event_timing_codes ETCO event_timing_codes
GEO general_encapsulated_object GEO general_encapsulated_object
GEOB general_encapsulated_object GEOB general_encapsulated_object
GRID group_identification_registration GRID group_identification_registration
IPL involved_people_list IPL involved_people_list
IPLS involved_people_list IPLS involved_people_list
LINK linked_information LINK linked_information
LNK linked_information LNK linked_information
MCDI music_cd_identifier MCDI music_cd_identifier
MCI music_cd_identifier MCI music_cd_identifier
MLL mpeg_location_lookup_table MLL mpeg_location_lookup_table
MLLT mpeg_location_lookup_table MLLT mpeg_location_lookup_table
OWNE ownership_frame OWNE ownership_frame
PCNT play_counter PCNT play_counter
PIC attached_picture PIC attached_picture
POP popularimeter POP popularimeter
POPM popularimeter POPM popularimeter
POSS position_synchronisation_frame POSS position_synchronisation_frame
PRIV private_frame PRIV private_frame
RBUF recommended_buffer_size RBUF recommended_buffer_size
REV reverb REV reverb
RVA relative_volume_adjustment RVA relative_volume_adjustment
RVA2 relative_volume_adjustment RVA2 relative_volume_adjustment
RVAD relative_volume_adjustment RVAD relative_volume_adjustment
RVRB reverb RVRB reverb
SEEK seek_frame SEEK seek_frame
SIGN signature_frame SIGN signature_frame
SLT synchronised_lyric SLT synchronised_lyric
STC synced_tempo_codes STC synced_tempo_codes
SYLT synchronised_lyric SYLT synchronised_lyric
SYTC synchronised_tempo_codes SYTC synchronised_tempo_codes
TAL album TAL album
TALB album TALB album
TBP bpm TBP bpm
TBPM bpm TBPM bpm
TCM composer TCM composer
TCO content_type TCMP part_of_a_compilation
TCOM composer TCO genre
TCON content_type TCOM composer
TCOP copyright_message TCON genre
TCR copyright_message TCOP copyright_message
TDA date TCP part_of_a_compilation
TDAT date TCR copyright_message
TDEN encoding_time TDA date
TDLY playlist_delay TDAT date
TDOR original_release_time TDEN encoding_time
TDRC recording_time TDLY playlist_delay
TDRL release_time TDOR original_release_time
TDTG tagging_time TDRC recording_time
TDY playlist_delay TDRL release_time
TEN encoded_by TDTG tagging_time
TENC encoded_by TDY playlist_delay
TEXT lyricist TEN encoded_by
TFLT file_type TENC encoded_by
TFT file_type TEXT lyricist
TIM time TFLT file_type
TIME time TFT file_type
TIPL involved_people_list TIM time
TIT1 content_group_description TIME time
TIT2 title TIPL involved_people_list
TIT3 subtitle TIT1 content_group_description
TKE initial_key TIT2 title
TKEY initial_key TIT3 subtitle
TLA language TKE initial_key
TLAN language TKEY initial_key
TLE length TLA language
TLEN length TLAN language
TMCL musician_credits_list TLE length
TMED media_type TLEN length
TMOO mood TMCL musician_credits_list
TMT media_type TMED media_type
TOA original_artist TMOO mood
TOAL original_album TMT media_type
TOF original_filename TOA original_artist
TOFN original_filename TOAL original_album
TOL original_lyricist TOF original_filename
TOLY original_lyricist TOFN original_filename
TOPE original_artist TOL original_lyricist
TOR original_year TOLY original_lyricist
TORY original_year TOPE original_artist
TOT original_album TOR original_year
TOWN file_owner TORY original_year
TP1 artist TOT original_album
TP2 band TOWN file_owner
TP3 conductor TP1 artist
TP4 remixer TP2 band
TPA part_of_a_set TP3 conductor
TPB publisher TP4 remixer
TPE1 artist TPA part_of_a_set
TPE2 band TPB publisher
TPE3 conductor TPE1 artist
TPE4 remixer TPE2 band
TPOS part_of_a_set TPE3 conductor
TPRO produced_notice TPE4 remixer
TPUB publisher TPOS part_of_a_set
TRC isrc TPRO produced_notice
TRCK track_number TPUB publisher
TRD recording_dates TRC isrc
TRDA recording_dates TRCK track_number
TRK track_number TRD recording_dates
TRSN internet_radio_station_name TRDA recording_dates
TRSO internet_radio_station_owner TRK track_number
TSI size TRSN internet_radio_station_name
TSIZ size TRSO internet_radio_station_owner
TSOA album_sort_order TS2 album_artist_sort_order
TSOP performer_sort_order TSA album_sort_order
TSOT title_sort_order TSC composer_sort_order
TSRC isrc TSI size
TSS encoder_settings TSIZ size
TSSE encoder_settings TSO2 album_artist_sort_order
TSST set_subtitle TSOA album_sort_order
TT1 description TSOC composer_sort_order
TT2 title TSOP performer_sort_order
TT3 subtitle TSOT title_sort_order
TXT lyricist TSP performer_sort_order
TXX text TSRC isrc
TXXX text TSS encoder_settings
TYE year TSSE encoder_settings
TYER year TSST set_subtitle
UFI unique_file_identifier TST title_sort_order
UFID unique_file_identifier TT1 description
ULT unsychronised_lyric TT2 title
USER terms_of_use TT3 subtitle
USLT unsynchronised_lyric TXT lyricist
WAF url_file TXX text
WAR url_artist TXXX text
WAS url_source TYE year
WCM commercial_information TYER year
WCOM commercial_information UFI unique_file_identifier
WCOP copyright UFID unique_file_identifier
WCP copyright ULT unsychronised_lyric
WOAF url_file USER terms_of_use
WOAR url_artist USLT unsynchronised_lyric
WOAS url_source WAF url_file
WORS url_station WAR url_artist
WPAY url_payment WAS url_source
WPB url_publisher WCM commercial_information
WPUB url_publisher WCOM commercial_information
WXX url_user WCOP copyright
WXXX url_user WCP copyright
TFEA featured_artist WOAF url_file
TSTU recording_studio WOAR url_artist
rgad replay_gain_adjustment WOAS url_source
WORS url_station
*/ WPAY url_payment
WPB url_publisher
WPUB url_publisher
WXX url_user
WXXX url_user
TFEA featured_artist
TSTU recording_studio
rgad replay_gain_adjustment
*/
return getid3_lib::EmbeddedLookup($framename, $begin, __LINE__, __FILE__, 'id3v2-framename_short'); return getid3_lib::EmbeddedLookup($framename, $begin, __LINE__, __FILE__, 'id3v2-framename_short');
} }
@ -3067,12 +3137,14 @@ class getid3_id3v2
function IsValidID3v2FrameName($framename, $id3v2majorversion) { function IsValidID3v2FrameName($framename, $id3v2majorversion) {
switch ($id3v2majorversion) { switch ($id3v2majorversion) {
case 2: case 2:
return ereg('[A-Z][A-Z0-9]{2}', $framename); #return ereg('[A-Z][A-Z0-9]{2}', $framename);
return preg_match('/[A-Z][A-Z0-9]{2}/', $framename);
break; break;
case 3: case 3:
case 4: case 4:
return ereg('[A-Z][A-Z0-9]{3}', $framename); #return ereg('[A-Z][A-Z0-9]{3}', $framename);
return preg_match('/[A-Z][A-Z0-9]{3}/', $framename);
break; break;
} }
return false; return false;

View File

@ -20,6 +20,11 @@ class getid3_lyrics3
function getid3_lyrics3(&$fd, &$ThisFileInfo) { function getid3_lyrics3(&$fd, &$ThisFileInfo) {
// http://www.volweb.cz/str/tags.htm // http://www.volweb.cz/str/tags.htm
if ($ThisFileInfo['filesize'] >= pow(2, 31)) {
$ThisFileInfo['warning'][] = 'Unable to check for Lyrics3 because file is larger than 2GB';
return false;
}
fseek($fd, (0 - 128 - 9 - 6), SEEK_END); // end - ID3v1 - LYRICSEND - [Lyrics3size] fseek($fd, (0 - 128 - 9 - 6), SEEK_END); // end - ID3v1 - LYRICSEND - [Lyrics3size]
$lyrics3_id3v1 = fread($fd, 128 + 9 + 6); $lyrics3_id3v1 = fread($fd, 128 + 9 + 6);
$lyrics3lsz = substr($lyrics3_id3v1, 0, 6); // Lyrics3size $lyrics3lsz = substr($lyrics3_id3v1, 0, 6); // Lyrics3size
@ -96,6 +101,7 @@ class getid3_lyrics3
$GETID3_ERRORARRAY = &$ThisFileInfo['warning']; $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.apetag.php', __FILE__, false)) { if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.apetag.php', __FILE__, false)) {
$tag = new getid3_apetag($fd, $ThisFileInfo, $ThisFileInfo['lyrics3']['tag_offset_start']); $tag = new getid3_apetag($fd, $ThisFileInfo, $ThisFileInfo['lyrics3']['tag_offset_start']);
unset($tag);
} }
} }
@ -107,6 +113,11 @@ class getid3_lyrics3
function getLyrics3Data(&$ThisFileInfo, &$fd, $endoffset, $version, $length) { function getLyrics3Data(&$ThisFileInfo, &$fd, $endoffset, $version, $length) {
// http://www.volweb.cz/str/tags.htm // http://www.volweb.cz/str/tags.htm
if ($endoffset >= pow(2, 31)) {
$ThisFileInfo['warning'][] = 'Unable to check for Lyrics3 because file is larger than 2GB';
return false;
}
fseek($fd, $endoffset, SEEK_SET); fseek($fd, $endoffset, SEEK_SET);
if ($length <= 0) { if ($length <= 0) {
return false; return false;
@ -163,8 +174,8 @@ class getid3_lyrics3
$i = 0; $i = 0;
$flagnames = array('lyrics', 'timestamps', 'inhibitrandom'); $flagnames = array('lyrics', 'timestamps', 'inhibitrandom');
foreach ($flagnames as $flagname) { foreach ($flagnames as $flagname) {
if (strlen($ParsedLyrics3['raw']['IND']) > ++$i) { if (strlen($ParsedLyrics3['raw']['IND']) > $i++) {
$ParsedLyrics3['flags'][$flagname] = $this->IntString2Bool(substr($ParsedLyrics3['raw']['IND'], $i, 1)); $ParsedLyrics3['flags'][$flagname] = $this->IntString2Bool(substr($ParsedLyrics3['raw']['IND'], $i, 1 - 1));
} }
} }
} }
@ -181,9 +192,9 @@ class getid3_lyrics3
foreach ($imagestrings as $key => $imagestring) { foreach ($imagestrings as $key => $imagestring) {
if (strpos($imagestring, '||') !== false) { if (strpos($imagestring, '||') !== false) {
$imagearray = explode('||', $imagestring); $imagearray = explode('||', $imagestring);
$ParsedLyrics3['images'][$key]['filename'] = $imagearray[0]; $ParsedLyrics3['images'][$key]['filename'] = @$imagearray[0];
$ParsedLyrics3['images'][$key]['description'] = $imagearray[1]; $ParsedLyrics3['images'][$key]['description'] = @$imagearray[1];
$ParsedLyrics3['images'][$key]['timestamp'] = $this->Lyrics3Timestamp2Seconds($imagearray[2]); $ParsedLyrics3['images'][$key]['timestamp'] = $this->Lyrics3Timestamp2Seconds(@$imagearray[2]);
} }
} }
} }

View File

@ -27,6 +27,11 @@ class getid3_write_id3v1
} }
function WriteID3v1() { function WriteID3v1() {
if ((filesize($this->filename) >= (pow(2, 31) - 128)) || (filesize($this->filename) < 0)) {
$this->errors[] = 'Unable to write ID3v1 because file is larger than 2GB';
return false;
}
// File MUST be writeable - CHMOD(646) at least // File MUST be writeable - CHMOD(646) at least
if (is_writeable($this->filename)) { if (is_writeable($this->filename)) {
if ($fp_source = @fopen($this->filename, 'r+b')) { if ($fp_source = @fopen($this->filename, 'r+b')) {
@ -37,6 +42,7 @@ class getid3_write_id3v1
} else { } else {
fseek($fp_source, 0, SEEK_END); // append new ID3v1 tag fseek($fp_source, 0, SEEK_END); // append new ID3v1 tag
} }
$this->tag_data['track'] = (isset($this->tag_data['track']) ? $this->tag_data['track'] : (isset($this->tag_data['track_number']) ? $this->tag_data['track_number'] : (isset($this->tag_data['tracknumber']) ? $this->tag_data['tracknumber'] : '')));
$new_id3v1_tag_data = getid3_id3v1::GenerateID3v1Tag( $new_id3v1_tag_data = getid3_id3v1::GenerateID3v1Tag(
@$this->tag_data['title'], @$this->tag_data['title'],
@ -66,6 +72,10 @@ class getid3_write_id3v1
// Initialize getID3 engine // Initialize getID3 engine
$getID3 = new getID3; $getID3 = new getID3;
$ThisFileInfo = $getID3->analyze($this->filename); $ThisFileInfo = $getID3->analyze($this->filename);
if ($ThisFileInfo['filesize'] >= (pow(2, 31) - 128)) {
// cannot write tags on files > 2GB
return false;
}
if (isset($ThisFileInfo['tags']['id3v1'])) { if (isset($ThisFileInfo['tags']['id3v1'])) {
foreach ($ThisFileInfo['tags']['id3v1'] as $key => $value) { foreach ($ThisFileInfo['tags']['id3v1'] as $key => $value) {
$id3v1data[$key] = implode(',', $value); $id3v1data[$key] = implode(',', $value);
@ -77,6 +87,11 @@ class getid3_write_id3v1
} }
function RemoveID3v1() { function RemoveID3v1() {
if ($ThisFileInfo['filesize'] >= pow(2, 31)) {
$this->errors[] = 'Unable to write ID3v1 because file is larger than 2GB';
return false;
}
// File MUST be writeable - CHMOD(646) at least // File MUST be writeable - CHMOD(646) at least
if (is_writeable($this->filename)) { if (is_writeable($this->filename)) {
if ($fp_source = @fopen($this->filename, 'r+b')) { if ($fp_source = @fopen($this->filename, 'r+b')) {

View File

@ -40,6 +40,11 @@ class getid3_write_id3v2
// Initialize getID3 engine // Initialize getID3 engine
$getID3 = new getID3; $getID3 = new getID3;
$OldThisFileInfo = $getID3->analyze($this->filename); $OldThisFileInfo = $getID3->analyze($this->filename);
if ($OldThisFileInfo['filesize'] >= pow(2, 31)) {
$this->errors[] = 'Unable to write ID3v2 because file is larger than 2GB';
fclose($fp_source);
return false;
}
if ($this->merge_existing_data) { if ($this->merge_existing_data) {
// merge with existing data // merge with existing data
if (!empty($OldThisFileInfo['id3v2'])) { if (!empty($OldThisFileInfo['id3v2'])) {
@ -139,7 +144,6 @@ class getid3_write_id3v2
} }
function RemoveID3v2() { function RemoveID3v2() {
// File MUST be writeable - CHMOD(646) at least. It's best if the // File MUST be writeable - CHMOD(646) at least. It's best if the
// directory is also writeable, because that method is both faster and less susceptible to errors. // directory is also writeable, because that method is both faster and less susceptible to errors.
if (is_writeable(dirname($this->filename))) { if (is_writeable(dirname($this->filename))) {
@ -150,6 +154,11 @@ class getid3_write_id3v2
// Initialize getID3 engine // Initialize getID3 engine
$getID3 = new getID3; $getID3 = new getID3;
$OldThisFileInfo = $getID3->analyze($this->filename); $OldThisFileInfo = $getID3->analyze($this->filename);
if ($OldThisFileInfo['filesize'] >= pow(2, 31)) {
$this->errors[] = 'Unable to remove ID3v2 because file is larger than 2GB';
fclose($fp_source);
return false;
}
rewind($fp_source); rewind($fp_source);
if ($OldThisFileInfo['avdataoffset'] !== false) { if ($OldThisFileInfo['avdataoffset'] !== false) {
fseek($fp_source, $OldThisFileInfo['avdataoffset'], SEEK_SET); fseek($fp_source, $OldThisFileInfo['avdataoffset'], SEEK_SET);
@ -179,6 +188,11 @@ class getid3_write_id3v2
// Initialize getID3 engine // Initialize getID3 engine
$getID3 = new getID3; $getID3 = new getID3;
$OldThisFileInfo = $getID3->analyze($this->filename); $OldThisFileInfo = $getID3->analyze($this->filename);
if ($OldThisFileInfo['filesize'] >= pow(2, 31)) {
$this->errors[] = 'Unable to remove ID3v2 because file is larger than 2GB';
fclose($fp_source);
return false;
}
rewind($fp_source); rewind($fp_source);
if ($OldThisFileInfo['avdataoffset'] !== false) { if ($OldThisFileInfo['avdataoffset'] !== false) {
fseek($fp_source, $OldThisFileInfo['avdataoffset'], SEEK_SET); fseek($fp_source, $OldThisFileInfo['avdataoffset'], SEEK_SET);
@ -1894,6 +1908,7 @@ class getid3_write_id3v2
$ID3v2ShortFrameNameLookup[2]['beats_per_minute'] = 'TBP'; $ID3v2ShortFrameNameLookup[2]['beats_per_minute'] = 'TBP';
$ID3v2ShortFrameNameLookup[2]['composer'] = 'TCM'; $ID3v2ShortFrameNameLookup[2]['composer'] = 'TCM';
$ID3v2ShortFrameNameLookup[2]['genre'] = 'TCO'; $ID3v2ShortFrameNameLookup[2]['genre'] = 'TCO';
$ID3v2ShortFrameNameLookup[2]['itunescompilation'] = 'TCP';
$ID3v2ShortFrameNameLookup[2]['copyright'] = 'TCR'; $ID3v2ShortFrameNameLookup[2]['copyright'] = 'TCR';
$ID3v2ShortFrameNameLookup[2]['encoded_by'] = 'TEN'; $ID3v2ShortFrameNameLookup[2]['encoded_by'] = 'TEN';
$ID3v2ShortFrameNameLookup[2]['language'] = 'TLA'; $ID3v2ShortFrameNameLookup[2]['language'] = 'TLA';
@ -1949,6 +1964,7 @@ class getid3_write_id3v2
$ID3v2ShortFrameNameLookup[3]['synchronised_tempo_codes'] = 'SYTC'; $ID3v2ShortFrameNameLookup[3]['synchronised_tempo_codes'] = 'SYTC';
$ID3v2ShortFrameNameLookup[3]['album'] = 'TALB'; $ID3v2ShortFrameNameLookup[3]['album'] = 'TALB';
$ID3v2ShortFrameNameLookup[3]['beats_per_minute'] = 'TBPM'; $ID3v2ShortFrameNameLookup[3]['beats_per_minute'] = 'TBPM';
$ID3v2ShortFrameNameLookup[3]['itunescompilation'] = 'TCMP';
$ID3v2ShortFrameNameLookup[3]['composer'] = 'TCOM'; $ID3v2ShortFrameNameLookup[3]['composer'] = 'TCOM';
$ID3v2ShortFrameNameLookup[3]['genre'] = 'TCON'; $ID3v2ShortFrameNameLookup[3]['genre'] = 'TCON';
$ID3v2ShortFrameNameLookup[3]['copyright'] = 'TCOP'; $ID3v2ShortFrameNameLookup[3]['copyright'] = 'TCOP';
@ -1972,7 +1988,7 @@ class getid3_write_id3v2
$ID3v2ShortFrameNameLookup[3]['band'] = 'TPE2'; $ID3v2ShortFrameNameLookup[3]['band'] = 'TPE2';
$ID3v2ShortFrameNameLookup[3]['conductor'] = 'TPE3'; $ID3v2ShortFrameNameLookup[3]['conductor'] = 'TPE3';
$ID3v2ShortFrameNameLookup[3]['remixer'] = 'TPE4'; $ID3v2ShortFrameNameLookup[3]['remixer'] = 'TPE4';
$ID3v2ShortFrameNameLookup[3]['part_of_set'] = 'TPOS'; $ID3v2ShortFrameNameLookup[3]['part_of_a_set'] = 'TPOS';
$ID3v2ShortFrameNameLookup[3]['publisher'] = 'TPUB'; $ID3v2ShortFrameNameLookup[3]['publisher'] = 'TPUB';
$ID3v2ShortFrameNameLookup[3]['tracknumber'] = 'TRCK'; $ID3v2ShortFrameNameLookup[3]['tracknumber'] = 'TRCK';
$ID3v2ShortFrameNameLookup[3]['internet_radio_station_name'] = 'TRSN'; $ID3v2ShortFrameNameLookup[3]['internet_radio_station_name'] = 'TRSN';

View File

@ -52,7 +52,7 @@ class getid3_write_metaflac
if (GETID3_OS_ISWINDOWS) { if (GETID3_OS_ISWINDOWS) {
if (file_exists(GETID3_HELPERAPPSDIR.'metaflac.exe')) { if (file_exists(GETID3_HELPERAPPSDIR.'metaflac.exe')) {
//$commandline = '"'.GETID3_HELPERAPPSDIR.'metaflac.exe" --no-utf8-convert --remove-vc-all --import-vc-from="'.$tempcommentsfilename.'" "'.str_replace('/', '\\', $this->filename).'"'; //$commandline = '"'.GETID3_HELPERAPPSDIR.'metaflac.exe" --no-utf8-convert --remove-all-tags --import-tags-from="'.$tempcommentsfilename.'" "'.str_replace('/', '\\', $this->filename).'"';
// metaflac works fine if you copy-paste the above commandline into a command prompt, // metaflac works fine if you copy-paste the above commandline into a command prompt,
// but refuses to work with `backtick` if there are "doublequotes" present around BOTH // but refuses to work with `backtick` if there are "doublequotes" present around BOTH
// the metaflac pathname and the target filename. For whatever reason...?? // the metaflac pathname and the target filename. For whatever reason...??
@ -64,7 +64,7 @@ class getid3_write_metaflac
clearstatcache(); clearstatcache();
$timestampbeforewriting = filemtime($this->filename); $timestampbeforewriting = filemtime($this->filename);
$commandline = GETID3_HELPERAPPSDIR.'metaflac.exe --no-utf8-convert --remove-vc-all --import-vc-from="'.$tempcommentsfilename.'" "'.$this->filename.'" 2>&1'; $commandline = GETID3_HELPERAPPSDIR.'metaflac.exe --no-utf8-convert --remove-all-tags --import-tags-from="'.$tempcommentsfilename.'" "'.$this->filename.'" 2>&1';
$metaflacError = `$commandline`; $metaflacError = `$commandline`;
if (empty($metaflacError)) { if (empty($metaflacError)) {
@ -80,7 +80,7 @@ class getid3_write_metaflac
} else { } else {
// It's simpler on *nix // It's simpler on *nix
$commandline = 'metaflac --no-utf8-convert --remove-vc-all --import-vc-from='.$tempcommentsfilename.' "'.$this->filename.'" 2>&1'; $commandline = 'metaflac --no-utf8-convert --remove-all-tags --import-tags-from='.$tempcommentsfilename.' "'.$this->filename.'" 2>&1';
$metaflacError = `$commandline`; $metaflacError = `$commandline`;
} }
@ -116,7 +116,7 @@ class getid3_write_metaflac
clearstatcache(); clearstatcache();
$timestampbeforewriting = filemtime($this->filename); $timestampbeforewriting = filemtime($this->filename);
$commandline = GETID3_HELPERAPPSDIR.'metaflac.exe --remove-vc-all "'.$this->filename.'" 2>&1'; $commandline = GETID3_HELPERAPPSDIR.'metaflac.exe --remove-all-tags "'.$this->filename.'" 2>&1';
$metaflacError = `$commandline`; $metaflacError = `$commandline`;
if (empty($metaflacError)) { if (empty($metaflacError)) {
@ -132,7 +132,7 @@ class getid3_write_metaflac
} else { } else {
// It's simpler on *nix // It's simpler on *nix
$commandline = 'metaflac --remove-vc-all "'.$this->filename.'" 2>&1'; $commandline = 'metaflac --remove-all-tags "'.$this->filename.'" 2>&1';
$metaflacError = `$commandline`; $metaflacError = `$commandline`;
} }

View File

@ -27,7 +27,7 @@ function camp_import_error_handler()
function printUsage() function printUsage()
{ {
global $CC_CONFIG; global $CC_CONFIG;
echo "There are two ways to import audio files into Campcaster: linking\n"; echo "There are two ways to import audio files into Campcaster: linking\n";
echo "or copying.\n"; echo "or copying.\n";
echo "\n"; echo "\n";
@ -337,6 +337,13 @@ if (is_null($importMode)) {
exit(0); exit(0);
} }
global $CC_CONFIG;
if (!is_writable($CC_CONFIG["storageDir"])) {
echo "ERROR: You do not have write permissions to the directory you are trying to import to:\n " . $CC_CONFIG["storageDir"] . "\n\n";
exit;
}
global $g_fileCount; global $g_fileCount;
global $g_duplicates; global $g_duplicates;
if (is_array($files)) { if (is_array($files)) {

View File

@ -775,7 +775,7 @@ class Playlist extends StoredFile {
*/ */
public static function playlistTimeToSeconds($plt) public static function playlistTimeToSeconds($plt)
{ {
$arr = split(':', $plt); $arr = preg_split('/:/', $plt);
if (isset($arr[2])) { if (isset($arr[2])) {
return (intval($arr[0])*60 + intval($arr[1]))*60 + floatval($arr[2]); return (intval($arr[0])*60 + intval($arr[1]))*60 + floatval($arr[2]);
} }