wp/wp-includes/ID3/module.audio-video.riff.php
changeset 19 3d72ae0968f4
parent 16 a86126ab1dd4
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
    54 		$thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
    54 		$thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
    55 		$thisfile_riff_audio       = &$thisfile_riff['audio'];
    55 		$thisfile_riff_audio       = &$thisfile_riff['audio'];
    56 		$thisfile_riff_video       = &$thisfile_riff['video'];
    56 		$thisfile_riff_video       = &$thisfile_riff['video'];
    57 		$thisfile_riff_WAVE        = array();
    57 		$thisfile_riff_WAVE        = array();
    58 
    58 
       
    59 		$Original                 = array();
    59 		$Original['avdataoffset'] = $info['avdataoffset'];
    60 		$Original['avdataoffset'] = $info['avdataoffset'];
    60 		$Original['avdataend']    = $info['avdataend'];
    61 		$Original['avdataend']    = $info['avdataend'];
    61 
    62 
    62 		$this->fseek($info['avdataoffset']);
    63 		$this->fseek($info['avdataoffset']);
    63 		$RIFFheader = $this->fread(12);
    64 		$RIFFheader = $this->fread(12);
   294 
   295 
   295 				if (isset($thisfile_riff_WAVE['bext'][0]['data'])) {
   296 				if (isset($thisfile_riff_WAVE['bext'][0]['data'])) {
   296 					// shortcut
   297 					// shortcut
   297 					$thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0];
   298 					$thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0];
   298 
   299 
   299 					$thisfile_riff_WAVE_bext_0['title']          =                         trim(substr($thisfile_riff_WAVE_bext_0['data'],   0, 256));
   300 					$thisfile_riff_WAVE_bext_0['title']          =                              substr($thisfile_riff_WAVE_bext_0['data'],   0, 256);
   300 					$thisfile_riff_WAVE_bext_0['author']         =                         trim(substr($thisfile_riff_WAVE_bext_0['data'], 256,  32));
   301 					$thisfile_riff_WAVE_bext_0['author']         =                              substr($thisfile_riff_WAVE_bext_0['data'], 256,  32);
   301 					$thisfile_riff_WAVE_bext_0['reference']      =                         trim(substr($thisfile_riff_WAVE_bext_0['data'], 288,  32));
   302 					$thisfile_riff_WAVE_bext_0['reference']      =                              substr($thisfile_riff_WAVE_bext_0['data'], 288,  32);
       
   303 					foreach (array('title','author','reference') as $bext_key) {
       
   304 						// Some software (notably Logic Pro) may not blank existing data before writing a null-terminated string to the offsets
       
   305 						// assigned for text fields, resulting in a null-terminated string (or possibly just a single null) followed by garbage
       
   306 						// Keep only string as far as first null byte, discard rest of fixed-width data
       
   307 						// https://github.com/JamesHeinrich/getID3/issues/263
       
   308 						$null_terminator_offset = strpos($thisfile_riff_WAVE_bext_0[$bext_key], "\x00");
       
   309 						$thisfile_riff_WAVE_bext_0[$bext_key] = substr($thisfile_riff_WAVE_bext_0[$bext_key], 0, $null_terminator_offset);
       
   310 					}
       
   311 
   302 					$thisfile_riff_WAVE_bext_0['origin_date']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 320,  10);
   312 					$thisfile_riff_WAVE_bext_0['origin_date']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 320,  10);
   303 					$thisfile_riff_WAVE_bext_0['origin_time']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 330,   8);
   313 					$thisfile_riff_WAVE_bext_0['origin_time']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 330,   8);
   304 					$thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338,   8));
   314 					$thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338,   8));
   305 					$thisfile_riff_WAVE_bext_0['bwf_version']    = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 346,   1));
   315 					$thisfile_riff_WAVE_bext_0['bwf_version']    = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 346,   1));
   306 					$thisfile_riff_WAVE_bext_0['reserved']       =                              substr($thisfile_riff_WAVE_bext_0['data'], 347, 254);
   316 					$thisfile_riff_WAVE_bext_0['reserved']       =                              substr($thisfile_riff_WAVE_bext_0['data'], 347, 254);
   307 					$thisfile_riff_WAVE_bext_0['coding_history'] =         explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601)));
   317 					$thisfile_riff_WAVE_bext_0['coding_history'] =         explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601)));
   308 					if (preg_match('#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_date'], $matches_bext_date)) {
   318 					if (preg_match('#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_date'], $matches_bext_date)) {
   309 						if (preg_match('#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_time'], $matches_bext_time)) {
   319 						if (preg_match('#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_time'], $matches_bext_time)) {
       
   320 							$bext_timestamp = array();
   310 							list($dummy, $bext_timestamp['year'], $bext_timestamp['month'],  $bext_timestamp['day'])    = $matches_bext_date;
   321 							list($dummy, $bext_timestamp['year'], $bext_timestamp['month'],  $bext_timestamp['day'])    = $matches_bext_date;
   311 							list($dummy, $bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second']) = $matches_bext_time;
   322 							list($dummy, $bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second']) = $matches_bext_time;
   312 							$thisfile_riff_WAVE_bext_0['origin_date_unix'] = gmmktime($bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second'], $bext_timestamp['month'], $bext_timestamp['day'], $bext_timestamp['year']);
   323 							$thisfile_riff_WAVE_bext_0['origin_date_unix'] = gmmktime($bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second'], $bext_timestamp['month'], $bext_timestamp['day'], $bext_timestamp['year']);
   313 						} else {
   324 						} else {
   314 							$this->warning('RIFF.WAVE.BEXT.origin_time is invalid');
   325 							$this->warning('RIFF.WAVE.BEXT.origin_time is invalid');
   449 						}
   460 						}
   450 						unset($parsedXML);
   461 						unset($parsedXML);
   451 					}
   462 					}
   452 				}
   463 				}
   453 
   464 
   454 
   465 				if (isset($thisfile_riff_WAVE['guan'][0]['data'])) {
       
   466 					// shortcut
       
   467 					$thisfile_riff_WAVE_guan_0 = &$thisfile_riff_WAVE['guan'][0];
       
   468 					if (!empty($thisfile_riff_WAVE_guan_0['data']) && (substr($thisfile_riff_WAVE_guan_0['data'], 0, 14) == 'GUANO|Version:')) {
       
   469 						$thisfile_riff['guano'] = array();
       
   470 						foreach (explode("\n", $thisfile_riff_WAVE_guan_0['data']) as $line) {
       
   471 							if ($line) {
       
   472 								@list($key, $value) = explode(':', $line, 2);
       
   473 								if (substr($value, 0, 3) == '[{"') {
       
   474 									if ($decoded = @json_decode($value, true)) {
       
   475 										if (!empty($decoded) && (count($decoded) == 1)) {
       
   476 											$value = $decoded[0];
       
   477 										} else {
       
   478 											$value = $decoded;
       
   479 										}
       
   480 									}
       
   481 								}
       
   482 								$thisfile_riff['guano'] = array_merge_recursive($thisfile_riff['guano'], getid3_lib::CreateDeepArray($key, '|', $value));
       
   483 							}
       
   484 						}
       
   485 
       
   486 						// https://www.wildlifeacoustics.com/SCHEMA/GUANO.html
       
   487 						foreach ($thisfile_riff['guano'] as $key => $value) {
       
   488 							switch ($key) {
       
   489 								case 'Loc Position':
       
   490 									if (preg_match('#^([\\+\\-]?[0-9]+\\.[0-9]+) ([\\+\\-]?[0-9]+\\.[0-9]+)$#', $value, $matches)) {
       
   491 										list($dummy, $latitude, $longitude) = $matches;
       
   492 										$thisfile_riff['comments']['gps_latitude'][0]  = floatval($latitude);
       
   493 										$thisfile_riff['comments']['gps_longitude'][0] = floatval($longitude);
       
   494 										$thisfile_riff['guano'][$key] = floatval($latitude).' '.floatval($longitude);
       
   495 									}
       
   496 									break;
       
   497 								case 'Loc Elevation': // Elevation/altitude above mean sea level in meters
       
   498 									$thisfile_riff['comments']['gps_altitude'][0] = floatval($value);
       
   499 									$thisfile_riff['guano'][$key] = (float) $value;
       
   500 									break;
       
   501 								case 'Filter HP':        // High-pass filter frequency in kHz
       
   502 								case 'Filter LP':        // Low-pass filter frequency in kHz
       
   503 								case 'Humidity':         // Relative humidity as a percentage
       
   504 								case 'Length':           // Recording length in seconds
       
   505 								case 'Loc Accuracy':     // Estimated Position Error in meters
       
   506 								case 'Temperature Ext':  // External temperature in degrees Celsius outside the recorder's housing
       
   507 								case 'Temperature Int':  // Internal temperature in degrees Celsius inside the recorder's housing
       
   508 									$thisfile_riff['guano'][$key] = (float) $value;
       
   509 									break;
       
   510 								case 'Samplerate':       // Recording sample rate, Hz
       
   511 								case 'TE':               // Time-expansion factor. If not specified, then 1 (no time-expansion a.k.a. direct-recording) is assumed.
       
   512 									$thisfile_riff['guano'][$key] = (int) $value;
       
   513 									break;
       
   514 							}
       
   515 						}
       
   516 
       
   517 					} else {
       
   518 						$this->warning('RIFF.guan data not in expected format');
       
   519 					}
       
   520 				}
   455 
   521 
   456 				if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) {
   522 				if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) {
   457 					$thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
   523 					$thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
   458 					$info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
   524 					$info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
   459 				}
   525 				}
   731 					$thisfile_riff_video_current['frame_rate'] = round(1000000 / $thisfile_riff_raw_avih['dwMicroSecPerFrame'], 3);
   797 					$thisfile_riff_video_current['frame_rate'] = round(1000000 / $thisfile_riff_raw_avih['dwMicroSecPerFrame'], 3);
   732 					$thisfile_video['frame_rate'] = $thisfile_riff_video_current['frame_rate'];
   798 					$thisfile_video['frame_rate'] = $thisfile_riff_video_current['frame_rate'];
   733 				}
   799 				}
   734 				if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) {
   800 				if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) {
   735 					if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) {
   801 					if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) {
       
   802 						$thisfile_riff_raw_strf_strhfccType_streamindex = null;
   736 						for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) {
   803 						for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) {
   737 							if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) {
   804 							if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) {
   738 								$strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'];
   805 								$strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'];
   739 								$strhfccType = substr($strhData,  0, 4);
   806 								$strhfccType = substr($strhData,  0, 4);
   740 
   807 
  1067 				}
  1134 				}
  1068 /*
  1135 /*
  1069 				if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) {
  1136 				if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) {
  1070 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
  1137 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
  1071 					$getid3_temp = new getID3();
  1138 					$getid3_temp = new getID3();
  1072 					$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1139 					$getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
  1073 					$getid3_id3v2 = new getid3_id3v2($getid3_temp);
  1140 					$getid3_id3v2 = new getid3_id3v2($getid3_temp);
  1074 					$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8;
  1141 					$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8;
  1075 					if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
  1142 					if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
  1076 						$info['id3v2'] = $getid3_temp->info['id3v2'];
  1143 						$info['id3v2'] = $getid3_temp->info['id3v2'];
  1077 					}
  1144 					}
  1170 
  1237 
  1171 				if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
  1238 				if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
  1172 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, true);
  1239 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, true);
  1173 
  1240 
  1174 					$getid3_temp = new getID3();
  1241 					$getid3_temp = new getID3();
  1175 					$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1242 					$getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
  1176 					$getid3_mpeg = new getid3_mpeg($getid3_temp);
  1243 					$getid3_mpeg = new getid3_mpeg($getid3_temp);
  1177 					$getid3_mpeg->Analyze();
  1244 					$getid3_mpeg->Analyze();
  1178 					if (empty($getid3_temp->info['error'])) {
  1245 					if (empty($getid3_temp->info['error'])) {
  1179 						$info['audio']   = $getid3_temp->info['audio'];
  1246 						$info['audio']   = $getid3_temp->info['audio'];
  1180 						$info['video']   = $getid3_temp->info['video'];
  1247 						$info['video']   = $getid3_temp->info['video'];
  1256 
  1323 
  1257 				if (isset($thisfile_riff[$RIFFsubtype]['id3 '])) {
  1324 				if (isset($thisfile_riff[$RIFFsubtype]['id3 '])) {
  1258 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
  1325 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
  1259 
  1326 
  1260 					$getid3_temp = new getID3();
  1327 					$getid3_temp = new getID3();
  1261 					$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1328 					$getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
  1262 					$getid3_id3v2 = new getid3_id3v2($getid3_temp);
  1329 					$getid3_id3v2 = new getid3_id3v2($getid3_temp);
  1263 					$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8;
  1330 					$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8;
  1264 					if ($thisfile_riff[$RIFFsubtype]['id3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
  1331 					if ($thisfile_riff[$RIFFsubtype]['id3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
  1265 						$info['id3v2'] = $getid3_temp->info['id3v2'];
  1332 						$info['id3v2'] = $getid3_temp->info['id3v2'];
  1266 					}
  1333 					}
  1512 	public function ParseRIFF($startoffset, $maxoffset) {
  1579 	public function ParseRIFF($startoffset, $maxoffset) {
  1513 		$info = &$this->getid3->info;
  1580 		$info = &$this->getid3->info;
  1514 
  1581 
  1515 		$RIFFchunk = false;
  1582 		$RIFFchunk = false;
  1516 		$FoundAllChunksWeNeed = false;
  1583 		$FoundAllChunksWeNeed = false;
       
  1584 		$LISTchunkParent = null;
       
  1585 		$LISTchunkMaxOffset = null;
       
  1586 		$AC3syncwordBytes = pack('n', getid3_ac3::syncword); // 0x0B77 -> "\x0B\x77"
  1517 
  1587 
  1518 		try {
  1588 		try {
  1519 			$this->fseek($startoffset);
  1589 			$this->fseek($startoffset);
  1520 			$maxoffset = min($maxoffset, $info['avdataend']);
  1590 			$maxoffset = min($maxoffset, $info['avdataend']);
  1521 			while ($this->ftell() < $maxoffset) {
  1591 			while ($this->ftell() < $maxoffset) {
  1555 									$FirstFourBytes = substr($AudioChunkHeader, 8, 4);
  1625 									$FirstFourBytes = substr($AudioChunkHeader, 8, 4);
  1556 									if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
  1626 									if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
  1557 										// MP3
  1627 										// MP3
  1558 										if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
  1628 										if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
  1559 											$getid3_temp = new getID3();
  1629 											$getid3_temp = new getID3();
  1560 											$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1630 											$getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
  1561 											$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
  1631 											$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
  1562 											$getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
  1632 											$getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
  1563 											$getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
  1633 											$getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
  1564 											$getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
  1634 											$getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
  1565 											if (isset($getid3_temp->info['mpeg']['audio'])) {
  1635 											if (isset($getid3_temp->info['mpeg']['audio'])) {
  1573 												//$info['bitrate']               = $info['audio']['bitrate'];
  1643 												//$info['bitrate']               = $info['audio']['bitrate'];
  1574 											}
  1644 											}
  1575 											unset($getid3_temp, $getid3_mp3);
  1645 											unset($getid3_temp, $getid3_mp3);
  1576 										}
  1646 										}
  1577 
  1647 
  1578 									} elseif (strpos($FirstFourBytes, getid3_ac3::syncword) === 0) {
  1648 									} elseif (strpos($FirstFourBytes, $AC3syncwordBytes) === 0) {
  1579 
       
  1580 										// AC3
  1649 										// AC3
  1581 										$getid3_temp = new getID3();
  1650 										$getid3_temp = new getID3();
  1582 										$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1651 										$getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
  1583 										$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
  1652 										$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
  1584 										$getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
  1653 										$getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
  1585 										$getid3_ac3 = new getid3_ac3($getid3_temp);
  1654 										$getid3_ac3 = new getid3_ac3($getid3_temp);
  1586 										$getid3_ac3->Analyze();
  1655 										$getid3_ac3->Analyze();
  1587 										if (empty($getid3_temp->info['error'])) {
  1656 										if (empty($getid3_temp->info['error'])) {
  1638 								if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($testData, 0, 4))) {
  1707 								if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($testData, 0, 4))) {
  1639 
  1708 
  1640 									// Probably is MP3 data
  1709 									// Probably is MP3 data
  1641 									if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) {
  1710 									if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) {
  1642 										$getid3_temp = new getID3();
  1711 										$getid3_temp = new getID3();
  1643 										$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1712 										$getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
  1644 										$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1713 										$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1645 										$getid3_temp->info['avdataend']    = $info['avdataend'];
  1714 										$getid3_temp->info['avdataend']    = $info['avdataend'];
  1646 										$getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
  1715 										$getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
  1647 										$getid3_mp3->getOnlyMPEGaudioInfo($info['avdataoffset'], false);
  1716 										$getid3_mp3->getOnlyMPEGaudioInfo($info['avdataoffset'], false);
  1648 										if (empty($getid3_temp->info['error'])) {
  1717 										if (empty($getid3_temp->info['error'])) {
  1650 											$info['mpeg']  = $getid3_temp->info['mpeg'];
  1719 											$info['mpeg']  = $getid3_temp->info['mpeg'];
  1651 										}
  1720 										}
  1652 										unset($getid3_temp, $getid3_mp3);
  1721 										unset($getid3_temp, $getid3_mp3);
  1653 									}
  1722 									}
  1654 
  1723 
  1655 								} elseif (($isRegularAC3 = (substr($testData, 0, 2) == getid3_ac3::syncword)) || substr($testData, 8, 2) == strrev(getid3_ac3::syncword)) {
  1724 								} elseif (($isRegularAC3 = (substr($testData, 0, 2) == $AC3syncwordBytes)) || substr($testData, 8, 2) == strrev($AC3syncwordBytes)) {
  1656 
  1725 
  1657 									// This is probably AC-3 data
  1726 									// This is probably AC-3 data
  1658 									$getid3_temp = new getID3();
  1727 									$getid3_temp = new getID3();
  1659 									if ($isRegularAC3) {
  1728 									if ($isRegularAC3) {
  1660 										$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1729 										$getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
  1661 										$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1730 										$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1662 										$getid3_temp->info['avdataend']    = $info['avdataend'];
  1731 										$getid3_temp->info['avdataend']    = $info['avdataend'];
  1663 									}
  1732 									}
  1664 									$getid3_ac3 = new getid3_ac3($getid3_temp);
  1733 									$getid3_ac3 = new getid3_ac3($getid3_temp);
  1665 									if ($isRegularAC3) {
  1734 									if ($isRegularAC3) {
  1671 										$ac3_data = '';
  1740 										$ac3_data = '';
  1672 										for ($i = 0; $i < 28; $i += 2) {
  1741 										for ($i = 0; $i < 28; $i += 2) {
  1673 											$ac3_data .= substr($testData, 8 + $i + 1, 1);
  1742 											$ac3_data .= substr($testData, 8 + $i + 1, 1);
  1674 											$ac3_data .= substr($testData, 8 + $i + 0, 1);
  1743 											$ac3_data .= substr($testData, 8 + $i + 0, 1);
  1675 										}
  1744 										}
       
  1745 										$getid3_ac3->getid3->info['avdataoffset'] = 0;
       
  1746 										$getid3_ac3->getid3->info['avdataend']    = strlen($ac3_data);
  1676 										$getid3_ac3->AnalyzeString($ac3_data);
  1747 										$getid3_ac3->AnalyzeString($ac3_data);
  1677 									}
  1748 									}
  1678 
  1749 
  1679 									if (empty($getid3_temp->info['error'])) {
  1750 									if (empty($getid3_temp->info['error'])) {
  1680 										$info['audio'] = $getid3_temp->info['audio'];
  1751 										$info['audio'] = $getid3_temp->info['audio'];
  1689 
  1760 
  1690 								} elseif (preg_match('/^('.implode('|', array_map('preg_quote', getid3_dts::$syncwords)).')/', $testData)) {
  1761 								} elseif (preg_match('/^('.implode('|', array_map('preg_quote', getid3_dts::$syncwords)).')/', $testData)) {
  1691 
  1762 
  1692 									// This is probably DTS data
  1763 									// This is probably DTS data
  1693 									$getid3_temp = new getID3();
  1764 									$getid3_temp = new getID3();
  1694 									$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1765 									$getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
  1695 									$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1766 									$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1696 									$getid3_dts = new getid3_dts($getid3_temp);
  1767 									$getid3_dts = new getid3_dts($getid3_temp);
  1697 									$getid3_dts->Analyze();
  1768 									$getid3_dts->Analyze();
  1698 									if (empty($getid3_temp->info['error'])) {
  1769 									if (empty($getid3_temp->info['error'])) {
  1699 										$info['audio']            = $getid3_temp->info['audio'];
  1770 										$info['audio']            = $getid3_temp->info['audio'];
  1730 							case 'strh':
  1801 							case 'strh':
  1731 							case 'strf':
  1802 							case 'strf':
  1732 							case 'indx':
  1803 							case 'indx':
  1733 							case 'MEXT':
  1804 							case 'MEXT':
  1734 							case 'DISP':
  1805 							case 'DISP':
       
  1806 							case 'wamd':
       
  1807 							case 'guan':
  1735 								// always read data in
  1808 								// always read data in
  1736 							case 'JUNK':
  1809 							case 'JUNK':
  1737 								// should be: never read data in
  1810 								// should be: never read data in
  1738 								// but some programs write their version strings in a JUNK chunk (e.g. VirtualDub, AVIdemux, etc)
  1811 								// but some programs write their version strings in a JUNK chunk (e.g. VirtualDub, AVIdemux, etc)
  1739 								if ($chunksize < 1048576) {
  1812 								if ($chunksize < 1048576) {
  2074 	 *
  2147 	 *
  2075 	 * @return array
  2148 	 * @return array
  2076 	 */
  2149 	 */
  2077 	public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
  2150 	public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
  2078 
  2151 
       
  2152 		$parsed                    = array();
  2079 		$parsed['biSize']          = substr($BITMAPINFOHEADER,  0, 4); // number of bytes required by the BITMAPINFOHEADER structure
  2153 		$parsed['biSize']          = substr($BITMAPINFOHEADER,  0, 4); // number of bytes required by the BITMAPINFOHEADER structure
  2080 		$parsed['biWidth']         = substr($BITMAPINFOHEADER,  4, 4); // width of the bitmap in pixels
  2154 		$parsed['biWidth']         = substr($BITMAPINFOHEADER,  4, 4); // width of the bitmap in pixels
  2081 		$parsed['biHeight']        = substr($BITMAPINFOHEADER,  8, 4); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner
  2155 		$parsed['biHeight']        = substr($BITMAPINFOHEADER,  8, 4); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner
  2082 		$parsed['biPlanes']        = substr($BITMAPINFOHEADER, 12, 2); // number of color planes on the target device. In most cases this value must be set to 1
  2156 		$parsed['biPlanes']        = substr($BITMAPINFOHEADER, 12, 2); // number of color planes on the target device. In most cases this value must be set to 1
  2083 		$parsed['biBitCount']      = substr($BITMAPINFOHEADER, 14, 2); // Specifies the number of bits per pixels
  2157 		$parsed['biBitCount']      = substr($BITMAPINFOHEADER, 14, 2); // Specifies the number of bits per pixels