Make WordPress Core

Ticket #24737: ID3-1.9.7.2.diff

File ID3-1.9.7.2.diff, 115.8 KB (added by wonderboymusic, 11 years ago)
  • deleted file wp-includes/ID3/class-getid3.php

    diff --git a/wp-includes/ID3/class-getid3.php b/wp-includes/ID3/class-getid3.php
    deleted file mode 100644
    index 8c18163..0000000
    + -  
    1 <?php
    2 /////////////////////////////////////////////////////////////////
    3 /// getID3() by James Heinrich <info@getid3.org>               //
    4 //  available at http://getid3.sourceforge.net                 //
    5 //            or http://www.getid3.org                         //
    6 /////////////////////////////////////////////////////////////////
    7 //                                                             //
    8 // Please see readme.txt for more information                  //
    9 //                                                            ///
    10 /////////////////////////////////////////////////////////////////
    11 
    12 // define a constant rather than looking up every time it is needed
    13 if (!defined('GETID3_OS_ISWINDOWS')) {
    14         define('GETID3_OS_ISWINDOWS', (stripos(PHP_OS, 'WIN') === 0));
    15 }
    16 // Get base path of getID3() - ONCE
    17 if (!defined('GETID3_INCLUDEPATH')) {
    18         define('GETID3_INCLUDEPATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
    19 }
    20 
    21 // attempt to define temp dir as something flexible but reliable
    22 $temp_dir = ini_get('upload_tmp_dir');
    23 if ($temp_dir && (!is_dir($temp_dir) || !is_readable($temp_dir))) {
    24         $temp_dir = '';
    25 }
    26 if (!$temp_dir && function_exists('sys_get_temp_dir')) {
    27         // PHP v5.2.1+
    28         // sys_get_temp_dir() may give inaccessible temp dir, e.g. with open_basedir on virtual hosts
    29         $temp_dir = sys_get_temp_dir();
    30 }
    31 $temp_dir = realpath($temp_dir);
    32 $open_basedir = ini_get('open_basedir');
    33 if ($open_basedir) {
    34         // e.g. "/var/www/vhosts/getid3.org/httpdocs/:/tmp/"
    35         $temp_dir     = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $temp_dir);
    36         $open_basedir = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $open_basedir);
    37         if (substr($temp_dir, -1, 1) != DIRECTORY_SEPARATOR) {
    38                 $temp_dir .= DIRECTORY_SEPARATOR;
    39         }
    40         $found_valid_tempdir = false;
    41         $open_basedirs = explode(PATH_SEPARATOR, $open_basedir);
    42         foreach ($open_basedirs as $basedir) {
    43                 if (substr($basedir, -1, 1) != DIRECTORY_SEPARATOR) {
    44                         $basedir .= DIRECTORY_SEPARATOR;
    45                 }
    46                 if (preg_match('#^'.preg_quote($basedir).'#', $temp_dir)) {
    47                         $found_valid_tempdir = true;
    48                         break;
    49                 }
    50         }
    51         if (!$found_valid_tempdir) {
    52                 $temp_dir = '';
    53         }
    54         unset($open_basedirs, $found_valid_tempdir, $basedir);
    55 }
    56 if (!$temp_dir) {
    57         $temp_dir = '*'; // invalid directory name should force tempnam() to use system default temp dir
    58 }
    59 // $temp_dir = '/something/else/';  // feel free to override temp dir here if it works better for your system
    60 define('GETID3_TEMP_DIR', $temp_dir);
    61 unset($open_basedir, $temp_dir);
    62 
    63 // End: Defines
    64 
    65 
    66 class getID3
    67 {
    68         // public: Settings
    69         public $encoding        = 'UTF-8';        // CASE SENSITIVE! - i.e. (must be supported by iconv()). Examples:  ISO-8859-1  UTF-8  UTF-16  UTF-16BE
    70         public $encoding_id3v1  = 'ISO-8859-1';   // Should always be 'ISO-8859-1', but some tags may be written in other encodings such as 'EUC-CN' or 'CP1252'
    71 
    72         // public: Optional tag checks - disable for speed.
    73         public $option_tag_id3v1         = true;  // Read and process ID3v1 tags
    74         public $option_tag_id3v2         = true;  // Read and process ID3v2 tags
    75         public $option_tag_lyrics3       = true;  // Read and process Lyrics3 tags
    76         public $option_tag_apetag        = true;  // Read and process APE tags
    77         public $option_tags_process      = true;  // Copy tags to root key 'tags' and encode to $this->encoding
    78         public $option_tags_html         = true;  // Copy tags to root key 'tags_html' properly translated from various encodings to HTML entities
    79 
    80         // public: Optional tag/comment calucations
    81         public $option_extra_info        = true;  // Calculate additional info such as bitrate, channelmode etc
    82 
    83         // public: Optional handling of embedded attachments (e.g. images)
    84         public $option_save_attachments  = true; // defaults to true (ATTACHMENTS_INLINE) for backward compatibility
    85 
    86         // public: Optional calculations
    87         public $option_md5_data          = false; // Get MD5 sum of data part - slow
    88         public $option_md5_data_source   = false; // Use MD5 of source file if availble - only FLAC and OptimFROG
    89         public $option_sha1_data         = false; // Get SHA1 sum of data part - slow
    90         public $option_max_2gb_check     = null;  // Check whether file is larger than 2GB and thus not supported by 32-bit PHP (null: auto-detect based on PHP_INT_MAX)
    91 
    92         // public: Read buffer size in bytes
    93         public $option_fread_buffer_size = 32768;
    94 
    95         // Public variables
    96         public $filename;                         // Filename of file being analysed.
    97         public $fp;                               // Filepointer to file being analysed.
    98         public $info;                             // Result array.
    99         public $tempdir = GETID3_TEMP_DIR;
    100 
    101         // Protected variables
    102         protected $startup_error   = '';
    103         protected $startup_warning = '';
    104         protected $memory_limit    = 0;
    105 
    106         const VERSION           = '1.9.5-20130220';
    107         const FREAD_BUFFER_SIZE = 32768;
    108 
    109         const ATTACHMENTS_NONE   = false;
    110         const ATTACHMENTS_INLINE = true;
    111 
    112         // public: constructor
    113         public function __construct() {
    114 
    115                 // Check for PHP version
    116                 $required_php_version = '5.0.5';
    117                 if (version_compare(PHP_VERSION, $required_php_version, '<')) {
    118                         $this->startup_error .= 'getID3() requires PHP v'.$required_php_version.' or higher - you are running v'.PHP_VERSION;
    119                         return false;
    120                 }
    121 
    122                 // Check memory
    123                 $this->memory_limit = ini_get('memory_limit');
    124                 if (preg_match('#([0-9]+)M#i', $this->memory_limit, $matches)) {
    125                         // could be stored as "16M" rather than 16777216 for example
    126                         $this->memory_limit = $matches[1] * 1048576;
    127                 } elseif (preg_match('#([0-9]+)G#i', $this->memory_limit, $matches)) { // The 'G' modifier is available since PHP 5.1.0
    128                         // could be stored as "2G" rather than 2147483648 for example
    129                         $this->memory_limit = $matches[1] * 1073741824;
    130                 }
    131                 if ($this->memory_limit <= 0) {
    132                         // memory limits probably disabled
    133                 } elseif ($this->memory_limit <= 4194304) {
    134                         $this->startup_error .= 'PHP has less than 4MB available memory and will very likely run out. Increase memory_limit in php.ini';
    135                 } elseif ($this->memory_limit <= 12582912) {
    136                         $this->startup_warning .= 'PHP has less than 12MB available memory and might run out if all modules are loaded. Increase memory_limit in php.ini';
    137                 }
    138 
    139                 // Check safe_mode off
    140                 if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
    141                         $this->warning('WARNING: Safe mode is on, shorten support disabled, md5data/sha1data for ogg vorbis disabled, ogg vorbos/flac tag writing disabled.');
    142                 }
    143 
    144                 if (intval(ini_get('mbstring.func_overload')) > 0) {
    145                         $this->warning('WARNING: php.ini contains "mbstring.func_overload = '.ini_get('mbstring.func_overload').'", this may break things.');
    146                 }
    147 
    148                 // Check for magic_quotes_runtime
    149                 if (function_exists('get_magic_quotes_runtime')) {
    150                         if (get_magic_quotes_runtime()) {
    151                                 return $this->startup_error('magic_quotes_runtime must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_runtime(0) and set_magic_quotes_runtime(1).');
    152                         }
    153                 }
    154 
    155                 // Check for magic_quotes_gpc
    156                 if (function_exists('magic_quotes_gpc')) {
    157                         if (get_magic_quotes_gpc()) {
    158                                 return $this->startup_error('magic_quotes_gpc must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_gpc(0) and set_magic_quotes_gpc(1).');
    159                         }
    160                 }
    161 
    162                 // Load support library
    163                 if (!include_once(GETID3_INCLUDEPATH.'getid3.lib.php')) {
    164                         $this->startup_error .= 'getid3.lib.php is missing or corrupt';
    165                 }
    166 
    167                 if ($this->option_max_2gb_check === null) {
    168                         $this->option_max_2gb_check = (PHP_INT_MAX <= 2147483647);
    169                 }
    170 
    171 
    172                 // Needed for Windows only:
    173                 // Define locations of helper applications for Shorten, VorbisComment, MetaFLAC
    174                 //   as well as other helper functions such as head, tail, md5sum, etc
    175                 // This path cannot contain spaces, but the below code will attempt to get the
    176                 //   8.3-equivalent path automatically
    177                 // IMPORTANT: This path must include the trailing slash
    178                 if (GETID3_OS_ISWINDOWS && !defined('GETID3_HELPERAPPSDIR')) {
    179 
    180                         $helperappsdir = GETID3_INCLUDEPATH.'..'.DIRECTORY_SEPARATOR.'helperapps'; // must not have any space in this path
    181 
    182                         if (!is_dir($helperappsdir)) {
    183                                 $this->startup_warning .= '"'.$helperappsdir.'" cannot be defined as GETID3_HELPERAPPSDIR because it does not exist';
    184                         } elseif (strpos(realpath($helperappsdir), ' ') !== false) {
    185                                 $DirPieces = explode(DIRECTORY_SEPARATOR, realpath($helperappsdir));
    186                                 $path_so_far = array();
    187                                 foreach ($DirPieces as $key => $value) {
    188                                         if (strpos($value, ' ') !== false) {
    189                                                 if (!empty($path_so_far)) {
    190                                                         $commandline = 'dir /x '.escapeshellarg(implode(DIRECTORY_SEPARATOR, $path_so_far));
    191                                                         $dir_listing = `$commandline`;
    192                                                         $lines = explode("\n", $dir_listing);
    193                                                         foreach ($lines as $line) {
    194                                                                 $line = trim($line);
    195                                                                 if (preg_match('#^([0-9/]{10}) +([0-9:]{4,5}( [AP]M)?) +(<DIR>|[0-9,]+) +([^ ]{0,11}) +(.+)$#', $line, $matches)) {
    196                                                                         list($dummy, $date, $time, $ampm, $filesize, $shortname, $filename) = $matches;
    197                                                                         if ((strtoupper($filesize) == '<DIR>') && (strtolower($filename) == strtolower($value))) {
    198                                                                                 $value = $shortname;
    199                                                                         }
    200                                                                 }
    201                                                         }
    202                                                 } else {
    203                                                         $this->startup_warning .= 'GETID3_HELPERAPPSDIR must not have any spaces in it - use 8dot3 naming convention if neccesary. You can run "dir /x" from the commandline to see the correct 8.3-style names.';
    204                                                 }
    205                                         }
    206                                         $path_so_far[] = $value;
    207                                 }
    208                                 $helperappsdir = implode(DIRECTORY_SEPARATOR, $path_so_far);
    209                         }
    210                         define('GETID3_HELPERAPPSDIR', $helperappsdir.DIRECTORY_SEPARATOR);
    211                 }
    212 
    213                 return true;
    214         }
    215 
    216         public function version() {
    217                 return self::VERSION;
    218         }
    219 
    220         public function fread_buffer_size() {
    221                 return $this->option_fread_buffer_size;
    222         }
    223 
    224         // public: setOption
    225         public function setOption($optArray) {
    226                 if (!is_array($optArray) || empty($optArray)) {
    227                         return false;
    228                 }
    229                 foreach ($optArray as $opt => $val) {
    230                         if (isset($this->$opt) === false) {
    231                                 continue;
    232                         }
    233                         $this->$opt = $val;
    234                 }
    235                 return true;
    236         }
    237 
    238         public function openfile($filename) {
    239                 try {
    240                         if (!empty($this->startup_error)) {
    241                                 throw new getid3_exception($this->startup_error);
    242                         }
    243                         if (!empty($this->startup_warning)) {
    244                                 $this->warning($this->startup_warning);
    245                         }
    246 
    247                         // init result array and set parameters
    248                         $this->filename = $filename;
    249                         $this->info = array();
    250                         $this->info['GETID3_VERSION']   = $this->version();
    251                         $this->info['php_memory_limit'] = $this->memory_limit;
    252 
    253                         // remote files not supported
    254                         if (preg_match('/^(ht|f)tp:\/\//', $filename)) {
    255                                 throw new getid3_exception('Remote files are not supported - please copy the file locally first');
    256                         }
    257 
    258                         $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename);
    259                         $filename = preg_replace('#(.+)'.preg_quote(DIRECTORY_SEPARATOR).'{2,}#U', '\1'.DIRECTORY_SEPARATOR, $filename);
    260 
    261                         // open local file
    262                         if (is_readable($filename) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) {
    263                                 // great
    264                         } else {
    265                                 throw new getid3_exception('Could not open "'.$filename.'" (does not exist, or is not a file)');
    266                         }
    267 
    268                         $this->info['filesize'] = filesize($filename);
    269                         // set redundant parameters - might be needed in some include file
    270                         $this->info['filename']     = basename($filename);
    271                         $this->info['filepath']     = str_replace('\\', '/', realpath(dirname($filename)));
    272                         $this->info['filenamepath'] = $this->info['filepath'].'/'.$this->info['filename'];
    273 
    274 
    275                         // option_max_2gb_check
    276                         if ($this->option_max_2gb_check) {
    277                                 // PHP (32-bit all, and 64-bit Windows) doesn't support integers larger than 2^31 (~2GB)
    278                                 // filesize() simply returns (filesize % (pow(2, 32)), no matter the actual filesize
    279                                 // ftell() returns 0 if seeking to the end is beyond the range of unsigned integer
    280                                 $fseek = fseek($this->fp, 0, SEEK_END);
    281                                 if (($fseek < 0) || (($this->info['filesize'] != 0) && (ftell($this->fp) == 0)) ||
    282                                         ($this->info['filesize'] < 0) ||
    283                                         (ftell($this->fp) < 0)) {
    284                                                 $real_filesize = getid3_lib::getFileSizeSyscall($this->info['filenamepath']);
    285 
    286                                                 if ($real_filesize === false) {
    287                                                         unset($this->info['filesize']);
    288                                                         fclose($this->fp);
    289                                                         throw new getid3_exception('Unable to determine actual filesize. File is most likely larger than '.round(PHP_INT_MAX / 1073741824).'GB and is not supported by PHP.');
    290                                                 } elseif (getid3_lib::intValueSupported($real_filesize)) {
    291                                                         unset($this->info['filesize']);
    292                                                         fclose($this->fp);
    293                                                         throw new getid3_exception('PHP seems to think the file is larger than '.round(PHP_INT_MAX / 1073741824).'GB, but filesystem reports it as '.number_format($real_filesize, 3).'GB, please report to info@getid3.org');
    294                                                 }
    295                                                 $this->info['filesize'] = $real_filesize;
    296                                                 $this->error('File is larger than '.round(PHP_INT_MAX / 1073741824).'GB (filesystem reports it as '.number_format($real_filesize, 3).'GB) and is not properly supported by PHP.');
    297                                 }
    298                         }
    299 
    300                         // set more parameters
    301                         $this->info['avdataoffset']        = 0;
    302                         $this->info['avdataend']           = $this->info['filesize'];
    303                         $this->info['fileformat']          = '';                // filled in later
    304                         $this->info['audio']['dataformat'] = '';                // filled in later, unset if not used
    305                         $this->info['video']['dataformat'] = '';                // filled in later, unset if not used
    306                         $this->info['tags']                = array();           // filled in later, unset if not used
    307                         $this->info['error']               = array();           // filled in later, unset if not used
    308                         $this->info['warning']             = array();           // filled in later, unset if not used
    309                         $this->info['comments']            = array();           // filled in later, unset if not used
    310                         $this->info['encoding']            = $this->encoding;   // required by id3v2 and iso modules - can be unset at the end if desired
    311 
    312                         return true;
    313 
    314                 } catch (Exception $e) {
    315                         $this->error($e->getMessage());
    316                 }
    317                 return false;
    318         }
    319 
    320         // public: analyze file
    321         public function analyze($filename) {
    322                 try {
    323                         if (!$this->openfile($filename)) {
    324                                 return $this->info;
    325                         }
    326 
    327                         // Handle tags
    328                         foreach (array('id3v2'=>'id3v2', 'id3v1'=>'id3v1', 'apetag'=>'ape', 'lyrics3'=>'lyrics3') as $tag_name => $tag_key) {
    329                                 $option_tag = 'option_tag_'.$tag_name;
    330                                 if ($this->$option_tag) {
    331                                         $this->include_module('tag.'.$tag_name);
    332                                         try {
    333                                                 $tag_class = 'getid3_'.$tag_name;
    334                                                 $tag = new $tag_class($this);
    335                                                 $tag->Analyze();
    336                                         }
    337                                         catch (getid3_exception $e) {
    338                                                 throw $e;
    339                                         }
    340                                 }
    341                         }
    342                         if (isset($this->info['id3v2']['tag_offset_start'])) {
    343                                 $this->info['avdataoffset'] = max($this->info['avdataoffset'], $this->info['id3v2']['tag_offset_end']);
    344                         }
    345                         foreach (array('id3v1'=>'id3v1', 'apetag'=>'ape', 'lyrics3'=>'lyrics3') as $tag_name => $tag_key) {
    346                                 if (isset($this->info[$tag_key]['tag_offset_start'])) {
    347                                         $this->info['avdataend'] = min($this->info['avdataend'], $this->info[$tag_key]['tag_offset_start']);
    348                                 }
    349                         }
    350 
    351                         // ID3v2 detection (NOT parsing), even if ($this->option_tag_id3v2 == false) done to make fileformat easier
    352                         if (!$this->option_tag_id3v2) {
    353                                 fseek($this->fp, 0, SEEK_SET);
    354                                 $header = fread($this->fp, 10);
    355                                 if ((substr($header, 0, 3) == 'ID3') && (strlen($header) == 10)) {
    356                                         $this->info['id3v2']['header']        = true;
    357                                         $this->info['id3v2']['majorversion']  = ord($header{3});
    358                                         $this->info['id3v2']['minorversion']  = ord($header{4});
    359                                         $this->info['avdataoffset']          += getid3_lib::BigEndian2Int(substr($header, 6, 4), 1) + 10; // length of ID3v2 tag in 10-byte header doesn't include 10-byte header length
    360                                 }
    361                         }
    362 
    363                         // read 32 kb file data
    364                         fseek($this->fp, $this->info['avdataoffset'], SEEK_SET);
    365                         $formattest = fread($this->fp, 32774);
    366 
    367                         // determine format
    368                         $determined_format = $this->GetFileFormat($formattest, $filename);
    369 
    370                         // unable to determine file format
    371                         if (!$determined_format) {
    372                                 fclose($this->fp);
    373                                 return $this->error('unable to determine file format');
    374                         }
    375 
    376                         // check for illegal ID3 tags
    377                         if (isset($determined_format['fail_id3']) && (in_array('id3v1', $this->info['tags']) || in_array('id3v2', $this->info['tags']))) {
    378                                 if ($determined_format['fail_id3'] === 'ERROR') {
    379                                         fclose($this->fp);
    380                                         return $this->error('ID3 tags not allowed on this file type.');
    381                                 } elseif ($determined_format['fail_id3'] === 'WARNING') {
    382                                         $this->warning('ID3 tags not allowed on this file type.');
    383                                 }
    384                         }
    385 
    386                         // check for illegal APE tags
    387                         if (isset($determined_format['fail_ape']) && in_array('ape', $this->info['tags'])) {
    388                                 if ($determined_format['fail_ape'] === 'ERROR') {
    389                                         fclose($this->fp);
    390                                         return $this->error('APE tags not allowed on this file type.');
    391                                 } elseif ($determined_format['fail_ape'] === 'WARNING') {
    392                                         $this->warning('APE tags not allowed on this file type.');
    393                                 }
    394                         }
    395 
    396                         // set mime type
    397                         $this->info['mime_type'] = $determined_format['mime_type'];
    398 
    399                         // supported format signature pattern detected, but module deleted
    400                         if (!file_exists(GETID3_INCLUDEPATH.$determined_format['include'])) {
    401                                 fclose($this->fp);
    402                                 return $this->error('Format not supported, module "'.$determined_format['include'].'" was removed.');
    403                         }
    404 
    405                         // module requires iconv support
    406                         // Check encoding/iconv support
    407                         if (!empty($determined_format['iconv_req']) && !function_exists('iconv') && !in_array($this->encoding, array('ISO-8859-1', 'UTF-8', 'UTF-16LE', 'UTF-16BE', 'UTF-16'))) {
    408                                 $errormessage = 'iconv() support is required for this module ('.$determined_format['include'].') for encodings other than ISO-8859-1, UTF-8, UTF-16LE, UTF16-BE, UTF-16. ';
    409                                 if (GETID3_OS_ISWINDOWS) {
    410                                         $errormessage .= 'PHP does not have iconv() support. Please enable php_iconv.dll in php.ini, and copy iconv.dll from c:/php/dlls to c:/windows/system32';
    411                                 } else {
    412                                         $errormessage .= 'PHP is not compiled with iconv() support. Please recompile with the --with-iconv switch';
    413                                 }
    414                                 return $this->error($errormessage);
    415                         }
    416 
    417                         // include module
    418                         include_once(GETID3_INCLUDEPATH.$determined_format['include']);
    419 
    420                         // instantiate module class
    421                         $class_name = 'getid3_'.$determined_format['module'];
    422                         if (!class_exists($class_name)) {
    423                                 return $this->error('Format not supported, module "'.$determined_format['include'].'" is corrupt.');
    424                         }
    425                         $class = new $class_name($this);
    426                         $class->Analyze();
    427                         unset($class);
    428 
    429                         // close file
    430                         fclose($this->fp);
    431 
    432                         // process all tags - copy to 'tags' and convert charsets
    433                         if ($this->option_tags_process) {
    434                                 $this->HandleAllTags();
    435                         }
    436 
    437                         // perform more calculations
    438                         if ($this->option_extra_info) {
    439                                 $this->ChannelsBitratePlaytimeCalculations();
    440                                 $this->CalculateCompressionRatioVideo();
    441                                 $this->CalculateCompressionRatioAudio();
    442                                 $this->CalculateReplayGain();
    443                                 $this->ProcessAudioStreams();
    444                         }
    445 
    446                         // get the MD5 sum of the audio/video portion of the file - without ID3/APE/Lyrics3/etc header/footer tags
    447                         if ($this->option_md5_data) {
    448                                 // do not calc md5_data if md5_data_source is present - set by flac only - future MPC/SV8 too
    449                                 if (!$this->option_md5_data_source || empty($this->info['md5_data_source'])) {
    450                                         $this->getHashdata('md5');
    451                                 }
    452                         }
    453 
    454                         // get the SHA1 sum of the audio/video portion of the file - without ID3/APE/Lyrics3/etc header/footer tags
    455                         if ($this->option_sha1_data) {
    456                                 $this->getHashdata('sha1');
    457                         }
    458 
    459                         // remove undesired keys
    460                         $this->CleanUp();
    461 
    462                 } catch (Exception $e) {
    463                         $this->error('Caught exception: '.$e->getMessage());
    464                 }
    465 
    466                 // return info array
    467                 return $this->info;
    468         }
    469 
    470 
    471         // private: error handling
    472         public function error($message) {
    473                 $this->CleanUp();
    474                 if (!isset($this->info['error'])) {
    475                         $this->info['error'] = array();
    476                 }
    477                 $this->info['error'][] = $message;
    478                 return $this->info;
    479         }
    480 
    481 
    482         // private: warning handling
    483         public function warning($message) {
    484                 $this->info['warning'][] = $message;
    485                 return true;
    486         }
    487 
    488 
    489         // private: CleanUp
    490         private function CleanUp() {
    491 
    492                 // remove possible empty keys
    493                 $AVpossibleEmptyKeys = array('dataformat', 'bits_per_sample', 'encoder_options', 'streams', 'bitrate');
    494                 foreach ($AVpossibleEmptyKeys as $dummy => $key) {
    495                         if (empty($this->info['audio'][$key]) && isset($this->info['audio'][$key])) {
    496                                 unset($this->info['audio'][$key]);
    497                         }
    498                         if (empty($this->info['video'][$key]) && isset($this->info['video'][$key])) {
    499                                 unset($this->info['video'][$key]);
    500                         }
    501                 }
    502 
    503                 // remove empty root keys
    504                 if (!empty($this->info)) {
    505                         foreach ($this->info as $key => $value) {
    506                                 if (empty($this->info[$key]) && ($this->info[$key] !== 0) && ($this->info[$key] !== '0')) {
    507                                         unset($this->info[$key]);
    508                                 }
    509                         }
    510                 }
    511 
    512                 // remove meaningless entries from unknown-format files
    513                 if (empty($this->info['fileformat'])) {
    514                         if (isset($this->info['avdataoffset'])) {
    515                                 unset($this->info['avdataoffset']);
    516                         }
    517                         if (isset($this->info['avdataend'])) {
    518                                 unset($this->info['avdataend']);
    519                         }
    520                 }
    521 
    522                 // remove possible duplicated identical entries
    523                 if (!empty($this->info['error'])) {
    524                         $this->info['error'] = array_values(array_unique($this->info['error']));
    525                 }
    526                 if (!empty($this->info['warning'])) {
    527                         $this->info['warning'] = array_values(array_unique($this->info['warning']));
    528                 }
    529 
    530                 // remove "global variable" type keys
    531                 unset($this->info['php_memory_limit']);
    532 
    533                 return true;
    534         }
    535 
    536 
    537         // return array containing information about all supported formats
    538         public function GetFileFormatArray() {
    539                 static $format_info = array();
    540                 if (empty($format_info)) {
    541                         $format_info = array(
    542 
    543                                 // Audio formats
    544 
    545                                 // AC-3   - audio      - Dolby AC-3 / Dolby Digital
    546                                 'ac3'  => array(
    547                                                         'pattern'   => '^\x0B\x77',
    548                                                         'group'     => 'audio',
    549                                                         'module'    => 'ac3',
    550                                                         'mime_type' => 'audio/ac3',
    551                                                 ),
    552 
    553                                 // AAC  - audio       - Advanced Audio Coding (AAC) - ADIF format
    554                                 'adif' => array(
    555                                                         'pattern'   => '^ADIF',
    556                                                         'group'     => 'audio',
    557                                                         'module'    => 'aac',
    558                                                         'mime_type' => 'application/octet-stream',
    559                                                         'fail_ape'  => 'WARNING',
    560                                                 ),
    561 
    562 /*
    563                                 // AA   - audio       - Audible Audiobook
    564                                 'aa'   => array(
    565                                                         'pattern'   => '^.{4}\x57\x90\x75\x36',
    566                                                         'group'     => 'audio',
    567                                                         'module'    => 'aa',
    568                                                         'mime_type' => 'audio/audible',
    569                                                 ),
    570 */
    571                                 // AAC  - audio       - Advanced Audio Coding (AAC) - ADTS format (very similar to MP3)
    572                                 'adts' => array(
    573                                                         'pattern'   => '^\xFF[\xF0-\xF1\xF8-\xF9]',
    574                                                         'group'     => 'audio',
    575                                                         'module'    => 'aac',
    576                                                         'mime_type' => 'application/octet-stream',
    577                                                         'fail_ape'  => 'WARNING',
    578                                                 ),
    579 
    580 
    581                                 // AU   - audio       - NeXT/Sun AUdio (AU)
    582                                 'au'   => array(
    583                                                         'pattern'   => '^\.snd',
    584                                                         'group'     => 'audio',
    585                                                         'module'    => 'au',
    586                                                         'mime_type' => 'audio/basic',
    587                                                 ),
    588 
    589                                 // AVR  - audio       - Audio Visual Research
    590                                 'avr'  => array(
    591                                                         'pattern'   => '^2BIT',
    592                                                         'group'     => 'audio',
    593                                                         'module'    => 'avr',
    594                                                         'mime_type' => 'application/octet-stream',
    595                                                 ),
    596 
    597                                 // BONK - audio       - Bonk v0.9+
    598                                 'bonk' => array(
    599                                                         'pattern'   => '^\x00(BONK|INFO|META| ID3)',
    600                                                         'group'     => 'audio',
    601                                                         'module'    => 'bonk',
    602                                                         'mime_type' => 'audio/xmms-bonk',
    603                                                 ),
    604 
    605                                 // DSS  - audio       - Digital Speech Standard
    606                                 'dss'  => array(
    607                                                         'pattern'   => '^[\x02-\x03]ds[s2]',
    608                                                         'group'     => 'audio',
    609                                                         'module'    => 'dss',
    610                                                         'mime_type' => 'application/octet-stream',
    611                                                 ),
    612 
    613                                 // DTS  - audio       - Dolby Theatre System
    614                                 'dts'  => array(
    615                                                         'pattern'   => '^\x7F\xFE\x80\x01',
    616                                                         'group'     => 'audio',
    617                                                         'module'    => 'dts',
    618                                                         'mime_type' => 'audio/dts',
    619                                                 ),
    620 
    621                                 // FLAC - audio       - Free Lossless Audio Codec
    622                                 'flac' => array(
    623                                                         'pattern'   => '^fLaC',
    624                                                         'group'     => 'audio',
    625                                                         'module'    => 'flac',
    626                                                         'mime_type' => 'audio/x-flac',
    627                                                 ),
    628 
    629                                 // LA   - audio       - Lossless Audio (LA)
    630                                 'la'   => array(
    631                                                         'pattern'   => '^LA0[2-4]',
    632                                                         'group'     => 'audio',
    633                                                         'module'    => 'la',
    634                                                         'mime_type' => 'application/octet-stream',
    635                                                 ),
    636 
    637                                 // LPAC - audio       - Lossless Predictive Audio Compression (LPAC)
    638                                 'lpac' => array(
    639                                                         'pattern'   => '^LPAC',
    640                                                         'group'     => 'audio',
    641                                                         'module'    => 'lpac',
    642                                                         'mime_type' => 'application/octet-stream',
    643                                                 ),
    644 
    645                                 // MIDI - audio       - MIDI (Musical Instrument Digital Interface)
    646                                 'midi' => array(
    647                                                         'pattern'   => '^MThd',
    648                                                         'group'     => 'audio',
    649                                                         'module'    => 'midi',
    650                                                         'mime_type' => 'audio/midi',
    651                                                 ),
    652 
    653                                 // MAC  - audio       - Monkey's Audio Compressor
    654                                 'mac'  => array(
    655                                                         'pattern'   => '^MAC ',
    656                                                         'group'     => 'audio',
    657                                                         'module'    => 'monkey',
    658                                                         'mime_type' => 'application/octet-stream',
    659                                                 ),
    660 
    661 // has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available
    662 //                              // MOD  - audio       - MODule (assorted sub-formats)
    663 //                              'mod'  => array(
    664 //                                                      'pattern'   => '^.{1080}(M\\.K\\.|M!K!|FLT4|FLT8|[5-9]CHN|[1-3][0-9]CH)',
    665 //                                                      'group'     => 'audio',
    666 //                                                      'module'    => 'mod',
    667 //                                                      'option'    => 'mod',
    668 //                                                      'mime_type' => 'audio/mod',
    669 //                                              ),
    670 
    671                                 // MOD  - audio       - MODule (Impulse Tracker)
    672                                 'it'   => array(
    673                                                         'pattern'   => '^IMPM',
    674                                                         'group'     => 'audio',
    675                                                         'module'    => 'mod',
    676                                                         //'option'    => 'it',
    677                                                         'mime_type' => 'audio/it',
    678                                                 ),
    679 
    680                                 // MOD  - audio       - MODule (eXtended Module, various sub-formats)
    681                                 'xm'   => array(
    682                                                         'pattern'   => '^Extended Module',
    683                                                         'group'     => 'audio',
    684                                                         'module'    => 'mod',
    685                                                         //'option'    => 'xm',
    686                                                         'mime_type' => 'audio/xm',
    687                                                 ),
    688 
    689                                 // MOD  - audio       - MODule (ScreamTracker)
    690                                 's3m'  => array(
    691                                                         'pattern'   => '^.{44}SCRM',
    692                                                         'group'     => 'audio',
    693                                                         'module'    => 'mod',
    694                                                         //'option'    => 's3m',
    695                                                         'mime_type' => 'audio/s3m',
    696                                                 ),
    697 
    698                                 // MPC  - audio       - Musepack / MPEGplus
    699                                 'mpc'  => array(
    700                                                         '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])',
    701                                                         'group'     => 'audio',
    702                                                         'module'    => 'mpc',
    703                                                         'mime_type' => 'audio/x-musepack',
    704                                                 ),
    705 
    706                                 // MP3  - audio       - MPEG-audio Layer 3 (very similar to AAC-ADTS)
    707                                 'mp3'  => array(
    708                                                         'pattern'   => '^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\x0B\x10-\x1B\x20-\x2B\x30-\x3B\x40-\x4B\x50-\x5B\x60-\x6B\x70-\x7B\x80-\x8B\x90-\x9B\xA0-\xAB\xB0-\xBB\xC0-\xCB\xD0-\xDB\xE0-\xEB\xF0-\xFB]',
    709                                                         'group'     => 'audio',
    710                                                         'module'    => 'mp3',
    711                                                         'mime_type' => 'audio/mpeg',
    712                                                 ),
    713 
    714                                 // OFR  - audio       - OptimFROG
    715                                 'ofr'  => array(
    716                                                         'pattern'   => '^(\*RIFF|OFR)',
    717                                                         'group'     => 'audio',
    718                                                         'module'    => 'optimfrog',
    719                                                         'mime_type' => 'application/octet-stream',
    720                                                 ),
    721 
    722                                 // RKAU - audio       - RKive AUdio compressor
    723                                 'rkau' => array(
    724                                                         'pattern'   => '^RKA',
    725                                                         'group'     => 'audio',
    726                                                         'module'    => 'rkau',
    727                                                         'mime_type' => 'application/octet-stream',
    728                                                 ),
    729 
    730                                 // SHN  - audio       - Shorten
    731                                 'shn'  => array(
    732                                                         'pattern'   => '^ajkg',
    733                                                         'group'     => 'audio',
    734                                                         'module'    => 'shorten',
    735                                                         'mime_type' => 'audio/xmms-shn',
    736                                                         'fail_id3'  => 'ERROR',
    737                                                         'fail_ape'  => 'ERROR',
    738                                                 ),
    739 
    740                                 // TTA  - audio       - TTA Lossless Audio Compressor (http://tta.corecodec.org)
    741                                 'tta'  => array(
    742                                                         'pattern'   => '^TTA',  // could also be '^TTA(\x01|\x02|\x03|2|1)'
    743                                                         'group'     => 'audio',
    744                                                         'module'    => 'tta',
    745                                                         'mime_type' => 'application/octet-stream',
    746                                                 ),
    747 
    748                                 // VOC  - audio       - Creative Voice (VOC)
    749                                 'voc'  => array(
    750                                                         'pattern'   => '^Creative Voice File',
    751                                                         'group'     => 'audio',
    752                                                         'module'    => 'voc',
    753                                                         'mime_type' => 'audio/voc',
    754                                                 ),
    755 
    756                                 // VQF  - audio       - transform-domain weighted interleave Vector Quantization Format (VQF)
    757                                 'vqf'  => array(
    758                                                         'pattern'   => '^TWIN',
    759                                                         'group'     => 'audio',
    760                                                         'module'    => 'vqf',
    761                                                         'mime_type' => 'application/octet-stream',
    762                                                 ),
    763 
    764                                 // WV  - audio        - WavPack (v4.0+)
    765                                 'wv'   => array(
    766                                                         'pattern'   => '^wvpk',
    767                                                         'group'     => 'audio',
    768                                                         'module'    => 'wavpack',
    769                                                         'mime_type' => 'application/octet-stream',
    770                                                 ),
    771 
    772 
    773                                 // Audio-Video formats
    774 
    775                                 // ASF  - audio/video - Advanced Streaming Format, Windows Media Video, Windows Media Audio
    776                                 'asf'  => array(
    777                                                         'pattern'   => '^\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C',
    778                                                         'group'     => 'audio-video',
    779                                                         'module'    => 'asf',
    780                                                         'mime_type' => 'video/x-ms-asf',
    781                                                         'iconv_req' => false,
    782                                                 ),
    783 
    784                                 // BINK - audio/video - Bink / Smacker
    785                                 'bink' => array(
    786                                                         'pattern'   => '^(BIK|SMK)',
    787                                                         'group'     => 'audio-video',
    788                                                         'module'    => 'bink',
    789                                                         'mime_type' => 'application/octet-stream',
    790                                                 ),
    791 
    792                                 // FLV  - audio/video - FLash Video
    793                                 'flv' => array(
    794                                                         'pattern'   => '^FLV\x01',
    795                                                         'group'     => 'audio-video',
    796                                                         'module'    => 'flv',
    797                                                         'mime_type' => 'video/x-flv',
    798                                                 ),
    799 
    800                                 // MKAV - audio/video - Mastroka
    801                                 'matroska' => array(
    802                                                         'pattern'   => '^\x1A\x45\xDF\xA3',
    803                                                         'group'     => 'audio-video',
    804                                                         'module'    => 'matroska',
    805                                                         'mime_type' => 'video/x-matroska', // may also be audio/x-matroska
    806                                                 ),
    807 
    808                                 // MPEG - audio/video - MPEG (Moving Pictures Experts Group)
    809                                 'mpeg' => array(
    810                                                         'pattern'   => '^\x00\x00\x01(\xBA|\xB3)',
    811                                                         'group'     => 'audio-video',
    812                                                         'module'    => 'mpeg',
    813                                                         'mime_type' => 'video/mpeg',
    814                                                 ),
    815 
    816                                 // NSV  - audio/video - Nullsoft Streaming Video (NSV)
    817                                 'nsv'  => array(
    818                                                         'pattern'   => '^NSV[sf]',
    819                                                         'group'     => 'audio-video',
    820                                                         'module'    => 'nsv',
    821                                                         'mime_type' => 'application/octet-stream',
    822                                                 ),
    823 
    824                                 // Ogg  - audio/video - Ogg (Ogg-Vorbis, Ogg-FLAC, Speex, Ogg-Theora(*), Ogg-Tarkin(*))
    825                                 'ogg'  => array(
    826                                                         'pattern'   => '^OggS',
    827                                                         'group'     => 'audio',
    828                                                         'module'    => 'ogg',
    829                                                         'mime_type' => 'application/ogg',
    830                                                         'fail_id3'  => 'WARNING',
    831                                                         'fail_ape'  => 'WARNING',
    832                                                 ),
    833 
    834                                 // QT   - audio/video - Quicktime
    835                                 'quicktime' => array(
    836                                                         'pattern'   => '^.{4}(cmov|free|ftyp|mdat|moov|pnot|skip|wide)',
    837                                                         'group'     => 'audio-video',
    838                                                         'module'    => 'quicktime',
    839                                                         'mime_type' => 'video/quicktime',
    840                                                 ),
    841 
    842                                 // RIFF - audio/video - Resource Interchange File Format (RIFF) / WAV / AVI / CD-audio / SDSS = renamed variant used by SmartSound QuickTracks (www.smartsound.com) / FORM = Audio Interchange File Format (AIFF)
    843                                 'riff' => array(
    844                                                         'pattern'   => '^(RIFF|SDSS|FORM)',
    845                                                         'group'     => 'audio-video',
    846                                                         'module'    => 'riff',
    847                                                         'mime_type' => 'audio/x-wave',
    848                                                         'fail_ape'  => 'WARNING',
    849                                                 ),
    850 
    851                                 // Real - audio/video - RealAudio, RealVideo
    852                                 'real' => array(
    853                                                         'pattern'   => '^(\\.RMF|\\.ra)',
    854                                                         'group'     => 'audio-video',
    855                                                         'module'    => 'real',
    856                                                         'mime_type' => 'audio/x-realaudio',
    857                                                 ),
    858 
    859                                 // SWF - audio/video - ShockWave Flash
    860                                 'swf' => array(
    861                                                         'pattern'   => '^(F|C)WS',
    862                                                         'group'     => 'audio-video',
    863                                                         'module'    => 'swf',
    864                                                         'mime_type' => 'application/x-shockwave-flash',
    865                                                 ),
    866 
    867                                 // TS - audio/video - MPEG-2 Transport Stream
    868                                 'ts' => array(
    869                                                         'pattern'   => '^(\x47.{187}){10,}', // packets are 188 bytes long and start with 0x47 "G".  Check for at least 10 packets matching this pattern
    870                                                         'group'     => 'audio-video',
    871                                                         'module'    => 'ts',
    872                                                         'mime_type' => 'video/MP2T',
    873                                                 ),
    874 
    875 
    876                                 // Still-Image formats
    877 
    878                                 // BMP  - still image - Bitmap (Windows, OS/2; uncompressed, RLE8, RLE4)
    879                                 'bmp'  => array(
    880                                                         'pattern'   => '^BM',
    881                                                         'group'     => 'graphic',
    882                                                         'module'    => 'bmp',
    883                                                         'mime_type' => 'image/bmp',
    884                                                         'fail_id3'  => 'ERROR',
    885                                                         'fail_ape'  => 'ERROR',
    886                                                 ),
    887 
    888                                 // GIF  - still image - Graphics Interchange Format
    889                                 'gif'  => array(
    890                                                         'pattern'   => '^GIF',
    891                                                         'group'     => 'graphic',
    892                                                         'module'    => 'gif',
    893                                                         'mime_type' => 'image/gif',
    894                                                         'fail_id3'  => 'ERROR',
    895                                                         'fail_ape'  => 'ERROR',
    896                                                 ),
    897 
    898                                 // JPEG - still image - Joint Photographic Experts Group (JPEG)
    899                                 'jpg'  => array(
    900                                                         'pattern'   => '^\xFF\xD8\xFF',
    901                                                         'group'     => 'graphic',
    902                                                         'module'    => 'jpg',
    903                                                         'mime_type' => 'image/jpeg',
    904                                                         'fail_id3'  => 'ERROR',
    905                                                         'fail_ape'  => 'ERROR',
    906                                                 ),
    907 
    908                                 // PCD  - still image - Kodak Photo CD
    909                                 'pcd'  => array(
    910                                                         'pattern'   => '^.{2048}PCD_IPI\x00',
    911                                                         'group'     => 'graphic',
    912                                                         'module'    => 'pcd',
    913                                                         'mime_type' => 'image/x-photo-cd',
    914                                                         'fail_id3'  => 'ERROR',
    915                                                         'fail_ape'  => 'ERROR',
    916                                                 ),
    917 
    918 
    919                                 // PNG  - still image - Portable Network Graphics (PNG)
    920                                 'png'  => array(
    921                                                         'pattern'   => '^\x89\x50\x4E\x47\x0D\x0A\x1A\x0A',
    922                                                         'group'     => 'graphic',
    923                                                         'module'    => 'png',
    924                                                         'mime_type' => 'image/png',
    925                                                         'fail_id3'  => 'ERROR',
    926                                                         'fail_ape'  => 'ERROR',
    927                                                 ),
    928 
    929 
    930                                 // SVG  - still image - Scalable Vector Graphics (SVG)
    931                                 'svg'  => array(
    932                                                         'pattern'   => '(<!DOCTYPE svg PUBLIC |xmlns="http:\/\/www\.w3\.org\/2000\/svg")',
    933                                                         'group'     => 'graphic',
    934                                                         'module'    => 'svg',
    935                                                         'mime_type' => 'image/svg+xml',
    936                                                         'fail_id3'  => 'ERROR',
    937                                                         'fail_ape'  => 'ERROR',
    938                                                 ),
    939 
    940 
    941                                 // TIFF - still image - Tagged Information File Format (TIFF)
    942                                 'tiff' => array(
    943                                                         'pattern'   => '^(II\x2A\x00|MM\x00\x2A)',
    944                                                         'group'     => 'graphic',
    945                                                         'module'    => 'tiff',
    946                                                         'mime_type' => 'image/tiff',
    947                                                         'fail_id3'  => 'ERROR',
    948                                                         'fail_ape'  => 'ERROR',
    949                                                 ),
    950 
    951 
    952                                 // EFAX - still image - eFax (TIFF derivative)
    953                                 'efax'  => array(
    954                                                         'pattern'   => '^\xDC\xFE',
    955                                                         'group'     => 'graphic',
    956                                                         'module'    => 'efax',
    957                                                         'mime_type' => 'image/efax',
    958                                                         'fail_id3'  => 'ERROR',
    959                                                         'fail_ape'  => 'ERROR',
    960                                                 ),
    961 
    962 
    963                                 // Data formats
    964 
    965                                 // ISO  - data        - International Standards Organization (ISO) CD-ROM Image
    966                                 'iso'  => array(
    967                                                         'pattern'   => '^.{32769}CD001',
    968                                                         'group'     => 'misc',
    969                                                         'module'    => 'iso',
    970                                                         'mime_type' => 'application/octet-stream',
    971                                                         'fail_id3'  => 'ERROR',
    972                                                         'fail_ape'  => 'ERROR',
    973                                                         'iconv_req' => false,
    974                                                 ),
    975 
    976                                 // RAR  - data        - RAR compressed data
    977                                 'rar'  => array(
    978                                                         'pattern'   => '^Rar\!',
    979                                                         'group'     => 'archive',
    980                                                         'module'    => 'rar',
    981                                                         'mime_type' => 'application/octet-stream',
    982                                                         'fail_id3'  => 'ERROR',
    983                                                         'fail_ape'  => 'ERROR',
    984                                                 ),
    985 
    986                                 // SZIP - audio/data  - SZIP compressed data
    987                                 'szip' => array(
    988                                                         'pattern'   => '^SZ\x0A\x04',
    989                                                         'group'     => 'archive',
    990                                                         'module'    => 'szip',
    991                                                         'mime_type' => 'application/octet-stream',
    992                                                         'fail_id3'  => 'ERROR',
    993                                                         'fail_ape'  => 'ERROR',
    994                                                 ),
    995 
    996                                 // TAR  - data        - TAR compressed data
    997                                 'tar'  => array(
    998                                                         'pattern'   => '^.{100}[0-9\x20]{7}\x00[0-9\x20]{7}\x00[0-9\x20]{7}\x00[0-9\x20\x00]{12}[0-9\x20\x00]{12}',
    999                                                         'group'     => 'archive',
    1000                                                         'module'    => 'tar',
    1001                                                         'mime_type' => 'application/x-tar',
    1002                                                         'fail_id3'  => 'ERROR',
    1003                                                         'fail_ape'  => 'ERROR',
    1004                                                 ),
    1005 
    1006                                 // GZIP  - data        - GZIP compressed data
    1007                                 'gz'  => array(
    1008                                                         'pattern'   => '^\x1F\x8B\x08',
    1009                                                         'group'     => 'archive',
    1010                                                         'module'    => 'gzip',
    1011                                                         'mime_type' => 'application/x-gzip',
    1012                                                         'fail_id3'  => 'ERROR',
    1013                                                         'fail_ape'  => 'ERROR',
    1014                                                 ),
    1015 
    1016                                 // ZIP  - data         - ZIP compressed data
    1017                                 'zip'  => array(
    1018                                                         'pattern'   => '^PK\x03\x04',
    1019                                                         'group'     => 'archive',
    1020                                                         'module'    => 'zip',
    1021                                                         'mime_type' => 'application/zip',
    1022                                                         'fail_id3'  => 'ERROR',
    1023                                                         'fail_ape'  => 'ERROR',
    1024                                                 ),
    1025 
    1026 
    1027                                 // Misc other formats
    1028 
    1029                                 // PAR2 - data        - Parity Volume Set Specification 2.0
    1030                                 'par2' => array (
    1031                                                         'pattern'   => '^PAR2\x00PKT',
    1032                                                         'group'     => 'misc',
    1033                                                         'module'    => 'par2',
    1034                                                         'mime_type' => 'application/octet-stream',
    1035                                                         'fail_id3'  => 'ERROR',
    1036                                                         'fail_ape'  => 'ERROR',
    1037                                                 ),
    1038 
    1039                                 // PDF  - data        - Portable Document Format
    1040                                 'pdf'  => array(
    1041                                                         'pattern'   => '^\x25PDF',
    1042                                                         'group'     => 'misc',
    1043                                                         'module'    => 'pdf',
    1044                                                         'mime_type' => 'application/pdf',
    1045                                                         'fail_id3'  => 'ERROR',
    1046                                                         'fail_ape'  => 'ERROR',
    1047                                                 ),
    1048 
    1049                                 // MSOFFICE  - data   - ZIP compressed data
    1050                                 'msoffice' => array(
    1051                                                         'pattern'   => '^\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1', // D0CF11E == DOCFILE == Microsoft Office Document
    1052                                                         'group'     => 'misc',
    1053                                                         'module'    => 'msoffice',
    1054                                                         'mime_type' => 'application/octet-stream',
    1055                                                         'fail_id3'  => 'ERROR',
    1056                                                         'fail_ape'  => 'ERROR',
    1057                                                 ),
    1058 
    1059                                  // CUE  - data       - CUEsheet (index to single-file disc images)
    1060                                  'cue' => array(
    1061                                                         'pattern'   => '', // empty pattern means cannot be automatically detected, will fall through all other formats and match based on filename and very basic file contents
    1062                                                         'group'     => 'misc',
    1063                                                         'module'    => 'cue',
    1064                                                         'mime_type' => 'application/octet-stream',
    1065                                                    ),
    1066 
    1067                         );
    1068                 }
    1069 
    1070                 return $format_info;
    1071         }
    1072 
    1073 
    1074 
    1075         public function GetFileFormat(&$filedata, $filename='') {
    1076                 // this function will determine the format of a file based on usually
    1077                 // the first 2-4 bytes of the file (8 bytes for PNG, 16 bytes for JPG,
    1078                 // and in the case of ISO CD image, 6 bytes offset 32kb from the start
    1079                 // of the file).
    1080 
    1081                 // Identify file format - loop through $format_info and detect with reg expr
    1082                 foreach ($this->GetFileFormatArray() as $format_name => $info) {
    1083                         // The /s switch on preg_match() forces preg_match() NOT to treat
    1084                         // newline (0x0A) characters as special chars but do a binary match
    1085                         if (!empty($info['pattern']) && preg_match('#'.$info['pattern'].'#s', $filedata)) {
    1086                                 $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php';
    1087                                 return $info;
    1088                         }
    1089                 }
    1090 
    1091 
    1092                 if (preg_match('#\.mp[123a]$#i', $filename)) {
    1093                         // Too many mp3 encoders on the market put gabage in front of mpeg files
    1094                         // use assume format on these if format detection failed
    1095                         $GetFileFormatArray = $this->GetFileFormatArray();
    1096                         $info = $GetFileFormatArray['mp3'];
    1097                         $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php';
    1098                         return $info;
    1099                 } elseif (preg_match('/\.cue$/i', $filename) && preg_match('#FILE "[^"]+" (BINARY|MOTOROLA|AIFF|WAVE|MP3)#', $filedata)) {
    1100                         // there's not really a useful consistent "magic" at the beginning of .cue files to identify them
    1101                         // so until I think of something better, just go by filename if all other format checks fail
    1102                         // and verify there's at least one instance of "TRACK xx AUDIO" in the file
    1103                         $GetFileFormatArray = $this->GetFileFormatArray();
    1104                         $info = $GetFileFormatArray['cue'];
    1105                         $info['include']   = 'module.'.$info['group'].'.'.$info['module'].'.php';
    1106                         return $info;
    1107                 }
    1108 
    1109                 return false;
    1110         }
    1111 
    1112 
    1113         // converts array to $encoding charset from $this->encoding
    1114         public function CharConvert(&$array, $encoding) {
    1115 
    1116                 // identical encoding - end here
    1117                 if ($encoding == $this->encoding) {
    1118                         return;
    1119                 }
    1120 
    1121                 // loop thru array
    1122                 foreach ($array as $key => $value) {
    1123 
    1124                         // go recursive
    1125                         if (is_array($value)) {
    1126                                 $this->CharConvert($array[$key], $encoding);
    1127                         }
    1128 
    1129                         // convert string
    1130                         elseif (is_string($value)) {
    1131                                 $array[$key] = trim(getid3_lib::iconv_fallback($encoding, $this->encoding, $value));
    1132                         }
    1133                 }
    1134         }
    1135 
    1136 
    1137         public function HandleAllTags() {
    1138 
    1139                 // key name => array (tag name, character encoding)
    1140                 static $tags;
    1141                 if (empty($tags)) {
    1142                         $tags = array(
    1143                                 'asf'       => array('asf'           , 'UTF-16LE'),
    1144                                 'midi'      => array('midi'          , 'ISO-8859-1'),
    1145                                 'nsv'       => array('nsv'           , 'ISO-8859-1'),
    1146                                 'ogg'       => array('vorbiscomment' , 'UTF-8'),
    1147                                 'png'       => array('png'           , 'UTF-8'),
    1148                                 'tiff'      => array('tiff'          , 'ISO-8859-1'),
    1149                                 'quicktime' => array('quicktime'     , 'UTF-8'),
    1150                                 'real'      => array('real'          , 'ISO-8859-1'),
    1151                                 'vqf'       => array('vqf'           , 'ISO-8859-1'),
    1152                                 'zip'       => array('zip'           , 'ISO-8859-1'),
    1153                                 'riff'      => array('riff'          , 'ISO-8859-1'),
    1154                                 'lyrics3'   => array('lyrics3'       , 'ISO-8859-1'),
    1155                                 'id3v1'     => array('id3v1'         , $this->encoding_id3v1),
    1156                                 'id3v2'     => array('id3v2'         , 'UTF-8'), // not according to the specs (every frame can have a different encoding), but getID3() force-converts all encodings to UTF-8
    1157                                 'ape'       => array('ape'           , 'UTF-8'),
    1158                                 'cue'       => array('cue'           , 'ISO-8859-1'),
    1159                                 'matroska'  => array('matroska'      , 'UTF-8'),
    1160                                 'flac'      => array('vorbiscomment' , 'UTF-8'),
    1161                                 'divxtag'   => array('divx'          , 'ISO-8859-1'),
    1162                         );
    1163                 }
    1164 
    1165                 // loop through comments array
    1166                 foreach ($tags as $comment_name => $tagname_encoding_array) {
    1167                         list($tag_name, $encoding) = $tagname_encoding_array;
    1168 
    1169                         // fill in default encoding type if not already present
    1170                         if (isset($this->info[$comment_name]) && !isset($this->info[$comment_name]['encoding'])) {
    1171                                 $this->info[$comment_name]['encoding'] = $encoding;
    1172                         }
    1173 
    1174                         // copy comments if key name set
    1175                         if (!empty($this->info[$comment_name]['comments'])) {
    1176                                 foreach ($this->info[$comment_name]['comments'] as $tag_key => $valuearray) {
    1177                                         foreach ($valuearray as $key => $value) {
    1178                                                 if (is_string($value)) {
    1179                                                         $value = trim($value, " \r\n\t"); // do not trim nulls from $value!! Unicode characters will get mangled if trailing nulls are removed!
    1180                                                 }
    1181                                                 if ($value) {
    1182                                                         $this->info['tags'][trim($tag_name)][trim($tag_key)][] = $value;
    1183                                                 }
    1184                                         }
    1185                                         if ($tag_key == 'picture') {
    1186                                                 unset($this->info[$comment_name]['comments'][$tag_key]);
    1187                                         }
    1188                                 }
    1189 
    1190                                 if (!isset($this->info['tags'][$tag_name])) {
    1191                                         // comments are set but contain nothing but empty strings, so skip
    1192                                         continue;
    1193                                 }
    1194 
    1195                                 if ($this->option_tags_html) {
    1196                                         foreach ($this->info['tags'][$tag_name] as $tag_key => $valuearray) {
    1197                                                 foreach ($valuearray as $key => $value) {
    1198                                                         if (is_string($value)) {
    1199                                                                 //$this->info['tags_html'][$tag_name][$tag_key][$key] = getid3_lib::MultiByteCharString2HTML($value, $encoding);
    1200                                                                 $this->info['tags_html'][$tag_name][$tag_key][$key] = str_replace('&#0;', '', trim(getid3_lib::MultiByteCharString2HTML($value, $encoding)));
    1201                                                         } else {
    1202                                                                 $this->info['tags_html'][$tag_name][$tag_key][$key] = $value;
    1203                                                         }
    1204                                                 }
    1205                                         }
    1206                                 }
    1207 
    1208                                 $this->CharConvert($this->info['tags'][$tag_name], $encoding);           // only copy gets converted!
    1209                         }
    1210 
    1211                 }
    1212 
    1213                 // pictures can take up a lot of space, and we don't need multiple copies of them
    1214                 // let there be a single copy in [comments][picture], and not elsewhere
    1215                 if (!empty($this->info['tags'])) {
    1216                         $unset_keys = array('tags', 'tags_html');
    1217                         foreach ($this->info['tags'] as $tagtype => $tagarray) {
    1218                                 foreach ($tagarray as $tagname => $tagdata) {
    1219                                         if ($tagname == 'picture') {
    1220                                                 foreach ($tagdata as $key => $tagarray) {
    1221                                                         $this->info['comments']['picture'][] = $tagarray;
    1222                                                         if (isset($tagarray['data']) && isset($tagarray['image_mime'])) {
    1223                                                                 if (isset($this->info['tags'][$tagtype][$tagname][$key])) {
    1224                                                                         unset($this->info['tags'][$tagtype][$tagname][$key]);
    1225                                                                 }
    1226                                                                 if (isset($this->info['tags_html'][$tagtype][$tagname][$key])) {
    1227                                                                         unset($this->info['tags_html'][$tagtype][$tagname][$key]);
    1228                                                                 }
    1229                                                         }
    1230                                                 }
    1231                                         }
    1232                                 }
    1233                                 foreach ($unset_keys as $unset_key) {
    1234                                         // remove possible empty keys from (e.g. [tags][id3v2][picture])
    1235                                         if (empty($this->info[$unset_key][$tagtype]['picture'])) {
    1236                                                 unset($this->info[$unset_key][$tagtype]['picture']);
    1237                                         }
    1238                                         if (empty($this->info[$unset_key][$tagtype])) {
    1239                                                 unset($this->info[$unset_key][$tagtype]);
    1240                                         }
    1241                                         if (empty($this->info[$unset_key])) {
    1242                                                 unset($this->info[$unset_key]);
    1243                                         }
    1244                                 }
    1245                                 // remove duplicate copy of picture data from (e.g. [id3v2][comments][picture])
    1246                                 if (isset($this->info[$tagtype]['comments']['picture'])) {
    1247                                         unset($this->info[$tagtype]['comments']['picture']);
    1248                                 }
    1249                                 if (empty($this->info[$tagtype]['comments'])) {
    1250                                         unset($this->info[$tagtype]['comments']);
    1251                                 }
    1252                                 if (empty($this->info[$tagtype])) {
    1253                                         unset($this->info[$tagtype]);
    1254                                 }
    1255                         }
    1256                 }
    1257                 return true;
    1258         }
    1259 
    1260 
    1261         public function getHashdata($algorithm) {
    1262                 switch ($algorithm) {
    1263                         case 'md5':
    1264                         case 'sha1':
    1265                                 break;
    1266 
    1267                         default:
    1268                                 return $this->error('bad algorithm "'.$algorithm.'" in getHashdata()');
    1269                                 break;
    1270                 }
    1271 
    1272                 if (!empty($this->info['fileformat']) && !empty($this->info['dataformat']) && ($this->info['fileformat'] == 'ogg') && ($this->info['audio']['dataformat'] == 'vorbis')) {
    1273 
    1274                         // We cannot get an identical md5_data value for Ogg files where the comments
    1275                         // span more than 1 Ogg page (compared to the same audio data with smaller
    1276                         // comments) using the normal getID3() method of MD5'ing the data between the
    1277                         // end of the comments and the end of the file (minus any trailing tags),
    1278                         // because the page sequence numbers of the pages that the audio data is on
    1279                         // do not match. Under normal circumstances, where comments are smaller than
    1280                         // the nominal 4-8kB page size, then this is not a problem, but if there are
    1281                         // very large comments, the only way around it is to strip off the comment
    1282                         // tags with vorbiscomment and MD5 that file.
    1283                         // This procedure must be applied to ALL Ogg files, not just the ones with
    1284                         // comments larger than 1 page, because the below method simply MD5's the
    1285                         // whole file with the comments stripped, not just the portion after the
    1286                         // comments block (which is the standard getID3() method.
    1287 
    1288                         // The above-mentioned problem of comments spanning multiple pages and changing
    1289                         // page sequence numbers likely happens for OggSpeex and OggFLAC as well, but
    1290                         // currently vorbiscomment only works on OggVorbis files.
    1291 
    1292                         if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
    1293 
    1294                                 $this->warning('Failed making system call to vorbiscomment.exe - '.$algorithm.'_data is incorrect - error returned: PHP running in Safe Mode (backtick operator not available)');
    1295                                 $this->info[$algorithm.'_data'] = false;
    1296 
    1297                         } else {
    1298 
    1299                                 // Prevent user from aborting script
    1300                                 $old_abort = ignore_user_abort(true);
    1301 
    1302                                 // Create empty file
    1303                                 $empty = tempnam(GETID3_TEMP_DIR, 'getID3');
    1304                                 touch($empty);
    1305 
    1306                                 // Use vorbiscomment to make temp file without comments
    1307                                 $temp = tempnam(GETID3_TEMP_DIR, 'getID3');
    1308                                 $file = $this->info['filenamepath'];
    1309 
    1310                                 if (GETID3_OS_ISWINDOWS) {
    1311 
    1312                                         if (file_exists(GETID3_HELPERAPPSDIR.'vorbiscomment.exe')) {
    1313 
    1314                                                 $commandline = '"'.GETID3_HELPERAPPSDIR.'vorbiscomment.exe" -w -c "'.$empty.'" "'.$file.'" "'.$temp.'"';
    1315                                                 $VorbisCommentError = `$commandline`;
    1316 
    1317                                         } else {
    1318 
    1319                                                 $VorbisCommentError = 'vorbiscomment.exe not found in '.GETID3_HELPERAPPSDIR;
    1320 
    1321                                         }
    1322 
    1323                                 } else {
    1324 
    1325                                         $commandline = 'vorbiscomment -w -c "'.$empty.'" "'.$file.'" "'.$temp.'" 2>&1';
    1326                                         $commandline = 'vorbiscomment -w -c '.escapeshellarg($empty).' '.escapeshellarg($file).' '.escapeshellarg($temp).' 2>&1';
    1327                                         $VorbisCommentError = `$commandline`;
    1328 
    1329                                 }
    1330 
    1331                                 if (!empty($VorbisCommentError)) {
    1332 
    1333                                         $this->info['warning'][]         = 'Failed making system call to vorbiscomment(.exe) - '.$algorithm.'_data will be incorrect. If vorbiscomment is unavailable, please download from http://www.vorbis.com/download.psp and put in the getID3() directory. Error returned: '.$VorbisCommentError;
    1334                                         $this->info[$algorithm.'_data']  = false;
    1335 
    1336                                 } else {
    1337 
    1338                                         // Get hash of newly created file
    1339                                         switch ($algorithm) {
    1340                                                 case 'md5':
    1341                                                         $this->info[$algorithm.'_data'] = md5_file($temp);
    1342                                                         break;
    1343 
    1344                                                 case 'sha1':
    1345                                                         $this->info[$algorithm.'_data'] = sha1_file($temp);
    1346                                                         break;
    1347                                         }
    1348                                 }
    1349 
    1350                                 // Clean up
    1351                                 unlink($empty);
    1352                                 unlink($temp);
    1353 
    1354                                 // Reset abort setting
    1355                                 ignore_user_abort($old_abort);
    1356 
    1357                         }
    1358 
    1359                 } else {
    1360 
    1361                         if (!empty($this->info['avdataoffset']) || (isset($this->info['avdataend']) && ($this->info['avdataend'] < $this->info['filesize']))) {
    1362 
    1363                                 // get hash from part of file
    1364                                 $this->info[$algorithm.'_data'] = getid3_lib::hash_data($this->info['filenamepath'], $this->info['avdataoffset'], $this->info['avdataend'], $algorithm);
    1365 
    1366                         } else {
    1367 
    1368                                 // get hash from whole file
    1369                                 switch ($algorithm) {
    1370                                         case 'md5':
    1371                                                 $this->info[$algorithm.'_data'] = md5_file($this->info['filenamepath']);
    1372                                                 break;
    1373 
    1374                                         case 'sha1':
    1375                                                 $this->info[$algorithm.'_data'] = sha1_file($this->info['filenamepath']);
    1376                                                 break;
    1377                                 }
    1378                         }
    1379 
    1380                 }
    1381                 return true;
    1382         }
    1383 
    1384 
    1385         public function ChannelsBitratePlaytimeCalculations() {
    1386 
    1387                 // set channelmode on audio
    1388                 if (!empty($this->info['audio']['channelmode']) || !isset($this->info['audio']['channels'])) {
    1389                         // ignore
    1390                 } elseif ($this->info['audio']['channels'] == 1) {
    1391                         $this->info['audio']['channelmode'] = 'mono';
    1392                 } elseif ($this->info['audio']['channels'] == 2) {
    1393                         $this->info['audio']['channelmode'] = 'stereo';
    1394                 }
    1395 
    1396                 // Calculate combined bitrate - audio + video
    1397                 $CombinedBitrate  = 0;
    1398                 $CombinedBitrate += (isset($this->info['audio']['bitrate']) ? $this->info['audio']['bitrate'] : 0);
    1399                 $CombinedBitrate += (isset($this->info['video']['bitrate']) ? $this->info['video']['bitrate'] : 0);
    1400                 if (($CombinedBitrate > 0) && empty($this->info['bitrate'])) {
    1401                         $this->info['bitrate'] = $CombinedBitrate;
    1402                 }
    1403                 //if ((isset($this->info['video']) && !isset($this->info['video']['bitrate'])) || (isset($this->info['audio']) && !isset($this->info['audio']['bitrate']))) {
    1404                 //      // for example, VBR MPEG video files cannot determine video bitrate:
    1405                 //      // should not set overall bitrate and playtime from audio bitrate only
    1406                 //      unset($this->info['bitrate']);
    1407                 //}
    1408 
    1409                 // video bitrate undetermined, but calculable
    1410                 if (isset($this->info['video']['dataformat']) && $this->info['video']['dataformat'] && (!isset($this->info['video']['bitrate']) || ($this->info['video']['bitrate'] == 0))) {
    1411                         // if video bitrate not set
    1412                         if (isset($this->info['audio']['bitrate']) && ($this->info['audio']['bitrate'] > 0) && ($this->info['audio']['bitrate'] == $this->info['bitrate'])) {
    1413                                 // AND if audio bitrate is set to same as overall bitrate
    1414                                 if (isset($this->info['playtime_seconds']) && ($this->info['playtime_seconds'] > 0)) {
    1415                                         // AND if playtime is set
    1416                                         if (isset($this->info['avdataend']) && isset($this->info['avdataoffset'])) {
    1417                                                 // AND if AV data offset start/end is known
    1418                                                 // THEN we can calculate the video bitrate
    1419                                                 $this->info['bitrate'] = round((($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['playtime_seconds']);
    1420                                                 $this->info['video']['bitrate'] = $this->info['bitrate'] - $this->info['audio']['bitrate'];
    1421                                         }
    1422                                 }
    1423                         }
    1424                 }
    1425 
    1426                 if ((!isset($this->info['playtime_seconds']) || ($this->info['playtime_seconds'] <= 0)) && !empty($this->info['bitrate'])) {
    1427                         $this->info['playtime_seconds'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['bitrate'];
    1428                 }
    1429 
    1430                 if (!isset($this->info['bitrate']) && !empty($this->info['playtime_seconds'])) {
    1431                         $this->info['bitrate'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['playtime_seconds'];
    1432                 }
    1433                 if (isset($this->info['bitrate']) && empty($this->info['audio']['bitrate']) && empty($this->info['video']['bitrate'])) {
    1434                         if (isset($this->info['audio']['dataformat']) && empty($this->info['video']['resolution_x'])) {
    1435                                 // audio only
    1436                                 $this->info['audio']['bitrate'] = $this->info['bitrate'];
    1437                         } elseif (isset($this->info['video']['resolution_x']) && empty($this->info['audio']['dataformat'])) {
    1438                                 // video only
    1439                                 $this->info['video']['bitrate'] = $this->info['bitrate'];
    1440                         }
    1441                 }
    1442 
    1443                 // Set playtime string
    1444                 if (!empty($this->info['playtime_seconds']) && empty($this->info['playtime_string'])) {
    1445                         $this->info['playtime_string'] = getid3_lib::PlaytimeString($this->info['playtime_seconds']);
    1446                 }
    1447         }
    1448 
    1449 
    1450         public function CalculateCompressionRatioVideo() {
    1451                 if (empty($this->info['video'])) {
    1452                         return false;
    1453                 }
    1454                 if (empty($this->info['video']['resolution_x']) || empty($this->info['video']['resolution_y'])) {
    1455                         return false;
    1456                 }
    1457                 if (empty($this->info['video']['bits_per_sample'])) {
    1458                         return false;
    1459                 }
    1460 
    1461                 switch ($this->info['video']['dataformat']) {
    1462                         case 'bmp':
    1463                         case 'gif':
    1464                         case 'jpeg':
    1465                         case 'jpg':
    1466                         case 'png':
    1467                         case 'tiff':
    1468                                 $FrameRate = 1;
    1469                                 $PlaytimeSeconds = 1;
    1470                                 $BitrateCompressed = $this->info['filesize'] * 8;
    1471                                 break;
    1472 
    1473                         default:
    1474                                 if (!empty($this->info['video']['frame_rate'])) {
    1475                                         $FrameRate = $this->info['video']['frame_rate'];
    1476                                 } else {
    1477                                         return false;
    1478                                 }
    1479                                 if (!empty($this->info['playtime_seconds'])) {
    1480                                         $PlaytimeSeconds = $this->info['playtime_seconds'];
    1481                                 } else {
    1482                                         return false;
    1483                                 }
    1484                                 if (!empty($this->info['video']['bitrate'])) {
    1485                                         $BitrateCompressed = $this->info['video']['bitrate'];
    1486                                 } else {
    1487                                         return false;
    1488                                 }
    1489                                 break;
    1490                 }
    1491                 $BitrateUncompressed = $this->info['video']['resolution_x'] * $this->info['video']['resolution_y'] * $this->info['video']['bits_per_sample'] * $FrameRate;
    1492 
    1493                 $this->info['video']['compression_ratio'] = $BitrateCompressed / $BitrateUncompressed;
    1494                 return true;
    1495         }
    1496 
    1497 
    1498         public function CalculateCompressionRatioAudio() {
    1499                 if (empty($this->info['audio']['bitrate']) || empty($this->info['audio']['channels']) || empty($this->info['audio']['sample_rate']) || !is_numeric($this->info['audio']['sample_rate'])) {
    1500                         return false;
    1501                 }
    1502                 $this->info['audio']['compression_ratio'] = $this->info['audio']['bitrate'] / ($this->info['audio']['channels'] * $this->info['audio']['sample_rate'] * (!empty($this->info['audio']['bits_per_sample']) ? $this->info['audio']['bits_per_sample'] : 16));
    1503 
    1504                 if (!empty($this->info['audio']['streams'])) {
    1505                         foreach ($this->info['audio']['streams'] as $streamnumber => $streamdata) {
    1506                                 if (!empty($streamdata['bitrate']) && !empty($streamdata['channels']) && !empty($streamdata['sample_rate'])) {
    1507                                         $this->info['audio']['streams'][$streamnumber]['compression_ratio'] = $streamdata['bitrate'] / ($streamdata['channels'] * $streamdata['sample_rate'] * (!empty($streamdata['bits_per_sample']) ? $streamdata['bits_per_sample'] : 16));
    1508                                 }
    1509                         }
    1510                 }
    1511                 return true;
    1512         }
    1513 
    1514 
    1515         public function CalculateReplayGain() {
    1516                 if (isset($this->info['replay_gain'])) {
    1517                         if (!isset($this->info['replay_gain']['reference_volume'])) {
    1518                                 $this->info['replay_gain']['reference_volume'] = (double) 89.0;
    1519                         }
    1520                         if (isset($this->info['replay_gain']['track']['adjustment'])) {
    1521                                 $this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment'];
    1522                         }
    1523                         if (isset($this->info['replay_gain']['album']['adjustment'])) {
    1524                                 $this->info['replay_gain']['album']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['album']['adjustment'];
    1525                         }
    1526 
    1527                         if (isset($this->info['replay_gain']['track']['peak'])) {
    1528                                 $this->info['replay_gain']['track']['max_noclip_gain'] = 0 - getid3_lib::RGADamplitude2dB($this->info['replay_gain']['track']['peak']);
    1529                         }
    1530                         if (isset($this->info['replay_gain']['album']['peak'])) {
    1531                                 $this->info['replay_gain']['album']['max_noclip_gain'] = 0 - getid3_lib::RGADamplitude2dB($this->info['replay_gain']['album']['peak']);
    1532                         }
    1533                 }
    1534                 return true;
    1535         }
    1536 
    1537         public function ProcessAudioStreams() {
    1538                 if (!empty($this->info['audio']['bitrate']) || !empty($this->info['audio']['channels']) || !empty($this->info['audio']['sample_rate'])) {
    1539                         if (!isset($this->info['audio']['streams'])) {
    1540                                 foreach ($this->info['audio'] as $key => $value) {
    1541                                         if ($key != 'streams') {
    1542                                                 $this->info['audio']['streams'][0][$key] = $value;
    1543                                         }
    1544                                 }
    1545                         }
    1546                 }
    1547                 return true;
    1548         }
    1549 
    1550         public function getid3_tempnam() {
    1551                 return tempnam($this->tempdir, 'gI3');
    1552         }
    1553 
    1554         public function include_module($name) {
    1555                 //if (!file_exists($this->include_path.'module.'.$name.'.php')) {
    1556                 if (!file_exists(GETID3_INCLUDEPATH.'module.'.$name.'.php')) {
    1557                         throw new getid3_exception('Required module.'.$name.'.php is missing.');
    1558                 }
    1559                 include_once(GETID3_INCLUDEPATH.'module.'.$name.'.php');
    1560                 return true;
    1561         }
    1562 
    1563 }
    1564 
    1565 
    1566 abstract class getid3_handler
    1567 {
    1568         protected $getid3;                       // pointer
    1569 
    1570         protected $data_string_flag     = false; // analyzing filepointer or string
    1571         protected $data_string          = '';    // string to analyze
    1572         protected $data_string_position = 0;     // seek position in string
    1573         protected $data_string_length   = 0;     // string length
    1574 
    1575         private $dependency_to = null;
    1576 
    1577 
    1578         public function __construct(getID3 $getid3, $call_module=null) {
    1579                 $this->getid3 = $getid3;
    1580 
    1581                 if ($call_module) {
    1582                         $this->dependency_to = str_replace('getid3_', '', $call_module);
    1583                 }
    1584         }
    1585 
    1586 
    1587         // Analyze from file pointer
    1588         abstract public function Analyze();
    1589 
    1590 
    1591         // Analyze from string instead
    1592         public function AnalyzeString($string) {
    1593                 // Enter string mode
    1594             $this->setStringMode($string);
    1595 
    1596                 // Save info
    1597                 $saved_avdataoffset = $this->getid3->info['avdataoffset'];
    1598                 $saved_avdataend    = $this->getid3->info['avdataend'];
    1599                 $saved_filesize     = (isset($this->getid3->info['filesize']) ? $this->getid3->info['filesize'] : null); // may be not set if called as dependency without openfile() call
    1600 
    1601                 // Reset some info
    1602                 $this->getid3->info['avdataoffset'] = 0;
    1603                 $this->getid3->info['avdataend']    = $this->getid3->info['filesize'] = $this->data_string_length;
    1604 
    1605                 // Analyze
    1606                 $this->Analyze();
    1607 
    1608                 // Restore some info
    1609                 $this->getid3->info['avdataoffset'] = $saved_avdataoffset;
    1610                 $this->getid3->info['avdataend']    = $saved_avdataend;
    1611                 $this->getid3->info['filesize']     = $saved_filesize;
    1612 
    1613                 // Exit string mode
    1614                 $this->data_string_flag = false;
    1615         }
    1616 
    1617         public function setStringMode($string) {
    1618                 $this->data_string_flag   = true;
    1619                 $this->data_string        = $string;
    1620                 $this->data_string_length = strlen($string);
    1621         }
    1622 
    1623         protected function ftell() {
    1624                 if ($this->data_string_flag) {
    1625                         return $this->data_string_position;
    1626                 }
    1627                 return ftell($this->getid3->fp);
    1628         }
    1629 
    1630         protected function fread($bytes) {
    1631                 if ($this->data_string_flag) {
    1632                         $this->data_string_position += $bytes;
    1633                         return substr($this->data_string, $this->data_string_position - $bytes, $bytes);
    1634                 }
    1635             $pos = $this->ftell() + $bytes;
    1636             if (!getid3_lib::intValueSupported($pos)) {
    1637                         throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().') because beyond PHP filesystem limit', 10);
    1638             }
    1639                 return fread($this->getid3->fp, $bytes);
    1640         }
    1641 
    1642         protected function fseek($bytes, $whence=SEEK_SET) {
    1643                 if ($this->data_string_flag) {
    1644                         switch ($whence) {
    1645                                 case SEEK_SET:
    1646                                         $this->data_string_position = $bytes;
    1647                                         break;
    1648 
    1649                                 case SEEK_CUR:
    1650                                         $this->data_string_position += $bytes;
    1651                                         break;
    1652 
    1653                                 case SEEK_END:
    1654                                         $this->data_string_position = $this->data_string_length + $bytes;
    1655                                         break;
    1656                         }
    1657                         return 0;
    1658             } else {
    1659                 $pos = $bytes;
    1660                 if ($whence == SEEK_CUR) {
    1661                                 $pos = $this->ftell() + $bytes;
    1662                 } elseif ($whence == SEEK_END) {
    1663                                 $pos = $this->info['filesize'] + $bytes;
    1664                 }
    1665                 if (!getid3_lib::intValueSupported($pos)) {
    1666                                 throw new getid3_exception('cannot fseek('.$pos.') because beyond PHP filesystem limit', 10);
    1667                         }
    1668                 }
    1669                 return fseek($this->getid3->fp, $bytes, $whence);
    1670         }
    1671 
    1672         protected function feof() {
    1673                 if ($this->data_string_flag) {
    1674                         return $this->data_string_position >= $this->data_string_length;
    1675                 }
    1676                 return feof($this->getid3->fp);
    1677         }
    1678 
    1679         final protected function isDependencyFor($module) {
    1680                 return $this->dependency_to == $module;
    1681         }
    1682 
    1683         protected function error($text)
    1684         {
    1685                 $this->getid3->info['error'][] = $text;
    1686 
    1687                 return false;
    1688         }
    1689 
    1690         protected function warning($text)
    1691         {
    1692                 return $this->getid3->warning($text);
    1693         }
    1694 
    1695         protected function notice($text)
    1696         {
    1697                 // does nothing for now
    1698         }
    1699 
    1700         public function saveAttachment($name, $offset, $length, $image_mime=null) {
    1701                 try {
    1702 
    1703                         // do not extract at all
    1704                         if ($this->getid3->option_save_attachments === getID3::ATTACHMENTS_NONE) {
    1705 
    1706                                 $attachment = null; // do not set any
    1707 
    1708                         // extract to return array
    1709                         } elseif ($this->getid3->option_save_attachments === getID3::ATTACHMENTS_INLINE) {
    1710 
    1711                                 $this->fseek($offset);
    1712                                 $attachment = $this->fread($length); // get whole data in one pass, till it is anyway stored in memory
    1713                                 if ($attachment === false || strlen($attachment) != $length) {
    1714                                         throw new Exception('failed to read attachment data');
    1715                                 }
    1716 
    1717                         // assume directory path is given
    1718                         } else {
    1719 
    1720                                 // set up destination path
    1721                                 $dir = rtrim(str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->getid3->option_save_attachments), DIRECTORY_SEPARATOR);
    1722                                 if (!is_dir($dir) || !is_writable($dir)) { // check supplied directory
    1723                                         throw new Exception('supplied path ('.$dir.') does not exist, or is not writable');
    1724                                 }
    1725                                 $dest = $dir.DIRECTORY_SEPARATOR.$name.($image_mime ? '.'.getid3_lib::ImageExtFromMime($image_mime) : '');
    1726 
    1727                                 // create dest file
    1728                                 if (($fp_dest = fopen($dest, 'wb')) == false) {
    1729                                         throw new Exception('failed to create file '.$dest);
    1730                                 }
    1731 
    1732                                 // copy data
    1733                                 $this->fseek($offset);
    1734                                 $buffersize = ($this->data_string_flag ? $length : $this->getid3->fread_buffer_size());
    1735                                 $bytesleft = $length;
    1736                                 while ($bytesleft > 0) {
    1737                                         if (($buffer = $this->fread(min($buffersize, $bytesleft))) === false || ($byteswritten = fwrite($fp_dest, $buffer)) === false || ($byteswritten === 0)) {
    1738                                                 throw new Exception($buffer === false ? 'not enough data to read' : 'failed to write to destination file, may be not enough disk space');
    1739                                         }
    1740                                         $bytesleft -= $byteswritten;
    1741                                 }
    1742 
    1743                                 fclose($fp_dest);
    1744                                 $attachment = $dest;
    1745 
    1746                         }
    1747 
    1748                 } catch (Exception $e) {
    1749 
    1750                         // close and remove dest file if created
    1751                         if (isset($fp_dest) && is_resource($fp_dest)) {
    1752                                 fclose($fp_dest);
    1753                                 unlink($dest);
    1754                         }
    1755 
    1756                         // do not set any is case of error
    1757                         $attachment = null;
    1758                         $this->warning('Failed to extract attachment '.$name.': '.$e->getMessage());
    1759 
    1760                 }
    1761 
    1762                 // seek to the end of attachment
    1763                 $this->fseek($offset + $length);
    1764 
    1765                 return $attachment;
    1766         }
    1767 }
    1768 
    1769 class getid3_exception extends Exception {
    1770         public $message;
    1771 }
    1772  No newline at end of file
  • wp-includes/ID3/getid3.lib.php

    diff --git a/wp-includes/ID3/getid3.lib.php b/wp-includes/ID3/getid3.lib.php
    index f0b9c94..f8df233 100644
    a b class getid3_lib 
    11381138                static $tempdir = '';
    11391139                if (empty($tempdir)) {
    11401140                        // yes this is ugly, feel free to suggest a better way
    1141                         require_once(dirname(__FILE__).'/class-getid3.php');
     1141                        require_once(dirname(__FILE__).'/getid3.php');
    11421142                        $getid3_temp = new getID3();
    11431143                        $tempdir = $getid3_temp->tempdir;
    11441144                        unset($getid3_temp);
  • wp-includes/ID3/license.txt

    diff --git a/wp-includes/ID3/license.txt b/wp-includes/ID3/license.txt
    index 9fec808..85f4356 100644
    a b  
    1             GNU GENERAL PUBLIC LICENSE
    2                Version 2, June 1991
     1/////////////////////////////////////////////////////////////////
     2/// getID3() by James Heinrich <info@getid3.org>               //
     3//  available at http://getid3.sourceforge.net                 //
     4//            or http://www.getid3.org                         //
     5/////////////////////////////////////////////////////////////////
    36
    4  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
    5               59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6  Everyone is permitted to copy and distribute verbatim copies
    7  of this license document, but changing it is not allowed.
     7*****************************************************************
     8*****************************************************************
    89
    9                 Preamble
     10   getID3() is released under multiple licenses. You may choose
     11   from the following licenses, and use getID3 according to the
     12   terms of the license most suitable to your project.
    1013
    11   The licenses for most software are designed to take away your
    12 freedom to share and change it.  By contrast, the GNU General Public
    13 License is intended to guarantee your freedom to share and change free
    14 software--to make sure the software is free for all its users.  This
    15 General Public License applies to most of the Free Software
    16 Foundation's software and to any other program whose authors commit to
    17 using it.  (Some other Free Software Foundation software is covered by
    18 the GNU Library General Public License instead.)  You can apply it to
    19 your programs, too.
     14GNU GPL: https://gnu.org/licenses/gpl.html                   (v3)
     15         https://gnu.org/licenses/old-licenses/gpl-2.0.html  (v2)
     16         https://gnu.org/licenses/old-licenses/gpl-1.0.html  (v1)
    2017
    21   When we speak of free software, we are referring to freedom, not
    22 price.  Our General Public Licenses are designed to make sure that you
    23 have the freedom to distribute copies of free software (and charge for
    24 this service if you wish), that you receive source code or can get it
    25 if you want it, that you can change the software or use pieces of it
    26 in new free programs; and that you know you can do these things.
     18GNU LGPL: https://gnu.org/licenses/lgpl.html                 (v3)
    2719
    28   To protect your rights, we need to make restrictions that forbid
    29 anyone to deny you these rights or to ask you to surrender the rights.
    30 These restrictions translate to certain responsibilities for you if you
    31 distribute copies of the software, or if you modify it.
     20Mozilla MPL: http://www.mozilla.org/MPL/2.0/                 (v2)
    3221
    33   For example, if you distribute copies of such a program, whether
    34 gratis or for a fee, you must give the recipients all the rights that
    35 you have.  You must make sure that they, too, receive or can get the
    36 source code.  And you must show them these terms so they know their
    37 rights.
     22getID3 Commercial License: http://getid3.org/#gCL (payment required)
    3823
    39   We protect your rights with two steps: (1) copyright the software, and
    40 (2) offer you this license which gives you legal permission to copy,
    41 distribute and/or modify the software.
     24*****************************************************************
     25*****************************************************************
    4226
    43   Also, for each author's protection and ours, we want to make certain
    44 that everyone understands that there is no warranty for this free
    45 software.  If the software is modified by someone else and passed on, we
    46 want its recipients to know that what they have is not the original, so
    47 that any problems introduced by others will not reflect on the original
    48 authors' reputations.
    49 
    50   Finally, any free program is threatened constantly by software
    51 patents.  We wish to avoid the danger that redistributors of a free
    52 program will individually obtain patent licenses, in effect making the
    53 program proprietary.  To prevent this, we have made it clear that any
    54 patent must be licensed for everyone's free use or not licensed at all.
    55 
    56   The precise terms and conditions for copying, distribution and
    57 modification follow.
    58 
    5927
    60             GNU GENERAL PUBLIC LICENSE
    61    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
    62 
    63   0. This License applies to any program or other work which contains
    64 a notice placed by the copyright holder saying it may be distributed
    65 under the terms of this General Public License.  The "Program", below,
    66 refers to any such program or work, and a "work based on the Program"
    67 means either the Program or any derivative work under copyright law:
    68 that is to say, a work containing the Program or a portion of it,
    69 either verbatim or with modifications and/or translated into another
    70 language.  (Hereinafter, translation is included without limitation in
    71 the term "modification".)  Each licensee is addressed as "you".
    72 
    73 Activities other than copying, distribution and modification are not
    74 covered by this License; they are outside its scope.  The act of
    75 running the Program is not restricted, and the output from the Program
    76 is covered only if its contents constitute a work based on the
    77 Program (independent of having been made by running the Program).
    78 Whether that is true depends on what the Program does.
    79 
    80   1. You may copy and distribute verbatim copies of the Program's
    81 source code as you receive it, in any medium, provided that you
    82 conspicuously and appropriately publish on each copy an appropriate
    83 copyright notice and disclaimer of warranty; keep intact all the
    84 notices that refer to this License and to the absence of any warranty;
    85 and give any other recipients of the Program a copy of this License
    86 along with the Program.
    87 
    88 You may charge a fee for the physical act of transferring a copy, and
    89 you may at your option offer warranty protection in exchange for a fee.
    90 
    91   2. You may modify your copy or copies of the Program or any portion
    92 of it, thus forming a work based on the Program, and copy and
    93 distribute such modifications or work under the terms of Section 1
    94 above, provided that you also meet all of these conditions:
    95 
    96     a) You must cause the modified files to carry prominent notices
    97     stating that you changed the files and the date of any change.
    98 
    99     b) You must cause any work that you distribute or publish, that in
    100     whole or in part contains or is derived from the Program or any
    101     part thereof, to be licensed as a whole at no charge to all third
    102     parties under the terms of this License.
    103 
    104     c) If the modified program normally reads commands interactively
    105     when run, you must cause it, when started running for such
    106     interactive use in the most ordinary way, to print or display an
    107     announcement including an appropriate copyright notice and a
    108     notice that there is no warranty (or else, saying that you provide
    109     a warranty) and that users may redistribute the program under
    110     these conditions, and telling the user how to view a copy of this
    111     License.  (Exception: if the Program itself is interactive but
    112     does not normally print such an announcement, your work based on
    113     the Program is not required to print an announcement.)
    114 
    11528
    116 These requirements apply to the modified work as a whole.  If
    117 identifiable sections of that work are not derived from the Program,
    118 and can be reasonably considered independent and separate works in
    119 themselves, then this License, and its terms, do not apply to those
    120 sections when you distribute them as separate works.  But when you
    121 distribute the same sections as part of a whole which is a work based
    122 on the Program, the distribution of the whole must be on the terms of
    123 this License, whose permissions for other licensees extend to the
    124 entire whole, and thus to each and every part regardless of who wrote it.
    125 
    126 Thus, it is not the intent of this section to claim rights or contest
    127 your rights to work written entirely by you; rather, the intent is to
    128 exercise the right to control the distribution of derivative or
    129 collective works based on the Program.
    130 
    131 In addition, mere aggregation of another work not based on the Program
    132 with the Program (or with a work based on the Program) on a volume of
    133 a storage or distribution medium does not bring the other work under
    134 the scope of this License.
    135 
    136   3. You may copy and distribute the Program (or a work based on it,
    137 under Section 2) in object code or executable form under the terms of
    138 Sections 1 and 2 above provided that you also do one of the following:
    139 
    140     a) Accompany it with the complete corresponding machine-readable
    141     source code, which must be distributed under the terms of Sections
    142     1 and 2 above on a medium customarily used for software interchange; or,
    143 
    144     b) Accompany it with a written offer, valid for at least three
    145     years, to give any third party, for a charge no more than your
    146     cost of physically performing source distribution, a complete
    147     machine-readable copy of the corresponding source code, to be
    148     distributed under the terms of Sections 1 and 2 above on a medium
    149     customarily used for software interchange; or,
    150 
    151     c) Accompany it with the information you received as to the offer
    152     to distribute corresponding source code.  (This alternative is
    153     allowed only for noncommercial distribution and only if you
    154     received the program in object code or executable form with such
    155     an offer, in accord with Subsection b above.)
    156 
    157 The source code for a work means the preferred form of the work for
    158 making modifications to it.  For an executable work, complete source
    159 code means all the source code for all modules it contains, plus any
    160 associated interface definition files, plus the scripts used to
    161 control compilation and installation of the executable.  However, as a
    162 special exception, the source code distributed need not include
    163 anything that is normally distributed (in either source or binary
    164 form) with the major components (compiler, kernel, and so on) of the
    165 operating system on which the executable runs, unless that component
    166 itself accompanies the executable.
    167 
    168 If distribution of executable or object code is made by offering
    169 access to copy from a designated place, then offering equivalent
    170 access to copy the source code from the same place counts as
    171 distribution of the source code, even though third parties are not
    172 compelled to copy the source along with the object code.
    173 
    17429
    175   4. You may not copy, modify, sublicense, or distribute the Program
    176 except as expressly provided under this License.  Any attempt
    177 otherwise to copy, modify, sublicense or distribute the Program is
    178 void, and will automatically terminate your rights under this License.
    179 However, parties who have received copies, or rights, from you under
    180 this License will not have their licenses terminated so long as such
    181 parties remain in full compliance.
    182 
    183   5. You are not required to accept this License, since you have not
    184 signed it.  However, nothing else grants you permission to modify or
    185 distribute the Program or its derivative works.  These actions are
    186 prohibited by law if you do not accept this License.  Therefore, by
    187 modifying or distributing the Program (or any work based on the
    188 Program), you indicate your acceptance of this License to do so, and
    189 all its terms and conditions for copying, distributing or modifying
    190 the Program or works based on it.
    191 
    192   6. Each time you redistribute the Program (or any work based on the
    193 Program), the recipient automatically receives a license from the
    194 original licensor to copy, distribute or modify the Program subject to
    195 these terms and conditions.  You may not impose any further
    196 restrictions on the recipients' exercise of the rights granted herein.
    197 You are not responsible for enforcing compliance by third parties to
    198 this License.
    199 
    200   7. If, as a consequence of a court judgment or allegation of patent
    201 infringement or for any other reason (not limited to patent issues),
    202 conditions are imposed on you (whether by court order, agreement or
    203 otherwise) that contradict the conditions of this License, they do not
    204 excuse you from the conditions of this License.  If you cannot
    205 distribute so as to satisfy simultaneously your obligations under this
    206 License and any other pertinent obligations, then as a consequence you
    207 may not distribute the Program at all.  For example, if a patent
    208 license would not permit royalty-free redistribution of the Program by
    209 all those who receive copies directly or indirectly through you, then
    210 the only way you could satisfy both it and this License would be to
    211 refrain entirely from distribution of the Program.
    212 
    213 If any portion of this section is held invalid or unenforceable under
    214 any particular circumstance, the balance of the section is intended to
    215 apply and the section as a whole is intended to apply in other
    216 circumstances.
    217 
    218 It is not the purpose of this section to induce you to infringe any
    219 patents or other property right claims or to contest validity of any
    220 such claims; this section has the sole purpose of protecting the
    221 integrity of the free software distribution system, which is
    222 implemented by public license practices.  Many people have made
    223 generous contributions to the wide range of software distributed
    224 through that system in reliance on consistent application of that
    225 system; it is up to the author/donor to decide if he or she is willing
    226 to distribute software through any other system and a licensee cannot
    227 impose that choice.
    228 
    229 This section is intended to make thoroughly clear what is believed to
    230 be a consequence of the rest of this License.
    231 
    23230
    233   8. If the distribution and/or use of the Program is restricted in
    234 certain countries either by patents or by copyrighted interfaces, the
    235 original copyright holder who places the Program under this License
    236 may add an explicit geographical distribution limitation excluding
    237 those countries, so that distribution is permitted only in or among
    238 countries not thus excluded.  In such case, this License incorporates
    239 the limitation as if written in the body of this License.
    240 
    241   9. The Free Software Foundation may publish revised and/or new versions
    242 of the General Public License from time to time.  Such new versions will
    243 be similar in spirit to the present version, but may differ in detail to
    244 address new problems or concerns.
    245 
    246 Each version is given a distinguishing version number.  If the Program
    247 specifies a version number of this License which applies to it and "any
    248 later version", you have the option of following the terms and conditions
    249 either of that version or of any later version published by the Free
    250 Software Foundation.  If the Program does not specify a version number of
    251 this License, you may choose any version ever published by the Free Software
    252 Foundation.
    253 
    254   10. If you wish to incorporate parts of the Program into other free
    255 programs whose distribution conditions are different, write to the author
    256 to ask for permission.  For software which is copyrighted by the Free
    257 Software Foundation, write to the Free Software Foundation; we sometimes
    258 make exceptions for this.  Our decision will be guided by the two goals
    259 of preserving the free status of all derivatives of our free software and
    260 of promoting the sharing and reuse of software generally.
    261 
    262                 NO WARRANTY
    263 
    264   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
    265 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
    266 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
    267 PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
    268 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    269 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
    270 TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
    271 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
    272 REPAIR OR CORRECTION.
    273 
    274   12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
    275 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
    276 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
    277 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
    278 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
    279 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
    280 YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
    281 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
    282 POSSIBILITY OF SUCH DAMAGES.
    283 
    284              END OF TERMS AND CONDITIONS
    285 
    28631
    287         How to Apply These Terms to Your New Programs
    288 
    289   If you develop a new program, and you want it to be of the greatest
    290 possible use to the public, the best way to achieve this is to make it
    291 free software which everyone can redistribute and change under these terms.
    292 
    293   To do so, attach the following notices to the program.  It is safest
    294 to attach them to the start of each source file to most effectively
    295 convey the exclusion of warranty; and each file should have at least
    296 the "copyright" line and a pointer to where the full notice is found.
    297 
    298     <one line to give the program's name and a brief idea of what it does.>
    299     Copyright (C) <year>  <name of author>
    300 
    301     This program is free software; you can redistribute it and/or modify
    302     it under the terms of the GNU General Public License as published by
    303     the Free Software Foundation; either version 2 of the License, or
    304     (at your option) any later version.
    305 
    306     This program is distributed in the hope that it will be useful,
    307     but WITHOUT ANY WARRANTY; without even the implied warranty of
    308     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    309     GNU General Public License for more details.
    310 
    311     You should have received a copy of the GNU General Public License
    312     along with this program; if not, write to the Free Software
    313     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    314 
    315 
    316 Also add information on how to contact you by electronic and paper mail.
    317 
    318 If the program is interactive, make it output a short notice like this
    319 when it starts in an interactive mode:
    320 
    321     Gnomovision version 69, Copyright (C) year name of author
    322     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    323     This is free software, and you are welcome to redistribute it
    324     under certain conditions; type `show c' for details.
    325 
    326 The hypothetical commands `show w' and `show c' should show the appropriate
    327 parts of the General Public License.  Of course, the commands you use may
    328 be called something other than `show w' and `show c'; they could even be
    329 mouse-clicks or menu items--whatever suits your program.
    330 
    331 You should also get your employer (if you work as a programmer) or your
    332 school, if any, to sign a "copyright disclaimer" for the program, if
    333 necessary.  Here is a sample; alter the names:
    334 
    335   Yoyodyne, Inc., hereby disclaims all copyright interest in the program
    336   `Gnomovision' (which makes passes at compilers) written by James Hacker.
    337 
    338   <signature of Ty Coon>, 1 April 1989
    339   Ty Coon, President of Vice
    340 
  • wp-includes/ID3/module.audio-video.matroska.php

    -This General Public License does not permit incorporating your program into
    -proprietary programs.  If your program is a subroutine library, you may
    -consider it more useful to permit linking proprietary applications with the
    -library.  If this is what you want to do, use the GNU Library General
    -Public License instead of this License.
    +Copies of each of the above licenses are included in the 'licenses'
    +directory of the getID3 distribution.
    diff --git a/wp-includes/ID3/module.audio-video.matroska.php b/wp-includes/ID3/module.audio-video.matroska.php
    index 3c1921f..8fe89a5 100644
    a b class getid3_matroska extends getid3_handler 
    216216{
    217217        // public options
    218218        public static $hide_clusters    = true;  // if true, do not return information about CLUSTER chunks, since there's a lot of them and they're not usually useful [default: TRUE]
    219     public static $parse_whole_file = false; // true to parse the whole file, not only header [default: FALSE]
     219        public static $parse_whole_file = false; // true to parse the whole file, not only header [default: FALSE]
    220220
    221     // private parser settings/placeholders
    222     private $EBMLbuffer        = '';
    223     private $EBMLbuffer_offset = 0;
    224     private $EBMLbuffer_length = 0;
    225     private $current_offset    = 0;
    226     private $unuseful_elements = array(EBML_ID_CRC32, EBML_ID_VOID);
     221        // private parser settings/placeholders
     222        private $EBMLbuffer        = '';
     223        private $EBMLbuffer_offset = 0;
     224        private $EBMLbuffer_length = 0;
     225        private $current_offset    = 0;
     226        private $unuseful_elements = array(EBML_ID_CRC32, EBML_ID_VOID);
    227227
    228228        public function Analyze()
    229229        {
    class getid3_matroska extends getid3_handler 
    495495                        }
    496496                }
    497497
    498         // determine mime type
     498                // determine mime type
    499499                if (!empty($info['video']['streams'])) {
    500500                        $info['mime_type'] = ($info['matroska']['doctype'] == 'webm' ? 'video/webm' : 'video/x-matroska');
    501501                } elseif (!empty($info['audio']['streams'])) {
    class getid3_matroska extends getid3_handler 
    507507                return true;
    508508        }
    509509
    510     private function parseEBML(&$info) {
     510        private function parseEBML(&$info) {
    511511                // http://www.matroska.org/technical/specs/index.html#EBMLBasics
    512512                $this->current_offset = $info['avdataoffset'];
    513513
    class getid3_matroska extends getid3_handler 
    536536                                                                $info['matroska']['doctype'] = $element_data['data'];
    537537                                                                break;
    538538
    539                                                         case EBML_ID_CRC32: // not useful, ignore
    540                                                                 $this->current_offset = $element_data['end'];
    541                                                                 unset($element_data);
    542                                                                 break;
    543 
    544539                                                        default:
    545540                                                                $this->unhandledElement('header', __LINE__, $element_data);
    546541                                                }
    547                                                 if (!empty($element_data)) {
    548                                                         unset($element_data['offset'], $element_data['end']);
    549                                                         $info['matroska']['header']['elements'][] = $element_data;
    550                                                 }
     542                                               
     543                                                unset($element_data['offset'], $element_data['end']);
     544                                                $info['matroska']['header']['elements'][] = $element_data;
    551545                                        }
    552546                                        break;
    553547
    class getid3_matroska extends getid3_handler 
    874868                                                                                                switch ($sub_subelement['id']) {
    875869
    876870                                                                                                        case EBML_ID_CUETRACKPOSITIONS:
    877                                                         $cuetrackpositions_entry = array();
     871                                                                                                                $cuetrackpositions_entry = array();
    878872
    879873                                                                                                                while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], true)) {
    880874                                                                                                                        switch ($sub_sub_subelement['id']) {
    class getid3_matroska extends getid3_handler 
    912906                                                                break;
    913907
    914908                                                        case EBML_ID_TAGS: // Element containing elements specific to Tracks/Chapters.
    915                                 $tags_entry = array();
     909                                                                $tags_entry = array();
    916910
    917911                                                                while ($this->getEBMLelement($subelement, $element_data['end'], false)) {
    918912                                                                        switch ($subelement['id']) {
    class getid3_matroska extends getid3_handler 
    12091203                                        $this->unhandledElement('root', __LINE__, $top_element);
    12101204                        }
    12111205                }
    1212     }
     1206        }
    12131207
    12141208        private function EnsureBufferHasEnoughData($min_data=1024) {
    12151209                if (($this->current_offset - $this->EBMLbuffer_offset) >= ($this->EBMLbuffer_length - $min_data)) {
    class getid3_matroska extends getid3_handler 
    13911385                }
    13921386                $block_data['flags']['lacing_type'] = self::BlockLacingType($block_data['flags']['lacing']);
    13931387
    1394         // Lace (when lacing bit is set)
     1388                // Lace (when lacing bit is set)
    13951389                if ($block_data['flags']['lacing'] > 0) {
    13961390                        $block_data['lace_frames'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(1)) + 1; // Number of frames in the lace-1 (uint8)
    13971391                        if ($block_data['flags']['lacing'] != 0x02) {
  • wp-includes/ID3/module.audio-video.quicktime.php

    diff --git a/wp-includes/ID3/module.audio-video.quicktime.php b/wp-includes/ID3/module.audio-video.quicktime.php
    index db63dab..31f28cf 100644
    a b  
    1010// module.audio-video.quicktime.php                            //
    1111// module for analyzing Quicktime and MP3-in-MP4 files         //
    1212// dependencies: module.audio.mp3.php                          //
     13// dependencies: module.tag.id3v2.php                          //
    1314//                                                            ///
    1415/////////////////////////////////////////////////////////////////
    1516
    1617getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
     18getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); // needed for ISO 639-2 language code lookup
    1719
    1820class getid3_quicktime extends getid3_handler
    1921{
    class getid3_quicktime extends getid3_handler 
    170172
    171173                $info = &$this->getid3->info;
    172174
    173                 $atom_parent = array_pop($atomHierarchy);
     175                //$atom_parent = array_pop($atomHierarchy);
     176                $atom_parent = end($atomHierarchy); // http://www.getid3.org/phpBB3/viewtopic.php?t=1717
    174177                array_push($atomHierarchy, $atomname);
    175178                $atom_structure['hierarchy'] = implode(' ', $atomHierarchy);
    176179                $atom_structure['name']      = $atomname;
    class getid3_quicktime extends getid3_handler 
    366369                                                        $boxsmallsize = getid3_lib::BigEndian2Int(substr($atom_data, $atomoffset,     2));
    367370                                                        $boxsmalltype =                           substr($atom_data, $atomoffset + 2, 2);
    368371                                                        $boxsmalldata =                           substr($atom_data, $atomoffset + 4, $boxsmallsize);
     372                                                        if ($boxsmallsize <= 1) {
     373                                                                $info['warning'][] = 'Invalid QuickTime atom smallbox size "'.$boxsmallsize.'" in atom "'.$atomname.'" at offset: '.($atom_structure['offset'] + $atomoffset);
     374                                                                $atom_structure['data'] = null;
     375                                                                $atomoffset = strlen($atom_data);
     376                                                                break;
     377                                                        }
    369378                                                        switch ($boxsmalltype) {
    370379                                                                case "\x10\xB5":
    371380                                                                        $atom_structure['data'] = $boxsmalldata;
    class getid3_quicktime extends getid3_handler 
    657666                                        switch ($atom_structure['sample_description_table'][$i]['encoder_vendor']) {
    658667
    659668                                                case "\x00\x00\x00\x00":
    660                                                         // audio atom
     669                                                        // audio tracks
    661670                                                        $atom_structure['sample_description_table'][$i]['audio_channels']       =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'],  8,  2));
    662671                                                        $atom_structure['sample_description_table'][$i]['audio_bit_depth']      =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 10,  2));
    663672                                                        $atom_structure['sample_description_table'][$i]['audio_compression_id'] =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 12,  2));
    664673                                                        $atom_structure['sample_description_table'][$i]['audio_packet_size']    =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 14,  2));
    665674                                                        $atom_structure['sample_description_table'][$i]['audio_sample_rate']    = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 16,  4));
    666675
     676                                                        // video tracks
     677                                                        // http://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap3/qtff3.html
     678                                                        $atom_structure['sample_description_table'][$i]['temporal_quality'] =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'],  8,  4));
     679                                                        $atom_structure['sample_description_table'][$i]['spatial_quality']  =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 12,  4));
     680                                                        $atom_structure['sample_description_table'][$i]['width']            =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 16,  2));
     681                                                        $atom_structure['sample_description_table'][$i]['height']           =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 18,  2));
     682                                                        $atom_structure['sample_description_table'][$i]['resolution_x']     = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 24,  4));
     683                                                        $atom_structure['sample_description_table'][$i]['resolution_y']     = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 28,  4));
     684                                                        $atom_structure['sample_description_table'][$i]['data_size']        =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 32,  4));
     685                                                        $atom_structure['sample_description_table'][$i]['frame_count']      =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 36,  2));
     686                                                        $atom_structure['sample_description_table'][$i]['compressor_name']  =                             substr($atom_structure['sample_description_table'][$i]['data'], 38,  4);
     687                                                        $atom_structure['sample_description_table'][$i]['pixel_depth']      =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 42,  2));
     688                                                        $atom_structure['sample_description_table'][$i]['color_table_id']   =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 44,  2));
     689
    667690                                                        switch ($atom_structure['sample_description_table'][$i]['data_format']) {
     691                                                                case '2vuY':
    668692                                                                case 'avc1':
     693                                                                case 'cvid':
     694                                                                case 'dvc ':
     695                                                                case 'dvcp':
     696                                                                case 'gif ':
     697                                                                case 'h263':
     698                                                                case 'jpeg':
     699                                                                case 'kpcd':
     700                                                                case 'mjpa':
     701                                                                case 'mjpb':
    669702                                                                case 'mp4v':
     703                                                                case 'png ':
     704                                                                case 'raw ':
     705                                                                case 'rle ':
     706                                                                case 'rpza':
     707                                                                case 'smc ':
     708                                                                case 'SVQ1':
     709                                                                case 'SVQ3':
     710                                                                case 'tiff':
     711                                                                case 'v210':
     712                                                                case 'v216':
     713                                                                case 'v308':
     714                                                                case 'v408':
     715                                                                case 'v410':
     716                                                                case 'yuv2':
    670717                                                                        $info['fileformat'] = 'mp4';
    671718                                                                        $info['video']['fourcc'] = $atom_structure['sample_description_table'][$i]['data_format'];
    672                                                                         //$info['warning'][] = 'This version of getID3() ['.$this->getid3->version().'] does not fully support MPEG-4 audio/video streams'; // 2011-02-18: why am I warning about this again? What's not supported?
     719// http://www.getid3.org/phpBB3/viewtopic.php?t=1550
     720//if ((!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($atom_structure['sample_description_table'][$i]['width'])) && (empty($info['video']['resolution_x']) || empty($info['video']['resolution_y']) || (number_format($info['video']['resolution_x'], 6) != number_format(round($info['video']['resolution_x']), 6)) || (number_format($info['video']['resolution_y'], 6) != number_format(round($info['video']['resolution_y']), 6)))) { // ugly check for floating point numbers
     721if (!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($atom_structure['sample_description_table'][$i]['height'])) {
     722        // assume that values stored here are more important than values stored in [tkhd] atom
     723        $info['video']['resolution_x'] = $atom_structure['sample_description_table'][$i]['width'];
     724        $info['video']['resolution_y'] = $atom_structure['sample_description_table'][$i]['height'];
     725        $info['quicktime']['video']['resolution_x'] = $info['video']['resolution_x'];
     726        $info['quicktime']['video']['resolution_y'] = $info['video']['resolution_y'];
     727}
    673728                                                                        break;
    674729
    675730                                                                case 'qtvr':
    class getid3_quicktime extends getid3_handler 
    11211176                                $atom_structure['alternate_group']     =   getid3_lib::BigEndian2Int(substr($atom_data, 34, 2));
    11221177                                $atom_structure['volume']              =   getid3_lib::FixedPoint8_8(substr($atom_data, 36, 2));
    11231178                                $atom_structure['reserved3']           =   getid3_lib::BigEndian2Int(substr($atom_data, 38, 2));
     1179// http://developer.apple.com/library/mac/#documentation/QuickTime/RM/MovieBasics/MTEditing/K-Chapter/11MatrixFunctions.html
     1180// http://developer.apple.com/library/mac/#documentation/QuickTime/qtff/QTFFChap4/qtff4.html#//apple_ref/doc/uid/TP40000939-CH206-18737
    11241181                                $atom_structure['matrix_a']            = getid3_lib::FixedPoint16_16(substr($atom_data, 40, 4));
    11251182                                $atom_structure['matrix_b']            = getid3_lib::FixedPoint16_16(substr($atom_data, 44, 4));
    1126                                 $atom_structure['matrix_u']            = getid3_lib::FixedPoint16_16(substr($atom_data, 48, 4));
     1183                                $atom_structure['matrix_u']            =  getid3_lib::FixedPoint2_30(substr($atom_data, 48, 4));
    11271184                                $atom_structure['matrix_c']            = getid3_lib::FixedPoint16_16(substr($atom_data, 52, 4));
    11281185                                $atom_structure['matrix_d']            = getid3_lib::FixedPoint16_16(substr($atom_data, 56, 4));
    1129                                 $atom_structure['matrix_v']            = getid3_lib::FixedPoint16_16(substr($atom_data, 60, 4));
    1130                                 $atom_structure['matrix_x']            =  getid3_lib::FixedPoint2_30(substr($atom_data, 64, 4));
    1131                                 $atom_structure['matrix_y']            =  getid3_lib::FixedPoint2_30(substr($atom_data, 68, 4));
     1186                                $atom_structure['matrix_v']            =  getid3_lib::FixedPoint2_30(substr($atom_data, 60, 4));
     1187                                $atom_structure['matrix_x']            = getid3_lib::FixedPoint16_16(substr($atom_data, 64, 4));
     1188                                $atom_structure['matrix_y']            = getid3_lib::FixedPoint16_16(substr($atom_data, 68, 4));
    11321189                                $atom_structure['matrix_w']            =  getid3_lib::FixedPoint2_30(substr($atom_data, 72, 4));
    11331190                                $atom_structure['width']               = getid3_lib::FixedPoint16_16(substr($atom_data, 76, 4));
    11341191                                $atom_structure['height']              = getid3_lib::FixedPoint16_16(substr($atom_data, 80, 4));
    1135 
    11361192                                $atom_structure['flags']['enabled']    = (bool) ($atom_structure['flags_raw'] & 0x0001);
    11371193                                $atom_structure['flags']['in_movie']   = (bool) ($atom_structure['flags_raw'] & 0x0002);
    11381194                                $atom_structure['flags']['in_preview'] = (bool) ($atom_structure['flags_raw'] & 0x0004);
    class getid3_quicktime extends getid3_handler 
    13841440
    13851441
    13861442        public function QuicktimeLanguageLookup($languageid) {
     1443                // http://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap4/qtff4.html#//apple_ref/doc/uid/TP40000939-CH206-34353
    13871444                static $QuicktimeLanguageLookup = array();
    13881445                if (empty($QuicktimeLanguageLookup)) {
    1389                         $QuicktimeLanguageLookup[0]   = 'English';
    1390                         $QuicktimeLanguageLookup[1]   = 'French';
    1391                         $QuicktimeLanguageLookup[2]   = 'German';
    1392                         $QuicktimeLanguageLookup[3]   = 'Italian';
    1393                         $QuicktimeLanguageLookup[4]   = 'Dutch';
    1394                         $QuicktimeLanguageLookup[5]   = 'Swedish';
    1395                         $QuicktimeLanguageLookup[6]   = 'Spanish';
    1396                         $QuicktimeLanguageLookup[7]   = 'Danish';
    1397                         $QuicktimeLanguageLookup[8]   = 'Portuguese';
    1398                         $QuicktimeLanguageLookup[9]   = 'Norwegian';
    1399                         $QuicktimeLanguageLookup[10]  = 'Hebrew';
    1400                         $QuicktimeLanguageLookup[11]  = 'Japanese';
    1401                         $QuicktimeLanguageLookup[12]  = 'Arabic';
    1402                         $QuicktimeLanguageLookup[13]  = 'Finnish';
    1403                         $QuicktimeLanguageLookup[14]  = 'Greek';
    1404                         $QuicktimeLanguageLookup[15]  = 'Icelandic';
    1405                         $QuicktimeLanguageLookup[16]  = 'Maltese';
    1406                         $QuicktimeLanguageLookup[17]  = 'Turkish';
    1407                         $QuicktimeLanguageLookup[18]  = 'Croatian';
    1408                         $QuicktimeLanguageLookup[19]  = 'Chinese (Traditional)';
    1409                         $QuicktimeLanguageLookup[20]  = 'Urdu';
    1410                         $QuicktimeLanguageLookup[21]  = 'Hindi';
    1411                         $QuicktimeLanguageLookup[22]  = 'Thai';
    1412                         $QuicktimeLanguageLookup[23]  = 'Korean';
    1413                         $QuicktimeLanguageLookup[24]  = 'Lithuanian';
    1414                         $QuicktimeLanguageLookup[25]  = 'Polish';
    1415                         $QuicktimeLanguageLookup[26]  = 'Hungarian';
    1416                         $QuicktimeLanguageLookup[27]  = 'Estonian';
    1417                         $QuicktimeLanguageLookup[28]  = 'Lettish';
    1418                         $QuicktimeLanguageLookup[28]  = 'Latvian';
    1419                         $QuicktimeLanguageLookup[29]  = 'Saamisk';
    1420                         $QuicktimeLanguageLookup[29]  = 'Lappish';
    1421                         $QuicktimeLanguageLookup[30]  = 'Faeroese';
    1422                         $QuicktimeLanguageLookup[31]  = 'Farsi';
    1423                         $QuicktimeLanguageLookup[31]  = 'Persian';
    1424                         $QuicktimeLanguageLookup[32]  = 'Russian';
    1425                         $QuicktimeLanguageLookup[33]  = 'Chinese (Simplified)';
    1426                         $QuicktimeLanguageLookup[34]  = 'Flemish';
    1427                         $QuicktimeLanguageLookup[35]  = 'Irish';
    1428                         $QuicktimeLanguageLookup[36]  = 'Albanian';
    1429                         $QuicktimeLanguageLookup[37]  = 'Romanian';
    1430                         $QuicktimeLanguageLookup[38]  = 'Czech';
    1431                         $QuicktimeLanguageLookup[39]  = 'Slovak';
    1432                         $QuicktimeLanguageLookup[40]  = 'Slovenian';
    1433                         $QuicktimeLanguageLookup[41]  = 'Yiddish';
    1434                         $QuicktimeLanguageLookup[42]  = 'Serbian';
    1435                         $QuicktimeLanguageLookup[43]  = 'Macedonian';
    1436                         $QuicktimeLanguageLookup[44]  = 'Bulgarian';
    1437                         $QuicktimeLanguageLookup[45]  = 'Ukrainian';
    1438                         $QuicktimeLanguageLookup[46]  = 'Byelorussian';
    1439                         $QuicktimeLanguageLookup[47]  = 'Uzbek';
    1440                         $QuicktimeLanguageLookup[48]  = 'Kazakh';
    1441                         $QuicktimeLanguageLookup[49]  = 'Azerbaijani';
    1442                         $QuicktimeLanguageLookup[50]  = 'AzerbaijanAr';
    1443                         $QuicktimeLanguageLookup[51]  = 'Armenian';
    1444                         $QuicktimeLanguageLookup[52]  = 'Georgian';
    1445                         $QuicktimeLanguageLookup[53]  = 'Moldavian';
    1446                         $QuicktimeLanguageLookup[54]  = 'Kirghiz';
    1447                         $QuicktimeLanguageLookup[55]  = 'Tajiki';
    1448                         $QuicktimeLanguageLookup[56]  = 'Turkmen';
    1449                         $QuicktimeLanguageLookup[57]  = 'Mongolian';
    1450                         $QuicktimeLanguageLookup[58]  = 'MongolianCyr';
    1451                         $QuicktimeLanguageLookup[59]  = 'Pashto';
    1452                         $QuicktimeLanguageLookup[60]  = 'Kurdish';
    1453                         $QuicktimeLanguageLookup[61]  = 'Kashmiri';
    1454                         $QuicktimeLanguageLookup[62]  = 'Sindhi';
    1455                         $QuicktimeLanguageLookup[63]  = 'Tibetan';
    1456                         $QuicktimeLanguageLookup[64]  = 'Nepali';
    1457                         $QuicktimeLanguageLookup[65]  = 'Sanskrit';
    1458                         $QuicktimeLanguageLookup[66]  = 'Marathi';
    1459                         $QuicktimeLanguageLookup[67]  = 'Bengali';
    1460                         $QuicktimeLanguageLookup[68]  = 'Assamese';
    1461                         $QuicktimeLanguageLookup[69]  = 'Gujarati';
    1462                         $QuicktimeLanguageLookup[70]  = 'Punjabi';
    1463                         $QuicktimeLanguageLookup[71]  = 'Oriya';
    1464                         $QuicktimeLanguageLookup[72]  = 'Malayalam';
    1465                         $QuicktimeLanguageLookup[73]  = 'Kannada';
    1466                         $QuicktimeLanguageLookup[74]  = 'Tamil';
    1467                         $QuicktimeLanguageLookup[75]  = 'Telugu';
    1468                         $QuicktimeLanguageLookup[76]  = 'Sinhalese';
    1469                         $QuicktimeLanguageLookup[77]  = 'Burmese';
    1470                         $QuicktimeLanguageLookup[78]  = 'Khmer';
    1471                         $QuicktimeLanguageLookup[79]  = 'Lao';
    1472                         $QuicktimeLanguageLookup[80]  = 'Vietnamese';
    1473                         $QuicktimeLanguageLookup[81]  = 'Indonesian';
    1474                         $QuicktimeLanguageLookup[82]  = 'Tagalog';
    1475                         $QuicktimeLanguageLookup[83]  = 'MalayRoman';
    1476                         $QuicktimeLanguageLookup[84]  = 'MalayArabic';
    1477                         $QuicktimeLanguageLookup[85]  = 'Amharic';
    1478                         $QuicktimeLanguageLookup[86]  = 'Tigrinya';
    1479                         $QuicktimeLanguageLookup[87]  = 'Galla';
    1480                         $QuicktimeLanguageLookup[87]  = 'Oromo';
    1481                         $QuicktimeLanguageLookup[88]  = 'Somali';
    1482                         $QuicktimeLanguageLookup[89]  = 'Swahili';
    1483                         $QuicktimeLanguageLookup[90]  = 'Ruanda';
    1484                         $QuicktimeLanguageLookup[91]  = 'Rundi';
    1485                         $QuicktimeLanguageLookup[92]  = 'Chewa';
    1486                         $QuicktimeLanguageLookup[93]  = 'Malagasy';
    1487                         $QuicktimeLanguageLookup[94]  = 'Esperanto';
    1488                         $QuicktimeLanguageLookup[128] = 'Welsh';
    1489                         $QuicktimeLanguageLookup[129] = 'Basque';
    1490                         $QuicktimeLanguageLookup[130] = 'Catalan';
    1491                         $QuicktimeLanguageLookup[131] = 'Latin';
    1492                         $QuicktimeLanguageLookup[132] = 'Quechua';
    1493                         $QuicktimeLanguageLookup[133] = 'Guarani';
    1494                         $QuicktimeLanguageLookup[134] = 'Aymara';
    1495                         $QuicktimeLanguageLookup[135] = 'Tatar';
    1496                         $QuicktimeLanguageLookup[136] = 'Uighur';
    1497                         $QuicktimeLanguageLookup[137] = 'Dzongkha';
    1498                         $QuicktimeLanguageLookup[138] = 'JavaneseRom';
     1446                        $QuicktimeLanguageLookup[0]     = 'English';
     1447                        $QuicktimeLanguageLookup[1]     = 'French';
     1448                        $QuicktimeLanguageLookup[2]     = 'German';
     1449                        $QuicktimeLanguageLookup[3]     = 'Italian';
     1450                        $QuicktimeLanguageLookup[4]     = 'Dutch';
     1451                        $QuicktimeLanguageLookup[5]     = 'Swedish';
     1452                        $QuicktimeLanguageLookup[6]     = 'Spanish';
     1453                        $QuicktimeLanguageLookup[7]     = 'Danish';
     1454                        $QuicktimeLanguageLookup[8]     = 'Portuguese';
     1455                        $QuicktimeLanguageLookup[9]     = 'Norwegian';
     1456                        $QuicktimeLanguageLookup[10]    = 'Hebrew';
     1457                        $QuicktimeLanguageLookup[11]    = 'Japanese';
     1458                        $QuicktimeLanguageLookup[12]    = 'Arabic';
     1459                        $QuicktimeLanguageLookup[13]    = 'Finnish';
     1460                        $QuicktimeLanguageLookup[14]    = 'Greek';
     1461                        $QuicktimeLanguageLookup[15]    = 'Icelandic';
     1462                        $QuicktimeLanguageLookup[16]    = 'Maltese';
     1463                        $QuicktimeLanguageLookup[17]    = 'Turkish';
     1464                        $QuicktimeLanguageLookup[18]    = 'Croatian';
     1465                        $QuicktimeLanguageLookup[19]    = 'Chinese (Traditional)';
     1466                        $QuicktimeLanguageLookup[20]    = 'Urdu';
     1467                        $QuicktimeLanguageLookup[21]    = 'Hindi';
     1468                        $QuicktimeLanguageLookup[22]    = 'Thai';
     1469                        $QuicktimeLanguageLookup[23]    = 'Korean';
     1470                        $QuicktimeLanguageLookup[24]    = 'Lithuanian';
     1471                        $QuicktimeLanguageLookup[25]    = 'Polish';
     1472                        $QuicktimeLanguageLookup[26]    = 'Hungarian';
     1473                        $QuicktimeLanguageLookup[27]    = 'Estonian';
     1474                        $QuicktimeLanguageLookup[28]    = 'Lettish';
     1475                        $QuicktimeLanguageLookup[28]    = 'Latvian';
     1476                        $QuicktimeLanguageLookup[29]    = 'Saamisk';
     1477                        $QuicktimeLanguageLookup[29]    = 'Lappish';
     1478                        $QuicktimeLanguageLookup[30]    = 'Faeroese';
     1479                        $QuicktimeLanguageLookup[31]    = 'Farsi';
     1480                        $QuicktimeLanguageLookup[31]    = 'Persian';
     1481                        $QuicktimeLanguageLookup[32]    = 'Russian';
     1482                        $QuicktimeLanguageLookup[33]    = 'Chinese (Simplified)';
     1483                        $QuicktimeLanguageLookup[34]    = 'Flemish';
     1484                        $QuicktimeLanguageLookup[35]    = 'Irish';
     1485                        $QuicktimeLanguageLookup[36]    = 'Albanian';
     1486                        $QuicktimeLanguageLookup[37]    = 'Romanian';
     1487                        $QuicktimeLanguageLookup[38]    = 'Czech';
     1488                        $QuicktimeLanguageLookup[39]    = 'Slovak';
     1489                        $QuicktimeLanguageLookup[40]    = 'Slovenian';
     1490                        $QuicktimeLanguageLookup[41]    = 'Yiddish';
     1491                        $QuicktimeLanguageLookup[42]    = 'Serbian';
     1492                        $QuicktimeLanguageLookup[43]    = 'Macedonian';
     1493                        $QuicktimeLanguageLookup[44]    = 'Bulgarian';
     1494                        $QuicktimeLanguageLookup[45]    = 'Ukrainian';
     1495                        $QuicktimeLanguageLookup[46]    = 'Byelorussian';
     1496                        $QuicktimeLanguageLookup[47]    = 'Uzbek';
     1497                        $QuicktimeLanguageLookup[48]    = 'Kazakh';
     1498                        $QuicktimeLanguageLookup[49]    = 'Azerbaijani';
     1499                        $QuicktimeLanguageLookup[50]    = 'AzerbaijanAr';
     1500                        $QuicktimeLanguageLookup[51]    = 'Armenian';
     1501                        $QuicktimeLanguageLookup[52]    = 'Georgian';
     1502                        $QuicktimeLanguageLookup[53]    = 'Moldavian';
     1503                        $QuicktimeLanguageLookup[54]    = 'Kirghiz';
     1504                        $QuicktimeLanguageLookup[55]    = 'Tajiki';
     1505                        $QuicktimeLanguageLookup[56]    = 'Turkmen';
     1506                        $QuicktimeLanguageLookup[57]    = 'Mongolian';
     1507                        $QuicktimeLanguageLookup[58]    = 'MongolianCyr';
     1508                        $QuicktimeLanguageLookup[59]    = 'Pashto';
     1509                        $QuicktimeLanguageLookup[60]    = 'Kurdish';
     1510                        $QuicktimeLanguageLookup[61]    = 'Kashmiri';
     1511                        $QuicktimeLanguageLookup[62]    = 'Sindhi';
     1512                        $QuicktimeLanguageLookup[63]    = 'Tibetan';
     1513                        $QuicktimeLanguageLookup[64]    = 'Nepali';
     1514                        $QuicktimeLanguageLookup[65]    = 'Sanskrit';
     1515                        $QuicktimeLanguageLookup[66]    = 'Marathi';
     1516                        $QuicktimeLanguageLookup[67]    = 'Bengali';
     1517                        $QuicktimeLanguageLookup[68]    = 'Assamese';
     1518                        $QuicktimeLanguageLookup[69]    = 'Gujarati';
     1519                        $QuicktimeLanguageLookup[70]    = 'Punjabi';
     1520                        $QuicktimeLanguageLookup[71]    = 'Oriya';
     1521                        $QuicktimeLanguageLookup[72]    = 'Malayalam';
     1522                        $QuicktimeLanguageLookup[73]    = 'Kannada';
     1523                        $QuicktimeLanguageLookup[74]    = 'Tamil';
     1524                        $QuicktimeLanguageLookup[75]    = 'Telugu';
     1525                        $QuicktimeLanguageLookup[76]    = 'Sinhalese';
     1526                        $QuicktimeLanguageLookup[77]    = 'Burmese';
     1527                        $QuicktimeLanguageLookup[78]    = 'Khmer';
     1528                        $QuicktimeLanguageLookup[79]    = 'Lao';
     1529                        $QuicktimeLanguageLookup[80]    = 'Vietnamese';
     1530                        $QuicktimeLanguageLookup[81]    = 'Indonesian';
     1531                        $QuicktimeLanguageLookup[82]    = 'Tagalog';
     1532                        $QuicktimeLanguageLookup[83]    = 'MalayRoman';
     1533                        $QuicktimeLanguageLookup[84]    = 'MalayArabic';
     1534                        $QuicktimeLanguageLookup[85]    = 'Amharic';
     1535                        $QuicktimeLanguageLookup[86]    = 'Tigrinya';
     1536                        $QuicktimeLanguageLookup[87]    = 'Galla';
     1537                        $QuicktimeLanguageLookup[87]    = 'Oromo';
     1538                        $QuicktimeLanguageLookup[88]    = 'Somali';
     1539                        $QuicktimeLanguageLookup[89]    = 'Swahili';
     1540                        $QuicktimeLanguageLookup[90]    = 'Ruanda';
     1541                        $QuicktimeLanguageLookup[91]    = 'Rundi';
     1542                        $QuicktimeLanguageLookup[92]    = 'Chewa';
     1543                        $QuicktimeLanguageLookup[93]    = 'Malagasy';
     1544                        $QuicktimeLanguageLookup[94]    = 'Esperanto';
     1545                        $QuicktimeLanguageLookup[128]   = 'Welsh';
     1546                        $QuicktimeLanguageLookup[129]   = 'Basque';
     1547                        $QuicktimeLanguageLookup[130]   = 'Catalan';
     1548                        $QuicktimeLanguageLookup[131]   = 'Latin';
     1549                        $QuicktimeLanguageLookup[132]   = 'Quechua';
     1550                        $QuicktimeLanguageLookup[133]   = 'Guarani';
     1551                        $QuicktimeLanguageLookup[134]   = 'Aymara';
     1552                        $QuicktimeLanguageLookup[135]   = 'Tatar';
     1553                        $QuicktimeLanguageLookup[136]   = 'Uighur';
     1554                        $QuicktimeLanguageLookup[137]   = 'Dzongkha';
     1555                        $QuicktimeLanguageLookup[138]   = 'JavaneseRom';
     1556                        $QuicktimeLanguageLookup[32767] = 'Unspecified';
     1557                }
     1558                if (($languageid > 138) && ($languageid < 32767)) {
     1559                        /*
     1560                        ISO Language Codes - http://www.loc.gov/standards/iso639-2/php/code_list.php
     1561                        Because the language codes specified by ISO 639-2/T are three characters long, they must be packed to fit into a 16-bit field.
     1562                        The packing algorithm must map each of the three characters, which are always lowercase, into a 5-bit integer and then concatenate
     1563                        these integers into the least significant 15 bits of a 16-bit integer, leaving the 16-bit integer's most significant bit set to zero.
     1564                       
     1565                        One algorithm for performing this packing is to treat each ISO character as a 16-bit integer. Subtract 0x60 from the first character
     1566                        and multiply by 2^10 (0x400), subtract 0x60 from the second character and multiply by 2^5 (0x20), subtract 0x60 from the third character,
     1567                        and add the three 16-bit values. This will result in a single 16-bit value with the three codes correctly packed into the 15 least
     1568                        significant bits and the most significant bit set to zero.
     1569                        */
     1570                        $iso_language_id  = '';
     1571                        $iso_language_id .= chr((($languageid & 0x7C00) >> 10) + 0x60);
     1572                        $iso_language_id .= chr((($languageid & 0x03E0) >>  5) + 0x60);
     1573                        $iso_language_id .= chr((($languageid & 0x001F) >>  0) + 0x60);
     1574                        $QuicktimeLanguageLookup[$languageid] = getid3_id3v2::LanguageLookup($iso_language_id);
    14991575                }
    15001576                return (isset($QuicktimeLanguageLookup[$languageid]) ? $QuicktimeLanguageLookup[$languageid] : 'invalid');
    15011577        }
  • wp-includes/ID3/module.tag.id3v2.php

    diff --git a/wp-includes/ID3/module.tag.id3v2.php b/wp-includes/ID3/module.tag.id3v2.php
    index 23784e9..b08f9f9 100644
    a b class getid3_id3v2 extends getid3_handler 
    667667
    668668                        if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) {
    669669                                // ID3v2.3 specs say that TPE1 (and others) can contain multiple artist values separated with /
    670                                 // This of course breaks when an aritst name contains slash character, e.g. "AC/DC"
     670                                // This of course breaks when an artist name contains slash character, e.g. "AC/DC"
    671671                                // MP3tag (maybe others) implement alternative system where multiple artists are null-separated, which makes more sense
    672672                                // getID3 will split null-separated artists into multiple artists and leave slash-separated ones to the user
    673673                                switch ($parsedFrame['encoding']) {
    class getid3_id3v2 extends getid3_handler 
    34103410                return (($majorversion == 2) ? 6 : 10);
    34113411        }
    34123412
    3413 }
    3414  No newline at end of file
     3413}
     3414
  • wp-includes/ID3/readme.txt

    diff --git a/wp-includes/ID3/readme.txt b/wp-includes/ID3/readme.txt
    index 548ba64..337e84f 100644
    a b  
    33//  available at http://getid3.sourceforge.net                 //
    44//            or http://www.getid3.org                         //
    55/////////////////////////////////////////////////////////////////
    6 //                                                             //
    7 // changelog.txt - part of getID3()                            //
    8 // See readme.txt for more details                             //
    9 //                                                            ///
    10 /////////////////////////////////////////////////////////////////
    116
    12         This code is released under the GNU GPL:
    13           http://www.gnu.org/copyleft/gpl.html
     7*****************************************************************
     8*****************************************************************
     9
     10   getID3() is released under multiple licenses. You may choose
     11   from the following licenses, and use getID3 according to the
     12   terms of the license most suitable to your project.
     13
     14GNU GPL: https://gnu.org/licenses/gpl.html                   (v3)
     15         https://gnu.org/licenses/old-licenses/gpl-2.0.html  (v2)
     16         https://gnu.org/licenses/old-licenses/gpl-1.0.html  (v1)
     17
     18GNU LGPL: https://gnu.org/licenses/lgpl.html                 (v3)
     19
     20Mozilla MPL: http://www.mozilla.org/MPL/2.0/                 (v2)
     21
     22getID3 Commercial License: http://getid3.org/#gCL (payment required)
     23
     24*****************************************************************
     25*****************************************************************
     26Copies of each of the above licenses are included in the 'licenses'
     27directory of the getID3 distribution.
    1428
    15      +---------------------------------------------+
    16      | If you do use this code somewhere, send me  |
    17      | an email and tell me how/where you used it. |
    18      |                                             |
    19      | If you want to donate, there is a link on   |
    20      | http://www.getid3.org for PayPal donations. |
    21      +---------------------------------------------+
    2229
     30       +---------------------------------------------+
     31       | If you want to donate, there is a link on   |
     32       | http://www.getid3.org for PayPal donations. |
     33       +---------------------------------------------+
    2334
    2435
    2536Quick Start
    What does getID3() do? 
    5667===========================================================================
    5768
    5869Reads & parses (to varying degrees):
    59  ¤ tags:
     70# tags:
    6071  * APE (v1 and v2)
    6172  * ID3v1 (& ID3v1.1)
    6273  * ID3v2 (v2.4, v2.3, v2.2)
    6374  * Lyrics3 (v1 & v2)
    6475
    65  ¤ audio-lossy:
     76# audio-lossy:
    6677  * MP3/MP2/MP1
    6778  * MPC / Musepack
    6879  * Ogg (Vorbis, OggFLAC, Speex)
    Reads & parses (to varying degrees): 
    7485  * DSS
    7586  * VQF
    7687
    77  ¤ audio-lossless:
     88# audio-lossless:
    7889  * AIFF
    7990  * AU
    8091  * Bonk
    Reads & parses (to varying degrees): 
    93104  * WAV (RIFF)
    94105  * WavPack
    95106
    96  ¤ audio-video:
     107# audio-video:
    97108  * ASF: ASF, Windows Media Audio (WMA), Windows Media Video (WMV)
    98109  * AVI (RIFF)
    99110  * Flash
    Reads & parses (to varying degrees): 
    103114  * Quicktime (including MP4)
    104115  * RealVideo
    105116
    106  ¤ still image:
     117# still image:
    107118  * BMP
    108119  * GIF
    109120  * JPEG
    Reads & parses (to varying degrees): 
    112123  * SWF (Flash)
    113124  * PhotoCD
    114125
    115  ¤ data:
     126# data:
    116127  * ISO-9660 CD-ROM image (directory structure)
    117128  * SZIP (limited support)
    118129  * ZIP (directory structure)
    http://www.getid3.org/phpBB3/viewforum.php?f=7 
    298309  (http://web.inter.nl.net/users/hvdh/lossless/lossless.htm)
    299310* Support for RIFF-INFO chunks
    300311  * http://lotto.st-andrews.ac.uk/~njh/tag_interchange.html
    301     (thanks Nick Humfrey <njhØsurgeradio*co*uk>)
     312    (thanks Nick Humfrey <njh@surgeradio*co*uk>)
    302313  * http://abcavi.narod.ru/sof/abcavi/infotags.htm
    303314    (thanks Kibi)
    304315* Better support for Bink video
    http://www.getid3.org/phpBB3/viewforum.php?f=7 
    313324* Support for IFF
    314325* Support for ICO
    315326* Support for ANI
    316 * Support for EXE (comments, author, etc) (thanks p*quaedackersØplanet*nl)
     327* Support for EXE (comments, author, etc) (thanks p*quaedackers@planet*nl)
    317328* Support for DVD-IFO (region, subtitles, aspect ratio, etc)
    318   (thanks p*quaedackersØplanet*nl)
     329  (thanks p*quaedackers@planet*nl)
    319330* More complete support for SWF - parsing encapsulated MP3 and/or JPEG content
    320     (thanks n8n8Øyahoo*com)
     331    (thanks n8n8@yahoo*com)
    321332* Support for a2b
    322333* Optional scan-through-frames for AVI verification
    323   (thanks rockcohenØmassive-interactive*nl)
    324 * Support for TTF (thanks infoØbutterflyx*com)
     334  (thanks rockcohen@massive-interactive*nl)
     335* Support for TTF (thanks info@butterflyx*com)
    325336* Support for DSS (http://www.getid3.org/phpBB3/viewtopic.php?t=171)
    326337* Support for SMAF (http://smaf-yamaha.com/what/demo.html)
    327338  http://www.getid3.org/phpBB3/viewtopic.php?t=182
    328339* Support for AMR (http://www.getid3.org/phpBB3/viewtopic.php?t=195)
    329340* Support for 3gpp (http://www.getid3.org/phpBB3/viewtopic.php?t=195)
    330 * Support for ID4 (http://www.wackysoft.cjb.net grizlyY2KØhotmail*com)
     341* Support for ID4 (http://www.wackysoft.cjb.net grizlyY2K@hotmail*com)
    331342* Parse XML data returned in Ogg comments
    332 * Parse XML data from Quicktime SMIL metafiles (klausrathØmac*com)
     343* Parse XML data from Quicktime SMIL metafiles (klausrath@mac*com)
    333344* ID3v2 genre string creator function
    334345* More complete parsing of JPG
    335346* Support for all old-style ASF packets