PageRenderTime 141ms CodeModel.GetById 81ms app.highlight 50ms RepoModel.GetById 1ms app.codeStats 1ms

/sites/all/libraries/getid3/getid3/getid3.lib.php

https://bitbucket.org/micahw156/sites_chacadwa
PHP | 1323 lines | 1028 code | 173 blank | 122 comment | 247 complexity | adbbeab662b7e04194d166dad23555e7 MD5 | raw file
   1<?php
   2/////////////////////////////////////////////////////////////////
   3/// getID3() by James Heinrich <info@getid3.org>               //
   4//  available at http://getid3.sourceforge.net                 //
   5//            or http://www.getid3.org                         //
   6/////////////////////////////////////////////////////////////////
   7//                                                             //
   8// getid3.lib.php - part of getID3()                           //
   9// See readme.txt for more details                             //
  10//                                                            ///
  11/////////////////////////////////////////////////////////////////
  12
  13
  14class getid3_lib
  15{
  16
  17	function PrintHexBytes($string, $hex=true, $spaces=true, $htmlsafe=true) {
  18		$returnstring = '';
  19		for ($i = 0; $i < strlen($string); $i++) {
  20			if ($hex) {
  21				$returnstring .= str_pad(dechex(ord($string{$i})), 2, '0', STR_PAD_LEFT);
  22			} else {
  23				$returnstring .= ' '.(ereg("[\x20-\x7E]", $string{$i}) ? $string{$i} : '�');
  24			}
  25			if ($spaces) {
  26				$returnstring .= ' ';
  27			}
  28		}
  29		if ($htmlsafe) {
  30			$returnstring = htmlentities($returnstring);
  31		}
  32		return $returnstring;
  33	}
  34
  35	function SafeStripSlashes($text) {
  36		if (get_magic_quotes_gpc()) {
  37			return stripslashes($text);
  38		}
  39		return $text;
  40	}
  41
  42
  43	function trunc($floatnumber) {
  44		// truncates a floating-point number at the decimal point
  45		// returns int (if possible, otherwise float)
  46		if ($floatnumber >= 1) {
  47			$truncatednumber = floor($floatnumber);
  48		} elseif ($floatnumber <= -1) {
  49			$truncatednumber = ceil($floatnumber);
  50		} else {
  51			$truncatednumber = 0;
  52		}
  53		if ($truncatednumber <= 1073741824) { // 2^30
  54			$truncatednumber = (int) $truncatednumber;
  55		}
  56		return $truncatednumber;
  57	}
  58
  59
  60	function CastAsInt($floatnum) {
  61		// convert to float if not already
  62		$floatnum = (float) $floatnum;
  63
  64		// convert a float to type int, only if possible
  65		if (getid3_lib::trunc($floatnum) == $floatnum) {
  66			// it's not floating point
  67			if ($floatnum <= 1073741824) { // 2^30
  68				// it's within int range
  69				$floatnum = (int) $floatnum;
  70			}
  71		}
  72		return $floatnum;
  73	}
  74
  75
  76	function DecimalBinary2Float($binarynumerator) {
  77		$numerator   = getid3_lib::Bin2Dec($binarynumerator);
  78		$denominator = getid3_lib::Bin2Dec('1'.str_repeat('0', strlen($binarynumerator)));
  79		return ($numerator / $denominator);
  80	}
  81
  82
  83	function NormalizeBinaryPoint($binarypointnumber, $maxbits=52) {
  84		// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
  85		if (strpos($binarypointnumber, '.') === false) {
  86			$binarypointnumber = '0.'.$binarypointnumber;
  87		} elseif ($binarypointnumber{0} == '.') {
  88			$binarypointnumber = '0'.$binarypointnumber;
  89		}
  90		$exponent = 0;
  91		while (($binarypointnumber{0} != '1') || (substr($binarypointnumber, 1, 1) != '.')) {
  92			if (substr($binarypointnumber, 1, 1) == '.') {
  93				$exponent--;
  94				$binarypointnumber = substr($binarypointnumber, 2, 1).'.'.substr($binarypointnumber, 3);
  95			} else {
  96				$pointpos = strpos($binarypointnumber, '.');
  97				$exponent += ($pointpos - 1);
  98				$binarypointnumber = str_replace('.', '', $binarypointnumber);
  99				$binarypointnumber = $binarypointnumber{0}.'.'.substr($binarypointnumber, 1);
 100			}
 101		}
 102		$binarypointnumber = str_pad(substr($binarypointnumber, 0, $maxbits + 2), $maxbits + 2, '0', STR_PAD_RIGHT);
 103		return array('normalized'=>$binarypointnumber, 'exponent'=>(int) $exponent);
 104	}
 105
 106
 107	function Float2BinaryDecimal($floatvalue) {
 108		// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
 109		$maxbits = 128; // to how many bits of precision should the calculations be taken?
 110		$intpart   = getid3_lib::trunc($floatvalue);
 111		$floatpart = abs($floatvalue - $intpart);
 112		$pointbitstring = '';
 113		while (($floatpart != 0) && (strlen($pointbitstring) < $maxbits)) {
 114			$floatpart *= 2;
 115			$pointbitstring .= (string) getid3_lib::trunc($floatpart);
 116			$floatpart -= getid3_lib::trunc($floatpart);
 117		}
 118		$binarypointnumber = decbin($intpart).'.'.$pointbitstring;
 119		return $binarypointnumber;
 120	}
 121
 122
 123	function Float2String($floatvalue, $bits) {
 124		// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html
 125		switch ($bits) {
 126			case 32:
 127				$exponentbits = 8;
 128				$fractionbits = 23;
 129				break;
 130
 131			case 64:
 132				$exponentbits = 11;
 133				$fractionbits = 52;
 134				break;
 135
 136			default:
 137				return false;
 138				break;
 139		}
 140		if ($floatvalue >= 0) {
 141			$signbit = '0';
 142		} else {
 143			$signbit = '1';
 144		}
 145		$normalizedbinary  = getid3_lib::NormalizeBinaryPoint(getid3_lib::Float2BinaryDecimal($floatvalue), $fractionbits);
 146		$biasedexponent    = pow(2, $exponentbits - 1) - 1 + $normalizedbinary['exponent']; // (127 or 1023) +/- exponent
 147		$exponentbitstring = str_pad(decbin($biasedexponent), $exponentbits, '0', STR_PAD_LEFT);
 148		$fractionbitstring = str_pad(substr($normalizedbinary['normalized'], 2), $fractionbits, '0', STR_PAD_RIGHT);
 149
 150		return getid3_lib::BigEndian2String(getid3_lib::Bin2Dec($signbit.$exponentbitstring.$fractionbitstring), $bits % 8, false);
 151	}
 152
 153
 154	function LittleEndian2Float($byteword) {
 155		return getid3_lib::BigEndian2Float(strrev($byteword));
 156	}
 157
 158
 159	function BigEndian2Float($byteword) {
 160		// ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic
 161		// http://www.psc.edu/general/software/packages/ieee/ieee.html
 162		// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html
 163
 164		$bitword = getid3_lib::BigEndian2Bin($byteword);
 165		$signbit = $bitword{0};
 166
 167		switch (strlen($byteword) * 8) {
 168			case 32:
 169				$exponentbits = 8;
 170				$fractionbits = 23;
 171				break;
 172
 173			case 64:
 174				$exponentbits = 11;
 175				$fractionbits = 52;
 176				break;
 177
 178			case 80:
 179				// 80-bit Apple SANE format
 180				// http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/
 181				$exponentstring = substr($bitword, 1, 15);
 182				$isnormalized = intval($bitword{16});
 183				$fractionstring = substr($bitword, 17, 63);
 184				$exponent = pow(2, getid3_lib::Bin2Dec($exponentstring) - 16383);
 185				$fraction = $isnormalized + getid3_lib::DecimalBinary2Float($fractionstring);
 186				$floatvalue = $exponent * $fraction;
 187				if ($signbit == '1') {
 188					$floatvalue *= -1;
 189				}
 190				return $floatvalue;
 191				break;
 192
 193			default:
 194				return false;
 195				break;
 196		}
 197		$exponentstring = substr($bitword, 1, $exponentbits);
 198		$fractionstring = substr($bitword, $exponentbits + 1, $fractionbits);
 199		$exponent = getid3_lib::Bin2Dec($exponentstring);
 200		$fraction = getid3_lib::Bin2Dec($fractionstring);
 201
 202		if (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction != 0)) {
 203			// Not a Number
 204			$floatvalue = false;
 205		} elseif (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction == 0)) {
 206			if ($signbit == '1') {
 207				$floatvalue = '-infinity';
 208			} else {
 209				$floatvalue = '+infinity';
 210			}
 211		} elseif (($exponent == 0) && ($fraction == 0)) {
 212			if ($signbit == '1') {
 213				$floatvalue = -0;
 214			} else {
 215				$floatvalue = 0;
 216			}
 217			$floatvalue = ($signbit ? 0 : -0);
 218		} elseif (($exponent == 0) && ($fraction != 0)) {
 219			// These are 'unnormalized' values
 220			$floatvalue = pow(2, (-1 * (pow(2, $exponentbits - 1) - 2))) * getid3_lib::DecimalBinary2Float($fractionstring);
 221			if ($signbit == '1') {
 222				$floatvalue *= -1;
 223			}
 224		} elseif ($exponent != 0) {
 225			$floatvalue = pow(2, ($exponent - (pow(2, $exponentbits - 1) - 1))) * (1 + getid3_lib::DecimalBinary2Float($fractionstring));
 226			if ($signbit == '1') {
 227				$floatvalue *= -1;
 228			}
 229		}
 230		return (float) $floatvalue;
 231	}
 232
 233
 234	function BigEndian2Int($byteword, $synchsafe=false, $signed=false) {
 235		$intvalue = 0;
 236		$bytewordlen = strlen($byteword);
 237		for ($i = 0; $i < $bytewordlen; $i++) {
 238			if ($synchsafe) { // disregard MSB, effectively 7-bit bytes
 239				$intvalue = $intvalue | (ord($byteword{$i}) & 0x7F) << (($bytewordlen - 1 - $i) * 7);
 240			} else {
 241				$intvalue += ord($byteword{$i}) * pow(256, ($bytewordlen - 1 - $i));
 242			}
 243		}
 244		if ($signed && !$synchsafe) {
 245			// synchsafe ints are not allowed to be signed
 246			switch ($bytewordlen) {
 247				case 1:
 248				case 2:
 249				case 3:
 250				case 4:
 251					$signmaskbit = 0x80 << (8 * ($bytewordlen - 1));
 252					if ($intvalue & $signmaskbit) {
 253						$intvalue = 0 - ($intvalue & ($signmaskbit - 1));
 254					}
 255					break;
 256
 257				default:
 258					die('ERROR: Cannot have signed integers larger than 32-bits in getid3_lib::BigEndian2Int()');
 259					break;
 260			}
 261		}
 262		return getid3_lib::CastAsInt($intvalue);
 263	}
 264
 265
 266	function LittleEndian2Int($byteword, $signed=false) {
 267		return getid3_lib::BigEndian2Int(strrev($byteword), false, $signed);
 268	}
 269
 270
 271	function BigEndian2Bin($byteword) {
 272		$binvalue = '';
 273		$bytewordlen = strlen($byteword);
 274		for ($i = 0; $i < $bytewordlen; $i++) {
 275			$binvalue .= str_pad(decbin(ord($byteword{$i})), 8, '0', STR_PAD_LEFT);
 276		}
 277		return $binvalue;
 278	}
 279
 280
 281	function BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false) {
 282		if ($number < 0) {
 283			return false;
 284		}
 285		$maskbyte = (($synchsafe || $signed) ? 0x7F : 0xFF);
 286		$intstring = '';
 287		if ($signed) {
 288			if ($minbytes > 4) {
 289				die('ERROR: Cannot have signed integers larger than 32-bits in getid3_lib::BigEndian2String()');
 290			}
 291			$number = $number & (0x80 << (8 * ($minbytes - 1)));
 292		}
 293		while ($number != 0) {
 294			$quotient = ($number / ($maskbyte + 1));
 295			$intstring = chr(ceil(($quotient - floor($quotient)) * $maskbyte)).$intstring;
 296			$number = floor($quotient);
 297		}
 298		return str_pad($intstring, $minbytes, "\x00", STR_PAD_LEFT);
 299	}
 300
 301
 302	function Dec2Bin($number) {
 303		while ($number >= 256) {
 304			$bytes[] = (($number / 256) - (floor($number / 256))) * 256;
 305			$number = floor($number / 256);
 306		}
 307		$bytes[] = $number;
 308		$binstring = '';
 309		for ($i = 0; $i < count($bytes); $i++) {
 310			$binstring = (($i == count($bytes) - 1) ? decbin($bytes[$i]) : str_pad(decbin($bytes[$i]), 8, '0', STR_PAD_LEFT)).$binstring;
 311		}
 312		return $binstring;
 313	}
 314
 315
 316	function Bin2Dec($binstring, $signed=false) {
 317		$signmult = 1;
 318		if ($signed) {
 319			if ($binstring{0} == '1') {
 320				$signmult = -1;
 321			}
 322			$binstring = substr($binstring, 1);
 323		}
 324		$decvalue = 0;
 325		for ($i = 0; $i < strlen($binstring); $i++) {
 326			$decvalue += ((int) substr($binstring, strlen($binstring) - $i - 1, 1)) * pow(2, $i);
 327		}
 328		return getid3_lib::CastAsInt($decvalue * $signmult);
 329	}
 330
 331
 332	function Bin2String($binstring) {
 333		// return 'hi' for input of '0110100001101001'
 334		$string = '';
 335		$binstringreversed = strrev($binstring);
 336		for ($i = 0; $i < strlen($binstringreversed); $i += 8) {
 337			$string = chr(getid3_lib::Bin2Dec(strrev(substr($binstringreversed, $i, 8)))).$string;
 338		}
 339		return $string;
 340	}
 341
 342
 343	function LittleEndian2String($number, $minbytes=1, $synchsafe=false) {
 344		$intstring = '';
 345		while ($number > 0) {
 346			if ($synchsafe) {
 347				$intstring = $intstring.chr($number & 127);
 348				$number >>= 7;
 349			} else {
 350				$intstring = $intstring.chr($number & 255);
 351				$number >>= 8;
 352			}
 353		}
 354		return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
 355	}
 356
 357
 358	function array_merge_clobber($array1, $array2) {
 359		// written by kc�hireability*com
 360		// taken from http://www.php.net/manual/en/function.array-merge-recursive.php
 361		if (!is_array($array1) || !is_array($array2)) {
 362			return false;
 363		}
 364		$newarray = $array1;
 365		foreach ($array2 as $key => $val) {
 366			if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) {
 367				$newarray[$key] = getid3_lib::array_merge_clobber($newarray[$key], $val);
 368			} else {
 369				$newarray[$key] = $val;
 370			}
 371		}
 372		return $newarray;
 373	}
 374
 375
 376	function array_merge_noclobber($array1, $array2) {
 377		if (!is_array($array1) || !is_array($array2)) {
 378			return false;
 379		}
 380		$newarray = $array1;
 381		foreach ($array2 as $key => $val) {
 382			if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) {
 383				$newarray[$key] = getid3_lib::array_merge_noclobber($newarray[$key], $val);
 384			} elseif (!isset($newarray[$key])) {
 385				$newarray[$key] = $val;
 386			}
 387		}
 388		return $newarray;
 389	}
 390
 391
 392	function fileextension($filename, $numextensions=1) {
 393		if (strstr($filename, '.')) {
 394			$reversedfilename = strrev($filename);
 395			$offset = 0;
 396			for ($i = 0; $i < $numextensions; $i++) {
 397				$offset = strpos($reversedfilename, '.', $offset + 1);
 398				if ($offset === false) {
 399					return '';
 400				}
 401			}
 402			return strrev(substr($reversedfilename, 0, $offset));
 403		}
 404		return '';
 405	}
 406
 407
 408	function PlaytimeString($playtimeseconds) {
 409		$contentseconds = round((($playtimeseconds / 60) - floor($playtimeseconds / 60)) * 60);
 410		$contentminutes = floor($playtimeseconds / 60);
 411		if ($contentseconds >= 60) {
 412			$contentseconds -= 60;
 413			$contentminutes++;
 414		}
 415		return intval($contentminutes).':'.str_pad($contentseconds, 2, 0, STR_PAD_LEFT);
 416	}
 417
 418
 419	function image_type_to_mime_type($imagetypeid) {
 420		// only available in PHP v4.3.0+
 421		static $image_type_to_mime_type = array();
 422		if (empty($image_type_to_mime_type)) {
 423			$image_type_to_mime_type[1]  = 'image/gif';                     // GIF
 424			$image_type_to_mime_type[2]  = 'image/jpeg';                    // JPEG
 425			$image_type_to_mime_type[3]  = 'image/png';                     // PNG
 426			$image_type_to_mime_type[4]  = 'application/x-shockwave-flash'; // Flash
 427			$image_type_to_mime_type[5]  = 'image/psd';                     // PSD
 428			$image_type_to_mime_type[6]  = 'image/bmp';                     // BMP
 429			$image_type_to_mime_type[7]  = 'image/tiff';                    // TIFF: little-endian (Intel)
 430			$image_type_to_mime_type[8]  = 'image/tiff';                    // TIFF: big-endian (Motorola)
 431			//$image_type_to_mime_type[9]  = 'image/jpc';                   // JPC
 432			//$image_type_to_mime_type[10] = 'image/jp2';                   // JPC
 433			//$image_type_to_mime_type[11] = 'image/jpx';                   // JPC
 434			//$image_type_to_mime_type[12] = 'image/jb2';                   // JPC
 435			$image_type_to_mime_type[13] = 'application/x-shockwave-flash'; // Shockwave
 436			$image_type_to_mime_type[14] = 'image/iff';                     // IFF
 437		}
 438		return (isset($image_type_to_mime_type[$imagetypeid]) ? $image_type_to_mime_type[$imagetypeid] : 'application/octet-stream');
 439	}
 440
 441
 442	function DateMac2Unix($macdate) {
 443		// Macintosh timestamp: seconds since 00:00h January 1, 1904
 444		// UNIX timestamp:      seconds since 00:00h January 1, 1970
 445		return getid3_lib::CastAsInt($macdate - 2082844800);
 446	}
 447
 448
 449	function FixedPoint8_8($rawdata) {
 450		return getid3_lib::BigEndian2Int(substr($rawdata, 0, 1)) + (float) (getid3_lib::BigEndian2Int(substr($rawdata, 1, 1)) / pow(2, 8));
 451	}
 452
 453
 454	function FixedPoint16_16($rawdata) {
 455		return getid3_lib::BigEndian2Int(substr($rawdata, 0, 2)) + (float) (getid3_lib::BigEndian2Int(substr($rawdata, 2, 2)) / pow(2, 16));
 456	}
 457
 458
 459	function FixedPoint2_30($rawdata) {
 460		$binarystring = getid3_lib::BigEndian2Bin($rawdata);
 461		return getid3_lib::Bin2Dec(substr($binarystring, 0, 2)) + (float) (getid3_lib::Bin2Dec(substr($binarystring, 2, 30)) / 1073741824);
 462	}
 463
 464
 465	function CreateDeepArray($ArrayPath, $Separator, $Value) {
 466		// assigns $Value to a nested array path:
 467		//   $foo = getid3_lib::CreateDeepArray('/path/to/my', '/', 'file.txt')
 468		// is the same as:
 469		//   $foo = array('path'=>array('to'=>'array('my'=>array('file.txt'))));
 470		// or
 471		//   $foo['path']['to']['my'] = 'file.txt';
 472		while ($ArrayPath && ($ArrayPath{0} == $Separator)) {
 473			$ArrayPath = substr($ArrayPath, 1);
 474		}
 475		if (($pos = strpos($ArrayPath, $Separator)) !== false) {
 476			$ReturnedArray[substr($ArrayPath, 0, $pos)] = getid3_lib::CreateDeepArray(substr($ArrayPath, $pos + 1), $Separator, $Value);
 477		} else {
 478			$ReturnedArray[$ArrayPath] = $Value;
 479		}
 480		return $ReturnedArray;
 481	}
 482
 483	function array_max($arraydata, $returnkey=false) {
 484		$maxvalue = false;
 485		$maxkey = false;
 486		foreach ($arraydata as $key => $value) {
 487			if (!is_array($value)) {
 488				if ($value > $maxvalue) {
 489					$maxvalue = $value;
 490					$maxkey = $key;
 491				}
 492			}
 493		}
 494		return ($returnkey ? $maxkey : $maxvalue);
 495	}
 496
 497	function array_min($arraydata, $returnkey=false) {
 498		$minvalue = false;
 499		$minkey = false;
 500		foreach ($arraydata as $key => $value) {
 501			if (!is_array($value)) {
 502				if ($value > $minvalue) {
 503					$minvalue = $value;
 504					$minkey = $key;
 505				}
 506			}
 507		}
 508		return ($returnkey ? $minkey : $minvalue);
 509	}
 510
 511
 512	function md5_file($file) {
 513
 514		// md5_file() exists in PHP 4.2.0+.
 515		if (function_exists('md5_file')) {
 516			return md5_file($file);
 517		}
 518
 519		if (GETID3_OS_ISWINDOWS) {
 520
 521			$RequiredFiles = array('cygwin1.dll', 'md5sum.exe');
 522			foreach ($RequiredFiles as $required_file) {
 523				if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) {
 524					die(implode(' and ', $RequiredFiles).' are required in '.GETID3_HELPERAPPSDIR.' for getid3_lib::md5_file() to function under Windows in PHP < v4.2.0');
 525				}
 526			}
 527			$commandline = GETID3_HELPERAPPSDIR.'md5sum.exe "'.str_replace('/', DIRECTORY_SEPARATOR, $file).'"';
 528			if (ereg("^[\\]?([0-9a-f]{32})", strtolower(`$commandline`), $r)) {
 529				return $r[1];
 530			}
 531
 532		} else {
 533
 534			// The following works under UNIX only
 535			$file = str_replace('`', '\\`', $file);
 536			if (ereg("^([0-9a-f]{32})[ \t\n\r]", `md5sum "$file"`, $r)) {
 537				return $r[1];
 538			}
 539
 540		}
 541		return false;
 542	}
 543
 544
 545	function sha1_file($file) {
 546
 547		// sha1_file() exists in PHP 4.3.0+.
 548		if (function_exists('sha1_file')) {
 549			return sha1_file($file);
 550		}
 551
 552		$file = str_replace('`', '\\`', $file);
 553
 554		if (GETID3_OS_ISWINDOWS) {
 555
 556			$RequiredFiles = array('cygwin1.dll', 'sha1sum.exe');
 557			foreach ($RequiredFiles as $required_file) {
 558				if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) {
 559					die(implode(' and ', $RequiredFiles).' are required in '.GETID3_HELPERAPPSDIR.' for getid3_lib::sha1_file() to function under Windows in PHP < v4.3.0');
 560				}
 561			}
 562			$commandline = GETID3_HELPERAPPSDIR.'sha1sum.exe "'.str_replace('/', DIRECTORY_SEPARATOR, $file).'"';
 563			if (ereg("^sha1=([0-9a-f]{40})", strtolower(`$commandline`), $r)) {
 564				return $r[1];
 565			}
 566
 567		} else {
 568
 569			$commandline = 'sha1sum '.escapeshellarg($file).'';
 570			if (ereg("^([0-9a-f]{40})[ \t\n\r]", strtolower(`$commandline`), $r)) {
 571				return $r[1];
 572			}
 573
 574		}
 575
 576		return false;
 577	}
 578
 579
 580	// Allan Hansen <ah�artemis*dk>
 581	// getid3_lib::md5_data() - returns md5sum for a file from startuing position to absolute end position
 582	function hash_data($file, $offset, $end, $algorithm) {
 583
 584		switch ($algorithm) {
 585			case 'md5':
 586				$hash_function = 'md5_file';
 587				$unix_call     = 'md5sum';
 588				$windows_call  = 'md5sum.exe';
 589				$hash_length   = 32;
 590				break;
 591
 592			case 'sha1':
 593				$hash_function = 'sha1_file';
 594				$unix_call     = 'sha1sum';
 595				$windows_call  = 'sha1sum.exe';
 596				$hash_length   = 40;
 597				break;
 598
 599			default:
 600				die('Invalid algorithm ('.$algorithm.') in getid3_lib::hash_data()');
 601				break;
 602		}
 603		$size = $end - $offset;
 604		while (true) {
 605			if (GETID3_OS_ISWINDOWS) {
 606
 607				// It seems that sha1sum.exe for Windows only works on physical files, does not accept piped data
 608				// Fall back to create-temp-file method:
 609				if ($algorithm == 'sha1') {
 610					break;
 611				}
 612
 613				$RequiredFiles = array('cygwin1.dll', 'head.exe', 'tail.exe', $windows_call);
 614				foreach ($RequiredFiles as $required_file) {
 615					if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) {
 616						// helper apps not available - fall back to old method
 617						break;
 618					}
 619				}
 620				$commandline  = GETID3_HELPERAPPSDIR.'head.exe -c '.$end.' "'.escapeshellarg(str_replace('/', DIRECTORY_SEPARATOR, $file)).'" | ';
 621				$commandline .= GETID3_HELPERAPPSDIR.'tail.exe -c '.$size.' | ';
 622				$commandline .= GETID3_HELPERAPPSDIR.$windows_call;
 623
 624			} else {
 625
 626				$commandline  = 'head -c'.$end.' '.escapeshellarg($file).' | ';
 627				$commandline .= 'tail -c'.$size.' | ';
 628				$commandline .= $unix_call;
 629
 630			}
 631			if ((bool) ini_get('safe_mode')) {
 632				$ThisFileInfo['warning'][] = 'PHP running in Safe Mode - backtick operator not available, using slower non-system-call '.$algorithm.' algorithm';
 633				break;
 634			}
 635			return substr(`$commandline`, 0, $hash_length);
 636		}
 637
 638		// try to create a temporary file in the system temp directory - invalid dirname should force to system temp dir
 639		if (($data_filename = tempnam('*', 'getID3')) === false) {
 640			// can't find anywhere to create a temp file, just die
 641			return false;
 642		}
 643
 644		// Init
 645		$result = false;
 646
 647		// copy parts of file
 648		if ($fp = @fopen($file, 'rb')) {
 649
 650			if ($fp_data = @fopen($data_filename, 'wb')) {
 651
 652				fseek($fp, $offset, SEEK_SET);
 653				$byteslefttowrite = $end - $offset;
 654				while (($byteslefttowrite > 0) && ($buffer = fread($fp, GETID3_FREAD_BUFFER_SIZE))) {
 655					$byteswritten = fwrite($fp_data, $buffer, $byteslefttowrite);
 656					$byteslefttowrite -= $byteswritten;
 657				}
 658				fclose($fp_data);
 659				$result = getid3_lib::$hash_function($data_filename);
 660
 661			}
 662			fclose($fp);
 663		}
 664		unlink($data_filename);
 665		return $result;
 666	}
 667
 668
 669	function iconv_fallback_int_utf8($charval) {
 670		if ($charval < 128) {
 671			// 0bbbbbbb
 672			$newcharstring = chr($charval);
 673		} elseif ($charval < 2048) {
 674			// 110bbbbb 10bbbbbb
 675			$newcharstring  = chr(($charval >> 6) | 0xC0);
 676			$newcharstring .= chr(($charval & 0x3F) | 0x80);
 677		} elseif ($charval < 65536) {
 678			// 1110bbbb 10bbbbbb 10bbbbbb
 679			$newcharstring  = chr(($charval >> 12) | 0xE0);
 680			$newcharstring .= chr(($charval >>  6) | 0xC0);
 681			$newcharstring .= chr(($charval & 0x3F) | 0x80);
 682		} else {
 683			// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
 684			$newcharstring  = chr(($charval >> 18) | 0xF0);
 685			$newcharstring .= chr(($charval >> 12) | 0xC0);
 686			$newcharstring .= chr(($charval >>  6) | 0xC0);
 687			$newcharstring .= chr(($charval & 0x3F) | 0x80);
 688		}
 689		return $newcharstring;
 690	}
 691
 692	// ISO-8859-1 => UTF-8
 693	function iconv_fallback_iso88591_utf8($string, $bom=false) {
 694		if (function_exists('utf8_encode')) {
 695			return utf8_encode($string);
 696		}
 697		// utf8_encode() unavailable, use getID3()'s iconv_fallback() conversions (possibly PHP is compiled without XML support)
 698		$newcharstring = '';
 699		if ($bom) {
 700			$newcharstring .= "\xEF\xBB\xBF";
 701		}
 702		for ($i = 0; $i < strlen($string); $i++) {
 703			$charval = ord($string{$i});
 704			$newcharstring .= getid3_lib::iconv_fallback_int_utf8($charval);
 705		}
 706		return $newcharstring;
 707	}
 708
 709	// ISO-8859-1 => UTF-16BE
 710	function iconv_fallback_iso88591_utf16be($string, $bom=false) {
 711		$newcharstring = '';
 712		if ($bom) {
 713			$newcharstring .= "\xFE\xFF";
 714		}
 715		for ($i = 0; $i < strlen($string); $i++) {
 716			$newcharstring .= "\x00".$string{$i};
 717		}
 718		return $newcharstring;
 719	}
 720
 721	// ISO-8859-1 => UTF-16LE
 722	function iconv_fallback_iso88591_utf16le($string, $bom=false) {
 723		$newcharstring = '';
 724		if ($bom) {
 725			$newcharstring .= "\xFF\xFE";
 726		}
 727		for ($i = 0; $i < strlen($string); $i++) {
 728			$newcharstring .= $string{$i}."\x00";
 729		}
 730		return $newcharstring;
 731	}
 732
 733	// ISO-8859-1 => UTF-16LE (BOM)
 734	function iconv_fallback_iso88591_utf16($string) {
 735		return getid3_lib::iconv_fallback_iso88591_utf16le($string, true);
 736	}
 737
 738	// UTF-8 => ISO-8859-1
 739	function iconv_fallback_utf8_iso88591($string) {
 740		if (function_exists('utf8_decode')) {
 741			return utf8_decode($string);
 742		}
 743		// utf8_decode() unavailable, use getID3()'s iconv_fallback() conversions (possibly PHP is compiled without XML support)
 744		$newcharstring = '';
 745		$offset = 0;
 746		$stringlength = strlen($string);
 747		while ($offset < $stringlength) {
 748			if ((ord($string{$offset}) | 0x07) == 0xF7) {
 749				// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
 750				$charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
 751				           ((ord($string{($offset + 1)}) & 0x3F) << 12) &
 752				           ((ord($string{($offset + 2)}) & 0x3F) <<  6) &
 753				            (ord($string{($offset + 3)}) & 0x3F);
 754				$offset += 4;
 755			} elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
 756				// 1110bbbb 10bbbbbb 10bbbbbb
 757				$charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
 758				           ((ord($string{($offset + 1)}) & 0x3F) <<  6) &
 759				            (ord($string{($offset + 2)}) & 0x3F);
 760				$offset += 3;
 761			} elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
 762				// 110bbbbb 10bbbbbb
 763				$charval = ((ord($string{($offset + 0)}) & 0x1F) <<  6) &
 764				            (ord($string{($offset + 1)}) & 0x3F);
 765				$offset += 2;
 766			} elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
 767				// 0bbbbbbb
 768				$charval = ord($string{$offset});
 769				$offset += 1;
 770			} else {
 771				// error? throw some kind of warning here?
 772				$charval = false;
 773				$offset += 1;
 774			}
 775			if ($charval !== false) {
 776				$newcharstring .= (($charval < 256) ? chr($charval) : '?');
 777			}
 778		}
 779		return $newcharstring;
 780	}
 781
 782	// UTF-8 => UTF-16BE
 783	function iconv_fallback_utf8_utf16be($string, $bom=false) {
 784		$newcharstring = '';
 785		if ($bom) {
 786			$newcharstring .= "\xFE\xFF";
 787		}
 788		$offset = 0;
 789		$stringlength = strlen($string);
 790		while ($offset < $stringlength) {
 791			if ((ord($string{$offset}) | 0x07) == 0xF7) {
 792				// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
 793				$charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
 794				           ((ord($string{($offset + 1)}) & 0x3F) << 12) &
 795				           ((ord($string{($offset + 2)}) & 0x3F) <<  6) &
 796				            (ord($string{($offset + 3)}) & 0x3F);
 797				$offset += 4;
 798			} elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
 799				// 1110bbbb 10bbbbbb 10bbbbbb
 800				$charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
 801				           ((ord($string{($offset + 1)}) & 0x3F) <<  6) &
 802				            (ord($string{($offset + 2)}) & 0x3F);
 803				$offset += 3;
 804			} elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
 805				// 110bbbbb 10bbbbbb
 806				$charval = ((ord($string{($offset + 0)}) & 0x1F) <<  6) &
 807				            (ord($string{($offset + 1)}) & 0x3F);
 808				$offset += 2;
 809			} elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
 810				// 0bbbbbbb
 811				$charval = ord($string{$offset});
 812				$offset += 1;
 813			} else {
 814				// error? throw some kind of warning here?
 815				$charval = false;
 816				$offset += 1;
 817			}
 818			if ($charval !== false) {
 819				$newcharstring .= (($charval < 65536) ? getid3_lib::BigEndian2String($charval, 2) : "\x00".'?');
 820			}
 821		}
 822		return $newcharstring;
 823	}
 824
 825	// UTF-8 => UTF-16LE
 826	function iconv_fallback_utf8_utf16le($string, $bom=false) {
 827		$newcharstring = '';
 828		if ($bom) {
 829			$newcharstring .= "\xFF\xFE";
 830		}
 831		$offset = 0;
 832		$stringlength = strlen($string);
 833		while ($offset < $stringlength) {
 834			if ((ord($string{$offset}) | 0x07) == 0xF7) {
 835				// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
 836				$charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
 837				           ((ord($string{($offset + 1)}) & 0x3F) << 12) &
 838				           ((ord($string{($offset + 2)}) & 0x3F) <<  6) &
 839				            (ord($string{($offset + 3)}) & 0x3F);
 840				$offset += 4;
 841			} elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
 842				// 1110bbbb 10bbbbbb 10bbbbbb
 843				$charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
 844				           ((ord($string{($offset + 1)}) & 0x3F) <<  6) &
 845				            (ord($string{($offset + 2)}) & 0x3F);
 846				$offset += 3;
 847			} elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
 848				// 110bbbbb 10bbbbbb
 849				$charval = ((ord($string{($offset + 0)}) & 0x1F) <<  6) &
 850				            (ord($string{($offset + 1)}) & 0x3F);
 851				$offset += 2;
 852			} elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
 853				// 0bbbbbbb
 854				$charval = ord($string{$offset});
 855				$offset += 1;
 856			} else {
 857				// error? maybe throw some warning here?
 858				$charval = false;
 859				$offset += 1;
 860			}
 861			if ($charval !== false) {
 862				$newcharstring .= (($charval < 65536) ? getid3_lib::LittleEndian2String($charval, 2) : '?'."\x00");
 863			}
 864		}
 865		return $newcharstring;
 866	}
 867
 868	// UTF-8 => UTF-16LE (BOM)
 869	function iconv_fallback_utf8_utf16($string) {
 870		return getid3_lib::iconv_fallback_utf8_utf16le($string, true);
 871	}
 872
 873	// UTF-16BE => UTF-8
 874	function iconv_fallback_utf16be_utf8($string) {
 875		if (substr($string, 0, 2) == "\xFE\xFF") {
 876			// strip BOM
 877			$string = substr($string, 2);
 878		}
 879		$newcharstring = '';
 880		for ($i = 0; $i < strlen($string); $i += 2) {
 881			$charval = getid3_lib::BigEndian2Int(substr($string, $i, 2));
 882			$newcharstring .= getid3_lib::iconv_fallback_int_utf8($charval);
 883		}
 884		return $newcharstring;
 885	}
 886
 887	// UTF-16LE => UTF-8
 888	function iconv_fallback_utf16le_utf8($string) {
 889		if (substr($string, 0, 2) == "\xFF\xFE") {
 890			// strip BOM
 891			$string = substr($string, 2);
 892		}
 893		$newcharstring = '';
 894		for ($i = 0; $i < strlen($string); $i += 2) {
 895			$charval = getid3_lib::LittleEndian2Int(substr($string, $i, 2));
 896			$newcharstring .= getid3_lib::iconv_fallback_int_utf8($charval);
 897		}
 898		return $newcharstring;
 899	}
 900
 901	// UTF-16BE => ISO-8859-1
 902	function iconv_fallback_utf16be_iso88591($string) {
 903		if (substr($string, 0, 2) == "\xFE\xFF") {
 904			// strip BOM
 905			$string = substr($string, 2);
 906		}
 907		$newcharstring = '';
 908		for ($i = 0; $i < strlen($string); $i += 2) {
 909			$charval = getid3_lib::BigEndian2Int(substr($string, $i, 2));
 910			$newcharstring .= (($charval < 256) ? chr($charval) : '?');
 911		}
 912		return $newcharstring;
 913	}
 914
 915	// UTF-16LE => ISO-8859-1
 916	function iconv_fallback_utf16le_iso88591($string) {
 917		if (substr($string, 0, 2) == "\xFF\xFE") {
 918			// strip BOM
 919			$string = substr($string, 2);
 920		}
 921		$newcharstring = '';
 922		for ($i = 0; $i < strlen($string); $i += 2) {
 923			$charval = getid3_lib::LittleEndian2Int(substr($string, $i, 2));
 924			$newcharstring .= (($charval < 256) ? chr($charval) : '?');
 925		}
 926		return $newcharstring;
 927	}
 928
 929	// UTF-16 (BOM) => ISO-8859-1
 930	function iconv_fallback_utf16_iso88591($string) {
 931		$bom = substr($string, 0, 2);
 932		if ($bom == "\xFE\xFF") {
 933			return getid3_lib::iconv_fallback_utf16be_iso88591(substr($string, 2));
 934		} elseif ($bom == "\xFF\xFE") {
 935			return getid3_lib::iconv_fallback_utf16le_iso88591(substr($string, 2));
 936		}
 937		return $string;
 938	}
 939
 940	// UTF-16 (BOM) => UTF-8
 941	function iconv_fallback_utf16_utf8($string) {
 942		$bom = substr($string, 0, 2);
 943		if ($bom == "\xFE\xFF") {
 944			return getid3_lib::iconv_fallback_utf16be_utf8(substr($string, 2));
 945		} elseif ($bom == "\xFF\xFE") {
 946			return getid3_lib::iconv_fallback_utf16le_utf8(substr($string, 2));
 947		}
 948		return $string;
 949	}
 950
 951	function iconv_fallback($in_charset, $out_charset, $string) {
 952
 953		if ($in_charset == $out_charset) {
 954			return $string;
 955		}
 956
 957		static $iconv_broken_or_unavailable = array();
 958		if (is_null(@$iconv_broken_or_unavailable[$in_charset.'_'.$out_charset])) {
 959			$GETID3_ICONV_TEST_STRING = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~�������������������������������� �����������������������������������������������������������������������������������������������';
 960
 961			// Check iconv()
 962			if (function_exists('iconv')) {
 963				if (@iconv($in_charset, 'ISO-8859-1', @iconv('ISO-8859-1', $in_charset, $GETID3_ICONV_TEST_STRING)) == $GETID3_ICONV_TEST_STRING) {
 964					if (@iconv($out_charset, 'ISO-8859-1', @iconv('ISO-8859-1', $out_charset, $GETID3_ICONV_TEST_STRING)) == $GETID3_ICONV_TEST_STRING) {
 965						// everything works, use iconv()
 966						$iconv_broken_or_unavailable[$in_charset.'_'.$out_charset] = false;
 967					} else {
 968						// iconv() available, but broken. Use getID3()'s iconv_fallback() conversions instead
 969						// known issue in PHP v4.1.x
 970						$iconv_broken_or_unavailable[$in_charset.'_'.$out_charset] = true;
 971					}
 972				} else {
 973					// iconv() available, but broken. Use getID3()'s iconv_fallback() conversions instead
 974					// known issue in PHP v4.1.x
 975					$iconv_broken_or_unavailable[$in_charset.'_'.$out_charset] = true;
 976				}
 977			} else {
 978				// iconv() unavailable, use getID3()'s iconv_fallback() conversions
 979				$iconv_broken_or_unavailable[$in_charset.'_'.$out_charset] = true;
 980			}
 981		}
 982
 983		if ($iconv_broken_or_unavailable[$in_charset.'_'.$out_charset]) {
 984			static $ConversionFunctionList = array();
 985			if (empty($ConversionFunctionList)) {
 986				$ConversionFunctionList['ISO-8859-1']['UTF-8']    = 'iconv_fallback_iso88591_utf8';
 987				$ConversionFunctionList['ISO-8859-1']['UTF-16']   = 'iconv_fallback_iso88591_utf16';
 988				$ConversionFunctionList['ISO-8859-1']['UTF-16BE'] = 'iconv_fallback_iso88591_utf16be';
 989				$ConversionFunctionList['ISO-8859-1']['UTF-16LE'] = 'iconv_fallback_iso88591_utf16le';
 990				$ConversionFunctionList['UTF-8']['ISO-8859-1']    = 'iconv_fallback_utf8_iso88591';
 991				$ConversionFunctionList['UTF-8']['UTF-16']        = 'iconv_fallback_utf8_utf16';
 992				$ConversionFunctionList['UTF-8']['UTF-16BE']      = 'iconv_fallback_utf8_utf16be';
 993				$ConversionFunctionList['UTF-8']['UTF-16LE']      = 'iconv_fallback_utf8_utf16le';
 994				$ConversionFunctionList['UTF-16']['ISO-8859-1']   = 'iconv_fallback_utf16_iso88591';
 995				$ConversionFunctionList['UTF-16']['UTF-8']        = 'iconv_fallback_utf16_utf8';
 996				$ConversionFunctionList['UTF-16LE']['ISO-8859-1'] = 'iconv_fallback_utf16le_iso88591';
 997				$ConversionFunctionList['UTF-16LE']['UTF-8']      = 'iconv_fallback_utf16le_utf8';
 998				$ConversionFunctionList['UTF-16BE']['ISO-8859-1'] = 'iconv_fallback_utf16be_iso88591';
 999				$ConversionFunctionList['UTF-16BE']['UTF-8']      = 'iconv_fallback_utf16be_utf8';
1000			}
1001			if (isset($ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)])) {
1002				$ConversionFunction = $ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)];
1003				return getid3_lib::$ConversionFunction($string);
1004			}
1005			die('PHP does not have iconv() support - cannot convert from '.$in_charset.' to '.$out_charset);
1006		}
1007
1008		if ($converted_string = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) {
1009			switch ($out_charset) {
1010				case 'ISO-8859-1':
1011					$converted_string = rtrim($converted_string, "\x00");
1012					break;
1013			}
1014			return $converted_string;
1015		}
1016
1017		// iconv() may sometimes fail with "illegal character in input string" error message
1018		// and return an empty string, but returning the unconverted string is more useful
1019		return $string;
1020	}
1021
1022
1023	function MultiByteCharString2HTML($string, $charset='ISO-8859-1') {
1024		$HTMLstring = '';
1025
1026		switch ($charset) {
1027			case 'ISO-8859-1':
1028			case 'ISO8859-1':
1029			case 'ISO-8859-15':
1030			case 'ISO8859-15':
1031			case 'cp866':
1032			case 'ibm866':
1033			case '866':
1034			case 'cp1251':
1035			case 'Windows-1251':
1036			case 'win-1251':
1037			case '1251':
1038			case 'cp1252':
1039			case 'Windows-1252':
1040			case '1252':
1041			case 'KOI8-R':
1042			case 'koi8-ru':
1043			case 'koi8r':
1044			case 'BIG5':
1045			case '950':
1046			case 'GB2312':
1047			case '936':
1048			case 'BIG5-HKSCS':
1049			case 'Shift_JIS':
1050			case 'SJIS':
1051			case '932':
1052			case 'EUC-JP':
1053			case 'EUCJP':
1054				$HTMLstring = htmlentities($string, ENT_COMPAT, $charset);
1055				break;
1056
1057			case 'UTF-8':
1058				$strlen = strlen($string);
1059				for ($i = 0; $i < $strlen; $i++) {
1060					$char_ord_val = ord($string{$i});
1061					$charval = 0;
1062					if ($char_ord_val < 0x80) {
1063						$charval = $char_ord_val;
1064					} elseif ((($char_ord_val & 0xF0) >> 4) == 0x0F) {
1065						$charval  = (($char_ord_val & 0x07) << 18);
1066						$charval += ((ord($string{++$i}) & 0x3F) << 12);
1067						$charval += ((ord($string{++$i}) & 0x3F) << 6);
1068						$charval +=  (ord($string{++$i}) & 0x3F);
1069					} elseif ((($char_ord_val & 0xE0) >> 5) == 0x07) {
1070						$charval  = (($char_ord_val & 0x0F) << 12);
1071						$charval += ((ord($string{++$i}) & 0x3F) << 6);
1072						$charval +=  (ord($string{++$i}) & 0x3F);
1073					} elseif ((($char_ord_val & 0xC0) >> 6) == 0x03) {
1074						$charval  = (($char_ord_val & 0x1F) << 6);
1075						$charval += (ord($string{++$i}) & 0x3F);
1076					}
1077					if (($charval >= 32) && ($charval <= 127)) {
1078						$HTMLstring .= chr($charval);
1079					} else {
1080						$HTMLstring .= '&#'.$charval.';';
1081					}
1082				}
1083				break;
1084
1085			case 'UTF-16LE':
1086				for ($i = 0; $i < strlen($string); $i += 2) {
1087					$charval = getid3_lib::LittleEndian2Int(substr($string, $i, 2));
1088					if (($charval >= 32) && ($charval <= 127)) {
1089						$HTMLstring .= chr($charval);
1090					} else {
1091						$HTMLstring .= '&#'.$charval.';';
1092					}
1093				}
1094				break;
1095
1096			case 'UTF-16BE':
1097				for ($i = 0; $i < strlen($string); $i += 2) {
1098					$charval = getid3_lib::BigEndian2Int(substr($string, $i, 2));
1099					if (($charval >= 32) && ($charval <= 127)) {
1100						$HTMLstring .= chr($charval);
1101					} else {
1102						$HTMLstring .= '&#'.$charval.';';
1103					}
1104				}
1105				break;
1106
1107			default:
1108				$HTMLstring = 'ERROR: Character set "'.$charset.'" not supported in MultiByteCharString2HTML()';
1109				break;
1110		}
1111		return $HTMLstring;
1112	}
1113
1114
1115
1116	function RGADnameLookup($namecode) {
1117		static $RGADname = array();
1118		if (empty($RGADname)) {
1119			$RGADname[0] = 'not set';
1120			$RGADname[1] = 'Track Gain Adjustment';
1121			$RGADname[2] = 'Album Gain Adjustment';
1122		}
1123
1124		return (isset($RGADname[$namecode]) ? $RGADname[$namecode] : '');
1125	}
1126
1127
1128	function RGADoriginatorLookup($originatorcode) {
1129		static $RGADoriginator = array();
1130		if (empty($RGADoriginator)) {
1131			$RGADoriginator[0] = 'unspecified';
1132			$RGADoriginator[1] = 'pre-set by artist/producer/mastering engineer';
1133			$RGADoriginator[2] = 'set by user';
1134			$RGADoriginator[3] = 'determined automatically';
1135		}
1136
1137		return (isset($RGADoriginator[$originatorcode]) ? $RGADoriginator[$originatorcode] : '');
1138	}
1139
1140
1141	function RGADadjustmentLookup($rawadjustment, $signbit) {
1142		$adjustment = $rawadjustment / 10;
1143		if ($signbit == 1) {
1144			$adjustment *= -1;
1145		}
1146		return (float) $adjustment;
1147	}
1148
1149
1150	function RGADgainString($namecode, $originatorcode, $replaygain) {
1151		if ($replaygain < 0) {
1152			$signbit = '1';
1153		} else {
1154			$signbit = '0';
1155		}
1156		$storedreplaygain = intval(round($replaygain * 10));
1157		$gainstring  = str_pad(decbin($namecode), 3, '0', STR_PAD_LEFT);
1158		$gainstring .= str_pad(decbin($originatorcode), 3, '0', STR_PAD_LEFT);
1159		$gainstring .= $signbit;
1160		$gainstring .= str_pad(decbin($storedreplaygain), 9, '0', STR_PAD_LEFT);
1161
1162		return $gainstring;
1163	}
1164
1165	function RGADamplitude2dB($amplitude) {
1166		return 20 * log10($amplitude);
1167	}
1168
1169
1170	function GetDataImageSize($imgData) {
1171		$GetDataImageSize = false;
1172		if ($tempfilename = tempnam('*', 'getID3')) {
1173			if ($tmp = @fopen($tempfilename, 'wb')) {
1174				fwrite($tmp, $imgData);
1175				fclose($tmp);
1176				$GetDataImageSize = @GetImageSize($tempfilename);
1177			}
1178			unlink($tempfilename);
1179		}
1180		return $GetDataImageSize;
1181	}
1182
1183	function ImageTypesLookup($imagetypeid) {
1184		static $ImageTypesLookup = array();
1185		if (empty($ImageTypesLookup)) {
1186			$ImageTypesLookup[1]  = 'gif';
1187			$ImageTypesLookup[2]  = 'jpeg';
1188			$ImageTypesLookup[3]  = 'png';
1189			$ImageTypesLookup[4]  = 'swf';
1190			$ImageTypesLookup[5]  = 'psd';
1191			$ImageTypesLookup[6]  = 'bmp';
1192			$ImageTypesLookup[7]  = 'tiff (little-endian)';
1193			$ImageTypesLookup[8]  = 'tiff (big-endian)';
1194			$ImageTypesLookup[9]  = 'jpc';
1195			$ImageTypesLookup[10] = 'jp2';
1196			$ImageTypesLookup[11] = 'jpx';
1197			$ImageTypesLookup[12] = 'jb2';
1198			$ImageTypesLookup[13] = 'swc';
1199			$ImageTypesLookup[14] = 'iff';
1200		}
1201		return (isset($ImageTypesLookup[$imagetypeid]) ? $ImageTypesLookup[$imagetypeid] : '');
1202	}
1203
1204	function CopyTagsToComments(&$ThisFileInfo) {
1205
1206		// Copy all entries from ['tags'] into common ['comments'] 
1207		if (!empty($ThisFileInfo['tags'])) {
1208			foreach ($ThisFileInfo['tags'] as $tagtype => $tagarray) {
1209				foreach ($tagarray as $tagname => $tagdata) {
1210					foreach ($tagdata as $key => $value) {
1211						if (!empty($value)) {
1212							if (empty($ThisFileInfo['comments'][$tagname])) {
1213
1214								// fall through and append value
1215
1216							} elseif ($tagtype == 'id3v1') {
1217
1218								$newvaluelength = strlen(trim($value));
1219								foreach ($ThisFileInfo['comments'][$tagname] as $existingkey => $existingvalue) {
1220									$oldvaluelength = strlen(trim($existingvalue));
1221									if (($newvaluelength <= $oldvaluelength) && (substr($existingvalue, 0, $newvaluelength) == trim($value))) {
1222										// new value is identical but shorter-than (or equal-length to) one already in comments - skip
1223										break 2;
1224									}
1225								}
1226
1227							} else {
1228
1229								$newvaluelength = strlen(trim($value));
1230								foreach ($ThisFileInfo['comments'][$tagname] as $existingkey => $existingvalue) {
1231									$oldvaluelength = strlen(trim($existingvalue));
1232									if (($newvaluelength > $oldvaluelength) && (substr(trim($value), 0, strlen($existingvalue)) == $existingvalue)) {
1233										$ThisFileInfo['comments'][$tagname][$existingkey] = trim($value);
1234										break 2;
1235									}
1236								}
1237
1238							}
1239							if (empty($ThisFileInfo['comments'][$tagname]) || !in_array(trim($value), $ThisFileInfo['comments'][$tagname])) {
1240								$ThisFileInfo['comments'][$tagname][] = trim($value);
1241							}
1242						}
1243					}
1244				}
1245			}
1246			
1247			// Copy to ['comments_html'] 
1248    		foreach ($ThisFileInfo['comments'] as $field => $values) {
1249    		    foreach ($values as $index => $value) {
1250    		        $ThisFileInfo['comments_html'][$field][$index] = str_replace('&#0;', '', getid3_lib::MultiByteCharString2HTML($value, $ThisFileInfo['encoding']));
1251    		    }
1252            }
1253		}
1254	}
1255
1256
1257	function EmbeddedLookup($key, $begin, $end, $file, $name) {
1258
1259		// Cached
1260		static $cache;
1261		if (isset($cache[$file][$name])) {
1262			return @$cache[$file][$name][$key];
1263		}
1264
1265		// Init
1266		$keylength  = strlen($key);
1267		$line_count = $end - $begin - 7;
1268
1269		// Open php file
1270		$fp = fopen($file, 'r');
1271
1272		// Discard $begin lines
1273		for ($i = 0; $i < ($begin + 3); $i++) {
1274			fgets($fp, 1024);
1275		}
1276
1277		// Loop thru line
1278		while (0 < $line_count--) {
1279
1280			// Read line
1281			$line = ltrim(fgets($fp, 1024), "\t ");
1282
1283			// METHOD A: only cache the matching key - less memory but slower on next lookup of not-previously-looked-up key
1284			//$keycheck = substr($line, 0, $keylength);
1285			//if ($key == $keycheck)  {
1286			//	$cache[$file][$name][$keycheck] = substr($line, $keylength + 1);
1287			//	break;
1288			//}
1289
1290			// METHOD B: cache all keys in this lookup - more memory but faster on next lookup of not-previously-looked-up key
1291			//$cache[$file][$name][substr($line, 0, $keylength)] = trim(substr($line, $keylength + 1));
1292			@list($ThisKey, $ThisValue) = explode("\t", $line, 2);
1293			$cache[$file][$name][$ThisKey] = trim($ThisValue);
1294		}
1295
1296		// Close and return
1297		fclose($fp);
1298		return @$cache[$file][$name][$key];
1299	}
1300
1301	function IncludeDependency($filename, $sourcefile, $DieOnFailure=false) {
1302		global $GETID3_ERRORARRAY;
1303
1304		if (file_exists($filename)) {
1305			if (@include_once($filename)) {
1306				return true;
1307			} else {
1308				$diemessage = basename($sourcefile).' depends on '.$filename.', which has errors';
1309			}
1310		} else {
1311			$diemessage = basename($sourcefile).' depends on '.$filename.', which is missing';
1312		}
1313		if ($DieOnFailure) {
1314			die($diemessage);
1315		} else {
1316			$GETID3_ERRORARRAY[] = $diemessage;
1317		}
1318		return false;
1319	}
1320
1321}
1322
1323?>