Make WordPress Core

Ticket #48040: 48040.diff

File 48040.diff, 430.5 KB (added by jorbin, 5 years ago)

https://github.com/JamesHeinrich/getID3/compare/v1.9.14...00f3fbfd77e583099ca70a3cf0bc092e113d2b20

  • src/wp-includes/ID3/getid3.lib.php

     
    11<?php
     2
    23/////////////////////////////////////////////////////////////////
    34/// getID3() by James Heinrich <info@getid3.org>               //
    4 //  available at http://getid3.sourceforge.net                 //
    5 //            or http://www.getid3.org                         //
    6 //          also https://github.com/JamesHeinrich/getID3       //
    7 /////////////////////////////////////////////////////////////////
     5//  available at https://github.com/JamesHeinrich/getID3       //
     6//            or https://www.getid3.org                        //
     7//            or http://getid3.sourceforge.net                 //
    88//                                                             //
    99// getid3.lib.php - part of getID3()                           //
    10 // See readme.txt for more details                             //
     10//  see readme.txt for more details                            //
    1111//                                                            ///
    1212/////////////////////////////////////////////////////////////////
    1313
     
    1414
    1515class getid3_lib
    1616{
    17 
     17        /**
     18         * @param string $string
     19         * @param bool   $hex
     20         * @param bool   $spaces
     21         * @param string $htmlencoding
     22         *
     23         * @return string
     24         */
    1825        public static function PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8') {
    1926                $returnstring = '';
    2027                for ($i = 0; $i < strlen($string); $i++) {
    2128                        if ($hex) {
    22                                 $returnstring .= str_pad(dechex(ord($string{$i})), 2, '0', STR_PAD_LEFT);
     29                                $returnstring .= str_pad(dechex(ord($string[$i])), 2, '0', STR_PAD_LEFT);
    2330                        } else {
    24                                 $returnstring .= ' '.(preg_match("#[\x20-\x7E]#", $string{$i}) ? $string{$i} : '¤');
     31                                $returnstring .= ' '.(preg_match("#[\x20-\x7E]#", $string[$i]) ? $string[$i] : '¤');
    2532                        }
    2633                        if ($spaces) {
    2734                                $returnstring .= ' ';
     
    3643                return $returnstring;
    3744        }
    3845
     46        /**
     47         * Truncates a floating-point number at the decimal point.
     48         *
     49         * @param float $floatnumber
     50         *
     51         * @return float|int returns int (if possible, otherwise float)
     52         */
    3953        public static function trunc($floatnumber) {
    40                 // truncates a floating-point number at the decimal point
    41                 // returns int (if possible, otherwise float)
    4254                if ($floatnumber >= 1) {
    4355                        $truncatednumber = floor($floatnumber);
    4456                } elseif ($floatnumber <= -1) {
     
    5264                return $truncatednumber;
    5365        }
    5466
    55 
     67        /**
     68         * @param int|null $variable
     69         * @param int      $increment
     70         *
     71         * @return bool
     72         */
    5673        public static function safe_inc(&$variable, $increment=1) {
    5774                if (isset($variable)) {
    5875                        $variable += $increment;
     
    6279                return true;
    6380        }
    6481
     82        /**
     83         * @param int|float $floatnum
     84         *
     85         * @return int|float
     86         */
    6587        public static function CastAsInt($floatnum) {
    6688                // convert to float if not already
    6789                $floatnum = (float) $floatnum;
     
    7799                return $floatnum;
    78100        }
    79101
     102        /**
     103         * @param int $num
     104         *
     105         * @return bool
     106         */
    80107        public static function intValueSupported($num) {
    81108                // check if integers are 64-bit
    82109                static $hasINT64 = null;
     
    93120                return false;
    94121        }
    95122
     123        /**
     124         * @param string $fraction
     125         *
     126         * @return float
     127         */
    96128        public static function DecimalizeFraction($fraction) {
    97129                list($numerator, $denominator) = explode('/', $fraction);
    98130                return $numerator / ($denominator ? $denominator : 1);
    99131        }
    100132
    101 
     133        /**
     134         * @param string $binarynumerator
     135         *
     136         * @return float
     137         */
    102138        public static function DecimalBinary2Float($binarynumerator) {
    103139                $numerator   = self::Bin2Dec($binarynumerator);
    104140                $denominator = self::Bin2Dec('1'.str_repeat('0', strlen($binarynumerator)));
     
    105141                return ($numerator / $denominator);
    106142        }
    107143
    108 
     144        /**
     145         * @link http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
     146         *
     147         * @param string $binarypointnumber
     148         * @param int    $maxbits
     149         *
     150         * @return array
     151         */
    109152        public static function NormalizeBinaryPoint($binarypointnumber, $maxbits=52) {
    110                 // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
    111153                if (strpos($binarypointnumber, '.') === false) {
    112154                        $binarypointnumber = '0.'.$binarypointnumber;
    113                 } elseif ($binarypointnumber{0} == '.') {
     155                } elseif ($binarypointnumber[0] == '.') {
    114156                        $binarypointnumber = '0'.$binarypointnumber;
    115157                }
    116158                $exponent = 0;
    117                 while (($binarypointnumber{0} != '1') || (substr($binarypointnumber, 1, 1) != '.')) {
     159                while (($binarypointnumber[0] != '1') || (substr($binarypointnumber, 1, 1) != '.')) {
    118160                        if (substr($binarypointnumber, 1, 1) == '.') {
    119161                                $exponent--;
    120162                                $binarypointnumber = substr($binarypointnumber, 2, 1).'.'.substr($binarypointnumber, 3);
     
    122164                                $pointpos = strpos($binarypointnumber, '.');
    123165                                $exponent += ($pointpos - 1);
    124166                                $binarypointnumber = str_replace('.', '', $binarypointnumber);
    125                                 $binarypointnumber = $binarypointnumber{0}.'.'.substr($binarypointnumber, 1);
     167                                $binarypointnumber = $binarypointnumber[0].'.'.substr($binarypointnumber, 1);
    126168                        }
    127169                }
    128170                $binarypointnumber = str_pad(substr($binarypointnumber, 0, $maxbits + 2), $maxbits + 2, '0', STR_PAD_RIGHT);
     
    129171                return array('normalized'=>$binarypointnumber, 'exponent'=>(int) $exponent);
    130172        }
    131173
    132 
     174        /**
     175         * @link http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
     176         *
     177         * @param float $floatvalue
     178         *
     179         * @return string
     180         */
    133181        public static function Float2BinaryDecimal($floatvalue) {
    134                 // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
    135182                $maxbits = 128; // to how many bits of precision should the calculations be taken?
    136183                $intpart   = self::trunc($floatvalue);
    137184                $floatpart = abs($floatvalue - $intpart);
     
    145192                return $binarypointnumber;
    146193        }
    147194
    148 
     195        /**
     196         * @link http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html
     197         *
     198         * @param float $floatvalue
     199         * @param int $bits
     200         *
     201         * @return string|false
     202         */
    149203        public static function Float2String($floatvalue, $bits) {
    150                 // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html
     204                $exponentbits = 0;
     205                $fractionbits = 0;
    151206                switch ($bits) {
    152207                        case 32:
    153208                                $exponentbits = 8;
     
    176231                return self::BigEndian2String(self::Bin2Dec($signbit.$exponentbitstring.$fractionbitstring), $bits % 8, false);
    177232        }
    178233
    179 
     234        /**
     235         * @param string $byteword
     236         *
     237         * @return float|false
     238         */
    180239        public static function LittleEndian2Float($byteword) {
    181240                return self::BigEndian2Float(strrev($byteword));
    182241        }
    183242
    184 
     243        /**
     244         * ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic
     245         *
     246         * @link http://www.psc.edu/general/software/packages/ieee/ieee.html
     247         * @link http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html
     248         *
     249         * @param string $byteword
     250         *
     251         * @return float|false
     252         */
    185253        public static function BigEndian2Float($byteword) {
    186                 // ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic
    187                 // http://www.psc.edu/general/software/packages/ieee/ieee.html
    188                 // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html
    189 
    190254                $bitword = self::BigEndian2Bin($byteword);
    191255                if (!$bitword) {
    192256                        return 0;
    193257                }
    194                 $signbit = $bitword{0};
     258                $signbit = $bitword[0];
     259                $floatvalue = 0;
     260                $exponentbits = 0;
     261                $fractionbits = 0;
    195262
    196263                switch (strlen($byteword) * 8) {
    197264                        case 32:
     
    208275                                // 80-bit Apple SANE format
    209276                                // http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/
    210277                                $exponentstring = substr($bitword, 1, 15);
    211                                 $isnormalized = intval($bitword{16});
     278                                $isnormalized = intval($bitword[16]);
    212279                                $fractionstring = substr($bitword, 17, 63);
    213280                                $exponent = pow(2, self::Bin2Dec($exponentstring) - 16383);
    214281                                $fraction = $isnormalized + self::DecimalBinary2Float($fractionstring);
     
    259326                return (float) $floatvalue;
    260327        }
    261328
    262 
     329        /**
     330         * @param string $byteword
     331         * @param bool   $synchsafe
     332         * @param bool   $signed
     333         *
     334         * @return int|float|false
     335         * @throws Exception
     336         */
    263337        public static function BigEndian2Int($byteword, $synchsafe=false, $signed=false) {
    264338                $intvalue = 0;
    265339                $bytewordlen = strlen($byteword);
     
    269343                for ($i = 0; $i < $bytewordlen; $i++) {
    270344                        if ($synchsafe) { // disregard MSB, effectively 7-bit bytes
    271345                                //$intvalue = $intvalue | (ord($byteword{$i}) & 0x7F) << (($bytewordlen - 1 - $i) * 7); // faster, but runs into problems past 2^31 on 32-bit systems
    272                                 $intvalue += (ord($byteword{$i}) & 0x7F) * pow(2, ($bytewordlen - 1 - $i) * 7);
     346                                $intvalue += (ord($byteword[$i]) & 0x7F) * pow(2, ($bytewordlen - 1 - $i) * 7);
    273347                        } else {
    274                                 $intvalue += ord($byteword{$i}) * pow(256, ($bytewordlen - 1 - $i));
     348                                $intvalue += ord($byteword[$i]) * pow(256, ($bytewordlen - 1 - $i));
    275349                        }
    276350                }
    277351                if ($signed && !$synchsafe) {
     
    288362                return self::CastAsInt($intvalue);
    289363        }
    290364
    291 
     365        /**
     366         * @param string $byteword
     367         * @param bool   $signed
     368         *
     369         * @return int|float|false
     370         */
    292371        public static function LittleEndian2Int($byteword, $signed=false) {
    293372                return self::BigEndian2Int(strrev($byteword), false, $signed);
    294373        }
    295374
     375        /**
     376         * @param string $byteword
     377         *
     378         * @return string
     379         */
    296380        public static function LittleEndian2Bin($byteword) {
    297381                return self::BigEndian2Bin(strrev($byteword));
    298382        }
    299383
     384        /**
     385         * @param string $byteword
     386         *
     387         * @return string
     388         */
    300389        public static function BigEndian2Bin($byteword) {
    301390                $binvalue = '';
    302391                $bytewordlen = strlen($byteword);
    303392                for ($i = 0; $i < $bytewordlen; $i++) {
    304                         $binvalue .= str_pad(decbin(ord($byteword{$i})), 8, '0', STR_PAD_LEFT);
     393                        $binvalue .= str_pad(decbin(ord($byteword[$i])), 8, '0', STR_PAD_LEFT);
    305394                }
    306395                return $binvalue;
    307396        }
    308397
    309 
     398        /**
     399         * @param int  $number
     400         * @param int  $minbytes
     401         * @param bool $synchsafe
     402         * @param bool $signed
     403         *
     404         * @return string
     405         * @throws Exception
     406         */
    310407        public static function BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false) {
    311408                if ($number < 0) {
    312409                        throw new Exception('ERROR: self::BigEndian2String() does not support negative numbers');
     
    327424                return str_pad($intstring, $minbytes, "\x00", STR_PAD_LEFT);
    328425        }
    329426
    330 
     427        /**
     428         * @param int $number
     429         *
     430         * @return string
     431         */
    331432        public static function Dec2Bin($number) {
    332433                while ($number >= 256) {
    333434                        $bytes[] = (($number / 256) - (floor($number / 256))) * 256;
     
    341442                return $binstring;
    342443        }
    343444
    344 
     445        /**
     446         * @param string $binstring
     447         * @param bool   $signed
     448         *
     449         * @return int|float
     450         */
    345451        public static function Bin2Dec($binstring, $signed=false) {
    346452                $signmult = 1;
    347453                if ($signed) {
    348                         if ($binstring{0} == '1') {
     454                        if ($binstring[0] == '1') {
    349455                                $signmult = -1;
    350456                        }
    351457                        $binstring = substr($binstring, 1);
     
    357463                return self::CastAsInt($decvalue * $signmult);
    358464        }
    359465
    360 
     466        /**
     467         * @param string $binstring
     468         *
     469         * @return string
     470         */
    361471        public static function Bin2String($binstring) {
    362472                // return 'hi' for input of '0110100001101001'
    363473                $string = '';
     
    368478                return $string;
    369479        }
    370480
    371 
     481        /**
     482         * @param int  $number
     483         * @param int  $minbytes
     484         * @param bool $synchsafe
     485         *
     486         * @return string
     487         */
    372488        public static function LittleEndian2String($number, $minbytes=1, $synchsafe=false) {
    373489                $intstring = '';
    374490                while ($number > 0) {
     
    383499                return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
    384500        }
    385501
    386 
     502        /**
     503         * @param array $array1
     504         * @param array $array2
     505         *
     506         * @return array|false
     507         */
    387508        public static function array_merge_clobber($array1, $array2) {
    388509                // written by kcØhireability*com
    389510                // taken from http://www.php.net/manual/en/function.array-merge-recursive.php
     
    401522                return $newarray;
    402523        }
    403524
    404 
     525        /**
     526         * @param array $array1
     527         * @param array $array2
     528         *
     529         * @return array|false
     530         */
    405531        public static function array_merge_noclobber($array1, $array2) {
    406532                if (!is_array($array1) || !is_array($array2)) {
    407533                        return false;
     
    417543                return $newarray;
    418544        }
    419545
     546        /**
     547         * @param array $array1
     548         * @param array $array2
     549         *
     550         * @return array|false|null
     551         */
    420552        public static function flipped_array_merge_noclobber($array1, $array2) {
    421553                if (!is_array($array1) || !is_array($array2)) {
    422554                        return false;
     
    431563                return array_flip($newarray);
    432564        }
    433565
    434 
     566        /**
     567         * @param array $theArray
     568         *
     569         * @return bool
     570         */
    435571        public static function ksort_recursive(&$theArray) {
    436572                ksort($theArray);
    437573                foreach ($theArray as $key => $value) {
     
    442578                return true;
    443579        }
    444580
     581        /**
     582         * @param string $filename
     583         * @param int    $numextensions
     584         *
     585         * @return string
     586         */
    445587        public static function fileextension($filename, $numextensions=1) {
    446588                if (strstr($filename, '.')) {
    447589                        $reversedfilename = strrev($filename);
     
    457599                return '';
    458600        }
    459601
    460 
     602        /**
     603         * @param int $seconds
     604         *
     605         * @return string
     606         */
    461607        public static function PlaytimeString($seconds) {
    462608                $sign = (($seconds < 0) ? '-' : '');
    463609                $seconds = round(abs($seconds));
     
    467613                return $sign.($H ? $H.':' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).':'.str_pad($S, 2, 0, STR_PAD_LEFT);
    468614        }
    469615
    470 
     616        /**
     617         * @param int $macdate
     618         *
     619         * @return int|float
     620         */
    471621        public static function DateMac2Unix($macdate) {
    472622                // Macintosh timestamp: seconds since 00:00h January 1, 1904
    473623                // UNIX timestamp:      seconds since 00:00h January 1, 1970
     
    474624                return self::CastAsInt($macdate - 2082844800);
    475625        }
    476626
    477 
     627        /**
     628         * @param string $rawdata
     629         *
     630         * @return float
     631         */
    478632        public static function FixedPoint8_8($rawdata) {
    479633                return self::BigEndian2Int(substr($rawdata, 0, 1)) + (float) (self::BigEndian2Int(substr($rawdata, 1, 1)) / pow(2, 8));
    480634        }
    481635
    482 
     636        /**
     637         * @param string $rawdata
     638         *
     639         * @return float
     640         */
    483641        public static function FixedPoint16_16($rawdata) {
    484642                return self::BigEndian2Int(substr($rawdata, 0, 2)) + (float) (self::BigEndian2Int(substr($rawdata, 2, 2)) / pow(2, 16));
    485643        }
    486644
    487 
     645        /**
     646         * @param string $rawdata
     647         *
     648         * @return float
     649         */
    488650        public static function FixedPoint2_30($rawdata) {
    489651                $binarystring = self::BigEndian2Bin($rawdata);
    490652                return self::Bin2Dec(substr($binarystring, 0, 2)) + (float) (self::Bin2Dec(substr($binarystring, 2, 30)) / pow(2, 30));
     
    491653        }
    492654
    493655
     656        /**
     657         * @param string $ArrayPath
     658         * @param string $Separator
     659         * @param mixed $Value
     660         *
     661         * @return array
     662         */
    494663        public static function CreateDeepArray($ArrayPath, $Separator, $Value) {
    495664                // assigns $Value to a nested array path:
    496665                //   $foo = self::CreateDeepArray('/path/to/my', '/', 'file.txt')
     
    507676                return $ReturnedArray;
    508677        }
    509678
     679        /**
     680         * @param array $arraydata
     681         * @param bool  $returnkey
     682         *
     683         * @return int|false
     684         */
    510685        public static function array_max($arraydata, $returnkey=false) {
    511686                $maxvalue = false;
    512687                $maxkey = false;
     
    521696                return ($returnkey ? $maxkey : $maxvalue);
    522697        }
    523698
     699        /**
     700         * @param array $arraydata
     701         * @param bool  $returnkey
     702         *
     703         * @return int|false
     704         */
    524705        public static function array_min($arraydata, $returnkey=false) {
    525706                $minvalue = false;
    526707                $minkey = false;
     
    535716                return ($returnkey ? $minkey : $minvalue);
    536717        }
    537718
     719        /**
     720         * @param string $XMLstring
     721         *
     722         * @return array|false
     723         */
    538724        public static function XML2array($XMLstring) {
    539725                if (function_exists('simplexml_load_string') && function_exists('libxml_disable_entity_loader')) {
    540726                        // http://websec.io/2012/08/27/Preventing-XEE-in-PHP.html
     
    548734                return false;
    549735        }
    550736
     737        /**
     738        * @param SimpleXMLElement|array $XMLobject
     739        *
     740        * @return array
     741        */
    551742        public static function SimpleXMLelement2array($XMLobject) {
    552743                if (!is_object($XMLobject) && !is_array($XMLobject)) {
    553744                        return $XMLobject;
    554745                }
    555                 $XMLarray = (is_object($XMLobject) ? get_object_vars($XMLobject) : $XMLobject);
     746                $XMLarray = $XMLobject instanceof SimpleXMLElement ? get_object_vars($XMLobject) : $XMLobject;
    556747                foreach ($XMLarray as $key => $value) {
    557748                        $XMLarray[$key] = self::SimpleXMLelement2array($value);
    558749                }
     
    559750                return $XMLarray;
    560751        }
    561752
    562 
    563         // Allan Hansen <ahØartemis*dk>
    564         // self::md5_data() - returns md5sum for a file from startuing position to absolute end position
     753        /**
     754         * Returns checksum for a file from starting position to absolute end position.
     755         *
     756         * @param string $file
     757         * @param int    $offset
     758         * @param int    $end
     759         * @param string $algorithm
     760         *
     761         * @return string|false
     762         * @throws getid3_exception
     763         */
    565764        public static function hash_data($file, $offset, $end, $algorithm) {
    566                 static $tempdir = '';
    567765                if (!self::intValueSupported($end)) {
    568766                        return false;
    569767                }
    570                 switch ($algorithm) {
    571                         case 'md5':
    572                                 $hash_function = 'md5_file';
    573                                 $unix_call     = 'md5sum';
    574                                 $windows_call  = 'md5sum.exe';
    575                                 $hash_length   = 32;
    576                                 break;
     768                if (!in_array($algorithm, array('md5', 'sha1'))) {
     769                        throw new getid3_exception('Invalid algorithm ('.$algorithm.') in self::hash_data()');
     770                }
    577771
    578                         case 'sha1':
    579                                 $hash_function = 'sha1_file';
    580                                 $unix_call     = 'sha1sum';
    581                                 $windows_call  = 'sha1sum.exe';
    582                                 $hash_length   = 40;
    583                                 break;
    584 
    585                         default:
    586                                 throw new Exception('Invalid algorithm ('.$algorithm.') in self::hash_data()');
    587                                 break;
    588                 }
    589772                $size = $end - $offset;
    590                 while (true) {
    591                         if (GETID3_OS_ISWINDOWS) {
    592773
    593                                 // It seems that sha1sum.exe for Windows only works on physical files, does not accept piped data
    594                                 // Fall back to create-temp-file method:
    595                                 if ($algorithm == 'sha1') {
    596                                         break;
    597                                 }
    598 
    599                                 $RequiredFiles = array('cygwin1.dll', 'head.exe', 'tail.exe', $windows_call);
    600                                 foreach ($RequiredFiles as $required_file) {
    601                                         if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) {
    602                                                 // helper apps not available - fall back to old method
    603                                                 break 2;
    604                                         }
    605                                 }
    606                                 $commandline  = GETID3_HELPERAPPSDIR.'head.exe -c '.$end.' '.escapeshellarg(str_replace('/', DIRECTORY_SEPARATOR, $file)).' | ';
    607                                 $commandline .= GETID3_HELPERAPPSDIR.'tail.exe -c '.$size.' | ';
    608                                 $commandline .= GETID3_HELPERAPPSDIR.$windows_call;
    609 
    610                         } else {
    611 
    612                                 $commandline  = 'head -c'.$end.' '.escapeshellarg($file).' | ';
    613                                 $commandline .= 'tail -c'.$size.' | ';
    614                                 $commandline .= $unix_call;
    615 
    616                         }
    617                         if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
    618                                 //throw new Exception('PHP running in Safe Mode - backtick operator not available, using slower non-system-call '.$algorithm.' algorithm');
    619                                 break;
    620                         }
    621                         return substr(`$commandline`, 0, $hash_length);
     774                $fp = fopen($file, 'rb');
     775                fseek($fp, $offset);
     776                $ctx = hash_init($algorithm);
     777                while ($size > 0) {
     778                        $buffer = fread($fp, min($size, getID3::FREAD_BUFFER_SIZE));
     779                        hash_update($ctx, $buffer);
     780                        $size -= getID3::FREAD_BUFFER_SIZE;
    622781                }
     782                $hash = hash_final($ctx);
     783                fclose($fp);
    623784
    624                 if (empty($tempdir)) {
    625                         // yes this is ugly, feel free to suggest a better way
    626                         require_once(dirname(__FILE__).'/getid3.php');
    627                         $getid3_temp = new getID3();
    628                         $tempdir = $getid3_temp->tempdir;
    629                         unset($getid3_temp);
    630                 }
    631                 // try to create a temporary file in the system temp directory - invalid dirname should force to system temp dir
    632                 if (($data_filename = tempnam($tempdir, 'gI3')) === false) {
    633                         // can't find anywhere to create a temp file, just fail
    634                         return false;
    635                 }
    636 
    637                 // Init
    638                 $result = false;
    639 
    640                 // copy parts of file
    641                 try {
    642                         self::CopyFileParts($file, $data_filename, $offset, $end - $offset);
    643                         $result = $hash_function($data_filename);
    644                 } catch (Exception $e) {
    645                         throw new Exception('self::CopyFileParts() failed in getid_lib::hash_data(): '.$e->getMessage());
    646                 }
    647                 unlink($data_filename);
    648                 return $result;
     785                return $hash;
    649786        }
    650787
     788        /**
     789         * @param string $filename_source
     790         * @param string $filename_dest
     791         * @param int    $offset
     792         * @param int    $length
     793         *
     794         * @return bool
     795         * @throws Exception
     796         *
     797         * @deprecated Unused, may be removed in future versions of getID3
     798         */
    651799        public static function CopyFileParts($filename_source, $filename_dest, $offset, $length) {
    652800                if (!self::intValueSupported($offset + $length)) {
    653801                        throw new Exception('cannot copy file portion, it extends beyond the '.round(PHP_INT_MAX / 1073741824).'GB limit');
     
    660808                                                $byteswritten = fwrite($fp_dest, $buffer, $byteslefttowrite);
    661809                                                $byteslefttowrite -= $byteswritten;
    662810                                        }
     811                                        fclose($fp_dest);
    663812                                        return true;
    664813                                } else {
     814                                        fclose($fp_src);
    665815                                        throw new Exception('failed to seek to offset '.$offset.' in '.$filename_source);
    666816                                }
    667                                 fclose($fp_dest);
    668817                        } else {
    669818                                throw new Exception('failed to create file for writing '.$filename_dest);
    670819                        }
    671                         fclose($fp_src);
    672820                } else {
    673821                        throw new Exception('failed to open file for reading '.$filename_source);
    674822                }
    675                 return false;
    676823        }
    677824
     825        /**
     826         * @param int $charval
     827         *
     828         * @return string
     829         */
    678830        public static function iconv_fallback_int_utf8($charval) {
    679831                if ($charval < 128) {
    680832                        // 0bbbbbbb
     
    698850                return $newcharstring;
    699851        }
    700852
    701         // ISO-8859-1 => UTF-8
     853        /**
     854         * ISO-8859-1 => UTF-8
     855         *
     856         * @param string $string
     857         * @param bool   $bom
     858         *
     859         * @return string
     860         */
    702861        public static function iconv_fallback_iso88591_utf8($string, $bom=false) {
    703862                if (function_exists('utf8_encode')) {
    704863                        return utf8_encode($string);
     
    709868                        $newcharstring .= "\xEF\xBB\xBF";
    710869                }
    711870                for ($i = 0; $i < strlen($string); $i++) {
    712                         $charval = ord($string{$i});
     871                        $charval = ord($string[$i]);
    713872                        $newcharstring .= self::iconv_fallback_int_utf8($charval);
    714873                }
    715874                return $newcharstring;
    716875        }
    717876
    718         // ISO-8859-1 => UTF-16BE
     877        /**
     878         * ISO-8859-1 => UTF-16BE
     879         *
     880         * @param string $string
     881         * @param bool   $bom
     882         *
     883         * @return string
     884         */
    719885        public static function iconv_fallback_iso88591_utf16be($string, $bom=false) {
    720886                $newcharstring = '';
    721887                if ($bom) {
     
    722888                        $newcharstring .= "\xFE\xFF";
    723889                }
    724890                for ($i = 0; $i < strlen($string); $i++) {
    725                         $newcharstring .= "\x00".$string{$i};
     891                        $newcharstring .= "\x00".$string[$i];
    726892                }
    727893                return $newcharstring;
    728894        }
    729895
    730         // ISO-8859-1 => UTF-16LE
     896        /**
     897         * ISO-8859-1 => UTF-16LE
     898         *
     899         * @param string $string
     900         * @param bool   $bom
     901         *
     902         * @return string
     903         */
    731904        public static function iconv_fallback_iso88591_utf16le($string, $bom=false) {
    732905                $newcharstring = '';
    733906                if ($bom) {
     
    734907                        $newcharstring .= "\xFF\xFE";
    735908                }
    736909                for ($i = 0; $i < strlen($string); $i++) {
    737                         $newcharstring .= $string{$i}."\x00";
     910                        $newcharstring .= $string[$i]."\x00";
    738911                }
    739912                return $newcharstring;
    740913        }
    741914
    742         // ISO-8859-1 => UTF-16LE (BOM)
     915        /**
     916         * ISO-8859-1 => UTF-16LE (BOM)
     917         *
     918         * @param string $string
     919         *
     920         * @return string
     921         */
    743922        public static function iconv_fallback_iso88591_utf16($string) {
    744923                return self::iconv_fallback_iso88591_utf16le($string, true);
    745924        }
    746925
    747         // UTF-8 => ISO-8859-1
     926        /**
     927         * UTF-8 => ISO-8859-1
     928         *
     929         * @param string $string
     930         *
     931         * @return string
     932         */
    748933        public static function iconv_fallback_utf8_iso88591($string) {
    749934                if (function_exists('utf8_decode')) {
    750935                        return utf8_decode($string);
     
    754939                $offset = 0;
    755940                $stringlength = strlen($string);
    756941                while ($offset < $stringlength) {
    757                         if ((ord($string{$offset}) | 0x07) == 0xF7) {
     942                        if ((ord($string[$offset]) | 0x07) == 0xF7) {
    758943                                // 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
    759                                 $charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
    760                                                    ((ord($string{($offset + 1)}) & 0x3F) << 12) &
    761                                                    ((ord($string{($offset + 2)}) & 0x3F) <<  6) &
    762                                                         (ord($string{($offset + 3)}) & 0x3F);
     944                                $charval = ((ord($string[($offset + 0)]) & 0x07) << 18) &
     945                                                   ((ord($string[($offset + 1)]) & 0x3F) << 12) &
     946                                                   ((ord($string[($offset + 2)]) & 0x3F) <<  6) &
     947                                                        (ord($string[($offset + 3)]) & 0x3F);
    763948                                $offset += 4;
    764                         } elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
     949                        } elseif ((ord($string[$offset]) | 0x0F) == 0xEF) {
    765950                                // 1110bbbb 10bbbbbb 10bbbbbb
    766                                 $charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
    767                                                    ((ord($string{($offset + 1)}) & 0x3F) <<  6) &
    768                                                         (ord($string{($offset + 2)}) & 0x3F);
     951                                $charval = ((ord($string[($offset + 0)]) & 0x0F) << 12) &
     952                                                   ((ord($string[($offset + 1)]) & 0x3F) <<  6) &
     953                                                        (ord($string[($offset + 2)]) & 0x3F);
    769954                                $offset += 3;
    770                         } elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
     955                        } elseif ((ord($string[$offset]) | 0x1F) == 0xDF) {
    771956                                // 110bbbbb 10bbbbbb
    772                                 $charval = ((ord($string{($offset + 0)}) & 0x1F) <<  6) &
    773                                                         (ord($string{($offset + 1)}) & 0x3F);
     957                                $charval = ((ord($string[($offset + 0)]) & 0x1F) <<  6) &
     958                                                        (ord($string[($offset + 1)]) & 0x3F);
    774959                                $offset += 2;
    775                         } elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
     960                        } elseif ((ord($string[$offset]) | 0x7F) == 0x7F) {
    776961                                // 0bbbbbbb
    777                                 $charval = ord($string{$offset});
     962                                $charval = ord($string[$offset]);
    778963                                $offset += 1;
    779964                        } else {
    780965                                // error? throw some kind of warning here?
     
    788973                return $newcharstring;
    789974        }
    790975
    791         // UTF-8 => UTF-16BE
     976        /**
     977         * UTF-8 => UTF-16BE
     978         *
     979         * @param string $string
     980         * @param bool   $bom
     981         *
     982         * @return string
     983         */
    792984        public static function iconv_fallback_utf8_utf16be($string, $bom=false) {
    793985                $newcharstring = '';
    794986                if ($bom) {
     
    797989                $offset = 0;
    798990                $stringlength = strlen($string);
    799991                while ($offset < $stringlength) {
    800                         if ((ord($string{$offset}) | 0x07) == 0xF7) {
     992                        if ((ord($string[$offset]) | 0x07) == 0xF7) {
    801993                                // 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
    802                                 $charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
    803                                                    ((ord($string{($offset + 1)}) & 0x3F) << 12) &
    804                                                    ((ord($string{($offset + 2)}) & 0x3F) <<  6) &
    805                                                         (ord($string{($offset + 3)}) & 0x3F);
     994                                $charval = ((ord($string[($offset + 0)]) & 0x07) << 18) &
     995                                                   ((ord($string[($offset + 1)]) & 0x3F) << 12) &
     996                                                   ((ord($string[($offset + 2)]) & 0x3F) <<  6) &
     997                                                        (ord($string[($offset + 3)]) & 0x3F);
    806998                                $offset += 4;
    807                         } elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
     999                        } elseif ((ord($string[$offset]) | 0x0F) == 0xEF) {
    8081000                                // 1110bbbb 10bbbbbb 10bbbbbb
    809                                 $charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
    810                                                    ((ord($string{($offset + 1)}) & 0x3F) <<  6) &
    811                                                         (ord($string{($offset + 2)}) & 0x3F);
     1001                                $charval = ((ord($string[($offset + 0)]) & 0x0F) << 12) &
     1002                                                   ((ord($string[($offset + 1)]) & 0x3F) <<  6) &
     1003                                                        (ord($string[($offset + 2)]) & 0x3F);
    8121004                                $offset += 3;
    813                         } elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
     1005                        } elseif ((ord($string[$offset]) | 0x1F) == 0xDF) {
    8141006                                // 110bbbbb 10bbbbbb
    815                                 $charval = ((ord($string{($offset + 0)}) & 0x1F) <<  6) &
    816                                                         (ord($string{($offset + 1)}) & 0x3F);
     1007                                $charval = ((ord($string[($offset + 0)]) & 0x1F) <<  6) &
     1008                                                        (ord($string[($offset + 1)]) & 0x3F);
    8171009                                $offset += 2;
    818                         } elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
     1010                        } elseif ((ord($string[$offset]) | 0x7F) == 0x7F) {
    8191011                                // 0bbbbbbb
    820                                 $charval = ord($string{$offset});
     1012                                $charval = ord($string[$offset]);
    8211013                                $offset += 1;
    8221014                        } else {
    8231015                                // error? throw some kind of warning here?
     
    8311023                return $newcharstring;
    8321024        }
    8331025
    834         // UTF-8 => UTF-16LE
     1026        /**
     1027         * UTF-8 => UTF-16LE
     1028         *
     1029         * @param string $string
     1030         * @param bool   $bom
     1031         *
     1032         * @return string
     1033         */
    8351034        public static function iconv_fallback_utf8_utf16le($string, $bom=false) {
    8361035                $newcharstring = '';
    8371036                if ($bom) {
     
    8401039                $offset = 0;
    8411040                $stringlength = strlen($string);
    8421041                while ($offset < $stringlength) {
    843                         if ((ord($string{$offset}) | 0x07) == 0xF7) {
     1042                        if ((ord($string[$offset]) | 0x07) == 0xF7) {
    8441043                                // 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
    845                                 $charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
    846                                                    ((ord($string{($offset + 1)}) & 0x3F) << 12) &
    847                                                    ((ord($string{($offset + 2)}) & 0x3F) <<  6) &
    848                                                         (ord($string{($offset + 3)}) & 0x3F);
     1044                                $charval = ((ord($string[($offset + 0)]) & 0x07) << 18) &
     1045                                                   ((ord($string[($offset + 1)]) & 0x3F) << 12) &
     1046                                                   ((ord($string[($offset + 2)]) & 0x3F) <<  6) &
     1047                                                        (ord($string[($offset + 3)]) & 0x3F);
    8491048                                $offset += 4;
    850                         } elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
     1049                        } elseif ((ord($string[$offset]) | 0x0F) == 0xEF) {
    8511050                                // 1110bbbb 10bbbbbb 10bbbbbb
    852                                 $charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
    853                                                    ((ord($string{($offset + 1)}) & 0x3F) <<  6) &
    854                                                         (ord($string{($offset + 2)}) & 0x3F);
     1051                                $charval = ((ord($string[($offset + 0)]) & 0x0F) << 12) &
     1052                                                   ((ord($string[($offset + 1)]) & 0x3F) <<  6) &
     1053                                                        (ord($string[($offset + 2)]) & 0x3F);
    8551054                                $offset += 3;
    856                         } elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
     1055                        } elseif ((ord($string[$offset]) | 0x1F) == 0xDF) {
    8571056                                // 110bbbbb 10bbbbbb
    858                                 $charval = ((ord($string{($offset + 0)}) & 0x1F) <<  6) &
    859                                                         (ord($string{($offset + 1)}) & 0x3F);
     1057                                $charval = ((ord($string[($offset + 0)]) & 0x1F) <<  6) &
     1058                                                        (ord($string[($offset + 1)]) & 0x3F);
    8601059                                $offset += 2;
    861                         } elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
     1060                        } elseif ((ord($string[$offset]) | 0x7F) == 0x7F) {
    8621061                                // 0bbbbbbb
    863                                 $charval = ord($string{$offset});
     1062                                $charval = ord($string[$offset]);
    8641063                                $offset += 1;
    8651064                        } else {
    8661065                                // error? maybe throw some warning here?
     
    8741073                return $newcharstring;
    8751074        }
    8761075
    877         // UTF-8 => UTF-16LE (BOM)
     1076        /**
     1077         * UTF-8 => UTF-16LE (BOM)
     1078         *
     1079         * @param string $string
     1080         *
     1081         * @return string
     1082         */
    8781083        public static function iconv_fallback_utf8_utf16($string) {
    8791084                return self::iconv_fallback_utf8_utf16le($string, true);
    8801085        }
    8811086
    882         // UTF-16BE => UTF-8
     1087        /**
     1088         * UTF-16BE => UTF-8
     1089         *
     1090         * @param string $string
     1091         *
     1092         * @return string
     1093         */
    8831094        public static function iconv_fallback_utf16be_utf8($string) {
    8841095                if (substr($string, 0, 2) == "\xFE\xFF") {
    8851096                        // strip BOM
     
    8931104                return $newcharstring;
    8941105        }
    8951106
    896         // UTF-16LE => UTF-8
     1107        /**
     1108         * UTF-16LE => UTF-8
     1109         *
     1110         * @param string $string
     1111         *
     1112         * @return string
     1113         */
    8971114        public static function iconv_fallback_utf16le_utf8($string) {
    8981115                if (substr($string, 0, 2) == "\xFF\xFE") {
    8991116                        // strip BOM
     
    9071124                return $newcharstring;
    9081125        }
    9091126
    910         // UTF-16BE => ISO-8859-1
     1127        /**
     1128         * UTF-16BE => ISO-8859-1
     1129         *
     1130         * @param string $string
     1131         *
     1132         * @return string
     1133         */
    9111134        public static function iconv_fallback_utf16be_iso88591($string) {
    9121135                if (substr($string, 0, 2) == "\xFE\xFF") {
    9131136                        // strip BOM
     
    9211144                return $newcharstring;
    9221145        }
    9231146
    924         // UTF-16LE => ISO-8859-1
     1147        /**
     1148         * UTF-16LE => ISO-8859-1
     1149         *
     1150         * @param string $string
     1151         *
     1152         * @return string
     1153         */
    9251154        public static function iconv_fallback_utf16le_iso88591($string) {
    9261155                if (substr($string, 0, 2) == "\xFF\xFE") {
    9271156                        // strip BOM
     
    9351164                return $newcharstring;
    9361165        }
    9371166
    938         // UTF-16 (BOM) => ISO-8859-1
     1167        /**
     1168         * UTF-16 (BOM) => ISO-8859-1
     1169         *
     1170         * @param string $string
     1171         *
     1172         * @return string
     1173         */
    9391174        public static function iconv_fallback_utf16_iso88591($string) {
    9401175                $bom = substr($string, 0, 2);
    9411176                if ($bom == "\xFE\xFF") {
     
    9461181                return $string;
    9471182        }
    9481183
    949         // UTF-16 (BOM) => UTF-8
     1184        /**
     1185         * UTF-16 (BOM) => UTF-8
     1186         *
     1187         * @param string $string
     1188         *
     1189         * @return string
     1190         */
    9501191        public static function iconv_fallback_utf16_utf8($string) {
    9511192                $bom = substr($string, 0, 2);
    9521193                if ($bom == "\xFE\xFF") {
     
    9571198                return $string;
    9581199        }
    9591200
     1201        /**
     1202         * @param string $in_charset
     1203         * @param string $out_charset
     1204         * @param string $string
     1205         *
     1206         * @return string
     1207         * @throws Exception
     1208         */
    9601209        public static function iconv_fallback($in_charset, $out_charset, $string) {
    9611210
    9621211                if ($in_charset == $out_charset) {
     
    9631212                        return $string;
    9641213                }
    9651214
    966                 // mb_convert_encoding() availble
     1215                // mb_convert_encoding() available
    9671216                if (function_exists('mb_convert_encoding')) {
     1217                        if ((strtoupper($in_charset) == 'UTF-16') && (substr($string, 0, 2) != "\xFE\xFF") && (substr($string, 0, 2) != "\xFF\xFE")) {
     1218                                // if BOM missing, mb_convert_encoding will mishandle the conversion, assume UTF-16BE and prepend appropriate BOM
     1219                                $string = "\xFF\xFE".$string;
     1220                        }
     1221                        if ((strtoupper($in_charset) == 'UTF-16') && (strtoupper($out_charset) == 'UTF-8')) {
     1222                                if (($string == "\xFF\xFE") || ($string == "\xFE\xFF")) {
     1223                                        // if string consists of only BOM, mb_convert_encoding will return the BOM unmodified
     1224                                        return '';
     1225                                }
     1226                        }
    9681227                        if ($converted_string = @mb_convert_encoding($string, $out_charset, $in_charset)) {
    9691228                                switch ($out_charset) {
    9701229                                        case 'ISO-8859-1':
     
    9741233                                return $converted_string;
    9751234                        }
    9761235                        return $string;
    977                 }
    978                 // iconv() availble
    979                 else if (function_exists('iconv')) {
     1236
     1237                // iconv() available
     1238                } elseif (function_exists('iconv')) {
    9801239                        if ($converted_string = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) {
    9811240                                switch ($out_charset) {
    9821241                                        case 'ISO-8859-1':
     
    10171276                throw new Exception('PHP does not has mb_convert_encoding() or iconv() support - cannot convert from '.$in_charset.' to '.$out_charset);
    10181277        }
    10191278
     1279        /**
     1280         * @param mixed  $data
     1281         * @param string $charset
     1282         *
     1283         * @return mixed
     1284         */
    10201285        public static function recursiveMultiByteCharString2HTML($data, $charset='ISO-8859-1') {
    10211286                if (is_string($data)) {
    10221287                        return self::MultiByteCharString2HTML($data, $charset);
     
    10311296                return $data;
    10321297        }
    10331298
     1299        /**
     1300         * @param string|int|float $string
     1301         * @param string           $charset
     1302         *
     1303         * @return string
     1304         */
    10341305        public static function MultiByteCharString2HTML($string, $charset='ISO-8859-1') {
    10351306                $string = (string) $string; // in case trying to pass a numeric (float, int) string, would otherwise return an empty string
    10361307                $HTMLstring = '';
     
    10691340                        case 'utf-8':
    10701341                                $strlen = strlen($string);
    10711342                                for ($i = 0; $i < $strlen; $i++) {
    1072                                         $char_ord_val = ord($string{$i});
     1343                                        $char_ord_val = ord($string[$i]);
    10731344                                        $charval = 0;
    10741345                                        if ($char_ord_val < 0x80) {
    10751346                                                $charval = $char_ord_val;
    10761347                                        } elseif ((($char_ord_val & 0xF0) >> 4) == 0x0F  &&  $i+3 < $strlen) {
    10771348                                                $charval  = (($char_ord_val & 0x07) << 18);
    1078                                                 $charval += ((ord($string{++$i}) & 0x3F) << 12);
    1079                                                 $charval += ((ord($string{++$i}) & 0x3F) << 6);
    1080                                                 $charval +=  (ord($string{++$i}) & 0x3F);
     1349                                                $charval += ((ord($string[++$i]) & 0x3F) << 12);
     1350                                                $charval += ((ord($string[++$i]) & 0x3F) << 6);
     1351                                                $charval +=  (ord($string[++$i]) & 0x3F);
    10811352                                        } elseif ((($char_ord_val & 0xE0) >> 5) == 0x07  &&  $i+2 < $strlen) {
    10821353                                                $charval  = (($char_ord_val & 0x0F) << 12);
    1083                                                 $charval += ((ord($string{++$i}) & 0x3F) << 6);
    1084                                                 $charval +=  (ord($string{++$i}) & 0x3F);
     1354                                                $charval += ((ord($string[++$i]) & 0x3F) << 6);
     1355                                                $charval +=  (ord($string[++$i]) & 0x3F);
    10851356                                        } elseif ((($char_ord_val & 0xC0) >> 6) == 0x03  &&  $i+1 < $strlen) {
    10861357                                                $charval  = (($char_ord_val & 0x1F) << 6);
    1087                                                 $charval += (ord($string{++$i}) & 0x3F);
     1358                                                $charval += (ord($string[++$i]) & 0x3F);
    10881359                                        }
    10891360                                        if (($charval >= 32) && ($charval <= 127)) {
    10901361                                                $HTMLstring .= htmlentities(chr($charval));
     
    11231394                return $HTMLstring;
    11241395        }
    11251396
    1126 
    1127 
     1397        /**
     1398         * @param int $namecode
     1399         *
     1400         * @return string
     1401         */
    11281402        public static function RGADnameLookup($namecode) {
    11291403                static $RGADname = array();
    11301404                if (empty($RGADname)) {
     
    11361410                return (isset($RGADname[$namecode]) ? $RGADname[$namecode] : '');
    11371411        }
    11381412
    1139 
     1413        /**
     1414         * @param int $originatorcode
     1415         *
     1416         * @return string
     1417         */
    11401418        public static function RGADoriginatorLookup($originatorcode) {
    11411419                static $RGADoriginator = array();
    11421420                if (empty($RGADoriginator)) {
     
    11491427                return (isset($RGADoriginator[$originatorcode]) ? $RGADoriginator[$originatorcode] : '');
    11501428        }
    11511429
    1152 
     1430        /**
     1431         * @param int $rawadjustment
     1432         * @param int $signbit
     1433         *
     1434         * @return float
     1435         */
    11531436        public static function RGADadjustmentLookup($rawadjustment, $signbit) {
    1154                 $adjustment = $rawadjustment / 10;
     1437                $adjustment = (float) $rawadjustment / 10;
    11551438                if ($signbit == 1) {
    11561439                        $adjustment *= -1;
    11571440                }
    1158                 return (float) $adjustment;
     1441                return $adjustment;
    11591442        }
    11601443
    1161 
     1444        /**
     1445         * @param int $namecode
     1446         * @param int $originatorcode
     1447         * @param int $replaygain
     1448         *
     1449         * @return string
     1450         */
    11621451        public static function RGADgainString($namecode, $originatorcode, $replaygain) {
    11631452                if ($replaygain < 0) {
    11641453                        $signbit = '1';
     
    11741463                return $gainstring;
    11751464        }
    11761465
     1466        /**
     1467         * @param float $amplitude
     1468         *
     1469         * @return float
     1470         */
    11771471        public static function RGADamplitude2dB($amplitude) {
    11781472                return 20 * log10($amplitude);
    11791473        }
    11801474
    1181 
     1475        /**
     1476         * @param string $imgData
     1477         * @param array  $imageinfo
     1478         *
     1479         * @return array|false
     1480         */
    11821481        public static function GetDataImageSize($imgData, &$imageinfo=array()) {
    11831482                static $tempdir = '';
    11841483                if (empty($tempdir)) {
     
    12131512                return $GetDataImageSize;
    12141513        }
    12151514
     1515        /**
     1516         * @param string $mime_type
     1517         *
     1518         * @return string
     1519         */
    12161520        public static function ImageExtFromMime($mime_type) {
    12171521                // temporary way, works OK for now, but should be reworked in the future
    12181522                return str_replace(array('image/', 'x-', 'jpeg'), array('', '', 'jpg'), $mime_type);
    12191523        }
    12201524
    1221         public static function ImageTypesLookup($imagetypeid) {
    1222                 static $ImageTypesLookup = array();
    1223                 if (empty($ImageTypesLookup)) {
    1224                         $ImageTypesLookup[1]  = 'gif';
    1225                         $ImageTypesLookup[2]  = 'jpeg';
    1226                         $ImageTypesLookup[3]  = 'png';
    1227                         $ImageTypesLookup[4]  = 'swf';
    1228                         $ImageTypesLookup[5]  = 'psd';
    1229                         $ImageTypesLookup[6]  = 'bmp';
    1230                         $ImageTypesLookup[7]  = 'tiff (little-endian)';
    1231                         $ImageTypesLookup[8]  = 'tiff (big-endian)';
    1232                         $ImageTypesLookup[9]  = 'jpc';
    1233                         $ImageTypesLookup[10] = 'jp2';
    1234                         $ImageTypesLookup[11] = 'jpx';
    1235                         $ImageTypesLookup[12] = 'jb2';
    1236                         $ImageTypesLookup[13] = 'swc';
    1237                         $ImageTypesLookup[14] = 'iff';
    1238                 }
    1239                 return (isset($ImageTypesLookup[$imagetypeid]) ? $ImageTypesLookup[$imagetypeid] : '');
    1240         }
    1241 
     1525        /**
     1526         * @param array $ThisFileInfo
     1527         *
     1528         * @return bool
     1529         */
    12421530        public static function CopyTagsToComments(&$ThisFileInfo) {
    12431531
    12441532                // Copy all entries from ['tags'] into common ['comments']
     
    13261614                return true;
    13271615        }
    13281616
    1329 
     1617        /**
     1618         * @param string $key
     1619         * @param int    $begin
     1620         * @param int    $end
     1621         * @param string $file
     1622         * @param string $name
     1623         *
     1624         * @return string
     1625         */
    13301626        public static function EmbeddedLookup($key, $begin, $end, $file, $name) {
    13311627
    13321628                // Cached
     
    13731669                return (isset($cache[$file][$name][$key]) ? $cache[$file][$name][$key] : '');
    13741670        }
    13751671
     1672        /**
     1673         * @param string $filename
     1674         * @param string $sourcefile
     1675         * @param bool   $DieOnFailure
     1676         *
     1677         * @return bool
     1678         * @throws Exception
     1679         */
    13761680        public static function IncludeDependency($filename, $sourcefile, $DieOnFailure=false) {
    13771681                global $GETID3_ERRORARRAY;
    13781682
     
    13931697                return false;
    13941698        }
    13951699
     1700        /**
     1701         * @param string $string
     1702         *
     1703         * @return string
     1704         */
    13961705        public static function trimNullByte($string) {
    13971706                return trim($string, "\x00");
    13981707        }
    13991708
     1709        /**
     1710         * @param string $path
     1711         *
     1712         * @return float|bool
     1713         */
    14001714        public static function getFileSizeSyscall($path) {
    14011715                $filesize = false;
    14021716
     
    14211735                return $filesize;
    14221736        }
    14231737
     1738        /**
     1739         * @param string $filename
     1740         *
     1741         * @return string|false
     1742         */
     1743        public static function truepath($filename) {
     1744                // 2017-11-08: this could use some improvement, patches welcome
     1745                if (preg_match('#^(\\\\\\\\|//)[a-z0-9]#i', $filename, $matches)) {
     1746                        // PHP's built-in realpath function does not work on UNC Windows shares
     1747                        $goodpath = array();
     1748                        foreach (explode('/', str_replace('\\', '/', $filename)) as $part) {
     1749                                if ($part == '.') {
     1750                                        continue;
     1751                                }
     1752                                if ($part == '..') {
     1753                                        if (count($goodpath)) {
     1754                                                array_pop($goodpath);
     1755                                        } else {
     1756                                                // cannot step above this level, already at top level
     1757                                                return false;
     1758                                        }
     1759                                } else {
     1760                                        $goodpath[] = $part;
     1761                                }
     1762                        }
     1763                        return implode(DIRECTORY_SEPARATOR, $goodpath);
     1764                }
     1765                return realpath($filename);
     1766        }
    14241767
    14251768        /**
    1426         * Workaround for Bug #37268 (https://bugs.php.net/bug.php?id=37268)
    1427         * @param string $path A path.
    1428         * @param string $suffix If the name component ends in suffix this will also be cut off.
    1429         * @return string
    1430         */
     1769         * Workaround for Bug #37268 (https://bugs.php.net/bug.php?id=37268)
     1770         *
     1771         * @param string $path A path.
     1772         * @param string $suffix If the name component ends in suffix this will also be cut off.
     1773         *
     1774         * @return string
     1775         */
    14311776        public static function mb_basename($path, $suffix = null) {
    14321777                $splited = preg_split('#/#', rtrim($path, '/ '));
    14331778                return substr(basename('X'.$splited[count($splited) - 1], $suffix), 1);
  • src/wp-includes/ID3/getid3.php

     
    11<?php
    22/////////////////////////////////////////////////////////////////
    33/// getID3() by James Heinrich <info@getid3.org>               //
    4 //  available at http://getid3.sourceforge.net                 //
    5 //            or http://www.getid3.org                         //
    6 //          also https://github.com/JamesHeinrich/getID3       //
    7 /////////////////////////////////////////////////////////////////
     4//  available at https://github.com/JamesHeinrich/getID3       //
     5//            or https://www.getid3.org                        //
     6//            or http://getid3.sourceforge.net                 //
    87//                                                             //
    98// Please see readme.txt for more information                  //
    109//                                                            ///
     
    2625        define('ENT_SUBSTITUTE', (defined('ENT_IGNORE') ? ENT_IGNORE : 8));
    2726}
    2827
     28/*
     29https://www.getid3.org/phpBB3/viewtopic.php?t=2114
     30If you are running into a the problem where filenames with special characters are being handled
     31incorrectly by external helper programs (e.g. metaflac), notably with the special characters removed,
     32and you are passing in the filename in UTF8 (typically via a HTML form), try uncommenting this line:
     33*/
     34//setlocale(LC_CTYPE, 'en_US.UTF-8');
     35
    2936// attempt to define temp dir as something flexible but reliable
    3037$temp_dir = ini_get('upload_tmp_dir');
    3138if ($temp_dir && (!is_dir($temp_dir) || !is_readable($temp_dir))) {
     
    7481
    7582class getID3
    7683{
    77         // public: Settings
    78         public $encoding        = 'UTF-8';        // CASE SENSITIVE! - i.e. (must be supported by iconv()). Examples:  ISO-8859-1  UTF-8  UTF-16  UTF-16BE
    79         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'
     84        /*
     85         * Settings
     86         */
    8087
    81         // public: Optional tag checks - disable for speed.
    82         public $option_tag_id3v1         = true;  // Read and process ID3v1 tags
    83         public $option_tag_id3v2         = true;  // Read and process ID3v2 tags
    84         public $option_tag_lyrics3       = true;  // Read and process Lyrics3 tags
    85         public $option_tag_apetag        = true;  // Read and process APE tags
    86         public $option_tags_process      = true;  // Copy tags to root key 'tags' and encode to $this->encoding
    87         public $option_tags_html         = true;  // Copy tags to root key 'tags_html' properly translated from various encodings to HTML entities
     88        /**
     89         * CASE SENSITIVE! - i.e. (must be supported by iconv()). Examples:  ISO-8859-1  UTF-8  UTF-16  UTF-16BE
     90         *
     91         * @var string
     92         */
     93        public $encoding        = 'UTF-8';
    8894
    89         // public: Optional tag/comment calucations
    90         public $option_extra_info        = true;  // Calculate additional info such as bitrate, channelmode etc
     95        /**
     96         * Should always be 'ISO-8859-1', but some tags may be written in other encodings such as 'EUC-CN' or 'CP1252'
     97         *
     98         * @var string
     99         */
     100        public $encoding_id3v1  = 'ISO-8859-1';
    91101
    92         // public: Optional handling of embedded attachments (e.g. images)
    93         public $option_save_attachments  = true; // defaults to true (ATTACHMENTS_INLINE) for backward compatibility
     102        /*
     103         * Optional tag checks - disable for speed.
     104         */
    94105
    95         // public: Optional calculations
    96         public $option_md5_data          = false; // Get MD5 sum of data part - slow
    97         public $option_md5_data_source   = false; // Use MD5 of source file if availble - only FLAC and OptimFROG
    98         public $option_sha1_data         = false; // Get SHA1 sum of data part - slow
    99         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)
     106        /**
     107         * Read and process ID3v1 tags
     108         *
     109         * @var bool
     110         */
     111        public $option_tag_id3v1         = true;
    100112
    101         // public: Read buffer size in bytes
     113        /**
     114         * Read and process ID3v2 tags
     115         *
     116         * @var bool
     117         */
     118        public $option_tag_id3v2         = true;
     119
     120        /**
     121         * Read and process Lyrics3 tags
     122         *
     123         * @var bool
     124         */
     125        public $option_tag_lyrics3       = true;
     126
     127        /**
     128         * Read and process APE tags
     129         *
     130         * @var bool
     131         */
     132        public $option_tag_apetag        = true;
     133
     134        /**
     135         * Copy tags to root key 'tags' and encode to $this->encoding
     136         *
     137         * @var bool
     138         */
     139        public $option_tags_process      = true;
     140
     141        /**
     142         * Copy tags to root key 'tags_html' properly translated from various encodings to HTML entities
     143         *
     144         * @var bool
     145         */
     146        public $option_tags_html         = true;
     147
     148        /*
     149         * Optional tag/comment calculations
     150         */
     151
     152        /**
     153         * Calculate additional info such as bitrate, channelmode etc
     154         *
     155         * @var bool
     156         */
     157        public $option_extra_info        = true;
     158
     159        /*
     160         * Optional handling of embedded attachments (e.g. images)
     161         */
     162
     163        /**
     164         * Defaults to true (ATTACHMENTS_INLINE) for backward compatibility
     165         *
     166         * @var bool|string
     167         */
     168        public $option_save_attachments  = true;
     169
     170        /*
     171         * Optional calculations
     172         */
     173
     174        /**
     175         * Get MD5 sum of data part - slow
     176         *
     177         * @var bool
     178         */
     179        public $option_md5_data          = false;
     180
     181        /**
     182         * Use MD5 of source file if availble - only FLAC and OptimFROG
     183         *
     184         * @var bool
     185         */
     186        public $option_md5_data_source   = false;
     187
     188        /**
     189         * Get SHA1 sum of data part - slow
     190         *
     191         * @var bool
     192         */
     193        public $option_sha1_data         = false;
     194
     195        /**
     196         * Check whether file is larger than 2GB and thus not supported by 32-bit PHP (null: auto-detect based on
     197         * PHP_INT_MAX)
     198         *
     199         * @var bool|null
     200         */
     201        public $option_max_2gb_check;
     202
     203        /**
     204         * Read buffer size in bytes
     205         *
     206         * @var int
     207         */
    102208        public $option_fread_buffer_size = 32768;
    103209
    104210        // Public variables
    105         public $filename;                         // Filename of file being analysed.
    106         public $fp;                               // Filepointer to file being analysed.
    107         public $info;                             // Result array.
     211
     212        /**
     213         * Filename of file being analysed.
     214         *
     215         * @var string
     216         */
     217        public $filename;
     218
     219        /**
     220         * Filepointer to file being analysed.
     221         *
     222         * @var resource
     223         */
     224        public $fp;
     225
     226        /**
     227         * Result array.
     228         *
     229         * @var array
     230         */
     231        public $info;
     232
     233        /**
     234         * @var string
     235         */
    108236        public $tempdir = GETID3_TEMP_DIR;
     237
     238        /**
     239         * @var int
     240         */
    109241        public $memory_limit = 0;
    110242
    111         // Protected variables
     243        /**
     244         * @var string
     245         */
    112246        protected $startup_error   = '';
     247
     248        /**
     249         * @var string
     250         */
    113251        protected $startup_warning = '';
    114252
    115         const VERSION           = '1.9.14-201706111222';
     253        const VERSION           = '1.9.17-201907240906';
    116254        const FREAD_BUFFER_SIZE = 32768;
    117255
    118256        const ATTACHMENTS_NONE   = false;
    119257        const ATTACHMENTS_INLINE = true;
    120258
    121         // public: constructor
    122259        public function __construct() {
    123260
     261                // Check for PHP version
     262                $required_php_version = '5.3.0';
     263                if (version_compare(PHP_VERSION, $required_php_version, '<')) {
     264                        $this->startup_error .= 'getID3() requires PHP v'.$required_php_version.' or higher - you are running v'.PHP_VERSION."\n";
     265                        return;
     266                }
     267
    124268                // Check memory
    125269                $this->memory_limit = ini_get('memory_limit');
    126270                if (preg_match('#([0-9]+) ?M#i', $this->memory_limit, $matches)) {
     
    176320
    177321                // Needed for Windows only:
    178322                // Define locations of helper applications for Shorten, VorbisComment, MetaFLAC
    179                 //   as well as other helper functions such as head, tail, md5sum, etc
     323                //   as well as other helper functions such as head, etc
    180324                // This path cannot contain spaces, but the below code will attempt to get the
    181325                //   8.3-equivalent path automatically
    182326                // IMPORTANT: This path must include the trailing slash
     
    219363                        echo $this->startup_error;
    220364                        throw new getid3_exception($this->startup_error);
    221365                }
    222 
    223                 return true;
    224366        }
    225367
     368        /**
     369         * @return string
     370         */
    226371        public function version() {
    227372                return self::VERSION;
    228373        }
    229374
     375        /**
     376         * @return int
     377         */
    230378        public function fread_buffer_size() {
    231379                return $this->option_fread_buffer_size;
    232380        }
    233381
    234 
    235         // public: setOption
     382        /**
     383         * @param array $optArray
     384         *
     385         * @return bool
     386         */
    236387        public function setOption($optArray) {
    237388                if (!is_array($optArray) || empty($optArray)) {
    238389                        return false;
     
    246397                return true;
    247398        }
    248399
    249 
    250         public function openfile($filename, $filesize=null) {
     400        /**
     401         * @param string $filename
     402         * @param int    $filesize
     403         *
     404         * @return bool
     405         *
     406         * @throws getid3_exception
     407         */
     408        public function openfile($filename, $filesize=null, $fp=null) {
    251409                try {
    252410                        if (!empty($this->startup_error)) {
    253411                                throw new getid3_exception($this->startup_error);
     
    270428                        }
    271429
    272430                        $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename);
    273                         $filename = preg_replace('#(?<!gs:)('.preg_quote(DIRECTORY_SEPARATOR).'{2,})#', DIRECTORY_SEPARATOR, $filename);
     431                        //$filename = preg_replace('#(?<!gs:)('.preg_quote(DIRECTORY_SEPARATOR).'{2,})#', DIRECTORY_SEPARATOR, $filename);
    274432
    275433                        // open local file
    276                         //if (is_readable($filename) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) { // see http://www.getid3.org/phpBB3/viewtopic.php?t=1720
    277                         if ((is_readable($filename) || file_exists($filename)) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) {
     434                        //if (is_readable($filename) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) { // see https://www.getid3.org/phpBB3/viewtopic.php?t=1720
     435                        if (($fp != null) && ((get_resource_type($fp) == 'file') || (get_resource_type($fp) == 'stream'))) {
     436                                $this->fp = $fp;
     437                        } elseif ((is_readable($filename) || file_exists($filename)) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) {
    278438                                // great
    279439                        } else {
    280440                                $errormessagelist = array();
     
    331491                                                } elseif (getid3_lib::intValueSupported($real_filesize)) {
    332492                                                        unset($this->info['filesize']);
    333493                                                        fclose($this->fp);
    334                                                         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');
     494                                                        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 / 1073741824, 3).'GB, please report to info@getid3.org');
    335495                                                }
    336496                                                $this->info['filesize'] = $real_filesize;
    337                                                 $this->warning('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.');
     497                                                $this->warning('File is larger than '.round(PHP_INT_MAX / 1073741824).'GB (filesystem reports it as '.number_format($real_filesize / 1073741824, 3).'GB) and is not properly supported by PHP.');
    338498                                }
    339499                        }
    340500
     
    346506                return false;
    347507        }
    348508
    349         // public: analyze file
    350         public function analyze($filename, $filesize=null, $original_filename='') {
     509        /**
     510         * analyze file
     511         *
     512         * @param string $filename
     513         * @param int    $filesize
     514         * @param string $original_filename
     515         *
     516         * @return array
     517         */
     518        public function analyze($filename, $filesize=null, $original_filename='', $fp=null) {
    351519                try {
    352                         if (!$this->openfile($filename, $filesize)) {
     520                        if (!$this->openfile($filename, $filesize, $fp)) {
    353521                                return $this->info;
    354522                        }
    355523
     
    383551                                $header = fread($this->fp, 10);
    384552                                if ((substr($header, 0, 3) == 'ID3') && (strlen($header) == 10)) {
    385553                                        $this->info['id3v2']['header']        = true;
    386                                         $this->info['id3v2']['majorversion']  = ord($header{3});
    387                                         $this->info['id3v2']['minorversion']  = ord($header{4});
     554                                        $this->info['id3v2']['majorversion']  = ord($header[3]);
     555                                        $this->info['id3v2']['minorversion']  = ord($header[4]);
    388556                                        $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
    389557                                }
    390558                        }
     
    497665        }
    498666
    499667
    500         // private: error handling
     668        /**
     669         * Error handling.
     670         *
     671         * @param string $message
     672         *
     673         * @return array
     674         */
    501675        public function error($message) {
    502676                $this->CleanUp();
    503677                if (!isset($this->info['error'])) {
     
    508682        }
    509683
    510684
    511         // private: warning handling
     685        /**
     686         * Warning handling.
     687         *
     688         * @param string $message
     689         *
     690         * @return bool
     691         */
    512692        public function warning($message) {
    513693                $this->info['warning'][] = $message;
    514694                return true;
     
    515695        }
    516696
    517697
    518         // private: CleanUp
     698        /**
     699         * @return bool
     700         */
    519701        private function CleanUp() {
    520702
    521703                // remove possible empty keys
     
    562744                return true;
    563745        }
    564746
    565 
    566         // return array containing information about all supported formats
     747        /**
     748         * Return array containing information about all supported formats.
     749         *
     750         * @return array
     751         */
    567752        public function GetFileFormatArray() {
    568753                static $format_info = array();
    569754                if (empty($format_info)) {
     
    584769                                                        'pattern'   => '^ADIF',
    585770                                                        'group'     => 'audio',
    586771                                                        'module'    => 'aac',
    587                                                         'mime_type' => 'application/octet-stream',
     772                                                        'mime_type' => 'audio/aac',
    588773                                                        'fail_ape'  => 'WARNING',
    589774                                                ),
    590775
     
    602787                                                        'pattern'   => '^\\xFF[\\xF0-\\xF1\\xF8-\\xF9]',
    603788                                                        'group'     => 'audio',
    604789                                                        'module'    => 'aac',
    605                                                         'mime_type' => 'application/octet-stream',
     790                                                        'mime_type' => 'audio/aac',
    606791                                                        'fail_ape'  => 'WARNING',
    607792                                                ),
    608793
     
    649834
    650835                                // DSS  - audio       - Digital Speech Standard
    651836                                'dss'  => array(
    652                                                         'pattern'   => '^[\\x02-\\x06]ds[s2]',
     837                                                        'pattern'   => '^[\\x02-\\x08]ds[s2]',
    653838                                                        'group'     => 'audio',
    654839                                                        'module'    => 'dss',
    655840                                                        'mime_type' => 'application/octet-stream',
     
    668853                                                        'pattern'   => '^fLaC',
    669854                                                        'group'     => 'audio',
    670855                                                        'module'    => 'flac',
    671                                                         'mime_type' => 'audio/x-flac',
     856                                                        'mime_type' => 'audio/flac',
    672857                                                ),
    673858
    674859                                // LA   - audio       - Lossless Audio (LA)
     
    700885                                                        'pattern'   => '^MAC ',
    701886                                                        'group'     => 'audio',
    702887                                                        'module'    => 'monkey',
    703                                                         'mime_type' => 'application/octet-stream',
     888                                                        'mime_type' => 'audio/x-monkeys-audio',
    704889                                                ),
    705890
    706891// has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available
     
    8891074                                                        'pattern'   => '^(RIFF|SDSS|FORM)',
    8901075                                                        'group'     => 'audio-video',
    8911076                                                        'module'    => 'riff',
    892                                                         'mime_type' => 'audio/x-wav',
     1077                                                        'mime_type' => 'audio/wav',
    8931078                                                        'fail_ape'  => 'WARNING',
    8941079                                                ),
    8951080
     
    10531238                                                        'pattern'   => '^\\x1F\\x8B\\x08',
    10541239                                                        'group'     => 'archive',
    10551240                                                        'module'    => 'gzip',
    1056                                                         'mime_type' => 'application/x-gzip',
     1241                                                        'mime_type' => 'application/gzip',
    10571242                                                        'fail_id3'  => 'ERROR',
    10581243                                                        'fail_ape'  => 'ERROR',
    10591244                                                ),
     
    10681253                                                        'fail_ape'  => 'ERROR',
    10691254                                                ),
    10701255
     1256                                // XZ   - data         - XZ compressed data
     1257                                'xz'  => array(
     1258                                                        'pattern'   => '^\\xFD7zXZ\\x00',
     1259                                                        'group'     => 'archive',
     1260                                                        'module'    => 'xz',
     1261                                                        'mime_type' => 'application/x-xz',
     1262                                                        'fail_id3'  => 'ERROR',
     1263                                                        'fail_ape'  => 'ERROR',
     1264                                                ),
    10711265
     1266
    10721267                                // Misc other formats
    10731268
    10741269                                // PAR2 - data        - Parity Volume Set Specification 2.0
     
    11151310                return $format_info;
    11161311        }
    11171312
    1118 
    1119 
     1313        /**
     1314         * @param string $filedata
     1315         * @param string $filename
     1316         *
     1317         * @return mixed|false
     1318         */
    11201319        public function GetFileFormat(&$filedata, $filename='') {
    11211320                // this function will determine the format of a file based on usually
    11221321                // the first 2-4 bytes of the file (8 bytes for PNG, 16 bytes for JPG,
     
    11351334
    11361335
    11371336                if (preg_match('#\\.mp[123a]$#i', $filename)) {
    1138                         // Too many mp3 encoders on the market put gabage in front of mpeg files
     1337                        // Too many mp3 encoders on the market put garbage in front of mpeg files
    11391338                        // use assume format on these if format detection failed
    11401339                        $GetFileFormatArray = $this->GetFileFormatArray();
    11411340                        $info = $GetFileFormatArray['mp3'];
     
    11541353                return false;
    11551354        }
    11561355
    1157 
    1158         // converts array to $encoding charset from $this->encoding
     1356        /**
     1357         * Converts array to $encoding charset from $this->encoding.
     1358         *
     1359         * @param array  $array
     1360         * @param string $encoding
     1361         */
    11591362        public function CharConvert(&$array, $encoding) {
    11601363
    11611364                // identical encoding - end here
     
    11781381                }
    11791382        }
    11801383
    1181 
     1384        /**
     1385         * @return bool
     1386         */
    11821387        public function HandleAllTags() {
    11831388
    11841389                // key name => array (tag name, character encoding)
     
    12331438                                                }
    12341439                                        }
    12351440                                        if ($tag_key == 'picture') {
     1441                                                // pictures can take up a lot of space, and we don't need multiple copies of them; let there be a single copy in [comments][picture], and not elsewhere
    12361442                                                unset($this->info[$comment_name]['comments'][$tag_key]);
    12371443                                        }
    12381444                                }
     
    12461452
    12471453                                if ($this->option_tags_html) {
    12481454                                        foreach ($this->info['tags'][$tag_name] as $tag_key => $valuearray) {
     1455                                                if ($tag_key == 'picture') {
     1456                                                        // Do not to try to convert binary picture data to HTML
     1457                                                        // https://github.com/JamesHeinrich/getID3/issues/178
     1458                                                        continue;
     1459                                                }
    12491460                                                $this->info['tags_html'][$tag_name][$tag_key] = getid3_lib::recursiveMultiByteCharString2HTML($valuearray, $this->info[$comment_name]['encoding']);
    12501461                                        }
    12511462                                }
     
    12541465
    12551466                }
    12561467
    1257                 // pictures can take up a lot of space, and we don't need multiple copies of them
    1258                 // let there be a single copy in [comments][picture], and not elsewhere
     1468                // pictures can take up a lot of space, and we don't need multiple copies of them; let there be a single copy in [comments][picture], and not elsewhere
    12591469                if (!empty($this->info['tags'])) {
    12601470                        $unset_keys = array('tags', 'tags_html');
    12611471                        foreach ($this->info['tags'] as $tagtype => $tagarray) {
     
    13011511                return true;
    13021512        }
    13031513
     1514        /**
     1515         * @param string $algorithm
     1516         *
     1517         * @return array|bool
     1518         */
    13041519        public function getHashdata($algorithm) {
    13051520                switch ($algorithm) {
    13061521                        case 'md5':
     
    13651580
    13661581                                } else {
    13671582
    1368                                         $commandline = 'vorbiscomment -w -c "'.$empty.'" "'.$file.'" "'.$temp.'" 2>&1';
    13691583                                        $commandline = 'vorbiscomment -w -c '.escapeshellarg($empty).' '.escapeshellarg($file).' '.escapeshellarg($temp).' 2>&1';
    13701584                                        $VorbisCommentError = `$commandline`;
    13711585
     
    14241638                return true;
    14251639        }
    14261640
    1427 
    14281641        public function ChannelsBitratePlaytimeCalculations() {
    14291642
    14301643                // set channelmode on audio
     
    14891702                }
    14901703        }
    14911704
    1492 
     1705        /**
     1706         * @return bool
     1707         */
    14931708        public function CalculateCompressionRatioVideo() {
    14941709                if (empty($this->info['video'])) {
    14951710                        return false;
     
    15371752                return true;
    15381753        }
    15391754
    1540 
     1755        /**
     1756         * @return bool
     1757         */
    15411758        public function CalculateCompressionRatioAudio() {
    15421759                if (empty($this->info['audio']['bitrate']) || empty($this->info['audio']['channels']) || empty($this->info['audio']['sample_rate']) || !is_numeric($this->info['audio']['sample_rate'])) {
    15431760                        return false;
     
    15541771                return true;
    15551772        }
    15561773
    1557 
     1774        /**
     1775         * @return bool
     1776         */
    15581777        public function CalculateReplayGain() {
    15591778                if (isset($this->info['replay_gain'])) {
    15601779                        if (!isset($this->info['replay_gain']['reference_volume'])) {
    1561                                 $this->info['replay_gain']['reference_volume'] = (double) 89.0;
     1780                                $this->info['replay_gain']['reference_volume'] = 89.0;
    15621781                        }
    15631782                        if (isset($this->info['replay_gain']['track']['adjustment'])) {
    15641783                                $this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment'];
     
    15771796                return true;
    15781797        }
    15791798
     1799        /**
     1800         * @return bool
     1801         */
    15801802        public function ProcessAudioStreams() {
    15811803                if (!empty($this->info['audio']['bitrate']) || !empty($this->info['audio']['channels']) || !empty($this->info['audio']['sample_rate'])) {
    15821804                        if (!isset($this->info['audio']['streams'])) {
     
    15901812                return true;
    15911813        }
    15921814
     1815        /**
     1816         * @return string|bool
     1817         */
    15931818        public function getid3_tempnam() {
    15941819                return tempnam($this->tempdir, 'gI3');
    15951820        }
    15961821
     1822        /**
     1823         * @param string $name
     1824         *
     1825         * @return bool
     1826         *
     1827         * @throws getid3_exception
     1828         */
    15971829        public function include_module($name) {
    15981830                //if (!file_exists($this->include_path.'module.'.$name.'.php')) {
    15991831                if (!file_exists(GETID3_INCLUDEPATH.'module.'.$name.'.php')) {
     
    16031835                return true;
    16041836        }
    16051837
    1606     public static function is_writable ($filename) {
    1607         $ret = is_writable($filename);
     1838        /**
     1839         * @param string $filename
     1840         *
     1841         * @return bool
     1842         */
     1843        public static function is_writable ($filename) {
     1844                $ret = is_writable($filename);
     1845                if (!$ret) {
     1846                        $perms = fileperms($filename);
     1847                        $ret = ($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002);
     1848                }
     1849                return $ret;
     1850        }
    16081851
    1609         if (!$ret) {
    1610             $perms = fileperms($filename);
    1611             $ret = ($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002);
    1612         }
    1613 
    1614         return $ret;
    1615     }
    1616 
    16171852}
    16181853
    16191854
    1620 abstract class getid3_handler {
     1855abstract class getid3_handler
     1856{
    16211857
    16221858        /**
    16231859        * @var getID3
     
    16241860        */
    16251861        protected $getid3;                       // pointer
    16261862
    1627         protected $data_string_flag     = false; // analyzing filepointer or string
    1628         protected $data_string          = '';    // string to analyze
    1629         protected $data_string_position = 0;     // seek position in string
    1630         protected $data_string_length   = 0;     // string length
     1863        /**
     1864         * Analyzing filepointer or string.
     1865         *
     1866         * @var bool
     1867         */
     1868        protected $data_string_flag     = false;
    16311869
    1632         private $dependency_to = null;
     1870        /**
     1871         * String to analyze.
     1872         *
     1873         * @var string
     1874         */
     1875        protected $data_string          = '';
    16331876
     1877        /**
     1878         * Seek position in string.
     1879         *
     1880         * @var int
     1881         */
     1882        protected $data_string_position = 0;
    16341883
     1884        /**
     1885         * String length.
     1886         *
     1887         * @var int
     1888         */
     1889        protected $data_string_length   = 0;
     1890
     1891        /**
     1892         * @var string
     1893         */
     1894        private $dependency_to;
     1895
     1896        /**
     1897         * getid3_handler constructor.
     1898         *
     1899         * @param getID3 $getid3
     1900         * @param string $call_module
     1901         */
    16351902        public function __construct(getID3 $getid3, $call_module=null) {
    16361903                $this->getid3 = $getid3;
    16371904
     
    16401907                }
    16411908        }
    16421909
    1643 
    1644         // Analyze from file pointer
     1910        /**
     1911         * Analyze from file pointer.
     1912         *
     1913         * @return bool
     1914         */
    16451915        abstract public function Analyze();
    16461916
    1647 
    1648         // Analyze from string instead
     1917        /**
     1918         * Analyze from string instead.
     1919         *
     1920         * @param string $string
     1921         */
    16491922        public function AnalyzeString($string) {
    16501923                // Enter string mode
    16511924                $this->setStringMode($string);
     
    16711944                $this->data_string_flag = false;
    16721945        }
    16731946
     1947        /**
     1948         * @param string $string
     1949         */
    16741950        public function setStringMode($string) {
    16751951                $this->data_string_flag   = true;
    16761952                $this->data_string        = $string;
     
    16771953                $this->data_string_length = strlen($string);
    16781954        }
    16791955
     1956        /**
     1957         * @return int|bool
     1958         */
    16801959        protected function ftell() {
    16811960                if ($this->data_string_flag) {
    16821961                        return $this->data_string_position;
     
    16841963                return ftell($this->getid3->fp);
    16851964        }
    16861965
     1966        /**
     1967         * @param int $bytes
     1968         *
     1969         * @return string|false
     1970         *
     1971         * @throws getid3_exception
     1972         */
    16871973        protected function fread($bytes) {
    16881974                if ($this->data_string_flag) {
    16891975                        $this->data_string_position += $bytes;
     
    16961982
    16971983                //return fread($this->getid3->fp, $bytes);
    16981984                /*
    1699                 * http://www.getid3.org/phpBB3/viewtopic.php?t=1930
     1985                * https://www.getid3.org/phpBB3/viewtopic.php?t=1930
    17001986                * "I found out that the root cause for the problem was how getID3 uses the PHP system function fread().
    17011987                * It seems to assume that fread() would always return as many bytes as were requested.
    17021988                * However, according the PHP manual (http://php.net/manual/en/function.fread.php), this is the case only with regular local files, but not e.g. with Linux pipes.
     
    17041990                */
    17051991                $contents = '';
    17061992                do {
     1993                        //if (($this->getid3->memory_limit > 0) && ($bytes > $this->getid3->memory_limit)) {
     1994                        if (($this->getid3->memory_limit > 0) && (($bytes / $this->getid3->memory_limit) > 0.99)) { // enable a more-fuzzy match to prevent close misses generating errors like "PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 33554464 bytes)"
     1995                                throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().') that is more than available PHP memory ('.$this->getid3->memory_limit.')', 10);
     1996                        }
    17071997                        $part = fread($this->getid3->fp, $bytes);
    17081998                        $partLength  = strlen($part);
    17091999                        $bytes      -= $partLength;
     
    17122002                return $contents;
    17132003        }
    17142004
     2005        /**
     2006         * @param int $bytes
     2007         * @param int $whence
     2008         *
     2009         * @return int
     2010         *
     2011         * @throws getid3_exception
     2012         */
    17152013        protected function fseek($bytes, $whence=SEEK_SET) {
    17162014                if ($this->data_string_flag) {
    17172015                        switch ($whence) {
     
    17422040                return fseek($this->getid3->fp, $bytes, $whence);
    17432041        }
    17442042
     2043        /**
     2044         * @return bool
     2045         */
    17452046        protected function feof() {
    17462047                if ($this->data_string_flag) {
    17472048                        return $this->data_string_position >= $this->data_string_length;
     
    17492050                return feof($this->getid3->fp);
    17502051        }
    17512052
     2053        /**
     2054         * @param string $module
     2055         *
     2056         * @return bool
     2057         */
    17522058        final protected function isDependencyFor($module) {
    17532059                return $this->dependency_to == $module;
    17542060        }
    17552061
     2062        /**
     2063         * @param string $text
     2064         *
     2065         * @return bool
     2066         */
    17562067        protected function error($text) {
    17572068                $this->getid3->info['error'][] = $text;
    17582069
     
    17592070                return false;
    17602071        }
    17612072
     2073        /**
     2074         * @param string $text
     2075         *
     2076         * @return bool
     2077         */
    17622078        protected function warning($text) {
    17632079                return $this->getid3->warning($text);
    17642080        }
    17652081
     2082        /**
     2083         * @param string $text
     2084         */
    17662085        protected function notice($text) {
    17672086                // does nothing for now
    17682087        }
    17692088
     2089        /**
     2090         * @param string $name
     2091         * @param int    $offset
     2092         * @param int    $length
     2093         * @param string $image_mime
     2094         *
     2095         * @return string|null
     2096         *
     2097         * @throws Exception
     2098         * @throws getid3_exception
     2099         */
    17702100        public function saveAttachment($name, $offset, $length, $image_mime=null) {
    17712101                try {
    17722102
     
    18202150                        // close and remove dest file if created
    18212151                        if (isset($fp_dest) && is_resource($fp_dest)) {
    18222152                                fclose($fp_dest);
     2153                        }
     2154
     2155                        if (isset($dest) && file_exists($dest)) {
    18232156                                unlink($dest);
    18242157                        }
    18252158
  • src/wp-includes/ID3/license.txt

     
    11/////////////////////////////////////////////////////////////////
    22/// getID3() by James Heinrich <info@getid3.org>               //
    33//  available at http://getid3.sourceforge.net                 //
    4 //            or http://www.getid3.org                         //
     4//            or https://www.getid3.org                        //
    55//          also https://github.com/JamesHeinrich/getID3       //
    66/////////////////////////////////////////////////////////////////
    77
     
    1818
    1919GNU LGPL: https://gnu.org/licenses/lgpl.html                 (v3)
    2020
    21 Mozilla MPL: http://www.mozilla.org/MPL/2.0/                 (v2)
     21Mozilla MPL: https://www.mozilla.org/MPL/2.0/                (v2)
    2222
    23 getID3 Commercial License: http://getid3.org/#gCL (payment required)
     23getID3 Commercial License: https://www.getid3.org/#gCL (payment required)
    2424
    2525*****************************************************************
    2626*****************************************************************
  • src/wp-includes/ID3/module.audio-video.asf.php

     
    11<?php
    22/////////////////////////////////////////////////////////////////
    33/// getID3() by James Heinrich <info@getid3.org>               //
    4 //  available at http://getid3.sourceforge.net                 //
    5 //            or http://www.getid3.org                         //
    6 //          also https://github.com/JamesHeinrich/getID3       //
     4//  available at https://github.com/JamesHeinrich/getID3       //
     5//            or https://www.getid3.org                        //
     6//            or http://getid3.sourceforge.net                 //
     7//  see readme.txt for more details                            //
    78/////////////////////////////////////////////////////////////////
    8 // See readme.txt for more details                             //
    9 /////////////////////////////////////////////////////////////////
    109//                                                             //
    1110// module.audio-video.asf.php                                  //
    1211// module for analyzing ASF, WMA and WMV files                 //
     
    1615
    1716getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
    1817
    19 class getid3_asf extends getid3_handler {
    20 
     18class getid3_asf extends getid3_handler
     19{
     20        /**
     21         * @param getID3 $getid3
     22         */
    2123        public function __construct(getID3 $getid3) {
    2224                parent::__construct($getid3);  // extends getid3_handler::__construct()
    2325
     
    3032                }
    3133        }
    3234
     35        /**
     36         * @return bool
     37         */
    3338        public function Analyze() {
    3439                $info = &$this->getid3->info;
    3540
     
    8388                $NextObjectOffset = $this->ftell();
    8489                $ASFHeaderData = $this->fread($thisfile_asf_headerobject['objectsize'] - 30);
    8590                $offset = 0;
     91                $thisfile_asf_streambitratepropertiesobject = array();
     92                $thisfile_asf_codeclistobject = array();
    8693
    8794                for ($HeaderObjectsCounter = 0; $HeaderObjectsCounter < $thisfile_asf_headerobject['headerobjects']; $HeaderObjectsCounter++) {
    8895                        $NextObjectGUID = substr($ASFHeaderData, $offset, 16);
     
    790797                                                        case 'wm/tracknumber':
    791798                                                        case 'tracknumber':
    792799                                                                // be careful casting to int: casting unicode strings to int gives unexpected results (stops parsing at first non-numeric character)
    793                                                                 $thisfile_asf_comments['track'] = array($this->TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
    794                                                                 foreach ($thisfile_asf_comments['track'] as $key => $value) {
     800                                                                $thisfile_asf_comments['track_number'] = array($this->TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
     801                                                                foreach ($thisfile_asf_comments['track_number'] as $key => $value) {
    795802                                                                        if (preg_match('/^[0-9\x00]+$/', $value)) {
    796                                                                                 $thisfile_asf_comments['track'][$key] = intval(str_replace("\x00", '', $value));
     803                                                                                $thisfile_asf_comments['track_number'][$key] = intval(str_replace("\x00", '', $value));
    797804                                                                        }
    798805                                                                }
    799806                                                                break;
    800807
    801808                                                        case 'wm/track':
    802                                                                 if (empty($thisfile_asf_comments['track'])) {
    803                                                                         $thisfile_asf_comments['track'] = array(1 + $this->TrimConvert($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
     809                                                                if (empty($thisfile_asf_comments['track_number'])) {
     810                                                                        $thisfile_asf_comments['track_number'] = array(1 + $this->TrimConvert($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
    804811                                                                }
    805812                                                                break;
    806813
     
    970977                                        break;
    971978                        }
    972979                }
    973                 if (isset($thisfile_asf_streambitrateproperties['bitrate_records_count'])) {
     980                if (isset($thisfile_asf_streambitratepropertiesobject['bitrate_records_count'])) {
    974981                        $ASFbitrateAudio = 0;
    975982                        $ASFbitrateVideo = 0;
    976                         for ($BitrateRecordsCounter = 0; $BitrateRecordsCounter < $thisfile_asf_streambitrateproperties['bitrate_records_count']; $BitrateRecordsCounter++) {
     983                        for ($BitrateRecordsCounter = 0; $BitrateRecordsCounter < $thisfile_asf_streambitratepropertiesobject['bitrate_records_count']; $BitrateRecordsCounter++) {
    977984                                if (isset($thisfile_asf_codeclistobject['codec_entries'][$BitrateRecordsCounter])) {
    978985                                        switch ($thisfile_asf_codeclistobject['codec_entries'][$BitrateRecordsCounter]['type_raw']) {
    979986                                                case 1:
    980                                                         $ASFbitrateVideo += $thisfile_asf_streambitrateproperties['bitrate_records'][$BitrateRecordsCounter]['bitrate'];
     987                                                        $ASFbitrateVideo += $thisfile_asf_streambitratepropertiesobject['bitrate_records'][$BitrateRecordsCounter]['bitrate'];
    981988                                                        break;
    982989
    983990                                                case 2:
    984                                                         $ASFbitrateAudio += $thisfile_asf_streambitrateproperties['bitrate_records'][$BitrateRecordsCounter]['bitrate'];
     991                                                        $ASFbitrateAudio += $thisfile_asf_streambitratepropertiesobject['bitrate_records'][$BitrateRecordsCounter]['bitrate'];
    985992                                                        break;
    986993
    987994                                                default:
     
    14401447                return true;
    14411448        }
    14421449
     1450        /**
     1451         * @param int $CodecListType
     1452         *
     1453         * @return string
     1454         */
    14431455        public static function codecListObjectTypeLookup($CodecListType) {
    14441456                static $lookup = array(
    14451457                        0x0001 => 'Video Codec',
     
    14501462                return (isset($lookup[$CodecListType]) ? $lookup[$CodecListType] : 'Invalid Codec Type');
    14511463        }
    14521464
     1465        /**
     1466         * @return array
     1467         */
    14531468        public static function KnownGUIDs() {
    14541469                static $GUIDarray = array(
    14551470                        'GETID3_ASF_Extended_Stream_Properties_Object'   => '14E6A5CB-C672-4332-8399-A96952065B5A',
     
    15641579                return $GUIDarray;
    15651580        }
    15661581
     1582        /**
     1583         * @param string $GUIDstring
     1584         *
     1585         * @return string|false
     1586         */
    15671587        public static function GUIDname($GUIDstring) {
    15681588                static $GUIDarray = array();
    15691589                if (empty($GUIDarray)) {
     
    15721592                return array_search($GUIDstring, $GUIDarray);
    15731593        }
    15741594
     1595        /**
     1596         * @param int $id
     1597         *
     1598         * @return string
     1599         */
    15751600        public static function ASFIndexObjectIndexTypeLookup($id) {
    15761601                static $ASFIndexObjectIndexTypeLookup = array();
    15771602                if (empty($ASFIndexObjectIndexTypeLookup)) {
     
    15821607                return (isset($ASFIndexObjectIndexTypeLookup[$id]) ? $ASFIndexObjectIndexTypeLookup[$id] : 'invalid');
    15831608        }
    15841609
     1610        /**
     1611         * @param string $GUIDstring
     1612         *
     1613         * @return string
     1614         */
    15851615        public static function GUIDtoBytestring($GUIDstring) {
    15861616                // Microsoft defines these 16-byte (128-bit) GUIDs in the strangest way:
    15871617                // first 4 bytes are in little-endian order
     
    16171647                return $hexbytecharstring;
    16181648        }
    16191649
     1650        /**
     1651         * @param string $Bytestring
     1652         *
     1653         * @return string
     1654         */
    16201655        public static function BytestringToGUID($Bytestring) {
    1621                 $GUIDstring  = str_pad(dechex(ord($Bytestring{3})),  2, '0', STR_PAD_LEFT);
    1622                 $GUIDstring .= str_pad(dechex(ord($Bytestring{2})),  2, '0', STR_PAD_LEFT);
    1623                 $GUIDstring .= str_pad(dechex(ord($Bytestring{1})),  2, '0', STR_PAD_LEFT);
    1624                 $GUIDstring .= str_pad(dechex(ord($Bytestring{0})),  2, '0', STR_PAD_LEFT);
     1656                $GUIDstring  = str_pad(dechex(ord($Bytestring[3])),  2, '0', STR_PAD_LEFT);
     1657                $GUIDstring .= str_pad(dechex(ord($Bytestring[2])),  2, '0', STR_PAD_LEFT);
     1658                $GUIDstring .= str_pad(dechex(ord($Bytestring[1])),  2, '0', STR_PAD_LEFT);
     1659                $GUIDstring .= str_pad(dechex(ord($Bytestring[0])),  2, '0', STR_PAD_LEFT);
    16251660                $GUIDstring .= '-';
    1626                 $GUIDstring .= str_pad(dechex(ord($Bytestring{5})),  2, '0', STR_PAD_LEFT);
    1627                 $GUIDstring .= str_pad(dechex(ord($Bytestring{4})),  2, '0', STR_PAD_LEFT);
     1661                $GUIDstring .= str_pad(dechex(ord($Bytestring[5])),  2, '0', STR_PAD_LEFT);
     1662                $GUIDstring .= str_pad(dechex(ord($Bytestring[4])),  2, '0', STR_PAD_LEFT);
    16281663                $GUIDstring .= '-';
    1629                 $GUIDstring .= str_pad(dechex(ord($Bytestring{7})),  2, '0', STR_PAD_LEFT);
    1630                 $GUIDstring .= str_pad(dechex(ord($Bytestring{6})),  2, '0', STR_PAD_LEFT);
     1664                $GUIDstring .= str_pad(dechex(ord($Bytestring[7])),  2, '0', STR_PAD_LEFT);
     1665                $GUIDstring .= str_pad(dechex(ord($Bytestring[6])),  2, '0', STR_PAD_LEFT);
    16311666                $GUIDstring .= '-';
    1632                 $GUIDstring .= str_pad(dechex(ord($Bytestring{8})),  2, '0', STR_PAD_LEFT);
    1633                 $GUIDstring .= str_pad(dechex(ord($Bytestring{9})),  2, '0', STR_PAD_LEFT);
     1667                $GUIDstring .= str_pad(dechex(ord($Bytestring[8])),  2, '0', STR_PAD_LEFT);
     1668                $GUIDstring .= str_pad(dechex(ord($Bytestring[9])),  2, '0', STR_PAD_LEFT);
    16341669                $GUIDstring .= '-';
    1635                 $GUIDstring .= str_pad(dechex(ord($Bytestring{10})), 2, '0', STR_PAD_LEFT);
    1636                 $GUIDstring .= str_pad(dechex(ord($Bytestring{11})), 2, '0', STR_PAD_LEFT);
    1637                 $GUIDstring .= str_pad(dechex(ord($Bytestring{12})), 2, '0', STR_PAD_LEFT);
    1638                 $GUIDstring .= str_pad(dechex(ord($Bytestring{13})), 2, '0', STR_PAD_LEFT);
    1639                 $GUIDstring .= str_pad(dechex(ord($Bytestring{14})), 2, '0', STR_PAD_LEFT);
    1640                 $GUIDstring .= str_pad(dechex(ord($Bytestring{15})), 2, '0', STR_PAD_LEFT);
     1670                $GUIDstring .= str_pad(dechex(ord($Bytestring[10])), 2, '0', STR_PAD_LEFT);
     1671                $GUIDstring .= str_pad(dechex(ord($Bytestring[11])), 2, '0', STR_PAD_LEFT);
     1672                $GUIDstring .= str_pad(dechex(ord($Bytestring[12])), 2, '0', STR_PAD_LEFT);
     1673                $GUIDstring .= str_pad(dechex(ord($Bytestring[13])), 2, '0', STR_PAD_LEFT);
     1674                $GUIDstring .= str_pad(dechex(ord($Bytestring[14])), 2, '0', STR_PAD_LEFT);
     1675                $GUIDstring .= str_pad(dechex(ord($Bytestring[15])), 2, '0', STR_PAD_LEFT);
    16411676
    16421677                return strtoupper($GUIDstring);
    16431678        }
    16441679
     1680        /**
     1681         * @param int  $FILETIME
     1682         * @param bool $round
     1683         *
     1684         * @return float|int
     1685         */
    16451686        public static function FILETIMEtoUNIXtime($FILETIME, $round=true) {
    16461687                // FILETIME is a 64-bit unsigned integer representing
    16471688                // the number of 100-nanosecond intervals since January 1, 1601
     
    16531694                return ($FILETIME - 116444736000000000) / 10000000;
    16541695        }
    16551696
     1697        /**
     1698         * @param int $WMpictureType
     1699         *
     1700         * @return string
     1701         */
    16561702        public static function WMpictureTypeLookup($WMpictureType) {
    16571703                static $lookup = null;
    16581704                if ($lookup === null) {
     
    16841730                return (isset($lookup[$WMpictureType]) ? $lookup[$WMpictureType] : '');
    16851731        }
    16861732
     1733        /**
     1734         * @param string $asf_header_extension_object_data
     1735         * @param int    $unhandled_sections
     1736         *
     1737         * @return array
     1738         */
    16871739        public function HeaderExtensionObjectDataParse(&$asf_header_extension_object_data, &$unhandled_sections) {
    16881740                // http://msdn.microsoft.com/en-us/library/bb643323.aspx
    16891741
     
    19301982                return $HeaderExtensionObjectParsed;
    19311983        }
    19321984
    1933 
     1985        /**
     1986         * @param int $id
     1987         *
     1988         * @return string
     1989         */
    19341990        public static function metadataLibraryObjectDataTypeLookup($id) {
    19351991                static $lookup = array(
    19361992                        0x0000 => 'Unicode string', // The data consists of a sequence of Unicode characters
     
    19442000                return (isset($lookup[$id]) ? $lookup[$id] : 'invalid');
    19452001        }
    19462002
     2003        /**
     2004         * @param string $data
     2005         *
     2006         * @return array
     2007         */
    19472008        public function ASF_WMpicture(&$data) {
    19482009                //typedef struct _WMPicture{
    19492010                //  LPWSTR  pwszMIMEType;
     
    19942055                return $WMpicture;
    19952056        }
    19962057
    1997 
    1998         // Remove terminator 00 00 and convert UTF-16LE to Latin-1
     2058        /**
     2059         * Remove terminator 00 00 and convert UTF-16LE to Latin-1.
     2060         *
     2061         * @param string $string
     2062         *
     2063         * @return string
     2064         */
    19992065        public static function TrimConvert($string) {
    20002066                return trim(getid3_lib::iconv_fallback('UTF-16LE', 'ISO-8859-1', self::TrimTerm($string)), ' ');
    20012067        }
    20022068
    2003 
    2004         // Remove terminator 00 00
     2069        /**
     2070         * Remove terminator 00 00.
     2071         *
     2072         * @param string $string
     2073         *
     2074         * @return string
     2075         */
    20052076        public static function TrimTerm($string) {
    20062077                // remove terminator, only if present (it should be, but...)
    20072078                if (substr($string, -2) === "\x00\x00") {
  • src/wp-includes/ID3/module.audio-video.flv.php

     
    11<?php
    22/////////////////////////////////////////////////////////////////
    33/// getID3() by James Heinrich <info@getid3.org>               //
    4 //  available at http://getid3.sourceforge.net                 //
    5 //            or http://www.getid3.org                         //
    6 //          also https://github.com/JamesHeinrich/getID3       //
     4//  available at https://github.com/JamesHeinrich/getID3       //
     5//            or https://www.getid3.org                        //
     6//            or http://getid3.sourceforge.net                 //
     7//  see readme.txt for more details                            //
     8/////////////////////////////////////////////////////////////////
    79//                                                             //
     10// module.audio-video.flv.php                                  //
     11// module for analyzing Shockwave Flash Video files            //
     12// dependencies: NONE                                          //
     13//                                                             //
     14/////////////////////////////////////////////////////////////////
     15//                                                             //
    816//  FLV module by Seth Kaufman <sethØwhirl-i-gig*com>          //
    917//                                                             //
    1018//  * version 0.1 (26 June 2005)                               //
    1119//                                                             //
    12 //                                                             //
    1320//  * version 0.1.1 (15 July 2005)                             //
    1421//  minor modifications by James Heinrich <info@getid3.org>    //
    1522//                                                             //
     
    4350//  handle GETID3_FLV_VIDEO_VP6FLV_ALPHA                       //
    4451//  improved AVCSequenceParameterSetReader::readData()         //
    4552//    by Xander Schouwerwou <schouwerwouØgmail*com>            //
    46 //                                                             //
    47 /////////////////////////////////////////////////////////////////
    48 //                                                             //
    49 // module.audio-video.flv.php                                  //
    50 // module for analyzing Shockwave Flash Video files            //
    51 // dependencies: NONE                                          //
    5253//                                                            ///
    5354/////////////////////////////////////////////////////////////////
    5455
     
    7374define('H264_PROFILE_HIGH444',            144);
    7475define('H264_PROFILE_HIGH444_PREDICTIVE', 244);
    7576
    76 class getid3_flv extends getid3_handler {
    77 
     77class getid3_flv extends getid3_handler
     78{
    7879        const magic = 'FLV';
    7980
    80         public $max_frames = 100000; // break out of the loop if too many frames have been scanned; only scan this many if meta frame does not contain useful duration
     81        /**
     82         * Break out of the loop if too many frames have been scanned; only scan this
     83         * many if meta frame does not contain useful duration.
     84         *
     85         * @var int
     86         */
     87        public $max_frames = 100000;
    8188
     89        /**
     90         * @return bool
     91         */
    8292        public function Analyze() {
    8393                $info = &$this->getid3->info;
    8494
     
    332342                return true;
    333343        }
    334344
    335 
     345        /**
     346         * @param int $id
     347         *
     348         * @return string|false
     349         */
    336350        public static function audioFormatLookup($id) {
    337351                static $lookup = array(
    338352                        0  => 'Linear PCM, platform endian',
     
    355369                return (isset($lookup[$id]) ? $lookup[$id] : false);
    356370        }
    357371
     372        /**
     373         * @param int $id
     374         *
     375         * @return int|false
     376         */
    358377        public static function audioRateLookup($id) {
    359378                static $lookup = array(
    360379                        0 =>  5500,
     
    365384                return (isset($lookup[$id]) ? $lookup[$id] : false);
    366385        }
    367386
     387        /**
     388         * @param int $id
     389         *
     390         * @return int|false
     391         */
    368392        public static function audioBitDepthLookup($id) {
    369393                static $lookup = array(
    370394                        0 =>  8,
     
    373397                return (isset($lookup[$id]) ? $lookup[$id] : false);
    374398        }
    375399
     400        /**
     401         * @param int $id
     402         *
     403         * @return string|false
     404         */
    376405        public static function videoCodecLookup($id) {
    377406                static $lookup = array(
    378407                        GETID3_FLV_VIDEO_H263         => 'Sorenson H.263',
     
    386415        }
    387416}
    388417
    389 class AMFStream {
     418class AMFStream
     419{
     420        /**
     421         * @var string
     422         */
    390423        public $bytes;
     424
     425        /**
     426         * @var int
     427         */
    391428        public $pos;
    392429
     430        /**
     431         * @param string $bytes
     432         */
    393433        public function __construct(&$bytes) {
    394434                $this->bytes =& $bytes;
    395435                $this->pos = 0;
    396436        }
    397437
    398         public function readByte() {
    399                 return getid3_lib::BigEndian2Int(substr($this->bytes, $this->pos++, 1));
     438        /**
     439         * @return int
     440         */
     441        public function readByte() { //  8-bit
     442                return ord(substr($this->bytes, $this->pos++, 1));
    400443        }
    401444
    402         public function readInt() {
     445        /**
     446         * @return int
     447         */
     448        public function readInt() { // 16-bit
    403449                return ($this->readByte() << 8) + $this->readByte();
    404450        }
    405451
    406         public function readLong() {
     452        /**
     453         * @return int
     454         */
     455        public function readLong() { // 32-bit
    407456                return ($this->readByte() << 24) + ($this->readByte() << 16) + ($this->readByte() << 8) + $this->readByte();
    408457        }
    409458
     459        /**
     460         * @return float|false
     461         */
    410462        public function readDouble() {
    411463                return getid3_lib::BigEndian2Float($this->read(8));
    412464        }
    413465
     466        /**
     467         * @return string
     468         */
    414469        public function readUTF() {
    415470                $length = $this->readInt();
    416471                return $this->read($length);
    417472        }
    418473
     474        /**
     475         * @return string
     476         */
    419477        public function readLongUTF() {
    420478                $length = $this->readLong();
    421479                return $this->read($length);
    422480        }
    423481
     482        /**
     483         * @param int $length
     484         *
     485         * @return string
     486         */
    424487        public function read($length) {
    425488                $val = substr($this->bytes, $this->pos, $length);
    426489                $this->pos += $length;
     
    427490                return $val;
    428491        }
    429492
     493        /**
     494         * @return int
     495         */
    430496        public function peekByte() {
    431497                $pos = $this->pos;
    432498                $val = $this->readByte();
     
    434500                return $val;
    435501        }
    436502
     503        /**
     504         * @return int
     505         */
    437506        public function peekInt() {
    438507                $pos = $this->pos;
    439508                $val = $this->readInt();
     
    441510                return $val;
    442511        }
    443512
     513        /**
     514         * @return int
     515         */
    444516        public function peekLong() {
    445517                $pos = $this->pos;
    446518                $val = $this->readLong();
     
    448520                return $val;
    449521        }
    450522
     523        /**
     524         * @return float|false
     525         */
    451526        public function peekDouble() {
    452527                $pos = $this->pos;
    453528                $val = $this->readDouble();
     
    455530                return $val;
    456531        }
    457532
     533        /**
     534         * @return string
     535         */
    458536        public function peekUTF() {
    459537                $pos = $this->pos;
    460538                $val = $this->readUTF();
     
    462540                return $val;
    463541        }
    464542
     543        /**
     544         * @return string
     545         */
    465546        public function peekLongUTF() {
    466547                $pos = $this->pos;
    467548                $val = $this->readLongUTF();
     
    470551        }
    471552}
    472553
    473 class AMFReader {
     554class AMFReader
     555{
     556        /**
     557        * @var AMFStream
     558        */
    474559        public $stream;
    475560
    476         public function __construct(&$stream) {
    477                 $this->stream =& $stream;
     561        /**
     562         * @param AMFStream $stream
     563         */
     564        public function __construct(AMFStream $stream) {
     565                $this->stream = $stream;
    478566        }
    479567
     568        /**
     569         * @return mixed
     570         */
    480571        public function readData() {
    481572                $value = null;
    482573
     
    547638                return $value;
    548639        }
    549640
     641        /**
     642         * @return float|false
     643         */
    550644        public function readDouble() {
    551645                return $this->stream->readDouble();
    552646        }
    553647
     648        /**
     649         * @return bool
     650         */
    554651        public function readBoolean() {
    555652                return $this->stream->readByte() == 1;
    556653        }
    557654
     655        /**
     656         * @return string
     657         */
    558658        public function readString() {
    559659                return $this->stream->readUTF();
    560660        }
    561661
     662        /**
     663         * @return array
     664         */
    562665        public function readObject() {
    563666                // Get highest numerical index - ignored
    564667//              $highestIndex = $this->stream->readLong();
    565668
    566669                $data = array();
     670                $key = null;
    567671
    568672                while ($key = $this->stream->readUTF()) {
    569673                        $data[$key] = $this->readData();
     
    576680                return $data;
    577681        }
    578682
     683        /**
     684         * @return array
     685         */
    579686        public function readMixedArray() {
    580687                // Get highest numerical index - ignored
    581688                $highestIndex = $this->stream->readLong();
    582689
    583690                $data = array();
     691                $key = null;
    584692
    585693                while ($key = $this->stream->readUTF()) {
    586694                        if (is_numeric($key)) {
    587                                 $key = (float) $key;
     695                                $key = (int) $key;
    588696                        }
    589697                        $data[$key] = $this->readData();
    590698                }
     
    597705                return $data;
    598706        }
    599707
     708        /**
     709         * @return array
     710         */
    600711        public function readArray() {
    601712                $length = $this->stream->readLong();
    602713                $data = array();
     
    607718                return $data;
    608719        }
    609720
     721        /**
     722         * @return float|false
     723         */
    610724        public function readDate() {
    611725                $timestamp = $this->stream->readDouble();
    612726                $timezone = $this->stream->readInt();
     
    613727                return $timestamp;
    614728        }
    615729
     730        /**
     731         * @return string
     732         */
    616733        public function readLongString() {
    617734                return $this->stream->readLongUTF();
    618735        }
    619736
     737        /**
     738         * @return string
     739         */
    620740        public function readXML() {
    621741                return $this->stream->readLongUTF();
    622742        }
    623743
     744        /**
     745         * @return array
     746         */
    624747        public function readTypedObject() {
    625748                $className = $this->stream->readUTF();
    626749                return $this->readObject();
     
    627750        }
    628751}
    629752
    630 class AVCSequenceParameterSetReader {
     753class AVCSequenceParameterSetReader
     754{
     755        /**
     756         * @var string
     757         */
    631758        public $sps;
    632759        public $start = 0;
    633760        public $currentBytes = 0;
    634761        public $currentBits = 0;
     762
     763        /**
     764         * @var int
     765         */
    635766        public $width;
     767
     768        /**
     769         * @var int
     770         */
    636771        public $height;
    637772
     773        /**
     774         * @param string $sps
     775         */
    638776        public function __construct($sps) {
    639777                $this->sps = $sps;
    640778        }
     
    691829                }
    692830        }
    693831
     832        /**
     833         * @param int $bits
     834         */
    694835        public function skipBits($bits) {
    695836                $newBits = $this->currentBits + $bits;
    696837                $this->currentBytes += (int)floor($newBits / 8);
     
    697838                $this->currentBits = $newBits % 8;
    698839        }
    699840
     841        /**
     842         * @return int
     843         */
    700844        public function getBit() {
    701845                $result = (getid3_lib::BigEndian2Int(substr($this->sps, $this->currentBytes, 1)) >> (7 - $this->currentBits)) & 0x01;
    702846                $this->skipBits(1);
     
    703847                return $result;
    704848        }
    705849
     850        /**
     851         * @param int $bits
     852         *
     853         * @return int
     854         */
    706855        public function getBits($bits) {
    707856                $result = 0;
    708857                for ($i = 0; $i < $bits; $i++) {
     
    711860                return $result;
    712861        }
    713862
     863        /**
     864         * @return int
     865         */
    714866        public function expGolombUe() {
    715867                $significantBits = 0;
    716868                $bit = $this->getBit();
     
    726878                return (1 << $significantBits) + $this->getBits($significantBits) - 1;
    727879        }
    728880
     881        /**
     882         * @return int
     883         */
    729884        public function expGolombSe() {
    730885                $result = $this->expGolombUe();
    731886                if (($result & 0x01) == 0) {
     
    735890                }
    736891        }
    737892
     893        /**
     894         * @return int
     895         */
    738896        public function getWidth() {
    739897                return $this->width;
    740898        }
    741899
     900        /**
     901         * @return int
     902         */
    742903        public function getHeight() {
    743904                return $this->height;
    744905        }
  • src/wp-includes/ID3/module.audio-video.matroska.php

     
    11<?php
     2
    23/////////////////////////////////////////////////////////////////
    34/// getID3() by James Heinrich <info@getid3.org>               //
    4 //  available at http://getid3.sourceforge.net                 //
    5 //            or http://www.getid3.org                         //
    6 //          also https://github.com/JamesHeinrich/getID3       //
     5//  available at https://github.com/JamesHeinrich/getID3       //
     6//            or https://www.getid3.org                        //
     7//            or http://getid3.sourceforge.net                 //
     8//  see readme.txt for more details                            //
    79/////////////////////////////////////////////////////////////////
    8 // See readme.txt for more details                             //
    9 /////////////////////////////////////////////////////////////////
    1010//                                                             //
    1111// module.audio-video.matriska.php                             //
    1212// module for analyzing Matroska containers                    //
     
    7272define('EBML_ID_FILEDESCRIPTION',               0x067E); //         [46][7E] -- A human-friendly name for the attached file.
    7373define('EBML_ID_FILEUID',                       0x06AE); //         [46][AE] -- Unique ID representing the file, as random as possible.
    7474define('EBML_ID_CONTENTENCALGO',                0x07E1); //         [47][E1] -- The encryption algorithm used. The value '0' means that the contents have not been encrypted but only signed. Predefined values:
    75 define('EBML_ID_CONTENTENCKEYID',               0x07E2); //         [47][E2] -- For public key algorithms this is the ID of the public key the the data was encrypted with.
     75define('EBML_ID_CONTENTENCKEYID',               0x07E2); //         [47][E2] -- For public key algorithms this is the ID of the public key the data was encrypted with.
    7676define('EBML_ID_CONTENTSIGNATURE',              0x07E3); //         [47][E3] -- A cryptographic signature of the contents.
    7777define('EBML_ID_CONTENTSIGKEYID',               0x07E4); //         [47][E4] -- This is the ID of the private key the data was signed with.
    7878define('EBML_ID_CONTENTSIGALGO',                0x07E5); //         [47][E5] -- The algorithm used for the signature. A value of '0' means that the contents have not been signed but only encrypted. Predefined values:
     
    215215*/
    216216class getid3_matroska extends getid3_handler
    217217{
    218         // public options
    219         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]
    220         public static $parse_whole_file = false; // true to parse the whole file, not only header [default: FALSE]
     218        /**
     219         * If true, do not return information about CLUSTER chunks, since there's a lot of them
     220         * and they're not usually useful [default: TRUE].
     221         *
     222         * @var bool
     223         */
     224        public static $hide_clusters    = true;
    221225
    222         // private parser settings/placeholders
     226        /**
     227         * True to parse the whole file, not only header [default: FALSE].
     228         *
     229         * @var bool
     230         */
     231        public static $parse_whole_file = false;
     232
     233        /*
     234         * Private parser settings/placeholders.
     235         */
    223236        private $EBMLbuffer        = '';
    224237        private $EBMLbuffer_offset = 0;
    225238        private $EBMLbuffer_length = 0;
     
    226239        private $current_offset    = 0;
    227240        private $unuseful_elements = array(EBML_ID_CRC32, EBML_ID_VOID);
    228241
     242        /**
     243         * @return bool
     244         */
    229245        public function Analyze()
    230246        {
    231247                $info = &$this->getid3->info;
     
    366382                                                                if (!empty($getid3_temp->info[$header_data_key])) {
    367383                                                                        $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info[$header_data_key];
    368384                                                                        if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) {
    369                                                                                 foreach ($getid3_temp->info['audio'] as $key => $value) {
    370                                                                                         $track_info[$key] = $value;
     385                                                                                foreach ($getid3_temp->info['audio'] as $sub_key => $value) {
     386                                                                                        $track_info[$sub_key] = $value;
    371387                                                                                }
    372388                                                                        }
    373389                                                                }
     
    421437                                                                if (!empty($getid3_temp->info['ogg'])) {
    422438                                                                        $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info['ogg'];
    423439                                                                        if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) {
    424                                                                                 foreach ($getid3_temp->info['audio'] as $key => $value) {
    425                                                                                         $track_info[$key] = $value;
     440                                                                                foreach ($getid3_temp->info['audio'] as $sub_key => $value) {
     441                                                                                        $track_info[$sub_key] = $value;
    426442                                                                                }
    427443                                                                        }
    428444                                                                }
     
    449465                                                                getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
    450466
    451467                                                                $parsed = getid3_riff::parseWAVEFORMATex($trackarray['CodecPrivate']);
    452                                                                 foreach ($parsed as $key => $value) {
    453                                                                         if ($key != 'raw') {
    454                                                                                 $track_info[$key] = $value;
     468                                                                foreach ($parsed as $sub_key => $value) {
     469                                                                        if ($sub_key != 'raw') {
     470                                                                                $track_info[$sub_key] = $value;
    455471                                                                        }
    456472                                                                }
    457473                                                                $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed;
     
    496512                return true;
    497513        }
    498514
     515        /**
     516         * @param array $info
     517         */
    499518        private function parseEBML(&$info) {
    500519                // http://www.matroska.org/technical/specs/index.html#EBMLBasics
    501520                $this->current_offset = $info['avdataoffset'];
     
    12281247                }
    12291248        }
    12301249
     1250        /**
     1251         * @param int $min_data
     1252         *
     1253         * @return bool
     1254         */
    12311255        private function EnsureBufferHasEnoughData($min_data=1024) {
    12321256                if (($this->current_offset - $this->EBMLbuffer_offset) >= ($this->EBMLbuffer_length - $min_data)) {
    12331257                        $read_bytes = max($min_data, $this->getid3->fread_buffer_size());
     
    12491273                return true;
    12501274        }
    12511275
     1276        /**
     1277         * @return int|float|false
     1278         */
    12521279        private function readEBMLint() {
    12531280                $actual_offset = $this->current_offset - $this->EBMLbuffer_offset;
    12541281
     
    12811308                return $int_value;
    12821309        }
    12831310
     1311        /**
     1312         * @param int  $length
     1313         * @param bool $check_buffer
     1314         *
     1315         * @return string|false
     1316         */
    12841317        private function readEBMLelementData($length, $check_buffer=false) {
    12851318                if ($check_buffer && !$this->EnsureBufferHasEnoughData($length)) {
    12861319                        return false;
     
    12901323                return $data;
    12911324        }
    12921325
     1326        /**
     1327         * @param array      $element
     1328         * @param int        $parent_end
     1329         * @param array|bool $get_data
     1330         *
     1331         * @return bool
     1332         */
    12931333        private function getEBMLelement(&$element, $parent_end, $get_data=false) {
    12941334                if ($this->current_offset >= $parent_end) {
    12951335                        return false;
     
    13261366                return true;
    13271367        }
    13281368
     1369        /**
     1370         * @param string $type
     1371         * @param int    $line
     1372         * @param array  $element
     1373         */
    13291374        private function unhandledElement($type, $line, $element) {
    13301375                // warn only about unknown and missed elements, not about unuseful
    13311376                if (!in_array($element['id'], $this->unuseful_elements)) {
     
    13381383                }
    13391384        }
    13401385
     1386        /**
     1387         * @param array $SimpleTagArray
     1388         *
     1389         * @return bool
     1390         */
    13411391        private function ExtractCommentsSimpleTag($SimpleTagArray) {
    13421392                if (!empty($SimpleTagArray['SimpleTag'])) {
    13431393                        foreach ($SimpleTagArray['SimpleTag'] as $SimpleTagKey => $SimpleTagData) {
     
    13531403                return true;
    13541404        }
    13551405
     1406        /**
     1407         * @param int $parent_end
     1408         *
     1409         * @return array
     1410         */
    13561411        private function HandleEMBLSimpleTag($parent_end) {
    13571412                $simpletag_entry = array();
    13581413
     
    13831438                return $simpletag_entry;
    13841439        }
    13851440
     1441        /**
     1442         * @param array $element
     1443         * @param int   $block_type
     1444         * @param array $info
     1445         *
     1446         * @return array
     1447         */
    13861448        private function HandleEMBLClusterBlock($element, $block_type, &$info) {
    13871449                // http://www.matroska.org/technical/specs/index.html#block_structure
    13881450                // http://www.matroska.org/technical/specs/index.html#simpleblock_structure
     
    14461508                return $block_data;
    14471509        }
    14481510
     1511        /**
     1512         * @param string $EBMLstring
     1513         *
     1514         * @return int|float|false
     1515         */
    14491516        private static function EBML2Int($EBMLstring) {
    14501517                // http://matroska.org/specs/
    14511518
     
    14881555                return getid3_lib::BigEndian2Int($EBMLstring);
    14891556        }
    14901557
     1558        /**
     1559         * @param int $EBMLdatestamp
     1560         *
     1561         * @return float
     1562         */
    14911563        private static function EBMLdate2unix($EBMLdatestamp) {
    14921564                // Date - signed 8 octets integer in nanoseconds with 0 indicating the precise beginning of the millennium (at 2001-01-01T00:00:00,000000000 UTC)
    14931565                // 978307200 == mktime(0, 0, 0, 1, 1, 2001) == January 1, 2001 12:00:00am UTC
     
    14941566                return round(($EBMLdatestamp / 1000000000) + 978307200);
    14951567        }
    14961568
     1569        /**
     1570         * @param int $target_type
     1571         *
     1572         * @return string|int
     1573         */
    14971574        public static function TargetTypeValue($target_type) {
    14981575                // http://www.matroska.org/technical/specs/tagging/index.html
    14991576                static $TargetTypeValue = array();
     
    15091586                return (isset($TargetTypeValue[$target_type]) ? $TargetTypeValue[$target_type] : $target_type);
    15101587        }
    15111588
     1589        /**
     1590         * @param int $lacingtype
     1591         *
     1592         * @return string|int
     1593         */
    15121594        public static function BlockLacingType($lacingtype) {
    15131595                // http://matroska.org/technical/specs/index.html#block_structure
    15141596                static $BlockLacingType = array();
     
    15211603                return (isset($BlockLacingType[$lacingtype]) ? $BlockLacingType[$lacingtype] : $lacingtype);
    15221604        }
    15231605
     1606        /**
     1607         * @param string $codecid
     1608         *
     1609         * @return string
     1610         */
    15241611        public static function CodecIDtoCommonName($codecid) {
    15251612                // http://www.matroska.org/technical/specs/codecid/index.html
    15261613                static $CodecIDlist = array();
     
    15571644                return (isset($CodecIDlist[$codecid]) ? $CodecIDlist[$codecid] : $codecid);
    15581645        }
    15591646
     1647        /**
     1648         * @param int $value
     1649         *
     1650         * @return string
     1651         */
    15601652        private static function EBMLidName($value) {
    15611653                static $EBMLidList = array();
    15621654                if (empty($EBMLidList)) {
     
    17551847                return (isset($EBMLidList[$value]) ? $EBMLidList[$value] : dechex($value));
    17561848        }
    17571849
     1850        /**
     1851         * @param int $value
     1852         *
     1853         * @return string
     1854         */
    17581855        public static function displayUnit($value) {
    17591856                // http://www.matroska.org/technical/specs/index.html#DisplayUnit
    17601857                static $units = array(
     
    17661863                return (isset($units[$value]) ? $units[$value] : 'unknown');
    17671864        }
    17681865
     1866        /**
     1867         * @param array $streams
     1868         *
     1869         * @return array
     1870         */
    17691871        private static function getDefaultStreamInfo($streams)
    17701872        {
     1873                $stream = array();
    17711874                foreach (array_reverse($streams) as $stream) {
    17721875                        if ($stream['default']) {
    17731876                                break;
  • src/wp-includes/ID3/module.audio-video.quicktime.php

     
    11<?php
     2
    23/////////////////////////////////////////////////////////////////
    34/// getID3() by James Heinrich <info@getid3.org>               //
    4 //  available at http://getid3.sourceforge.net                 //
    5 //            or http://www.getid3.org                         //
    6 //          also https://github.com/JamesHeinrich/getID3       //
     5//  available at https://github.com/JamesHeinrich/getID3       //
     6//            or https://www.getid3.org                        //
     7//            or http://getid3.sourceforge.net                 //
     8//  see readme.txt for more details                            //
    79/////////////////////////////////////////////////////////////////
    8 // See readme.txt for more details                             //
    9 /////////////////////////////////////////////////////////////////
    1010//                                                             //
    1111// module.audio-video.quicktime.php                            //
    1212// module for analyzing Quicktime and MP3-in-MP4 files         //
     
    2424        public $ReturnAtomData        = true;
    2525        public $ParseAllPossibleAtoms = false;
    2626
     27        /**
     28         * @return bool
     29         */
    2730        public function Analyze() {
    2831                $info = &$this->getid3->info;
    2932
     
    3538
    3639                $offset      = 0;
    3740                $atomcounter = 0;
    38                 $atom_data_read_buffer_size = max($this->getid3->option_fread_buffer_size * 1024, ($info['php_memory_limit'] ? round($info['php_memory_limit'] / 4) : 1024)); // set read buffer to 25% of PHP memory limit (if one is specified), otherwise use option_fread_buffer_size [default: 32MB]
     41                $atom_data_read_buffer_size = $info['php_memory_limit'] ? round($info['php_memory_limit'] / 4) : $this->getid3->option_fread_buffer_size * 1024; // set read buffer to 25% of PHP memory limit (if one is specified), otherwise use option_fread_buffer_size [default: 32MB]
    3942                while ($offset < $info['avdataend']) {
    4043                        if (!getid3_lib::intValueSupported($offset)) {
    4144                                $this->error('Unable to parse atom at offset '.$offset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions');
     
    162165                if (isset($info['bitrate']) && !isset($info['audio']['bitrate']) && !isset($info['quicktime']['video'])) {
    163166                        $info['audio']['bitrate'] = $info['bitrate'];
    164167                }
     168                if (!empty($info['bitrate']) && !empty($info['audio']['bitrate']) && empty($info['video']['bitrate']) && !empty($info['video']['frame_rate']) && !empty($info['video']['resolution_x']) && ($info['bitrate'] > $info['audio']['bitrate'])) {
     169                        $info['video']['bitrate'] = $info['bitrate'] - $info['audio']['bitrate'];
     170                }
    165171                if (!empty($info['playtime_seconds']) && !isset($info['video']['frame_rate']) && !empty($info['quicktime']['stts_framecount'])) {
    166172                        foreach ($info['quicktime']['stts_framecount'] as $key => $samples_count) {
    167173                                $samples_per_second = $samples_count / $info['playtime_seconds'];
     
    193199                if (empty($info['video']['dataformat']) && !empty($info['quicktime']['video'])) {
    194200                        $info['video']['dataformat'] = 'quicktime';
    195201                }
     202                if (isset($info['video']) && ($info['mime_type'] == 'audio/mp4') && empty($info['video']['resolution_x']) && empty($info['video']['resolution_y']))  {
     203                        unset($info['video']);
     204                }
    196205
    197206                return true;
    198207        }
    199208
     209        /**
     210         * @param string $atomname
     211         * @param int    $atomsize
     212         * @param string $atom_data
     213         * @param int    $baseoffset
     214         * @param array  $atomHierarchy
     215         * @param bool   $ParseAllPossibleAtoms
     216         *
     217         * @return array|false
     218         */
    200219        public function QuicktimeParseAtom($atomname, $atomsize, $atom_data, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) {
    201220                // http://developer.apple.com/techpubs/quicktime/qtdevdocs/APIREF/INDEX/atomalphaindex.htm
    202221                // https://code.google.com/p/mp4v2/wiki/iTunesMetadata
     
    203222
    204223                $info = &$this->getid3->info;
    205224
    206                 $atom_parent = end($atomHierarchy); // not array_pop($atomHierarchy); see http://www.getid3.org/phpBB3/viewtopic.php?t=1717
     225                $atom_parent = end($atomHierarchy); // not array_pop($atomHierarchy); see https://www.getid3.org/phpBB3/viewtopic.php?t=1717
    207226                array_push($atomHierarchy, $atomname);
    208227                $atom_structure['hierarchy'] = implode(' ', $atomHierarchy);
    209228                $atom_structure['name']      = $atomname;
    210229                $atom_structure['size']      = $atomsize;
    211230                $atom_structure['offset']    = $baseoffset;
    212                 switch ($atomname) {
    213                         case 'moov': // MOVie container atom
    214                         case 'trak': // TRAcK container atom
    215                         case 'clip': // CLIPping container atom
    216                         case 'matt': // track MATTe container atom
    217                         case 'edts': // EDiTS container atom
    218                         case 'tref': // Track REFerence container atom
    219                         case 'mdia': // MeDIA container atom
    220                         case 'minf': // Media INFormation container atom
    221                         case 'dinf': // Data INFormation container atom
    222                         case 'udta': // User DaTA container atom
    223                         case 'cmov': // Compressed MOVie container atom
    224                         case 'rmra': // Reference Movie Record Atom
    225                         case 'rmda': // Reference Movie Descriptor Atom
    226                         case 'gmhd': // Generic Media info HeaDer atom (seen on QTVR)
    227                                 $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
    228                                 break;
     231                if (substr($atomname, 0, 3) == "\x00\x00\x00") {
     232                        // https://github.com/JamesHeinrich/getID3/issues/139
     233                        $atomname = getid3_lib::BigEndian2Int($atomname);
     234                        $atom_structure['name'] = $atomname;
     235                        $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
     236                } else {
     237                        switch ($atomname) {
     238                                case 'moov': // MOVie container atom
     239                                case 'trak': // TRAcK container atom
     240                                case 'clip': // CLIPping container atom
     241                                case 'matt': // track MATTe container atom
     242                                case 'edts': // EDiTS container atom
     243                                case 'tref': // Track REFerence container atom
     244                                case 'mdia': // MeDIA container atom
     245                                case 'minf': // Media INFormation container atom
     246                                case 'dinf': // Data INFormation container atom
     247                                case 'udta': // User DaTA container atom
     248                                case 'cmov': // Compressed MOVie container atom
     249                                case 'rmra': // Reference Movie Record Atom
     250                                case 'rmda': // Reference Movie Descriptor Atom
     251                                case 'gmhd': // Generic Media info HeaDer atom (seen on QTVR)
     252                                        $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
     253                                        break;
    229254
    230                         case 'ilst': // Item LiST container atom
    231                                 if ($atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms)) {
    232                                         // some "ilst" atoms contain data atoms that have a numeric name, and the data is far more accessible if the returned array is compacted
    233                                         $allnumericnames = true;
    234                                         foreach ($atom_structure['subatoms'] as $subatomarray) {
    235                                                 if (!is_integer($subatomarray['name']) || (count($subatomarray['subatoms']) != 1)) {
    236                                                         $allnumericnames = false;
    237                                                         break;
    238                                                 }
    239                                         }
    240                                         if ($allnumericnames) {
    241                                                 $newData = array();
     255                                case 'ilst': // Item LiST container atom
     256                                        if ($atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms)) {
     257                                                // some "ilst" atoms contain data atoms that have a numeric name, and the data is far more accessible if the returned array is compacted
     258                                                $allnumericnames = true;
    242259                                                foreach ($atom_structure['subatoms'] as $subatomarray) {
    243                                                         foreach ($subatomarray['subatoms'] as $newData_subatomarray) {
    244                                                                 unset($newData_subatomarray['hierarchy'], $newData_subatomarray['name']);
    245                                                                 $newData[$subatomarray['name']] = $newData_subatomarray;
     260                                                        if (!is_integer($subatomarray['name']) || (count($subatomarray['subatoms']) != 1)) {
     261                                                                $allnumericnames = false;
    246262                                                                break;
    247263                                                        }
    248264                                                }
    249                                                 $atom_structure['data'] = $newData;
    250                                                 unset($atom_structure['subatoms']);
     265                                                if ($allnumericnames) {
     266                                                        $newData = array();
     267                                                        foreach ($atom_structure['subatoms'] as $subatomarray) {
     268                                                                foreach ($subatomarray['subatoms'] as $newData_subatomarray) {
     269                                                                        unset($newData_subatomarray['hierarchy'], $newData_subatomarray['name']);
     270                                                                        $newData[$subatomarray['name']] = $newData_subatomarray;
     271                                                                        break;
     272                                                                }
     273                                                        }
     274                                                        $atom_structure['data'] = $newData;
     275                                                        unset($atom_structure['subatoms']);
     276                                                }
    251277                                        }
    252                                 }
    253                                 break;
     278                                        break;
    254279
    255                         case "\x00\x00\x00\x01":
    256                         case "\x00\x00\x00\x02":
    257                         case "\x00\x00\x00\x03":
    258                         case "\x00\x00\x00\x04":
    259                         case "\x00\x00\x00\x05":
    260                                 $atomname = getid3_lib::BigEndian2Int($atomname);
    261                                 $atom_structure['name'] = $atomname;
    262                                 $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
    263                                 break;
    264 
    265                         case 'stbl': // Sample TaBLe container atom
    266                                 $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
    267                                 $isVideo = false;
    268                                 $framerate  = 0;
    269                                 $framecount = 0;
    270                                 foreach ($atom_structure['subatoms'] as $key => $value_array) {
    271                                         if (isset($value_array['sample_description_table'])) {
    272                                                 foreach ($value_array['sample_description_table'] as $key2 => $value_array2) {
    273                                                         if (isset($value_array2['data_format'])) {
    274                                                                 switch ($value_array2['data_format']) {
    275                                                                         case 'avc1':
    276                                                                         case 'mp4v':
    277                                                                                 // video data
    278                                                                                 $isVideo = true;
    279                                                                                 break;
    280                                                                         case 'mp4a':
    281                                                                                 // audio data
    282                                                                                 break;
     280                                case 'stbl': // Sample TaBLe container atom
     281                                        $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
     282                                        $isVideo = false;
     283                                        $framerate  = 0;
     284                                        $framecount = 0;
     285                                        foreach ($atom_structure['subatoms'] as $key => $value_array) {
     286                                                if (isset($value_array['sample_description_table'])) {
     287                                                        foreach ($value_array['sample_description_table'] as $key2 => $value_array2) {
     288                                                                if (isset($value_array2['data_format'])) {
     289                                                                        switch ($value_array2['data_format']) {
     290                                                                                case 'avc1':
     291                                                                                case 'mp4v':
     292                                                                                        // video data
     293                                                                                        $isVideo = true;
     294                                                                                        break;
     295                                                                                case 'mp4a':
     296                                                                                        // audio data
     297                                                                                        break;
     298                                                                        }
    283299                                                                }
    284300                                                        }
    285                                                 }
    286                                         } elseif (isset($value_array['time_to_sample_table'])) {
    287                                                 foreach ($value_array['time_to_sample_table'] as $key2 => $value_array2) {
    288                                                         if (isset($value_array2['sample_count']) && isset($value_array2['sample_duration']) && ($value_array2['sample_duration'] > 0)) {
    289                                                                 $framerate  = round($info['quicktime']['time_scale'] / $value_array2['sample_duration'], 3);
    290                                                                 $framecount = $value_array2['sample_count'];
     301                                                } elseif (isset($value_array['time_to_sample_table'])) {
     302                                                        foreach ($value_array['time_to_sample_table'] as $key2 => $value_array2) {
     303                                                                if (isset($value_array2['sample_count']) && isset($value_array2['sample_duration']) && ($value_array2['sample_duration'] > 0)) {
     304                                                                        $framerate  = round($info['quicktime']['time_scale'] / $value_array2['sample_duration'], 3);
     305                                                                        $framecount = $value_array2['sample_count'];
     306                                                                }
    291307                                                        }
    292308                                                }
    293309                                        }
    294                                 }
    295                                 if ($isVideo && $framerate) {
    296                                         $info['quicktime']['video']['frame_rate'] = $framerate;
    297                                         $info['video']['frame_rate'] = $info['quicktime']['video']['frame_rate'];
    298                                 }
    299                                 if ($isVideo && $framecount) {
    300                                         $info['quicktime']['video']['frame_count'] = $framecount;
    301                                 }
    302                                 break;
     310                                        if ($isVideo && $framerate) {
     311                                                $info['quicktime']['video']['frame_rate'] = $framerate;
     312                                                $info['video']['frame_rate'] = $info['quicktime']['video']['frame_rate'];
     313                                        }
     314                                        if ($isVideo && $framecount) {
     315                                                $info['quicktime']['video']['frame_count'] = $framecount;
     316                                        }
     317                                        break;
    303318
    304319
    305                         case "\xA9".'alb': // ALBum
    306                         case "\xA9".'ART': //
    307                         case "\xA9".'art': // ARTist
    308                         case "\xA9".'aut': //
    309                         case "\xA9".'cmt': // CoMmenT
    310                         case "\xA9".'com': // COMposer
    311                         case "\xA9".'cpy': //
    312                         case "\xA9".'day': // content created year
    313                         case "\xA9".'dir': //
    314                         case "\xA9".'ed1': //
    315                         case "\xA9".'ed2': //
    316                         case "\xA9".'ed3': //
    317                         case "\xA9".'ed4': //
    318                         case "\xA9".'ed5': //
    319                         case "\xA9".'ed6': //
    320                         case "\xA9".'ed7': //
    321                         case "\xA9".'ed8': //
    322                         case "\xA9".'ed9': //
    323                         case "\xA9".'enc': //
    324                         case "\xA9".'fmt': //
    325                         case "\xA9".'gen': // GENre
    326                         case "\xA9".'grp': // GRouPing
    327                         case "\xA9".'hst': //
    328                         case "\xA9".'inf': //
    329                         case "\xA9".'lyr': // LYRics
    330                         case "\xA9".'mak': //
    331                         case "\xA9".'mod': //
    332                         case "\xA9".'nam': // full NAMe
    333                         case "\xA9".'ope': //
    334                         case "\xA9".'PRD': //
    335                         case "\xA9".'prf': //
    336                         case "\xA9".'req': //
    337                         case "\xA9".'src': //
    338                         case "\xA9".'swr': //
    339                         case "\xA9".'too': // encoder
    340                         case "\xA9".'trk': // TRacK
    341                         case "\xA9".'url': //
    342                         case "\xA9".'wrn': //
    343                         case "\xA9".'wrt': // WRiTer
    344                         case '----': // itunes specific
    345                         case 'aART': // Album ARTist
    346                         case 'akID': // iTunes store account type
    347                         case 'apID': // Purchase Account
    348                         case 'atID': //
    349                         case 'catg': // CaTeGory
    350                         case 'cmID': //
    351                         case 'cnID': //
    352                         case 'covr': // COVeR artwork
    353                         case 'cpil': // ComPILation
    354                         case 'cprt': // CoPyRighT
    355                         case 'desc': // DESCription
    356                         case 'disk': // DISK number
    357                         case 'egid': // Episode Global ID
    358                         case 'geID': //
    359                         case 'gnre': // GeNRE
    360                         case 'hdvd': // HD ViDeo
    361                         case 'keyw': // KEYWord
    362                         case 'ldes': // Long DEScription
    363                         case 'pcst': // PodCaST
    364                         case 'pgap': // GAPless Playback
    365                         case 'plID': //
    366                         case 'purd': // PURchase Date
    367                         case 'purl': // Podcast URL
    368                         case 'rati': //
    369                         case 'rndu': //
    370                         case 'rpdu': //
    371                         case 'rtng': // RaTiNG
    372                         case 'sfID': // iTunes store country
    373                         case 'soaa': // SOrt Album Artist
    374                         case 'soal': // SOrt ALbum
    375                         case 'soar': // SOrt ARtist
    376                         case 'soco': // SOrt COmposer
    377                         case 'sonm': // SOrt NaMe
    378                         case 'sosn': // SOrt Show Name
    379                         case 'stik': //
    380                         case 'tmpo': // TeMPO (BPM)
    381                         case 'trkn': // TRacK Number
    382                         case 'tven': // tvEpisodeID
    383                         case 'tves': // TV EpiSode
    384                         case 'tvnn': // TV Network Name
    385                         case 'tvsh': // TV SHow Name
    386                         case 'tvsn': // TV SeasoN
    387                                 if ($atom_parent == 'udta') {
    388                                         // User data atom handler
    389                                         $atom_structure['data_length'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2));
    390                                         $atom_structure['language_id'] = getid3_lib::BigEndian2Int(substr($atom_data, 2, 2));
    391                                         $atom_structure['data']        =                           substr($atom_data, 4);
     320                                case "\xA9".'alb': // ALBum
     321                                case "\xA9".'ART': //
     322                                case "\xA9".'art': // ARTist
     323                                case "\xA9".'aut': //
     324                                case "\xA9".'cmt': // CoMmenT
     325                                case "\xA9".'com': // COMposer
     326                                case "\xA9".'cpy': //
     327                                case "\xA9".'day': // content created year
     328                                case "\xA9".'dir': //
     329                                case "\xA9".'ed1': //
     330                                case "\xA9".'ed2': //
     331                                case "\xA9".'ed3': //
     332                                case "\xA9".'ed4': //
     333                                case "\xA9".'ed5': //
     334                                case "\xA9".'ed6': //
     335                                case "\xA9".'ed7': //
     336                                case "\xA9".'ed8': //
     337                                case "\xA9".'ed9': //
     338                                case "\xA9".'enc': //
     339                                case "\xA9".'fmt': //
     340                                case "\xA9".'gen': // GENre
     341                                case "\xA9".'grp': // GRouPing
     342                                case "\xA9".'hst': //
     343                                case "\xA9".'inf': //
     344                                case "\xA9".'lyr': // LYRics
     345                                case "\xA9".'mak': //
     346                                case "\xA9".'mod': //
     347                                case "\xA9".'nam': // full NAMe
     348                                case "\xA9".'ope': //
     349                                case "\xA9".'PRD': //
     350                                case "\xA9".'prf': //
     351                                case "\xA9".'req': //
     352                                case "\xA9".'src': //
     353                                case "\xA9".'swr': //
     354                                case "\xA9".'too': // encoder
     355                                case "\xA9".'trk': // TRacK
     356                                case "\xA9".'url': //
     357                                case "\xA9".'wrn': //
     358                                case "\xA9".'wrt': // WRiTer
     359                                case '----': // itunes specific
     360                                case 'aART': // Album ARTist
     361                                case 'akID': // iTunes store account type
     362                                case 'apID': // Purchase Account
     363                                case 'atID': //
     364                                case 'catg': // CaTeGory
     365                                case 'cmID': //
     366                                case 'cnID': //
     367                                case 'covr': // COVeR artwork
     368                                case 'cpil': // ComPILation
     369                                case 'cprt': // CoPyRighT
     370                                case 'desc': // DESCription
     371                                case 'disk': // DISK number
     372                                case 'egid': // Episode Global ID
     373                                case 'geID': //
     374                                case 'gnre': // GeNRE
     375                                case 'hdvd': // HD ViDeo
     376                                case 'keyw': // KEYWord
     377                                case 'ldes': // Long DEScription
     378                                case 'pcst': // PodCaST
     379                                case 'pgap': // GAPless Playback
     380                                case 'plID': //
     381                                case 'purd': // PURchase Date
     382                                case 'purl': // Podcast URL
     383                                case 'rati': //
     384                                case 'rndu': //
     385                                case 'rpdu': //
     386                                case 'rtng': // RaTiNG
     387                                case 'sfID': // iTunes store country
     388                                case 'soaa': // SOrt Album Artist
     389                                case 'soal': // SOrt ALbum
     390                                case 'soar': // SOrt ARtist
     391                                case 'soco': // SOrt COmposer
     392                                case 'sonm': // SOrt NaMe
     393                                case 'sosn': // SOrt Show Name
     394                                case 'stik': //
     395                                case 'tmpo': // TeMPO (BPM)
     396                                case 'trkn': // TRacK Number
     397                                case 'tven': // tvEpisodeID
     398                                case 'tves': // TV EpiSode
     399                                case 'tvnn': // TV Network Name
     400                                case 'tvsh': // TV SHow Name
     401                                case 'tvsn': // TV SeasoN
     402                                        if ($atom_parent == 'udta') {
     403                                                // User data atom handler
     404                                                $atom_structure['data_length'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2));
     405                                                $atom_structure['language_id'] = getid3_lib::BigEndian2Int(substr($atom_data, 2, 2));
     406                                                $atom_structure['data']        =                           substr($atom_data, 4);
    392407
    393                                         $atom_structure['language']    = $this->QuicktimeLanguageLookup($atom_structure['language_id']);
    394                                         if (empty($info['comments']['language']) || (!in_array($atom_structure['language'], $info['comments']['language']))) {
    395                                                 $info['comments']['language'][] = $atom_structure['language'];
    396                                         }
    397                                 } else {
    398                                         // Apple item list box atom handler
    399                                         $atomoffset = 0;
    400                                         if (substr($atom_data, 2, 2) == "\x10\xB5") {
    401                                                 // not sure what it means, but observed on iPhone4 data.
    402                                                 // Each $atom_data has 2 bytes of datasize, plus 0x10B5, then data
    403                                                 while ($atomoffset < strlen($atom_data)) {
    404                                                         $boxsmallsize = getid3_lib::BigEndian2Int(substr($atom_data, $atomoffset,     2));
    405                                                         $boxsmalltype =                           substr($atom_data, $atomoffset + 2, 2);
    406                                                         $boxsmalldata =                           substr($atom_data, $atomoffset + 4, $boxsmallsize);
    407                                                         if ($boxsmallsize <= 1) {
    408                                                                 $this->warning('Invalid QuickTime atom smallbox size "'.$boxsmallsize.'" in atom "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" at offset: '.($atom_structure['offset'] + $atomoffset));
    409                                                                 $atom_structure['data'] = null;
    410                                                                 $atomoffset = strlen($atom_data);
    411                                                                 break;
    412                                                         }
    413                                                         switch ($boxsmalltype) {
    414                                                                 case "\x10\xB5":
    415                                                                         $atom_structure['data'] = $boxsmalldata;
    416                                                                         break;
    417                                                                 default:
    418                                                                         $this->warning('Unknown QuickTime smallbox type: "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $boxsmalltype).'" ('.trim(getid3_lib::PrintHexBytes($boxsmalltype)).') at offset '.$baseoffset);
    419                                                                         $atom_structure['data'] = $atom_data;
    420                                                                         break;
    421                                                         }
    422                                                         $atomoffset += (4 + $boxsmallsize);
     408                                                $atom_structure['language']    = $this->QuicktimeLanguageLookup($atom_structure['language_id']);
     409                                                if (empty($info['comments']['language']) || (!in_array($atom_structure['language'], $info['comments']['language']))) {
     410                                                        $info['comments']['language'][] = $atom_structure['language'];
    423411                                                }
    424412                                        } else {
    425                                                 while ($atomoffset < strlen($atom_data)) {
    426                                                         $boxsize = getid3_lib::BigEndian2Int(substr($atom_data, $atomoffset, 4));
    427                                                         $boxtype =                           substr($atom_data, $atomoffset + 4, 4);
    428                                                         $boxdata =                           substr($atom_data, $atomoffset + 8, $boxsize - 8);
    429                                                         if ($boxsize <= 1) {
    430                                                                 $this->warning('Invalid QuickTime atom box size "'.$boxsize.'" in atom "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" at offset: '.($atom_structure['offset'] + $atomoffset));
    431                                                                 $atom_structure['data'] = null;
    432                                                                 $atomoffset = strlen($atom_data);
    433                                                                 break;
     413                                                // Apple item list box atom handler
     414                                                $atomoffset = 0;
     415                                                if (substr($atom_data, 2, 2) == "\x10\xB5") {
     416                                                        // not sure what it means, but observed on iPhone4 data.
     417                                                        // Each $atom_data has 2 bytes of datasize, plus 0x10B5, then data
     418                                                        while ($atomoffset < strlen($atom_data)) {
     419                                                                $boxsmallsize = getid3_lib::BigEndian2Int(substr($atom_data, $atomoffset,     2));
     420                                                                $boxsmalltype =                           substr($atom_data, $atomoffset + 2, 2);
     421                                                                $boxsmalldata =                           substr($atom_data, $atomoffset + 4, $boxsmallsize);
     422                                                                if ($boxsmallsize <= 1) {
     423                                                                        $this->warning('Invalid QuickTime atom smallbox size "'.$boxsmallsize.'" in atom "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" at offset: '.($atom_structure['offset'] + $atomoffset));
     424                                                                        $atom_structure['data'] = null;
     425                                                                        $atomoffset = strlen($atom_data);
     426                                                                        break;
     427                                                                }
     428                                                                switch ($boxsmalltype) {
     429                                                                        case "\x10\xB5":
     430                                                                                $atom_structure['data'] = $boxsmalldata;
     431                                                                                break;
     432                                                                        default:
     433                                                                                $this->warning('Unknown QuickTime smallbox type: "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $boxsmalltype).'" ('.trim(getid3_lib::PrintHexBytes($boxsmalltype)).') at offset '.$baseoffset);
     434                                                                                $atom_structure['data'] = $atom_data;
     435                                                                                break;
     436                                                                }
     437                                                                $atomoffset += (4 + $boxsmallsize);
    434438                                                        }
    435                                                         $atomoffset += $boxsize;
    436 
    437                                                         switch ($boxtype) {
    438                                                                 case 'mean':
    439                                                                 case 'name':
    440                                                                         $atom_structure[$boxtype] = substr($boxdata, 4);
     439                                                } else {
     440                                                        while ($atomoffset < strlen($atom_data)) {
     441                                                                $boxsize = getid3_lib::BigEndian2Int(substr($atom_data, $atomoffset, 4));
     442                                                                $boxtype =                           substr($atom_data, $atomoffset + 4, 4);
     443                                                                $boxdata =                           substr($atom_data, $atomoffset + 8, $boxsize - 8);
     444                                                                if ($boxsize <= 1) {
     445                                                                        $this->warning('Invalid QuickTime atom box size "'.$boxsize.'" in atom "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" at offset: '.($atom_structure['offset'] + $atomoffset));
     446                                                                        $atom_structure['data'] = null;
     447                                                                        $atomoffset = strlen($atom_data);
    441448                                                                        break;
     449                                                                }
     450                                                                $atomoffset += $boxsize;
    442451
    443                                                                 case 'data':
    444                                                                         $atom_structure['version']   = getid3_lib::BigEndian2Int(substr($boxdata,  0, 1));
    445                                                                         $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($boxdata,  1, 3));
    446                                                                         switch ($atom_structure['flags_raw']) {
    447                                                                                 case  0: // data flag
    448                                                                                 case 21: // tmpo/cpil flag
    449                                                                                         switch ($atomname) {
    450                                                                                                 case 'cpil':
    451                                                                                                 case 'hdvd':
    452                                                                                                 case 'pcst':
    453                                                                                                 case 'pgap':
    454                                                                                                         // 8-bit integer (boolean)
    455                                                                                                         $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
    456                                                                                                         break;
     452                                                                switch ($boxtype) {
     453                                                                        case 'mean':
     454                                                                        case 'name':
     455                                                                                $atom_structure[$boxtype] = substr($boxdata, 4);
     456                                                                                break;
    457457
    458                                                                                                 case 'tmpo':
    459                                                                                                         // 16-bit integer
    460                                                                                                         $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 2));
    461                                                                                                         break;
     458                                                                        case 'data':
     459                                                                                $atom_structure['version']   = getid3_lib::BigEndian2Int(substr($boxdata,  0, 1));
     460                                                                                $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($boxdata,  1, 3));
     461                                                                                switch ($atom_structure['flags_raw']) {
     462                                                                                        case  0: // data flag
     463                                                                                        case 21: // tmpo/cpil flag
     464                                                                                                switch ($atomname) {
     465                                                                                                        case 'cpil':
     466                                                                                                        case 'hdvd':
     467                                                                                                        case 'pcst':
     468                                                                                                        case 'pgap':
     469                                                                                                                // 8-bit integer (boolean)
     470                                                                                                                $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
     471                                                                                                                break;
    462472
    463                                                                                                 case 'disk':
    464                                                                                                 case 'trkn':
    465                                                                                                         // binary
    466                                                                                                         $num       = getid3_lib::BigEndian2Int(substr($boxdata, 10, 2));
    467                                                                                                         $num_total = getid3_lib::BigEndian2Int(substr($boxdata, 12, 2));
    468                                                                                                         $atom_structure['data']  = empty($num) ? '' : $num;
    469                                                                                                         $atom_structure['data'] .= empty($num_total) ? '' : '/'.$num_total;
    470                                                                                                         break;
     473                                                                                                        case 'tmpo':
     474                                                                                                                // 16-bit integer
     475                                                                                                                $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 2));
     476                                                                                                                break;
    471477
    472                                                                                                 case 'gnre':
    473                                                                                                         // enum
    474                                                                                                         $GenreID = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
    475                                                                                                         $atom_structure['data']    = getid3_id3v1::LookupGenreName($GenreID - 1);
    476                                                                                                         break;
     478                                                                                                        case 'disk':
     479                                                                                                        case 'trkn':
     480                                                                                                                // binary
     481                                                                                                                $num       = getid3_lib::BigEndian2Int(substr($boxdata, 10, 2));
     482                                                                                                                $num_total = getid3_lib::BigEndian2Int(substr($boxdata, 12, 2));
     483                                                                                                                $atom_structure['data']  = empty($num) ? '' : $num;
     484                                                                                                                $atom_structure['data'] .= empty($num_total) ? '' : '/'.$num_total;
     485                                                                                                                break;
    477486
    478                                                                                                 case 'rtng':
    479                                                                                                         // 8-bit integer
    480                                                                                                         $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
    481                                                                                                         $atom_structure['data']    = $this->QuicktimeContentRatingLookup($atom_structure[$atomname]);
    482                                                                                                         break;
     487                                                                                                        case 'gnre':
     488                                                                                                                // enum
     489                                                                                                                $GenreID = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
     490                                                                                                                $atom_structure['data']    = getid3_id3v1::LookupGenreName($GenreID - 1);
     491                                                                                                                break;
    483492
    484                                                                                                 case 'stik':
    485                                                                                                         // 8-bit integer (enum)
    486                                                                                                         $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
    487                                                                                                         $atom_structure['data']    = $this->QuicktimeSTIKLookup($atom_structure[$atomname]);
    488                                                                                                         break;
     493                                                                                                        case 'rtng':
     494                                                                                                                // 8-bit integer
     495                                                                                                                $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
     496                                                                                                                $atom_structure['data']    = $this->QuicktimeContentRatingLookup($atom_structure[$atomname]);
     497                                                                                                                break;
    489498
    490                                                                                                 case 'sfID':
    491                                                                                                         // 32-bit integer
    492                                                                                                         $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
    493                                                                                                         $atom_structure['data']    = $this->QuicktimeStoreFrontCodeLookup($atom_structure[$atomname]);
    494                                                                                                         break;
     499                                                                                                        case 'stik':
     500                                                                                                                // 8-bit integer (enum)
     501                                                                                                                $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
     502                                                                                                                $atom_structure['data']    = $this->QuicktimeSTIKLookup($atom_structure[$atomname]);
     503                                                                                                                break;
    495504
    496                                                                                                 case 'egid':
    497                                                                                                 case 'purl':
    498                                                                                                         $atom_structure['data'] = substr($boxdata, 8);
    499                                                                                                         break;
     505                                                                                                        case 'sfID':
     506                                                                                                                // 32-bit integer
     507                                                                                                                $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
     508                                                                                                                $atom_structure['data']    = $this->QuicktimeStoreFrontCodeLookup($atom_structure[$atomname]);
     509                                                                                                                break;
    500510
    501                                                                                                 case 'plID':
    502                                                                                                         // 64-bit integer
    503                                                                                                         $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 8));
    504                                                                                                         break;
     511                                                                                                        case 'egid':
     512                                                                                                        case 'purl':
     513                                                                                                                $atom_structure['data'] = substr($boxdata, 8);
     514                                                                                                                break;
    505515
    506                                                                                                 case 'covr':
    507                                                                                                         $atom_structure['data'] = substr($boxdata, 8);
     516                                                                                                        case 'plID':
     517                                                                                                                // 64-bit integer
     518                                                                                                                $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 8));
     519                                                                                                                break;
     520
     521                                                                                                        case 'covr':
     522                                                                                                                $atom_structure['data'] = substr($boxdata, 8);
     523                                                                                                                // not a foolproof check, but better than nothing
     524                                                                                                                if (preg_match('#^\\xFF\\xD8\\xFF#', $atom_structure['data'])) {
     525                                                                                                                        $atom_structure['image_mime'] = 'image/jpeg';
     526                                                                                                                } elseif (preg_match('#^\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A#', $atom_structure['data'])) {
     527                                                                                                                        $atom_structure['image_mime'] = 'image/png';
     528                                                                                                                } elseif (preg_match('#^GIF#', $atom_structure['data'])) {
     529                                                                                                                        $atom_structure['image_mime'] = 'image/gif';
     530  &nb