Ticket #48040: 48040.diff
File 48040.diff, 430.5 KB (added by , 5 years ago) |
---|
-
src/wp-includes/ID3/getid3.lib.php
1 1 <?php 2 2 3 ///////////////////////////////////////////////////////////////// 3 4 /// 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 // 8 8 // // 9 9 // getid3.lib.php - part of getID3() // 10 // See readme.txt for more details//10 // see readme.txt for more details // 11 11 // /// 12 12 ///////////////////////////////////////////////////////////////// 13 13 … … 14 14 15 15 class getid3_lib 16 16 { 17 17 /** 18 * @param string $string 19 * @param bool $hex 20 * @param bool $spaces 21 * @param string $htmlencoding 22 * 23 * @return string 24 */ 18 25 public static function PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8') { 19 26 $returnstring = ''; 20 27 for ($i = 0; $i < strlen($string); $i++) { 21 28 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); 23 30 } else { 24 $returnstring .= ' '.(preg_match("#[\x20-\x7E]#", $string {$i}) ? $string{$i}: '¤');31 $returnstring .= ' '.(preg_match("#[\x20-\x7E]#", $string[$i]) ? $string[$i] : '¤'); 25 32 } 26 33 if ($spaces) { 27 34 $returnstring .= ' '; … … 36 43 return $returnstring; 37 44 } 38 45 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 */ 39 53 public static function trunc($floatnumber) { 40 // truncates a floating-point number at the decimal point41 // returns int (if possible, otherwise float)42 54 if ($floatnumber >= 1) { 43 55 $truncatednumber = floor($floatnumber); 44 56 } elseif ($floatnumber <= -1) { … … 52 64 return $truncatednumber; 53 65 } 54 66 55 67 /** 68 * @param int|null $variable 69 * @param int $increment 70 * 71 * @return bool 72 */ 56 73 public static function safe_inc(&$variable, $increment=1) { 57 74 if (isset($variable)) { 58 75 $variable += $increment; … … 62 79 return true; 63 80 } 64 81 82 /** 83 * @param int|float $floatnum 84 * 85 * @return int|float 86 */ 65 87 public static function CastAsInt($floatnum) { 66 88 // convert to float if not already 67 89 $floatnum = (float) $floatnum; … … 77 99 return $floatnum; 78 100 } 79 101 102 /** 103 * @param int $num 104 * 105 * @return bool 106 */ 80 107 public static function intValueSupported($num) { 81 108 // check if integers are 64-bit 82 109 static $hasINT64 = null; … … 93 120 return false; 94 121 } 95 122 123 /** 124 * @param string $fraction 125 * 126 * @return float 127 */ 96 128 public static function DecimalizeFraction($fraction) { 97 129 list($numerator, $denominator) = explode('/', $fraction); 98 130 return $numerator / ($denominator ? $denominator : 1); 99 131 } 100 132 101 133 /** 134 * @param string $binarynumerator 135 * 136 * @return float 137 */ 102 138 public static function DecimalBinary2Float($binarynumerator) { 103 139 $numerator = self::Bin2Dec($binarynumerator); 104 140 $denominator = self::Bin2Dec('1'.str_repeat('0', strlen($binarynumerator))); … … 105 141 return ($numerator / $denominator); 106 142 } 107 143 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 */ 109 152 public static function NormalizeBinaryPoint($binarypointnumber, $maxbits=52) { 110 // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html111 153 if (strpos($binarypointnumber, '.') === false) { 112 154 $binarypointnumber = '0.'.$binarypointnumber; 113 } elseif ($binarypointnumber {0}== '.') {155 } elseif ($binarypointnumber[0] == '.') { 114 156 $binarypointnumber = '0'.$binarypointnumber; 115 157 } 116 158 $exponent = 0; 117 while (($binarypointnumber {0}!= '1') || (substr($binarypointnumber, 1, 1) != '.')) {159 while (($binarypointnumber[0] != '1') || (substr($binarypointnumber, 1, 1) != '.')) { 118 160 if (substr($binarypointnumber, 1, 1) == '.') { 119 161 $exponent--; 120 162 $binarypointnumber = substr($binarypointnumber, 2, 1).'.'.substr($binarypointnumber, 3); … … 122 164 $pointpos = strpos($binarypointnumber, '.'); 123 165 $exponent += ($pointpos - 1); 124 166 $binarypointnumber = str_replace('.', '', $binarypointnumber); 125 $binarypointnumber = $binarypointnumber {0}.'.'.substr($binarypointnumber, 1);167 $binarypointnumber = $binarypointnumber[0].'.'.substr($binarypointnumber, 1); 126 168 } 127 169 } 128 170 $binarypointnumber = str_pad(substr($binarypointnumber, 0, $maxbits + 2), $maxbits + 2, '0', STR_PAD_RIGHT); … … 129 171 return array('normalized'=>$binarypointnumber, 'exponent'=>(int) $exponent); 130 172 } 131 173 132 174 /** 175 * @link http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html 176 * 177 * @param float $floatvalue 178 * 179 * @return string 180 */ 133 181 public static function Float2BinaryDecimal($floatvalue) { 134 // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html135 182 $maxbits = 128; // to how many bits of precision should the calculations be taken? 136 183 $intpart = self::trunc($floatvalue); 137 184 $floatpart = abs($floatvalue - $intpart); … … 145 192 return $binarypointnumber; 146 193 } 147 194 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 */ 149 203 public static function Float2String($floatvalue, $bits) { 150 // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html 204 $exponentbits = 0; 205 $fractionbits = 0; 151 206 switch ($bits) { 152 207 case 32: 153 208 $exponentbits = 8; … … 176 231 return self::BigEndian2String(self::Bin2Dec($signbit.$exponentbitstring.$fractionbitstring), $bits % 8, false); 177 232 } 178 233 179 234 /** 235 * @param string $byteword 236 * 237 * @return float|false 238 */ 180 239 public static function LittleEndian2Float($byteword) { 181 240 return self::BigEndian2Float(strrev($byteword)); 182 241 } 183 242 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 */ 185 253 public static function BigEndian2Float($byteword) { 186 // ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic187 // http://www.psc.edu/general/software/packages/ieee/ieee.html188 // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html189 190 254 $bitword = self::BigEndian2Bin($byteword); 191 255 if (!$bitword) { 192 256 return 0; 193 257 } 194 $signbit = $bitword{0}; 258 $signbit = $bitword[0]; 259 $floatvalue = 0; 260 $exponentbits = 0; 261 $fractionbits = 0; 195 262 196 263 switch (strlen($byteword) * 8) { 197 264 case 32: … … 208 275 // 80-bit Apple SANE format 209 276 // http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/ 210 277 $exponentstring = substr($bitword, 1, 15); 211 $isnormalized = intval($bitword {16});278 $isnormalized = intval($bitword[16]); 212 279 $fractionstring = substr($bitword, 17, 63); 213 280 $exponent = pow(2, self::Bin2Dec($exponentstring) - 16383); 214 281 $fraction = $isnormalized + self::DecimalBinary2Float($fractionstring); … … 259 326 return (float) $floatvalue; 260 327 } 261 328 262 329 /** 330 * @param string $byteword 331 * @param bool $synchsafe 332 * @param bool $signed 333 * 334 * @return int|float|false 335 * @throws Exception 336 */ 263 337 public static function BigEndian2Int($byteword, $synchsafe=false, $signed=false) { 264 338 $intvalue = 0; 265 339 $bytewordlen = strlen($byteword); … … 269 343 for ($i = 0; $i < $bytewordlen; $i++) { 270 344 if ($synchsafe) { // disregard MSB, effectively 7-bit bytes 271 345 //$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); 273 347 } else { 274 $intvalue += ord($byteword {$i}) * pow(256, ($bytewordlen - 1 - $i));348 $intvalue += ord($byteword[$i]) * pow(256, ($bytewordlen - 1 - $i)); 275 349 } 276 350 } 277 351 if ($signed && !$synchsafe) { … … 288 362 return self::CastAsInt($intvalue); 289 363 } 290 364 291 365 /** 366 * @param string $byteword 367 * @param bool $signed 368 * 369 * @return int|float|false 370 */ 292 371 public static function LittleEndian2Int($byteword, $signed=false) { 293 372 return self::BigEndian2Int(strrev($byteword), false, $signed); 294 373 } 295 374 375 /** 376 * @param string $byteword 377 * 378 * @return string 379 */ 296 380 public static function LittleEndian2Bin($byteword) { 297 381 return self::BigEndian2Bin(strrev($byteword)); 298 382 } 299 383 384 /** 385 * @param string $byteword 386 * 387 * @return string 388 */ 300 389 public static function BigEndian2Bin($byteword) { 301 390 $binvalue = ''; 302 391 $bytewordlen = strlen($byteword); 303 392 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); 305 394 } 306 395 return $binvalue; 307 396 } 308 397 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 */ 310 407 public static function BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false) { 311 408 if ($number < 0) { 312 409 throw new Exception('ERROR: self::BigEndian2String() does not support negative numbers'); … … 327 424 return str_pad($intstring, $minbytes, "\x00", STR_PAD_LEFT); 328 425 } 329 426 330 427 /** 428 * @param int $number 429 * 430 * @return string 431 */ 331 432 public static function Dec2Bin($number) { 332 433 while ($number >= 256) { 333 434 $bytes[] = (($number / 256) - (floor($number / 256))) * 256; … … 341 442 return $binstring; 342 443 } 343 444 344 445 /** 446 * @param string $binstring 447 * @param bool $signed 448 * 449 * @return int|float 450 */ 345 451 public static function Bin2Dec($binstring, $signed=false) { 346 452 $signmult = 1; 347 453 if ($signed) { 348 if ($binstring {0}== '1') {454 if ($binstring[0] == '1') { 349 455 $signmult = -1; 350 456 } 351 457 $binstring = substr($binstring, 1); … … 357 463 return self::CastAsInt($decvalue * $signmult); 358 464 } 359 465 360 466 /** 467 * @param string $binstring 468 * 469 * @return string 470 */ 361 471 public static function Bin2String($binstring) { 362 472 // return 'hi' for input of '0110100001101001' 363 473 $string = ''; … … 368 478 return $string; 369 479 } 370 480 371 481 /** 482 * @param int $number 483 * @param int $minbytes 484 * @param bool $synchsafe 485 * 486 * @return string 487 */ 372 488 public static function LittleEndian2String($number, $minbytes=1, $synchsafe=false) { 373 489 $intstring = ''; 374 490 while ($number > 0) { … … 383 499 return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT); 384 500 } 385 501 386 502 /** 503 * @param array $array1 504 * @param array $array2 505 * 506 * @return array|false 507 */ 387 508 public static function array_merge_clobber($array1, $array2) { 388 509 // written by kcØhireability*com 389 510 // taken from http://www.php.net/manual/en/function.array-merge-recursive.php … … 401 522 return $newarray; 402 523 } 403 524 404 525 /** 526 * @param array $array1 527 * @param array $array2 528 * 529 * @return array|false 530 */ 405 531 public static function array_merge_noclobber($array1, $array2) { 406 532 if (!is_array($array1) || !is_array($array2)) { 407 533 return false; … … 417 543 return $newarray; 418 544 } 419 545 546 /** 547 * @param array $array1 548 * @param array $array2 549 * 550 * @return array|false|null 551 */ 420 552 public static function flipped_array_merge_noclobber($array1, $array2) { 421 553 if (!is_array($array1) || !is_array($array2)) { 422 554 return false; … … 431 563 return array_flip($newarray); 432 564 } 433 565 434 566 /** 567 * @param array $theArray 568 * 569 * @return bool 570 */ 435 571 public static function ksort_recursive(&$theArray) { 436 572 ksort($theArray); 437 573 foreach ($theArray as $key => $value) { … … 442 578 return true; 443 579 } 444 580 581 /** 582 * @param string $filename 583 * @param int $numextensions 584 * 585 * @return string 586 */ 445 587 public static function fileextension($filename, $numextensions=1) { 446 588 if (strstr($filename, '.')) { 447 589 $reversedfilename = strrev($filename); … … 457 599 return ''; 458 600 } 459 601 460 602 /** 603 * @param int $seconds 604 * 605 * @return string 606 */ 461 607 public static function PlaytimeString($seconds) { 462 608 $sign = (($seconds < 0) ? '-' : ''); 463 609 $seconds = round(abs($seconds)); … … 467 613 return $sign.($H ? $H.':' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).':'.str_pad($S, 2, 0, STR_PAD_LEFT); 468 614 } 469 615 470 616 /** 617 * @param int $macdate 618 * 619 * @return int|float 620 */ 471 621 public static function DateMac2Unix($macdate) { 472 622 // Macintosh timestamp: seconds since 00:00h January 1, 1904 473 623 // UNIX timestamp: seconds since 00:00h January 1, 1970 … … 474 624 return self::CastAsInt($macdate - 2082844800); 475 625 } 476 626 477 627 /** 628 * @param string $rawdata 629 * 630 * @return float 631 */ 478 632 public static function FixedPoint8_8($rawdata) { 479 633 return self::BigEndian2Int(substr($rawdata, 0, 1)) + (float) (self::BigEndian2Int(substr($rawdata, 1, 1)) / pow(2, 8)); 480 634 } 481 635 482 636 /** 637 * @param string $rawdata 638 * 639 * @return float 640 */ 483 641 public static function FixedPoint16_16($rawdata) { 484 642 return self::BigEndian2Int(substr($rawdata, 0, 2)) + (float) (self::BigEndian2Int(substr($rawdata, 2, 2)) / pow(2, 16)); 485 643 } 486 644 487 645 /** 646 * @param string $rawdata 647 * 648 * @return float 649 */ 488 650 public static function FixedPoint2_30($rawdata) { 489 651 $binarystring = self::BigEndian2Bin($rawdata); 490 652 return self::Bin2Dec(substr($binarystring, 0, 2)) + (float) (self::Bin2Dec(substr($binarystring, 2, 30)) / pow(2, 30)); … … 491 653 } 492 654 493 655 656 /** 657 * @param string $ArrayPath 658 * @param string $Separator 659 * @param mixed $Value 660 * 661 * @return array 662 */ 494 663 public static function CreateDeepArray($ArrayPath, $Separator, $Value) { 495 664 // assigns $Value to a nested array path: 496 665 // $foo = self::CreateDeepArray('/path/to/my', '/', 'file.txt') … … 507 676 return $ReturnedArray; 508 677 } 509 678 679 /** 680 * @param array $arraydata 681 * @param bool $returnkey 682 * 683 * @return int|false 684 */ 510 685 public static function array_max($arraydata, $returnkey=false) { 511 686 $maxvalue = false; 512 687 $maxkey = false; … … 521 696 return ($returnkey ? $maxkey : $maxvalue); 522 697 } 523 698 699 /** 700 * @param array $arraydata 701 * @param bool $returnkey 702 * 703 * @return int|false 704 */ 524 705 public static function array_min($arraydata, $returnkey=false) { 525 706 $minvalue = false; 526 707 $minkey = false; … … 535 716 return ($returnkey ? $minkey : $minvalue); 536 717 } 537 718 719 /** 720 * @param string $XMLstring 721 * 722 * @return array|false 723 */ 538 724 public static function XML2array($XMLstring) { 539 725 if (function_exists('simplexml_load_string') && function_exists('libxml_disable_entity_loader')) { 540 726 // http://websec.io/2012/08/27/Preventing-XEE-in-PHP.html … … 548 734 return false; 549 735 } 550 736 737 /** 738 * @param SimpleXMLElement|array $XMLobject 739 * 740 * @return array 741 */ 551 742 public static function SimpleXMLelement2array($XMLobject) { 552 743 if (!is_object($XMLobject) && !is_array($XMLobject)) { 553 744 return $XMLobject; 554 745 } 555 $XMLarray = (is_object($XMLobject) ? get_object_vars($XMLobject) : $XMLobject);746 $XMLarray = $XMLobject instanceof SimpleXMLElement ? get_object_vars($XMLobject) : $XMLobject; 556 747 foreach ($XMLarray as $key => $value) { 557 748 $XMLarray[$key] = self::SimpleXMLelement2array($value); 558 749 } … … 559 750 return $XMLarray; 560 751 } 561 752 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 */ 565 764 public static function hash_data($file, $offset, $end, $algorithm) { 566 static $tempdir = '';567 765 if (!self::intValueSupported($end)) { 568 766 return false; 569 767 } 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 } 577 771 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 }589 772 $size = $end - $offset; 590 while (true) {591 if (GETID3_OS_ISWINDOWS) {592 773 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; 622 781 } 782 $hash = hash_final($ctx); 783 fclose($fp); 623 784 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; 649 786 } 650 787 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 */ 651 799 public static function CopyFileParts($filename_source, $filename_dest, $offset, $length) { 652 800 if (!self::intValueSupported($offset + $length)) { 653 801 throw new Exception('cannot copy file portion, it extends beyond the '.round(PHP_INT_MAX / 1073741824).'GB limit'); … … 660 808 $byteswritten = fwrite($fp_dest, $buffer, $byteslefttowrite); 661 809 $byteslefttowrite -= $byteswritten; 662 810 } 811 fclose($fp_dest); 663 812 return true; 664 813 } else { 814 fclose($fp_src); 665 815 throw new Exception('failed to seek to offset '.$offset.' in '.$filename_source); 666 816 } 667 fclose($fp_dest);668 817 } else { 669 818 throw new Exception('failed to create file for writing '.$filename_dest); 670 819 } 671 fclose($fp_src);672 820 } else { 673 821 throw new Exception('failed to open file for reading '.$filename_source); 674 822 } 675 return false;676 823 } 677 824 825 /** 826 * @param int $charval 827 * 828 * @return string 829 */ 678 830 public static function iconv_fallback_int_utf8($charval) { 679 831 if ($charval < 128) { 680 832 // 0bbbbbbb … … 698 850 return $newcharstring; 699 851 } 700 852 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 */ 702 861 public static function iconv_fallback_iso88591_utf8($string, $bom=false) { 703 862 if (function_exists('utf8_encode')) { 704 863 return utf8_encode($string); … … 709 868 $newcharstring .= "\xEF\xBB\xBF"; 710 869 } 711 870 for ($i = 0; $i < strlen($string); $i++) { 712 $charval = ord($string {$i});871 $charval = ord($string[$i]); 713 872 $newcharstring .= self::iconv_fallback_int_utf8($charval); 714 873 } 715 874 return $newcharstring; 716 875 } 717 876 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 */ 719 885 public static function iconv_fallback_iso88591_utf16be($string, $bom=false) { 720 886 $newcharstring = ''; 721 887 if ($bom) { … … 722 888 $newcharstring .= "\xFE\xFF"; 723 889 } 724 890 for ($i = 0; $i < strlen($string); $i++) { 725 $newcharstring .= "\x00".$string {$i};891 $newcharstring .= "\x00".$string[$i]; 726 892 } 727 893 return $newcharstring; 728 894 } 729 895 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 */ 731 904 public static function iconv_fallback_iso88591_utf16le($string, $bom=false) { 732 905 $newcharstring = ''; 733 906 if ($bom) { … … 734 907 $newcharstring .= "\xFF\xFE"; 735 908 } 736 909 for ($i = 0; $i < strlen($string); $i++) { 737 $newcharstring .= $string {$i}."\x00";910 $newcharstring .= $string[$i]."\x00"; 738 911 } 739 912 return $newcharstring; 740 913 } 741 914 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 */ 743 922 public static function iconv_fallback_iso88591_utf16($string) { 744 923 return self::iconv_fallback_iso88591_utf16le($string, true); 745 924 } 746 925 747 // UTF-8 => ISO-8859-1 926 /** 927 * UTF-8 => ISO-8859-1 928 * 929 * @param string $string 930 * 931 * @return string 932 */ 748 933 public static function iconv_fallback_utf8_iso88591($string) { 749 934 if (function_exists('utf8_decode')) { 750 935 return utf8_decode($string); … … 754 939 $offset = 0; 755 940 $stringlength = strlen($string); 756 941 while ($offset < $stringlength) { 757 if ((ord($string {$offset}) | 0x07) == 0xF7) {942 if ((ord($string[$offset]) | 0x07) == 0xF7) { 758 943 // 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); 763 948 $offset += 4; 764 } elseif ((ord($string {$offset}) | 0x0F) == 0xEF) {949 } elseif ((ord($string[$offset]) | 0x0F) == 0xEF) { 765 950 // 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); 769 954 $offset += 3; 770 } elseif ((ord($string {$offset}) | 0x1F) == 0xDF) {955 } elseif ((ord($string[$offset]) | 0x1F) == 0xDF) { 771 956 // 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); 774 959 $offset += 2; 775 } elseif ((ord($string {$offset}) | 0x7F) == 0x7F) {960 } elseif ((ord($string[$offset]) | 0x7F) == 0x7F) { 776 961 // 0bbbbbbb 777 $charval = ord($string {$offset});962 $charval = ord($string[$offset]); 778 963 $offset += 1; 779 964 } else { 780 965 // error? throw some kind of warning here? … … 788 973 return $newcharstring; 789 974 } 790 975 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 */ 792 984 public static function iconv_fallback_utf8_utf16be($string, $bom=false) { 793 985 $newcharstring = ''; 794 986 if ($bom) { … … 797 989 $offset = 0; 798 990 $stringlength = strlen($string); 799 991 while ($offset < $stringlength) { 800 if ((ord($string {$offset}) | 0x07) == 0xF7) {992 if ((ord($string[$offset]) | 0x07) == 0xF7) { 801 993 // 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); 806 998 $offset += 4; 807 } elseif ((ord($string {$offset}) | 0x0F) == 0xEF) {999 } elseif ((ord($string[$offset]) | 0x0F) == 0xEF) { 808 1000 // 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); 812 1004 $offset += 3; 813 } elseif ((ord($string {$offset}) | 0x1F) == 0xDF) {1005 } elseif ((ord($string[$offset]) | 0x1F) == 0xDF) { 814 1006 // 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); 817 1009 $offset += 2; 818 } elseif ((ord($string {$offset}) | 0x7F) == 0x7F) {1010 } elseif ((ord($string[$offset]) | 0x7F) == 0x7F) { 819 1011 // 0bbbbbbb 820 $charval = ord($string {$offset});1012 $charval = ord($string[$offset]); 821 1013 $offset += 1; 822 1014 } else { 823 1015 // error? throw some kind of warning here? … … 831 1023 return $newcharstring; 832 1024 } 833 1025 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 */ 835 1034 public static function iconv_fallback_utf8_utf16le($string, $bom=false) { 836 1035 $newcharstring = ''; 837 1036 if ($bom) { … … 840 1039 $offset = 0; 841 1040 $stringlength = strlen($string); 842 1041 while ($offset < $stringlength) { 843 if ((ord($string {$offset}) | 0x07) == 0xF7) {1042 if ((ord($string[$offset]) | 0x07) == 0xF7) { 844 1043 // 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); 849 1048 $offset += 4; 850 } elseif ((ord($string {$offset}) | 0x0F) == 0xEF) {1049 } elseif ((ord($string[$offset]) | 0x0F) == 0xEF) { 851 1050 // 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); 855 1054 $offset += 3; 856 } elseif ((ord($string {$offset}) | 0x1F) == 0xDF) {1055 } elseif ((ord($string[$offset]) | 0x1F) == 0xDF) { 857 1056 // 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); 860 1059 $offset += 2; 861 } elseif ((ord($string {$offset}) | 0x7F) == 0x7F) {1060 } elseif ((ord($string[$offset]) | 0x7F) == 0x7F) { 862 1061 // 0bbbbbbb 863 $charval = ord($string {$offset});1062 $charval = ord($string[$offset]); 864 1063 $offset += 1; 865 1064 } else { 866 1065 // error? maybe throw some warning here? … … 874 1073 return $newcharstring; 875 1074 } 876 1075 877 // UTF-8 => UTF-16LE (BOM) 1076 /** 1077 * UTF-8 => UTF-16LE (BOM) 1078 * 1079 * @param string $string 1080 * 1081 * @return string 1082 */ 878 1083 public static function iconv_fallback_utf8_utf16($string) { 879 1084 return self::iconv_fallback_utf8_utf16le($string, true); 880 1085 } 881 1086 882 // UTF-16BE => UTF-8 1087 /** 1088 * UTF-16BE => UTF-8 1089 * 1090 * @param string $string 1091 * 1092 * @return string 1093 */ 883 1094 public static function iconv_fallback_utf16be_utf8($string) { 884 1095 if (substr($string, 0, 2) == "\xFE\xFF") { 885 1096 // strip BOM … … 893 1104 return $newcharstring; 894 1105 } 895 1106 896 // UTF-16LE => UTF-8 1107 /** 1108 * UTF-16LE => UTF-8 1109 * 1110 * @param string $string 1111 * 1112 * @return string 1113 */ 897 1114 public static function iconv_fallback_utf16le_utf8($string) { 898 1115 if (substr($string, 0, 2) == "\xFF\xFE") { 899 1116 // strip BOM … … 907 1124 return $newcharstring; 908 1125 } 909 1126 910 // UTF-16BE => ISO-8859-1 1127 /** 1128 * UTF-16BE => ISO-8859-1 1129 * 1130 * @param string $string 1131 * 1132 * @return string 1133 */ 911 1134 public static function iconv_fallback_utf16be_iso88591($string) { 912 1135 if (substr($string, 0, 2) == "\xFE\xFF") { 913 1136 // strip BOM … … 921 1144 return $newcharstring; 922 1145 } 923 1146 924 // UTF-16LE => ISO-8859-1 1147 /** 1148 * UTF-16LE => ISO-8859-1 1149 * 1150 * @param string $string 1151 * 1152 * @return string 1153 */ 925 1154 public static function iconv_fallback_utf16le_iso88591($string) { 926 1155 if (substr($string, 0, 2) == "\xFF\xFE") { 927 1156 // strip BOM … … 935 1164 return $newcharstring; 936 1165 } 937 1166 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 */ 939 1174 public static function iconv_fallback_utf16_iso88591($string) { 940 1175 $bom = substr($string, 0, 2); 941 1176 if ($bom == "\xFE\xFF") { … … 946 1181 return $string; 947 1182 } 948 1183 949 // UTF-16 (BOM) => UTF-8 1184 /** 1185 * UTF-16 (BOM) => UTF-8 1186 * 1187 * @param string $string 1188 * 1189 * @return string 1190 */ 950 1191 public static function iconv_fallback_utf16_utf8($string) { 951 1192 $bom = substr($string, 0, 2); 952 1193 if ($bom == "\xFE\xFF") { … … 957 1198 return $string; 958 1199 } 959 1200 1201 /** 1202 * @param string $in_charset 1203 * @param string $out_charset 1204 * @param string $string 1205 * 1206 * @return string 1207 * @throws Exception 1208 */ 960 1209 public static function iconv_fallback($in_charset, $out_charset, $string) { 961 1210 962 1211 if ($in_charset == $out_charset) { … … 963 1212 return $string; 964 1213 } 965 1214 966 // mb_convert_encoding() avail ble1215 // mb_convert_encoding() available 967 1216 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 } 968 1227 if ($converted_string = @mb_convert_encoding($string, $out_charset, $in_charset)) { 969 1228 switch ($out_charset) { 970 1229 case 'ISO-8859-1': … … 974 1233 return $converted_string; 975 1234 } 976 1235 return $string; 977 } 978 // iconv() avail ble979 elseif (function_exists('iconv')) {1236 1237 // iconv() available 1238 } elseif (function_exists('iconv')) { 980 1239 if ($converted_string = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) { 981 1240 switch ($out_charset) { 982 1241 case 'ISO-8859-1': … … 1017 1276 throw new Exception('PHP does not has mb_convert_encoding() or iconv() support - cannot convert from '.$in_charset.' to '.$out_charset); 1018 1277 } 1019 1278 1279 /** 1280 * @param mixed $data 1281 * @param string $charset 1282 * 1283 * @return mixed 1284 */ 1020 1285 public static function recursiveMultiByteCharString2HTML($data, $charset='ISO-8859-1') { 1021 1286 if (is_string($data)) { 1022 1287 return self::MultiByteCharString2HTML($data, $charset); … … 1031 1296 return $data; 1032 1297 } 1033 1298 1299 /** 1300 * @param string|int|float $string 1301 * @param string $charset 1302 * 1303 * @return string 1304 */ 1034 1305 public static function MultiByteCharString2HTML($string, $charset='ISO-8859-1') { 1035 1306 $string = (string) $string; // in case trying to pass a numeric (float, int) string, would otherwise return an empty string 1036 1307 $HTMLstring = ''; … … 1069 1340 case 'utf-8': 1070 1341 $strlen = strlen($string); 1071 1342 for ($i = 0; $i < $strlen; $i++) { 1072 $char_ord_val = ord($string {$i});1343 $char_ord_val = ord($string[$i]); 1073 1344 $charval = 0; 1074 1345 if ($char_ord_val < 0x80) { 1075 1346 $charval = $char_ord_val; 1076 1347 } elseif ((($char_ord_val & 0xF0) >> 4) == 0x0F && $i+3 < $strlen) { 1077 1348 $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); 1081 1352 } elseif ((($char_ord_val & 0xE0) >> 5) == 0x07 && $i+2 < $strlen) { 1082 1353 $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); 1085 1356 } elseif ((($char_ord_val & 0xC0) >> 6) == 0x03 && $i+1 < $strlen) { 1086 1357 $charval = (($char_ord_val & 0x1F) << 6); 1087 $charval += (ord($string {++$i}) & 0x3F);1358 $charval += (ord($string[++$i]) & 0x3F); 1088 1359 } 1089 1360 if (($charval >= 32) && ($charval <= 127)) { 1090 1361 $HTMLstring .= htmlentities(chr($charval)); … … 1123 1394 return $HTMLstring; 1124 1395 } 1125 1396 1126 1127 1397 /** 1398 * @param int $namecode 1399 * 1400 * @return string 1401 */ 1128 1402 public static function RGADnameLookup($namecode) { 1129 1403 static $RGADname = array(); 1130 1404 if (empty($RGADname)) { … … 1136 1410 return (isset($RGADname[$namecode]) ? $RGADname[$namecode] : ''); 1137 1411 } 1138 1412 1139 1413 /** 1414 * @param int $originatorcode 1415 * 1416 * @return string 1417 */ 1140 1418 public static function RGADoriginatorLookup($originatorcode) { 1141 1419 static $RGADoriginator = array(); 1142 1420 if (empty($RGADoriginator)) { … … 1149 1427 return (isset($RGADoriginator[$originatorcode]) ? $RGADoriginator[$originatorcode] : ''); 1150 1428 } 1151 1429 1152 1430 /** 1431 * @param int $rawadjustment 1432 * @param int $signbit 1433 * 1434 * @return float 1435 */ 1153 1436 public static function RGADadjustmentLookup($rawadjustment, $signbit) { 1154 $adjustment = $rawadjustment / 10;1437 $adjustment = (float) $rawadjustment / 10; 1155 1438 if ($signbit == 1) { 1156 1439 $adjustment *= -1; 1157 1440 } 1158 return (float)$adjustment;1441 return $adjustment; 1159 1442 } 1160 1443 1161 1444 /** 1445 * @param int $namecode 1446 * @param int $originatorcode 1447 * @param int $replaygain 1448 * 1449 * @return string 1450 */ 1162 1451 public static function RGADgainString($namecode, $originatorcode, $replaygain) { 1163 1452 if ($replaygain < 0) { 1164 1453 $signbit = '1'; … … 1174 1463 return $gainstring; 1175 1464 } 1176 1465 1466 /** 1467 * @param float $amplitude 1468 * 1469 * @return float 1470 */ 1177 1471 public static function RGADamplitude2dB($amplitude) { 1178 1472 return 20 * log10($amplitude); 1179 1473 } 1180 1474 1181 1475 /** 1476 * @param string $imgData 1477 * @param array $imageinfo 1478 * 1479 * @return array|false 1480 */ 1182 1481 public static function GetDataImageSize($imgData, &$imageinfo=array()) { 1183 1482 static $tempdir = ''; 1184 1483 if (empty($tempdir)) { … … 1213 1512 return $GetDataImageSize; 1214 1513 } 1215 1514 1515 /** 1516 * @param string $mime_type 1517 * 1518 * @return string 1519 */ 1216 1520 public static function ImageExtFromMime($mime_type) { 1217 1521 // temporary way, works OK for now, but should be reworked in the future 1218 1522 return str_replace(array('image/', 'x-', 'jpeg'), array('', '', 'jpg'), $mime_type); 1219 1523 } 1220 1524 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 */ 1242 1530 public static function CopyTagsToComments(&$ThisFileInfo) { 1243 1531 1244 1532 // Copy all entries from ['tags'] into common ['comments'] … … 1326 1614 return true; 1327 1615 } 1328 1616 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 */ 1330 1626 public static function EmbeddedLookup($key, $begin, $end, $file, $name) { 1331 1627 1332 1628 // Cached … … 1373 1669 return (isset($cache[$file][$name][$key]) ? $cache[$file][$name][$key] : ''); 1374 1670 } 1375 1671 1672 /** 1673 * @param string $filename 1674 * @param string $sourcefile 1675 * @param bool $DieOnFailure 1676 * 1677 * @return bool 1678 * @throws Exception 1679 */ 1376 1680 public static function IncludeDependency($filename, $sourcefile, $DieOnFailure=false) { 1377 1681 global $GETID3_ERRORARRAY; 1378 1682 … … 1393 1697 return false; 1394 1698 } 1395 1699 1700 /** 1701 * @param string $string 1702 * 1703 * @return string 1704 */ 1396 1705 public static function trimNullByte($string) { 1397 1706 return trim($string, "\x00"); 1398 1707 } 1399 1708 1709 /** 1710 * @param string $path 1711 * 1712 * @return float|bool 1713 */ 1400 1714 public static function getFileSizeSyscall($path) { 1401 1715 $filesize = false; 1402 1716 … … 1421 1735 return $filesize; 1422 1736 } 1423 1737 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 } 1424 1767 1425 1768 /** 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 */ 1431 1776 public static function mb_basename($path, $suffix = null) { 1432 1777 $splited = preg_split('#/#', rtrim($path, '/ ')); 1433 1778 return substr(basename('X'.$splited[count($splited) - 1], $suffix), 1); -
src/wp-includes/ID3/getid3.php
1 1 <?php 2 2 ///////////////////////////////////////////////////////////////// 3 3 /// 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 // 8 7 // // 9 8 // Please see readme.txt for more information // 10 9 // /// … … 26 25 define('ENT_SUBSTITUTE', (defined('ENT_IGNORE') ? ENT_IGNORE : 8)); 27 26 } 28 27 28 /* 29 https://www.getid3.org/phpBB3/viewtopic.php?t=2114 30 If you are running into a the problem where filenames with special characters are being handled 31 incorrectly by external helper programs (e.g. metaflac), notably with the special characters removed, 32 and 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 29 36 // attempt to define temp dir as something flexible but reliable 30 37 $temp_dir = ini_get('upload_tmp_dir'); 31 38 if ($temp_dir && (!is_dir($temp_dir) || !is_readable($temp_dir))) { … … 74 81 75 82 class getID3 76 83 { 77 / / public: Settings78 public $encoding = 'UTF-8'; // CASE SENSITIVE! - i.e. (must be supported by iconv()). Examples: ISO-8859-1 UTF-8 UTF-16 UTF-16BE79 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 */ 80 87 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'; 88 94 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'; 91 101 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 */ 94 105 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; 100 112 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 */ 102 208 public $option_fread_buffer_size = 32768; 103 209 104 210 // 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 */ 108 236 public $tempdir = GETID3_TEMP_DIR; 237 238 /** 239 * @var int 240 */ 109 241 public $memory_limit = 0; 110 242 111 // Protected variables 243 /** 244 * @var string 245 */ 112 246 protected $startup_error = ''; 247 248 /** 249 * @var string 250 */ 113 251 protected $startup_warning = ''; 114 252 115 const VERSION = '1.9.1 4-201706111222';253 const VERSION = '1.9.17-201907240906'; 116 254 const FREAD_BUFFER_SIZE = 32768; 117 255 118 256 const ATTACHMENTS_NONE = false; 119 257 const ATTACHMENTS_INLINE = true; 120 258 121 // public: constructor122 259 public function __construct() { 123 260 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 124 268 // Check memory 125 269 $this->memory_limit = ini_get('memory_limit'); 126 270 if (preg_match('#([0-9]+) ?M#i', $this->memory_limit, $matches)) { … … 176 320 177 321 // Needed for Windows only: 178 322 // Define locations of helper applications for Shorten, VorbisComment, MetaFLAC 179 // as well as other helper functions such as head, tail, md5sum,etc323 // as well as other helper functions such as head, etc 180 324 // This path cannot contain spaces, but the below code will attempt to get the 181 325 // 8.3-equivalent path automatically 182 326 // IMPORTANT: This path must include the trailing slash … … 219 363 echo $this->startup_error; 220 364 throw new getid3_exception($this->startup_error); 221 365 } 222 223 return true;224 366 } 225 367 368 /** 369 * @return string 370 */ 226 371 public function version() { 227 372 return self::VERSION; 228 373 } 229 374 375 /** 376 * @return int 377 */ 230 378 public function fread_buffer_size() { 231 379 return $this->option_fread_buffer_size; 232 380 } 233 381 234 235 // public: setOption 382 /** 383 * @param array $optArray 384 * 385 * @return bool 386 */ 236 387 public function setOption($optArray) { 237 388 if (!is_array($optArray) || empty($optArray)) { 238 389 return false; … … 246 397 return true; 247 398 } 248 399 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) { 251 409 try { 252 410 if (!empty($this->startup_error)) { 253 411 throw new getid3_exception($this->startup_error); … … 270 428 } 271 429 272 430 $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); 274 432 275 433 // 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'))) { 278 438 // great 279 439 } else { 280 440 $errormessagelist = array(); … … 331 491 } elseif (getid3_lib::intValueSupported($real_filesize)) { 332 492 unset($this->info['filesize']); 333 493 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'); 335 495 } 336 496 $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.'); 338 498 } 339 499 } 340 500 … … 346 506 return false; 347 507 } 348 508 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) { 351 519 try { 352 if (!$this->openfile($filename, $filesize )) {520 if (!$this->openfile($filename, $filesize, $fp)) { 353 521 return $this->info; 354 522 } 355 523 … … 383 551 $header = fread($this->fp, 10); 384 552 if ((substr($header, 0, 3) == 'ID3') && (strlen($header) == 10)) { 385 553 $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]); 388 556 $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 389 557 } 390 558 } … … 497 665 } 498 666 499 667 500 // private: error handling 668 /** 669 * Error handling. 670 * 671 * @param string $message 672 * 673 * @return array 674 */ 501 675 public function error($message) { 502 676 $this->CleanUp(); 503 677 if (!isset($this->info['error'])) { … … 508 682 } 509 683 510 684 511 // private: warning handling 685 /** 686 * Warning handling. 687 * 688 * @param string $message 689 * 690 * @return bool 691 */ 512 692 public function warning($message) { 513 693 $this->info['warning'][] = $message; 514 694 return true; … … 515 695 } 516 696 517 697 518 // private: CleanUp 698 /** 699 * @return bool 700 */ 519 701 private function CleanUp() { 520 702 521 703 // remove possible empty keys … … 562 744 return true; 563 745 } 564 746 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 */ 567 752 public function GetFileFormatArray() { 568 753 static $format_info = array(); 569 754 if (empty($format_info)) { … … 584 769 'pattern' => '^ADIF', 585 770 'group' => 'audio', 586 771 'module' => 'aac', 587 'mime_type' => 'a pplication/octet-stream',772 'mime_type' => 'audio/aac', 588 773 'fail_ape' => 'WARNING', 589 774 ), 590 775 … … 602 787 'pattern' => '^\\xFF[\\xF0-\\xF1\\xF8-\\xF9]', 603 788 'group' => 'audio', 604 789 'module' => 'aac', 605 'mime_type' => 'a pplication/octet-stream',790 'mime_type' => 'audio/aac', 606 791 'fail_ape' => 'WARNING', 607 792 ), 608 793 … … 649 834 650 835 // DSS - audio - Digital Speech Standard 651 836 'dss' => array( 652 'pattern' => '^[\\x02-\\x0 6]ds[s2]',837 'pattern' => '^[\\x02-\\x08]ds[s2]', 653 838 'group' => 'audio', 654 839 'module' => 'dss', 655 840 'mime_type' => 'application/octet-stream', … … 668 853 'pattern' => '^fLaC', 669 854 'group' => 'audio', 670 855 'module' => 'flac', 671 'mime_type' => 'audio/ x-flac',856 'mime_type' => 'audio/flac', 672 857 ), 673 858 674 859 // LA - audio - Lossless Audio (LA) … … 700 885 'pattern' => '^MAC ', 701 886 'group' => 'audio', 702 887 'module' => 'monkey', 703 'mime_type' => 'a pplication/octet-stream',888 'mime_type' => 'audio/x-monkeys-audio', 704 889 ), 705 890 706 891 // has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available … … 889 1074 'pattern' => '^(RIFF|SDSS|FORM)', 890 1075 'group' => 'audio-video', 891 1076 'module' => 'riff', 892 'mime_type' => 'audio/ x-wav',1077 'mime_type' => 'audio/wav', 893 1078 'fail_ape' => 'WARNING', 894 1079 ), 895 1080 … … 1053 1238 'pattern' => '^\\x1F\\x8B\\x08', 1054 1239 'group' => 'archive', 1055 1240 'module' => 'gzip', 1056 'mime_type' => 'application/ x-gzip',1241 'mime_type' => 'application/gzip', 1057 1242 'fail_id3' => 'ERROR', 1058 1243 'fail_ape' => 'ERROR', 1059 1244 ), … … 1068 1253 'fail_ape' => 'ERROR', 1069 1254 ), 1070 1255 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 ), 1071 1265 1266 1072 1267 // Misc other formats 1073 1268 1074 1269 // PAR2 - data - Parity Volume Set Specification 2.0 … … 1115 1310 return $format_info; 1116 1311 } 1117 1312 1118 1119 1313 /** 1314 * @param string $filedata 1315 * @param string $filename 1316 * 1317 * @return mixed|false 1318 */ 1120 1319 public function GetFileFormat(&$filedata, $filename='') { 1121 1320 // this function will determine the format of a file based on usually 1122 1321 // the first 2-4 bytes of the file (8 bytes for PNG, 16 bytes for JPG, … … 1135 1334 1136 1335 1137 1336 if (preg_match('#\\.mp[123a]$#i', $filename)) { 1138 // Too many mp3 encoders on the market put ga bage in front of mpeg files1337 // Too many mp3 encoders on the market put garbage in front of mpeg files 1139 1338 // use assume format on these if format detection failed 1140 1339 $GetFileFormatArray = $this->GetFileFormatArray(); 1141 1340 $info = $GetFileFormatArray['mp3']; … … 1154 1353 return false; 1155 1354 } 1156 1355 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 */ 1159 1362 public function CharConvert(&$array, $encoding) { 1160 1363 1161 1364 // identical encoding - end here … … 1178 1381 } 1179 1382 } 1180 1383 1181 1384 /** 1385 * @return bool 1386 */ 1182 1387 public function HandleAllTags() { 1183 1388 1184 1389 // key name => array (tag name, character encoding) … … 1233 1438 } 1234 1439 } 1235 1440 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 1236 1442 unset($this->info[$comment_name]['comments'][$tag_key]); 1237 1443 } 1238 1444 } … … 1246 1452 1247 1453 if ($this->option_tags_html) { 1248 1454 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 } 1249 1460 $this->info['tags_html'][$tag_name][$tag_key] = getid3_lib::recursiveMultiByteCharString2HTML($valuearray, $this->info[$comment_name]['encoding']); 1250 1461 } 1251 1462 } … … 1254 1465 1255 1466 } 1256 1467 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 1259 1469 if (!empty($this->info['tags'])) { 1260 1470 $unset_keys = array('tags', 'tags_html'); 1261 1471 foreach ($this->info['tags'] as $tagtype => $tagarray) { … … 1301 1511 return true; 1302 1512 } 1303 1513 1514 /** 1515 * @param string $algorithm 1516 * 1517 * @return array|bool 1518 */ 1304 1519 public function getHashdata($algorithm) { 1305 1520 switch ($algorithm) { 1306 1521 case 'md5': … … 1365 1580 1366 1581 } else { 1367 1582 1368 $commandline = 'vorbiscomment -w -c "'.$empty.'" "'.$file.'" "'.$temp.'" 2>&1';1369 1583 $commandline = 'vorbiscomment -w -c '.escapeshellarg($empty).' '.escapeshellarg($file).' '.escapeshellarg($temp).' 2>&1'; 1370 1584 $VorbisCommentError = `$commandline`; 1371 1585 … … 1424 1638 return true; 1425 1639 } 1426 1640 1427 1428 1641 public function ChannelsBitratePlaytimeCalculations() { 1429 1642 1430 1643 // set channelmode on audio … … 1489 1702 } 1490 1703 } 1491 1704 1492 1705 /** 1706 * @return bool 1707 */ 1493 1708 public function CalculateCompressionRatioVideo() { 1494 1709 if (empty($this->info['video'])) { 1495 1710 return false; … … 1537 1752 return true; 1538 1753 } 1539 1754 1540 1755 /** 1756 * @return bool 1757 */ 1541 1758 public function CalculateCompressionRatioAudio() { 1542 1759 if (empty($this->info['audio']['bitrate']) || empty($this->info['audio']['channels']) || empty($this->info['audio']['sample_rate']) || !is_numeric($this->info['audio']['sample_rate'])) { 1543 1760 return false; … … 1554 1771 return true; 1555 1772 } 1556 1773 1557 1774 /** 1775 * @return bool 1776 */ 1558 1777 public function CalculateReplayGain() { 1559 1778 if (isset($this->info['replay_gain'])) { 1560 1779 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; 1562 1781 } 1563 1782 if (isset($this->info['replay_gain']['track']['adjustment'])) { 1564 1783 $this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment']; … … 1577 1796 return true; 1578 1797 } 1579 1798 1799 /** 1800 * @return bool 1801 */ 1580 1802 public function ProcessAudioStreams() { 1581 1803 if (!empty($this->info['audio']['bitrate']) || !empty($this->info['audio']['channels']) || !empty($this->info['audio']['sample_rate'])) { 1582 1804 if (!isset($this->info['audio']['streams'])) { … … 1590 1812 return true; 1591 1813 } 1592 1814 1815 /** 1816 * @return string|bool 1817 */ 1593 1818 public function getid3_tempnam() { 1594 1819 return tempnam($this->tempdir, 'gI3'); 1595 1820 } 1596 1821 1822 /** 1823 * @param string $name 1824 * 1825 * @return bool 1826 * 1827 * @throws getid3_exception 1828 */ 1597 1829 public function include_module($name) { 1598 1830 //if (!file_exists($this->include_path.'module.'.$name.'.php')) { 1599 1831 if (!file_exists(GETID3_INCLUDEPATH.'module.'.$name.'.php')) { … … 1603 1835 return true; 1604 1836 } 1605 1837 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 } 1608 1851 1609 if (!$ret) {1610 $perms = fileperms($filename);1611 $ret = ($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002);1612 }1613 1614 return $ret;1615 }1616 1617 1852 } 1618 1853 1619 1854 1620 abstract class getid3_handler { 1855 abstract class getid3_handler 1856 { 1621 1857 1622 1858 /** 1623 1859 * @var getID3 … … 1624 1860 */ 1625 1861 protected $getid3; // pointer 1626 1862 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; 1631 1869 1632 private $dependency_to = null; 1870 /** 1871 * String to analyze. 1872 * 1873 * @var string 1874 */ 1875 protected $data_string = ''; 1633 1876 1877 /** 1878 * Seek position in string. 1879 * 1880 * @var int 1881 */ 1882 protected $data_string_position = 0; 1634 1883 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 */ 1635 1902 public function __construct(getID3 $getid3, $call_module=null) { 1636 1903 $this->getid3 = $getid3; 1637 1904 … … 1640 1907 } 1641 1908 } 1642 1909 1643 1644 // Analyze from file pointer 1910 /** 1911 * Analyze from file pointer. 1912 * 1913 * @return bool 1914 */ 1645 1915 abstract public function Analyze(); 1646 1916 1647 1648 // Analyze from string instead 1917 /** 1918 * Analyze from string instead. 1919 * 1920 * @param string $string 1921 */ 1649 1922 public function AnalyzeString($string) { 1650 1923 // Enter string mode 1651 1924 $this->setStringMode($string); … … 1671 1944 $this->data_string_flag = false; 1672 1945 } 1673 1946 1947 /** 1948 * @param string $string 1949 */ 1674 1950 public function setStringMode($string) { 1675 1951 $this->data_string_flag = true; 1676 1952 $this->data_string = $string; … … 1677 1953 $this->data_string_length = strlen($string); 1678 1954 } 1679 1955 1956 /** 1957 * @return int|bool 1958 */ 1680 1959 protected function ftell() { 1681 1960 if ($this->data_string_flag) { 1682 1961 return $this->data_string_position; … … 1684 1963 return ftell($this->getid3->fp); 1685 1964 } 1686 1965 1966 /** 1967 * @param int $bytes 1968 * 1969 * @return string|false 1970 * 1971 * @throws getid3_exception 1972 */ 1687 1973 protected function fread($bytes) { 1688 1974 if ($this->data_string_flag) { 1689 1975 $this->data_string_position += $bytes; … … 1696 1982 1697 1983 //return fread($this->getid3->fp, $bytes); 1698 1984 /* 1699 * http ://www.getid3.org/phpBB3/viewtopic.php?t=19301985 * https://www.getid3.org/phpBB3/viewtopic.php?t=1930 1700 1986 * "I found out that the root cause for the problem was how getID3 uses the PHP system function fread(). 1701 1987 * It seems to assume that fread() would always return as many bytes as were requested. 1702 1988 * 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. … … 1704 1990 */ 1705 1991 $contents = ''; 1706 1992 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 } 1707 1997 $part = fread($this->getid3->fp, $bytes); 1708 1998 $partLength = strlen($part); 1709 1999 $bytes -= $partLength; … … 1712 2002 return $contents; 1713 2003 } 1714 2004 2005 /** 2006 * @param int $bytes 2007 * @param int $whence 2008 * 2009 * @return int 2010 * 2011 * @throws getid3_exception 2012 */ 1715 2013 protected function fseek($bytes, $whence=SEEK_SET) { 1716 2014 if ($this->data_string_flag) { 1717 2015 switch ($whence) { … … 1742 2040 return fseek($this->getid3->fp, $bytes, $whence); 1743 2041 } 1744 2042 2043 /** 2044 * @return bool 2045 */ 1745 2046 protected function feof() { 1746 2047 if ($this->data_string_flag) { 1747 2048 return $this->data_string_position >= $this->data_string_length; … … 1749 2050 return feof($this->getid3->fp); 1750 2051 } 1751 2052 2053 /** 2054 * @param string $module 2055 * 2056 * @return bool 2057 */ 1752 2058 final protected function isDependencyFor($module) { 1753 2059 return $this->dependency_to == $module; 1754 2060 } 1755 2061 2062 /** 2063 * @param string $text 2064 * 2065 * @return bool 2066 */ 1756 2067 protected function error($text) { 1757 2068 $this->getid3->info['error'][] = $text; 1758 2069 … … 1759 2070 return false; 1760 2071 } 1761 2072 2073 /** 2074 * @param string $text 2075 * 2076 * @return bool 2077 */ 1762 2078 protected function warning($text) { 1763 2079 return $this->getid3->warning($text); 1764 2080 } 1765 2081 2082 /** 2083 * @param string $text 2084 */ 1766 2085 protected function notice($text) { 1767 2086 // does nothing for now 1768 2087 } 1769 2088 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 */ 1770 2100 public function saveAttachment($name, $offset, $length, $image_mime=null) { 1771 2101 try { 1772 2102 … … 1820 2150 // close and remove dest file if created 1821 2151 if (isset($fp_dest) && is_resource($fp_dest)) { 1822 2152 fclose($fp_dest); 2153 } 2154 2155 if (isset($dest) && file_exists($dest)) { 1823 2156 unlink($dest); 1824 2157 } 1825 2158 -
src/wp-includes/ID3/license.txt
1 1 ///////////////////////////////////////////////////////////////// 2 2 /// getID3() by James Heinrich <info@getid3.org> // 3 3 // available at http://getid3.sourceforge.net // 4 // or http ://www.getid3.org//4 // or https://www.getid3.org // 5 5 // also https://github.com/JamesHeinrich/getID3 // 6 6 ///////////////////////////////////////////////////////////////// 7 7 … … 18 18 19 19 GNU LGPL: https://gnu.org/licenses/lgpl.html (v3) 20 20 21 Mozilla MPL: http ://www.mozilla.org/MPL/2.0/(v2)21 Mozilla MPL: https://www.mozilla.org/MPL/2.0/ (v2) 22 22 23 getID3 Commercial License: http ://getid3.org/#gCL (payment required)23 getID3 Commercial License: https://www.getid3.org/#gCL (payment required) 24 24 25 25 ***************************************************************** 26 26 ***************************************************************** -
src/wp-includes/ID3/module.audio-video.asf.php
1 1 <?php 2 2 ///////////////////////////////////////////////////////////////// 3 3 /// 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 // 7 8 ///////////////////////////////////////////////////////////////// 8 // See readme.txt for more details //9 /////////////////////////////////////////////////////////////////10 9 // // 11 10 // module.audio-video.asf.php // 12 11 // module for analyzing ASF, WMA and WMV files // … … 16 15 17 16 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true); 18 17 19 class getid3_asf extends getid3_handler { 20 18 class getid3_asf extends getid3_handler 19 { 20 /** 21 * @param getID3 $getid3 22 */ 21 23 public function __construct(getID3 $getid3) { 22 24 parent::__construct($getid3); // extends getid3_handler::__construct() 23 25 … … 30 32 } 31 33 } 32 34 35 /** 36 * @return bool 37 */ 33 38 public function Analyze() { 34 39 $info = &$this->getid3->info; 35 40 … … 83 88 $NextObjectOffset = $this->ftell(); 84 89 $ASFHeaderData = $this->fread($thisfile_asf_headerobject['objectsize'] - 30); 85 90 $offset = 0; 91 $thisfile_asf_streambitratepropertiesobject = array(); 92 $thisfile_asf_codeclistobject = array(); 86 93 87 94 for ($HeaderObjectsCounter = 0; $HeaderObjectsCounter < $thisfile_asf_headerobject['headerobjects']; $HeaderObjectsCounter++) { 88 95 $NextObjectGUID = substr($ASFHeaderData, $offset, 16); … … 790 797 case 'wm/tracknumber': 791 798 case 'tracknumber': 792 799 // 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) { 795 802 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)); 797 804 } 798 805 } 799 806 break; 800 807 801 808 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'])); 804 811 } 805 812 break; 806 813 … … 970 977 break; 971 978 } 972 979 } 973 if (isset($thisfile_asf_streambitrateproperties ['bitrate_records_count'])) {980 if (isset($thisfile_asf_streambitratepropertiesobject['bitrate_records_count'])) { 974 981 $ASFbitrateAudio = 0; 975 982 $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++) { 977 984 if (isset($thisfile_asf_codeclistobject['codec_entries'][$BitrateRecordsCounter])) { 978 985 switch ($thisfile_asf_codeclistobject['codec_entries'][$BitrateRecordsCounter]['type_raw']) { 979 986 case 1: 980 $ASFbitrateVideo += $thisfile_asf_streambitrateproperties ['bitrate_records'][$BitrateRecordsCounter]['bitrate'];987 $ASFbitrateVideo += $thisfile_asf_streambitratepropertiesobject['bitrate_records'][$BitrateRecordsCounter]['bitrate']; 981 988 break; 982 989 983 990 case 2: 984 $ASFbitrateAudio += $thisfile_asf_streambitrateproperties ['bitrate_records'][$BitrateRecordsCounter]['bitrate'];991 $ASFbitrateAudio += $thisfile_asf_streambitratepropertiesobject['bitrate_records'][$BitrateRecordsCounter]['bitrate']; 985 992 break; 986 993 987 994 default: … … 1440 1447 return true; 1441 1448 } 1442 1449 1450 /** 1451 * @param int $CodecListType 1452 * 1453 * @return string 1454 */ 1443 1455 public static function codecListObjectTypeLookup($CodecListType) { 1444 1456 static $lookup = array( 1445 1457 0x0001 => 'Video Codec', … … 1450 1462 return (isset($lookup[$CodecListType]) ? $lookup[$CodecListType] : 'Invalid Codec Type'); 1451 1463 } 1452 1464 1465 /** 1466 * @return array 1467 */ 1453 1468 public static function KnownGUIDs() { 1454 1469 static $GUIDarray = array( 1455 1470 'GETID3_ASF_Extended_Stream_Properties_Object' => '14E6A5CB-C672-4332-8399-A96952065B5A', … … 1564 1579 return $GUIDarray; 1565 1580 } 1566 1581 1582 /** 1583 * @param string $GUIDstring 1584 * 1585 * @return string|false 1586 */ 1567 1587 public static function GUIDname($GUIDstring) { 1568 1588 static $GUIDarray = array(); 1569 1589 if (empty($GUIDarray)) { … … 1572 1592 return array_search($GUIDstring, $GUIDarray); 1573 1593 } 1574 1594 1595 /** 1596 * @param int $id 1597 * 1598 * @return string 1599 */ 1575 1600 public static function ASFIndexObjectIndexTypeLookup($id) { 1576 1601 static $ASFIndexObjectIndexTypeLookup = array(); 1577 1602 if (empty($ASFIndexObjectIndexTypeLookup)) { … … 1582 1607 return (isset($ASFIndexObjectIndexTypeLookup[$id]) ? $ASFIndexObjectIndexTypeLookup[$id] : 'invalid'); 1583 1608 } 1584 1609 1610 /** 1611 * @param string $GUIDstring 1612 * 1613 * @return string 1614 */ 1585 1615 public static function GUIDtoBytestring($GUIDstring) { 1586 1616 // Microsoft defines these 16-byte (128-bit) GUIDs in the strangest way: 1587 1617 // first 4 bytes are in little-endian order … … 1617 1647 return $hexbytecharstring; 1618 1648 } 1619 1649 1650 /** 1651 * @param string $Bytestring 1652 * 1653 * @return string 1654 */ 1620 1655 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); 1625 1660 $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); 1628 1663 $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); 1631 1666 $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); 1634 1669 $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); 1641 1676 1642 1677 return strtoupper($GUIDstring); 1643 1678 } 1644 1679 1680 /** 1681 * @param int $FILETIME 1682 * @param bool $round 1683 * 1684 * @return float|int 1685 */ 1645 1686 public static function FILETIMEtoUNIXtime($FILETIME, $round=true) { 1646 1687 // FILETIME is a 64-bit unsigned integer representing 1647 1688 // the number of 100-nanosecond intervals since January 1, 1601 … … 1653 1694 return ($FILETIME - 116444736000000000) / 10000000; 1654 1695 } 1655 1696 1697 /** 1698 * @param int $WMpictureType 1699 * 1700 * @return string 1701 */ 1656 1702 public static function WMpictureTypeLookup($WMpictureType) { 1657 1703 static $lookup = null; 1658 1704 if ($lookup === null) { … … 1684 1730 return (isset($lookup[$WMpictureType]) ? $lookup[$WMpictureType] : ''); 1685 1731 } 1686 1732 1733 /** 1734 * @param string $asf_header_extension_object_data 1735 * @param int $unhandled_sections 1736 * 1737 * @return array 1738 */ 1687 1739 public function HeaderExtensionObjectDataParse(&$asf_header_extension_object_data, &$unhandled_sections) { 1688 1740 // http://msdn.microsoft.com/en-us/library/bb643323.aspx 1689 1741 … … 1930 1982 return $HeaderExtensionObjectParsed; 1931 1983 } 1932 1984 1933 1985 /** 1986 * @param int $id 1987 * 1988 * @return string 1989 */ 1934 1990 public static function metadataLibraryObjectDataTypeLookup($id) { 1935 1991 static $lookup = array( 1936 1992 0x0000 => 'Unicode string', // The data consists of a sequence of Unicode characters … … 1944 2000 return (isset($lookup[$id]) ? $lookup[$id] : 'invalid'); 1945 2001 } 1946 2002 2003 /** 2004 * @param string $data 2005 * 2006 * @return array 2007 */ 1947 2008 public function ASF_WMpicture(&$data) { 1948 2009 //typedef struct _WMPicture{ 1949 2010 // LPWSTR pwszMIMEType; … … 1994 2055 return $WMpicture; 1995 2056 } 1996 2057 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 */ 1999 2065 public static function TrimConvert($string) { 2000 2066 return trim(getid3_lib::iconv_fallback('UTF-16LE', 'ISO-8859-1', self::TrimTerm($string)), ' '); 2001 2067 } 2002 2068 2003 2004 // Remove terminator 00 00 2069 /** 2070 * Remove terminator 00 00. 2071 * 2072 * @param string $string 2073 * 2074 * @return string 2075 */ 2005 2076 public static function TrimTerm($string) { 2006 2077 // remove terminator, only if present (it should be, but...) 2007 2078 if (substr($string, -2) === "\x00\x00") { -
src/wp-includes/ID3/module.audio-video.flv.php
1 1 <?php 2 2 ///////////////////////////////////////////////////////////////// 3 3 /// 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 ///////////////////////////////////////////////////////////////// 7 9 // // 10 // module.audio-video.flv.php // 11 // module for analyzing Shockwave Flash Video files // 12 // dependencies: NONE // 13 // // 14 ///////////////////////////////////////////////////////////////// 15 // // 8 16 // FLV module by Seth Kaufman <sethØwhirl-i-gig*com> // 9 17 // // 10 18 // * version 0.1 (26 June 2005) // 11 19 // // 12 // //13 20 // * version 0.1.1 (15 July 2005) // 14 21 // minor modifications by James Heinrich <info@getid3.org> // 15 22 // // … … 43 50 // handle GETID3_FLV_VIDEO_VP6FLV_ALPHA // 44 51 // improved AVCSequenceParameterSetReader::readData() // 45 52 // 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 //52 53 // /// 53 54 ///////////////////////////////////////////////////////////////// 54 55 … … 73 74 define('H264_PROFILE_HIGH444', 144); 74 75 define('H264_PROFILE_HIGH444_PREDICTIVE', 244); 75 76 76 class getid3_flv extends getid3_handler {77 77 class getid3_flv extends getid3_handler 78 { 78 79 const magic = 'FLV'; 79 80 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; 81 88 89 /** 90 * @return bool 91 */ 82 92 public function Analyze() { 83 93 $info = &$this->getid3->info; 84 94 … … 332 342 return true; 333 343 } 334 344 335 345 /** 346 * @param int $id 347 * 348 * @return string|false 349 */ 336 350 public static function audioFormatLookup($id) { 337 351 static $lookup = array( 338 352 0 => 'Linear PCM, platform endian', … … 355 369 return (isset($lookup[$id]) ? $lookup[$id] : false); 356 370 } 357 371 372 /** 373 * @param int $id 374 * 375 * @return int|false 376 */ 358 377 public static function audioRateLookup($id) { 359 378 static $lookup = array( 360 379 0 => 5500, … … 365 384 return (isset($lookup[$id]) ? $lookup[$id] : false); 366 385 } 367 386 387 /** 388 * @param int $id 389 * 390 * @return int|false 391 */ 368 392 public static function audioBitDepthLookup($id) { 369 393 static $lookup = array( 370 394 0 => 8, … … 373 397 return (isset($lookup[$id]) ? $lookup[$id] : false); 374 398 } 375 399 400 /** 401 * @param int $id 402 * 403 * @return string|false 404 */ 376 405 public static function videoCodecLookup($id) { 377 406 static $lookup = array( 378 407 GETID3_FLV_VIDEO_H263 => 'Sorenson H.263', … … 386 415 } 387 416 } 388 417 389 class AMFStream { 418 class AMFStream 419 { 420 /** 421 * @var string 422 */ 390 423 public $bytes; 424 425 /** 426 * @var int 427 */ 391 428 public $pos; 392 429 430 /** 431 * @param string $bytes 432 */ 393 433 public function __construct(&$bytes) { 394 434 $this->bytes =& $bytes; 395 435 $this->pos = 0; 396 436 } 397 437 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)); 400 443 } 401 444 402 public function readInt() { 445 /** 446 * @return int 447 */ 448 public function readInt() { // 16-bit 403 449 return ($this->readByte() << 8) + $this->readByte(); 404 450 } 405 451 406 public function readLong() { 452 /** 453 * @return int 454 */ 455 public function readLong() { // 32-bit 407 456 return ($this->readByte() << 24) + ($this->readByte() << 16) + ($this->readByte() << 8) + $this->readByte(); 408 457 } 409 458 459 /** 460 * @return float|false 461 */ 410 462 public function readDouble() { 411 463 return getid3_lib::BigEndian2Float($this->read(8)); 412 464 } 413 465 466 /** 467 * @return string 468 */ 414 469 public function readUTF() { 415 470 $length = $this->readInt(); 416 471 return $this->read($length); 417 472 } 418 473 474 /** 475 * @return string 476 */ 419 477 public function readLongUTF() { 420 478 $length = $this->readLong(); 421 479 return $this->read($length); 422 480 } 423 481 482 /** 483 * @param int $length 484 * 485 * @return string 486 */ 424 487 public function read($length) { 425 488 $val = substr($this->bytes, $this->pos, $length); 426 489 $this->pos += $length; … … 427 490 return $val; 428 491 } 429 492 493 /** 494 * @return int 495 */ 430 496 public function peekByte() { 431 497 $pos = $this->pos; 432 498 $val = $this->readByte(); … … 434 500 return $val; 435 501 } 436 502 503 /** 504 * @return int 505 */ 437 506 public function peekInt() { 438 507 $pos = $this->pos; 439 508 $val = $this->readInt(); … … 441 510 return $val; 442 511 } 443 512 513 /** 514 * @return int 515 */ 444 516 public function peekLong() { 445 517 $pos = $this->pos; 446 518 $val = $this->readLong(); … … 448 520 return $val; 449 521 } 450 522 523 /** 524 * @return float|false 525 */ 451 526 public function peekDouble() { 452 527 $pos = $this->pos; 453 528 $val = $this->readDouble(); … … 455 530 return $val; 456 531 } 457 532 533 /** 534 * @return string 535 */ 458 536 public function peekUTF() { 459 537 $pos = $this->pos; 460 538 $val = $this->readUTF(); … … 462 540 return $val; 463 541 } 464 542 543 /** 544 * @return string 545 */ 465 546 public function peekLongUTF() { 466 547 $pos = $this->pos; 467 548 $val = $this->readLongUTF(); … … 470 551 } 471 552 } 472 553 473 class AMFReader { 554 class AMFReader 555 { 556 /** 557 * @var AMFStream 558 */ 474 559 public $stream; 475 560 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; 478 566 } 479 567 568 /** 569 * @return mixed 570 */ 480 571 public function readData() { 481 572 $value = null; 482 573 … … 547 638 return $value; 548 639 } 549 640 641 /** 642 * @return float|false 643 */ 550 644 public function readDouble() { 551 645 return $this->stream->readDouble(); 552 646 } 553 647 648 /** 649 * @return bool 650 */ 554 651 public function readBoolean() { 555 652 return $this->stream->readByte() == 1; 556 653 } 557 654 655 /** 656 * @return string 657 */ 558 658 public function readString() { 559 659 return $this->stream->readUTF(); 560 660 } 561 661 662 /** 663 * @return array 664 */ 562 665 public function readObject() { 563 666 // Get highest numerical index - ignored 564 667 // $highestIndex = $this->stream->readLong(); 565 668 566 669 $data = array(); 670 $key = null; 567 671 568 672 while ($key = $this->stream->readUTF()) { 569 673 $data[$key] = $this->readData(); … … 576 680 return $data; 577 681 } 578 682 683 /** 684 * @return array 685 */ 579 686 public function readMixedArray() { 580 687 // Get highest numerical index - ignored 581 688 $highestIndex = $this->stream->readLong(); 582 689 583 690 $data = array(); 691 $key = null; 584 692 585 693 while ($key = $this->stream->readUTF()) { 586 694 if (is_numeric($key)) { 587 $key = ( float) $key;695 $key = (int) $key; 588 696 } 589 697 $data[$key] = $this->readData(); 590 698 } … … 597 705 return $data; 598 706 } 599 707 708 /** 709 * @return array 710 */ 600 711 public function readArray() { 601 712 $length = $this->stream->readLong(); 602 713 $data = array(); … … 607 718 return $data; 608 719 } 609 720 721 /** 722 * @return float|false 723 */ 610 724 public function readDate() { 611 725 $timestamp = $this->stream->readDouble(); 612 726 $timezone = $this->stream->readInt(); … … 613 727 return $timestamp; 614 728 } 615 729 730 /** 731 * @return string 732 */ 616 733 public function readLongString() { 617 734 return $this->stream->readLongUTF(); 618 735 } 619 736 737 /** 738 * @return string 739 */ 620 740 public function readXML() { 621 741 return $this->stream->readLongUTF(); 622 742 } 623 743 744 /** 745 * @return array 746 */ 624 747 public function readTypedObject() { 625 748 $className = $this->stream->readUTF(); 626 749 return $this->readObject(); … … 627 750 } 628 751 } 629 752 630 class AVCSequenceParameterSetReader { 753 class AVCSequenceParameterSetReader 754 { 755 /** 756 * @var string 757 */ 631 758 public $sps; 632 759 public $start = 0; 633 760 public $currentBytes = 0; 634 761 public $currentBits = 0; 762 763 /** 764 * @var int 765 */ 635 766 public $width; 767 768 /** 769 * @var int 770 */ 636 771 public $height; 637 772 773 /** 774 * @param string $sps 775 */ 638 776 public function __construct($sps) { 639 777 $this->sps = $sps; 640 778 } … … 691 829 } 692 830 } 693 831 832 /** 833 * @param int $bits 834 */ 694 835 public function skipBits($bits) { 695 836 $newBits = $this->currentBits + $bits; 696 837 $this->currentBytes += (int)floor($newBits / 8); … … 697 838 $this->currentBits = $newBits % 8; 698 839 } 699 840 841 /** 842 * @return int 843 */ 700 844 public function getBit() { 701 845 $result = (getid3_lib::BigEndian2Int(substr($this->sps, $this->currentBytes, 1)) >> (7 - $this->currentBits)) & 0x01; 702 846 $this->skipBits(1); … … 703 847 return $result; 704 848 } 705 849 850 /** 851 * @param int $bits 852 * 853 * @return int 854 */ 706 855 public function getBits($bits) { 707 856 $result = 0; 708 857 for ($i = 0; $i < $bits; $i++) { … … 711 860 return $result; 712 861 } 713 862 863 /** 864 * @return int 865 */ 714 866 public function expGolombUe() { 715 867 $significantBits = 0; 716 868 $bit = $this->getBit(); … … 726 878 return (1 << $significantBits) + $this->getBits($significantBits) - 1; 727 879 } 728 880 881 /** 882 * @return int 883 */ 729 884 public function expGolombSe() { 730 885 $result = $this->expGolombUe(); 731 886 if (($result & 0x01) == 0) { … … 735 890 } 736 891 } 737 892 893 /** 894 * @return int 895 */ 738 896 public function getWidth() { 739 897 return $this->width; 740 898 } 741 899 900 /** 901 * @return int 902 */ 742 903 public function getHeight() { 743 904 return $this->height; 744 905 } -
src/wp-includes/ID3/module.audio-video.matroska.php
1 1 <?php 2 2 3 ///////////////////////////////////////////////////////////////// 3 4 /// 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 // 7 9 ///////////////////////////////////////////////////////////////// 8 // See readme.txt for more details //9 /////////////////////////////////////////////////////////////////10 10 // // 11 11 // module.audio-video.matriska.php // 12 12 // module for analyzing Matroska containers // … … 72 72 define('EBML_ID_FILEDESCRIPTION', 0x067E); // [46][7E] -- A human-friendly name for the attached file. 73 73 define('EBML_ID_FILEUID', 0x06AE); // [46][AE] -- Unique ID representing the file, as random as possible. 74 74 define('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 thedata was encrypted with.75 define('EBML_ID_CONTENTENCKEYID', 0x07E2); // [47][E2] -- For public key algorithms this is the ID of the public key the data was encrypted with. 76 76 define('EBML_ID_CONTENTSIGNATURE', 0x07E3); // [47][E3] -- A cryptographic signature of the contents. 77 77 define('EBML_ID_CONTENTSIGKEYID', 0x07E4); // [47][E4] -- This is the ID of the private key the data was signed with. 78 78 define('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: … … 215 215 */ 216 216 class getid3_matroska extends getid3_handler 217 217 { 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; 221 225 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 */ 223 236 private $EBMLbuffer = ''; 224 237 private $EBMLbuffer_offset = 0; 225 238 private $EBMLbuffer_length = 0; … … 226 239 private $current_offset = 0; 227 240 private $unuseful_elements = array(EBML_ID_CRC32, EBML_ID_VOID); 228 241 242 /** 243 * @return bool 244 */ 229 245 public function Analyze() 230 246 { 231 247 $info = &$this->getid3->info; … … 366 382 if (!empty($getid3_temp->info[$header_data_key])) { 367 383 $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info[$header_data_key]; 368 384 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; 371 387 } 372 388 } 373 389 } … … 421 437 if (!empty($getid3_temp->info['ogg'])) { 422 438 $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info['ogg']; 423 439 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; 426 442 } 427 443 } 428 444 } … … 449 465 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true); 450 466 451 467 $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; 455 471 } 456 472 } 457 473 $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed; … … 496 512 return true; 497 513 } 498 514 515 /** 516 * @param array $info 517 */ 499 518 private function parseEBML(&$info) { 500 519 // http://www.matroska.org/technical/specs/index.html#EBMLBasics 501 520 $this->current_offset = $info['avdataoffset']; … … 1228 1247 } 1229 1248 } 1230 1249 1250 /** 1251 * @param int $min_data 1252 * 1253 * @return bool 1254 */ 1231 1255 private function EnsureBufferHasEnoughData($min_data=1024) { 1232 1256 if (($this->current_offset - $this->EBMLbuffer_offset) >= ($this->EBMLbuffer_length - $min_data)) { 1233 1257 $read_bytes = max($min_data, $this->getid3->fread_buffer_size()); … … 1249 1273 return true; 1250 1274 } 1251 1275 1276 /** 1277 * @return int|float|false 1278 */ 1252 1279 private function readEBMLint() { 1253 1280 $actual_offset = $this->current_offset - $this->EBMLbuffer_offset; 1254 1281 … … 1281 1308 return $int_value; 1282 1309 } 1283 1310 1311 /** 1312 * @param int $length 1313 * @param bool $check_buffer 1314 * 1315 * @return string|false 1316 */ 1284 1317 private function readEBMLelementData($length, $check_buffer=false) { 1285 1318 if ($check_buffer && !$this->EnsureBufferHasEnoughData($length)) { 1286 1319 return false; … … 1290 1323 return $data; 1291 1324 } 1292 1325 1326 /** 1327 * @param array $element 1328 * @param int $parent_end 1329 * @param array|bool $get_data 1330 * 1331 * @return bool 1332 */ 1293 1333 private function getEBMLelement(&$element, $parent_end, $get_data=false) { 1294 1334 if ($this->current_offset >= $parent_end) { 1295 1335 return false; … … 1326 1366 return true; 1327 1367 } 1328 1368 1369 /** 1370 * @param string $type 1371 * @param int $line 1372 * @param array $element 1373 */ 1329 1374 private function unhandledElement($type, $line, $element) { 1330 1375 // warn only about unknown and missed elements, not about unuseful 1331 1376 if (!in_array($element['id'], $this->unuseful_elements)) { … … 1338 1383 } 1339 1384 } 1340 1385 1386 /** 1387 * @param array $SimpleTagArray 1388 * 1389 * @return bool 1390 */ 1341 1391 private function ExtractCommentsSimpleTag($SimpleTagArray) { 1342 1392 if (!empty($SimpleTagArray['SimpleTag'])) { 1343 1393 foreach ($SimpleTagArray['SimpleTag'] as $SimpleTagKey => $SimpleTagData) { … … 1353 1403 return true; 1354 1404 } 1355 1405 1406 /** 1407 * @param int $parent_end 1408 * 1409 * @return array 1410 */ 1356 1411 private function HandleEMBLSimpleTag($parent_end) { 1357 1412 $simpletag_entry = array(); 1358 1413 … … 1383 1438 return $simpletag_entry; 1384 1439 } 1385 1440 1441 /** 1442 * @param array $element 1443 * @param int $block_type 1444 * @param array $info 1445 * 1446 * @return array 1447 */ 1386 1448 private function HandleEMBLClusterBlock($element, $block_type, &$info) { 1387 1449 // http://www.matroska.org/technical/specs/index.html#block_structure 1388 1450 // http://www.matroska.org/technical/specs/index.html#simpleblock_structure … … 1446 1508 return $block_data; 1447 1509 } 1448 1510 1511 /** 1512 * @param string $EBMLstring 1513 * 1514 * @return int|float|false 1515 */ 1449 1516 private static function EBML2Int($EBMLstring) { 1450 1517 // http://matroska.org/specs/ 1451 1518 … … 1488 1555 return getid3_lib::BigEndian2Int($EBMLstring); 1489 1556 } 1490 1557 1558 /** 1559 * @param int $EBMLdatestamp 1560 * 1561 * @return float 1562 */ 1491 1563 private static function EBMLdate2unix($EBMLdatestamp) { 1492 1564 // Date - signed 8 octets integer in nanoseconds with 0 indicating the precise beginning of the millennium (at 2001-01-01T00:00:00,000000000 UTC) 1493 1565 // 978307200 == mktime(0, 0, 0, 1, 1, 2001) == January 1, 2001 12:00:00am UTC … … 1494 1566 return round(($EBMLdatestamp / 1000000000) + 978307200); 1495 1567 } 1496 1568 1569 /** 1570 * @param int $target_type 1571 * 1572 * @return string|int 1573 */ 1497 1574 public static function TargetTypeValue($target_type) { 1498 1575 // http://www.matroska.org/technical/specs/tagging/index.html 1499 1576 static $TargetTypeValue = array(); … … 1509 1586 return (isset($TargetTypeValue[$target_type]) ? $TargetTypeValue[$target_type] : $target_type); 1510 1587 } 1511 1588 1589 /** 1590 * @param int $lacingtype 1591 * 1592 * @return string|int 1593 */ 1512 1594 public static function BlockLacingType($lacingtype) { 1513 1595 // http://matroska.org/technical/specs/index.html#block_structure 1514 1596 static $BlockLacingType = array(); … … 1521 1603 return (isset($BlockLacingType[$lacingtype]) ? $BlockLacingType[$lacingtype] : $lacingtype); 1522 1604 } 1523 1605 1606 /** 1607 * @param string $codecid 1608 * 1609 * @return string 1610 */ 1524 1611 public static function CodecIDtoCommonName($codecid) { 1525 1612 // http://www.matroska.org/technical/specs/codecid/index.html 1526 1613 static $CodecIDlist = array(); … … 1557 1644 return (isset($CodecIDlist[$codecid]) ? $CodecIDlist[$codecid] : $codecid); 1558 1645 } 1559 1646 1647 /** 1648 * @param int $value 1649 * 1650 * @return string 1651 */ 1560 1652 private static function EBMLidName($value) { 1561 1653 static $EBMLidList = array(); 1562 1654 if (empty($EBMLidList)) { … … 1755 1847 return (isset($EBMLidList[$value]) ? $EBMLidList[$value] : dechex($value)); 1756 1848 } 1757 1849 1850 /** 1851 * @param int $value 1852 * 1853 * @return string 1854 */ 1758 1855 public static function displayUnit($value) { 1759 1856 // http://www.matroska.org/technical/specs/index.html#DisplayUnit 1760 1857 static $units = array( … … 1766 1863 return (isset($units[$value]) ? $units[$value] : 'unknown'); 1767 1864 } 1768 1865 1866 /** 1867 * @param array $streams 1868 * 1869 * @return array 1870 */ 1769 1871 private static function getDefaultStreamInfo($streams) 1770 1872 { 1873 $stream = array(); 1771 1874 foreach (array_reverse($streams) as $stream) { 1772 1875 if ($stream['default']) { 1773 1876 break; -
src/wp-includes/ID3/module.audio-video.quicktime.php
1 1 <?php 2 2 3 ///////////////////////////////////////////////////////////////// 3 4 /// 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 // 7 9 ///////////////////////////////////////////////////////////////// 8 // See readme.txt for more details //9 /////////////////////////////////////////////////////////////////10 10 // // 11 11 // module.audio-video.quicktime.php // 12 12 // module for analyzing Quicktime and MP3-in-MP4 files // … … 24 24 public $ReturnAtomData = true; 25 25 public $ParseAllPossibleAtoms = false; 26 26 27 /** 28 * @return bool 29 */ 27 30 public function Analyze() { 28 31 $info = &$this->getid3->info; 29 32 … … 35 38 36 39 $offset = 0; 37 40 $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] 39 42 while ($offset < $info['avdataend']) { 40 43 if (!getid3_lib::intValueSupported($offset)) { 41 44 $this->error('Unable to parse atom at offset '.$offset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions'); … … 162 165 if (isset($info['bitrate']) && !isset($info['audio']['bitrate']) && !isset($info['quicktime']['video'])) { 163 166 $info['audio']['bitrate'] = $info['bitrate']; 164 167 } 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 } 165 171 if (!empty($info['playtime_seconds']) && !isset($info['video']['frame_rate']) && !empty($info['quicktime']['stts_framecount'])) { 166 172 foreach ($info['quicktime']['stts_framecount'] as $key => $samples_count) { 167 173 $samples_per_second = $samples_count / $info['playtime_seconds']; … … 193 199 if (empty($info['video']['dataformat']) && !empty($info['quicktime']['video'])) { 194 200 $info['video']['dataformat'] = 'quicktime'; 195 201 } 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 } 196 205 197 206 return true; 198 207 } 199 208 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 */ 200 219 public function QuicktimeParseAtom($atomname, $atomsize, $atom_data, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) { 201 220 // http://developer.apple.com/techpubs/quicktime/qtdevdocs/APIREF/INDEX/atomalphaindex.htm 202 221 // https://code.google.com/p/mp4v2/wiki/iTunesMetadata … … 203 222 204 223 $info = &$this->getid3->info; 205 224 206 $atom_parent = end($atomHierarchy); // not array_pop($atomHierarchy); see http ://www.getid3.org/phpBB3/viewtopic.php?t=1717225 $atom_parent = end($atomHierarchy); // not array_pop($atomHierarchy); see https://www.getid3.org/phpBB3/viewtopic.php?t=1717 207 226 array_push($atomHierarchy, $atomname); 208 227 $atom_structure['hierarchy'] = implode(' ', $atomHierarchy); 209 228 $atom_structure['name'] = $atomname; 210 229 $atom_structure['size'] = $atomsize; 211 230 $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; 229 254 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; 242 259 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; 246 262 break; 247 263 } 248 264 } 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 } 251 277 } 252 } 253 break; 278 break; 254 279 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 } 283 299 } 284 300 } 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 } 291 307 } 292 308 } 293 309 } 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; 303 318 304 319 305 case "\xA9".'alb': // ALBum306 case "\xA9".'ART': //307 case "\xA9".'art': // ARTist308 case "\xA9".'aut': //309 case "\xA9".'cmt': // CoMmenT310 case "\xA9".'com': // COMposer311 case "\xA9".'cpy': //312 case "\xA9".'day': // content created year313 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': // GENre326 case "\xA9".'grp': // GRouPing327 case "\xA9".'hst': //328 case "\xA9".'inf': //329 case "\xA9".'lyr': // LYRics330 case "\xA9".'mak': //331 case "\xA9".'mod': //332 case "\xA9".'nam': // full NAMe333 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': // encoder340 case "\xA9".'trk': // TRacK341 case "\xA9".'url': //342 case "\xA9".'wrn': //343 case "\xA9".'wrt': // WRiTer344 case '----': // itunes specific345 case 'aART': // Album ARTist346 case 'akID': // iTunes store account type347 case 'apID': // Purchase Account348 case 'atID': //349 case 'catg': // CaTeGory350 case 'cmID': //351 case 'cnID': //352 case 'covr': // COVeR artwork353 case 'cpil': // ComPILation354 case 'cprt': // CoPyRighT355 case 'desc': // DESCription356 case 'disk': // DISK number357 case 'egid': // Episode Global ID358 case 'geID': //359 case 'gnre': // GeNRE360 case 'hdvd': // HD ViDeo361 case 'keyw': // KEYWord362 case 'ldes': // Long DEScription363 case 'pcst': // PodCaST364 case 'pgap': // GAPless Playback365 case 'plID': //366 case 'purd': // PURchase Date367 case 'purl': // Podcast URL368 case 'rati': //369 case 'rndu': //370 case 'rpdu': //371 case 'rtng': // RaTiNG372 case 'sfID': // iTunes store country373 case 'soaa': // SOrt Album Artist374 case 'soal': // SOrt ALbum375 case 'soar': // SOrt ARtist376 case 'soco': // SOrt COmposer377 case 'sonm': // SOrt NaMe378 case 'sosn': // SOrt Show Name379 case 'stik': //380 case 'tmpo': // TeMPO (BPM)381 case 'trkn': // TRacK Number382 case 'tven': // tvEpisodeID383 case 'tves': // TV EpiSode384 case 'tvnn': // TV Network Name385 case 'tvsh': // TV SHow Name386 case 'tvsn': // TV SeasoN387 if ($atom_parent == 'udta') {388 // User data atom handler389 $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); 392 407 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']; 423 411 } 424 412 } 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); 434 438 } 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); 441 448 break; 449 } 450 $atomoffset += $boxsize; 442 451 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; 457 457 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; 462 472 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; 471 477 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; 477 486 478 case 'rtng':479 // 8-bit integer480 $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; 483 492 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; 489 498 490 case 'sfID':491 // 32-bit integer492 $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; 495 504 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; 500 510 501 case 'plID':502 // 64-bit integer503 $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; 505 515 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#',