wp/wp-includes/ID3/module.audio-video.riff.php
changeset 16 a86126ab1dd4
parent 7 cf61fcea0001
child 19 3d72ae0968f4
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
     1 <?php
     1 <?php
       
     2 
     2 /////////////////////////////////////////////////////////////////
     3 /////////////////////////////////////////////////////////////////
     3 /// getID3() by James Heinrich <info@getid3.org>               //
     4 /// getID3() by James Heinrich <info@getid3.org>               //
     4 //  available at http://getid3.sourceforge.net                 //
     5 //  available at https://github.com/JamesHeinrich/getID3       //
     5 //            or http://www.getid3.org                         //
     6 //            or https://www.getid3.org                        //
     6 //          also https://github.com/JamesHeinrich/getID3       //
     7 //            or http://getid3.sourceforge.net                 //
     7 /////////////////////////////////////////////////////////////////
     8 //  see readme.txt for more details                            //
     8 // See readme.txt for more details                             //
       
     9 /////////////////////////////////////////////////////////////////
     9 /////////////////////////////////////////////////////////////////
    10 //                                                             //
    10 //                                                             //
    11 // module.audio-video.riff.php                                 //
    11 // module.audio-video.riff.php                                 //
    12 // module for analyzing RIFF files                             //
    12 // module for analyzing RIFF files                             //
    13 // multiple formats supported by this module:                  //
    13 // multiple formats supported by this module:                  //
    21 /**
    21 /**
    22 * @todo Parse AC-3/DTS audio inside WAVE correctly
    22 * @todo Parse AC-3/DTS audio inside WAVE correctly
    23 * @todo Rewrite RIFF parser totally
    23 * @todo Rewrite RIFF parser totally
    24 */
    24 */
    25 
    25 
       
    26 if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
       
    27 	exit;
       
    28 }
    26 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
    29 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
    27 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, true);
    30 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, true);
    28 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.dts.php', __FILE__, true);
    31 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.dts.php', __FILE__, true);
    29 
    32 
    30 class getid3_riff extends getid3_handler {
    33 class getid3_riff extends getid3_handler
    31 
    34 {
    32 	protected $container = 'riff'; // default
    35 	protected $container = 'riff'; // default
    33 
    36 
       
    37 	/**
       
    38 	 * @return bool
       
    39 	 *
       
    40 	 * @throws getid3_exception
       
    41 	 */
    34 	public function Analyze() {
    42 	public function Analyze() {
    35 		$info = &$this->getid3->info;
    43 		$info = &$this->getid3->info;
    36 
    44 
    37 		// initialize these values to an empty array, otherwise they default to NULL
    45 		// initialize these values to an empty array, otherwise they default to NULL
    38 		// and you can't append array values to a NULL value
    46 		// and you can't append array values to a NULL value
    44 		$thisfile_audio            = &$info['audio'];
    52 		$thisfile_audio            = &$info['audio'];
    45 		$thisfile_video            = &$info['video'];
    53 		$thisfile_video            = &$info['video'];
    46 		$thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
    54 		$thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
    47 		$thisfile_riff_audio       = &$thisfile_riff['audio'];
    55 		$thisfile_riff_audio       = &$thisfile_riff['audio'];
    48 		$thisfile_riff_video       = &$thisfile_riff['video'];
    56 		$thisfile_riff_video       = &$thisfile_riff['video'];
       
    57 		$thisfile_riff_WAVE        = array();
    49 
    58 
    50 		$Original['avdataoffset'] = $info['avdataoffset'];
    59 		$Original['avdataoffset'] = $info['avdataoffset'];
    51 		$Original['avdataend']    = $info['avdataend'];
    60 		$Original['avdataend']    = $info['avdataend'];
    52 
    61 
    53 		$this->fseek($info['avdataoffset']);
    62 		$this->fseek($info['avdataoffset']);
   195 					}
   204 					}
   196 					$thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw'];
   205 					$thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw'];
   197 					unset($thisfile_riff_audio[$streamindex]['raw']);
   206 					unset($thisfile_riff_audio[$streamindex]['raw']);
   198 					$thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
   207 					$thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
   199 
   208 
   200 					$thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
   209 					$thisfile_audio = (array) getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
   201 					if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') {
   210 					if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') {
   202 						$this->warning('Audio codec = '.$thisfile_audio['codec']);
   211 						$this->warning('Audio codec = '.$thisfile_audio['codec']);
   203 					}
   212 					}
   204 					$thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
   213 					$thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
   205 
   214 
   355 						$thisfile_riff_WAVE_cart_0['post_time'][$i]['usage_fourcc'] =                  substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8), 4);
   364 						$thisfile_riff_WAVE_cart_0['post_time'][$i]['usage_fourcc'] =                  substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8), 4);
   356 						$thisfile_riff_WAVE_cart_0['post_time'][$i]['timer_value']  = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8) + 4, 4));
   365 						$thisfile_riff_WAVE_cart_0['post_time'][$i]['timer_value']  = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8) + 4, 4));
   357 					}
   366 					}
   358 					$thisfile_riff_WAVE_cart_0['url']              =                 trim(substr($thisfile_riff_WAVE_cart_0['data'],  748, 1024));
   367 					$thisfile_riff_WAVE_cart_0['url']              =                 trim(substr($thisfile_riff_WAVE_cart_0['data'],  748, 1024));
   359 					$thisfile_riff_WAVE_cart_0['tag_text']         = explode("\r\n", trim(substr($thisfile_riff_WAVE_cart_0['data'], 1772)));
   368 					$thisfile_riff_WAVE_cart_0['tag_text']         = explode("\r\n", trim(substr($thisfile_riff_WAVE_cart_0['data'], 1772)));
       
   369 					$thisfile_riff['comments']['tag_text'][]       =                      substr($thisfile_riff_WAVE_cart_0['data'], 1772);
   360 
   370 
   361 					$thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist'];
   371 					$thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist'];
   362 					$thisfile_riff['comments']['title'][]  = $thisfile_riff_WAVE_cart_0['title'];
   372 					$thisfile_riff['comments']['title'][]  = $thisfile_riff_WAVE_cart_0['title'];
   363 				}
   373 				}
   364 
   374 
   403 
   413 
   404 					$tagmapping = array(
   414 					$tagmapping = array(
   405 						'tracktitle'=>'title',
   415 						'tracktitle'=>'title',
   406 						'category'  =>'genre',
   416 						'category'  =>'genre',
   407 						'cdtitle'   =>'album',
   417 						'cdtitle'   =>'album',
   408 						'tracktitle'=>'title',
       
   409 					);
   418 					);
   410 					foreach ($tagmapping as $fromkey => $tokey) {
   419 					foreach ($tagmapping as $fromkey => $tokey) {
   411 						if (isset($thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey])) {
   420 						if (isset($thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey])) {
   412 							$thisfile_riff['comments'][$tokey][] = $thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey];
   421 							$thisfile_riff['comments'][$tokey][] = $thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey];
   413 						}
   422 						}
   611 				$info['mime_type']  = 'video/avi';
   620 				$info['mime_type']  = 'video/avi';
   612 
   621 
   613 				$thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably
   622 				$thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably
   614 				$thisfile_video['dataformat']   = 'avi';
   623 				$thisfile_video['dataformat']   = 'avi';
   615 
   624 
       
   625 				$thisfile_riff_video_current = array();
       
   626 
   616 				if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) {
   627 				if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) {
   617 					$info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['movi']['offset'] + 8;
   628 					$info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['movi']['offset'] + 8;
   618 					if (isset($thisfile_riff['AVIX'])) {
   629 					if (isset($thisfile_riff['AVIX'])) {
   619 						$info['avdataend'] = $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['offset'] + $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['size'];
   630 						$info['avdataend'] = $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['offset'] + $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['size'];
   620 					} else {
   631 					} else {
   693 						'interleaved'  => 0x00000100,
   704 						'interleaved'  => 0x00000100,
   694 						'trustcktype'  => 0x00000800,
   705 						'trustcktype'  => 0x00000800,
   695 						'capturedfile' => 0x00010000,
   706 						'capturedfile' => 0x00010000,
   696 						'copyrighted'  => 0x00020010,
   707 						'copyrighted'  => 0x00020010,
   697 					);
   708 					);
   698                     foreach ($flags as $flag => $value) {
   709 					foreach ($flags as $flag => $value) {
   699 						$thisfile_riff_raw_avih['flags'][$flag] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & $value);
   710 						$thisfile_riff_raw_avih['flags'][$flag] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & $value);
   700 					}
   711 					}
   701 
   712 
   702 					// shortcut
   713 					// shortcut
   703 					$thisfile_riff_video[$streamindex] = array();
   714 					$thisfile_riff_video[$streamindex] = array();
       
   715 					/** @var array $thisfile_riff_video_current */
   704 					$thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
   716 					$thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
   705 
   717 
   706 					if ($thisfile_riff_raw_avih['dwWidth'] > 0) {
   718 					if ($thisfile_riff_raw_avih['dwWidth'] > 0) {
   707 						$thisfile_riff_video_current['frame_width'] = $thisfile_riff_raw_avih['dwWidth'];
   719 						$thisfile_riff_video_current['frame_width'] = $thisfile_riff_raw_avih['dwWidth'];
   708 						$thisfile_video['resolution_x']             = $thisfile_riff_video_current['frame_width'];
   720 						$thisfile_video['resolution_x']             = $thisfile_riff_video_current['frame_width'];
   865 
   877 
   866 									}
   878 									}
   867 								}
   879 								}
   868 							}
   880 							}
   869 
   881 
   870 							if (isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
   882 							if (isset($thisfile_riff_raw_strf_strhfccType_streamindex) && isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
   871 
   883 
   872 								$thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
   884 								$thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
   873 								if (self::fourccLookup($thisfile_video['fourcc'])) {
   885 								if (self::fourccLookup($thisfile_video['fourcc'])) {
   874 									$thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_video['fourcc']);
   886 									$thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_video['fourcc']);
   875 									$thisfile_video['codec']              = $thisfile_riff_video_current['codec'];
   887 									$thisfile_video['codec']              = $thisfile_riff_video_current['codec'];
   912 
   924 
   913 
   925 
   914 			// http://en.wikipedia.org/wiki/CD-DA
   926 			// http://en.wikipedia.org/wiki/CD-DA
   915 			case 'CDDA':
   927 			case 'CDDA':
   916 				$info['fileformat'] = 'cda';
   928 				$info['fileformat'] = 'cda';
   917 			    unset($info['mime_type']);
   929 				unset($info['mime_type']);
   918 
   930 
   919 				$thisfile_audio_dataformat      = 'cda';
   931 				$thisfile_audio_dataformat      = 'cda';
   920 
   932 
   921 				$info['avdataoffset'] = 44;
   933 				$info['avdataoffset'] = 44;
   922 
   934 
   932 					$thisfile_riff_CDDA_fmt_0['unknown6']           = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 16, 4));
   944 					$thisfile_riff_CDDA_fmt_0['unknown6']           = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 16, 4));
   933 					$thisfile_riff_CDDA_fmt_0['unknown7']           = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 20, 4));
   945 					$thisfile_riff_CDDA_fmt_0['unknown7']           = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 20, 4));
   934 
   946 
   935 					$thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75;
   947 					$thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75;
   936 					$thisfile_riff_CDDA_fmt_0['playtime_seconds']     = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75;
   948 					$thisfile_riff_CDDA_fmt_0['playtime_seconds']     = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75;
   937 					$info['comments']['track']                = $thisfile_riff_CDDA_fmt_0['track_num'];
   949 					$info['comments']['track_number']         = $thisfile_riff_CDDA_fmt_0['track_num'];
   938 					$info['playtime_seconds']                 = $thisfile_riff_CDDA_fmt_0['playtime_seconds'];
   950 					$info['playtime_seconds']                 = $thisfile_riff_CDDA_fmt_0['playtime_seconds'];
   939 
   951 
   940 					// hardcoded data for CD-audio
   952 					// hardcoded data for CD-audio
   941 					$thisfile_audio['lossless']        = true;
   953 					$thisfile_audio['lossless']        = true;
   942 					$thisfile_audio['sample_rate']     = 44100;
   954 					$thisfile_audio['sample_rate']     = 44100;
   945 					$thisfile_audio['bitrate']         = $thisfile_audio['sample_rate'] * $thisfile_audio['channels'] * $thisfile_audio['bits_per_sample'];
   957 					$thisfile_audio['bitrate']         = $thisfile_audio['sample_rate'] * $thisfile_audio['channels'] * $thisfile_audio['bits_per_sample'];
   946 					$thisfile_audio['bitrate_mode']    = 'cbr';
   958 					$thisfile_audio['bitrate_mode']    = 'cbr';
   947 				}
   959 				}
   948 				break;
   960 				break;
   949 
   961 
   950             // http://en.wikipedia.org/wiki/AIFF
   962 			// http://en.wikipedia.org/wiki/AIFF
   951 			case 'AIFF':
   963 			case 'AIFF':
   952 			case 'AIFC':
   964 			case 'AIFC':
   953 				$info['fileformat'] = 'aiff';
   965 				$info['fileformat'] = 'aiff';
   954 				$info['mime_type']  = 'audio/x-aiff';
   966 				$info['mime_type']  = 'audio/x-aiff';
   955 
   967 
  1055 				}
  1067 				}
  1056 /*
  1068 /*
  1057 				if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) {
  1069 				if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) {
  1058 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
  1070 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
  1059 					$getid3_temp = new getID3();
  1071 					$getid3_temp = new getID3();
  1060 					$getid3_temp->openfile($this->getid3->filename);
  1072 					$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1061 					$getid3_id3v2 = new getid3_id3v2($getid3_temp);
  1073 					$getid3_id3v2 = new getid3_id3v2($getid3_temp);
  1062 					$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8;
  1074 					$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8;
  1063 					if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
  1075 					if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
  1064 						$info['id3v2'] = $getid3_temp->info['id3v2'];
  1076 						$info['id3v2'] = $getid3_temp->info['id3v2'];
  1065 					}
  1077 					}
  1075 
  1087 
  1076 				$thisfile_audio['bitrate_mode']    = 'cbr';
  1088 				$thisfile_audio['bitrate_mode']    = 'cbr';
  1077 				$thisfile_audio_dataformat         = '8svx';
  1089 				$thisfile_audio_dataformat         = '8svx';
  1078 				$thisfile_audio['bits_per_sample'] = 8;
  1090 				$thisfile_audio['bits_per_sample'] = 8;
  1079 				$thisfile_audio['channels']        = 1; // overridden below, if need be
  1091 				$thisfile_audio['channels']        = 1; // overridden below, if need be
       
  1092 				$ActualBitsPerSample               = 0;
  1080 
  1093 
  1081 				if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) {
  1094 				if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) {
  1082 					$info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8;
  1095 					$info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8;
  1083 					$info['avdataend']    = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size'];
  1096 					$info['avdataend']    = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size'];
  1084 					if ($info['avdataend'] > $info['filesize']) {
  1097 					if ($info['avdataend'] > $info['filesize']) {
  1112 							$thisfile_audio['lossless'] = false;
  1125 							$thisfile_audio['lossless'] = false;
  1113 							$ActualBitsPerSample        = 4;
  1126 							$ActualBitsPerSample        = 4;
  1114 							break;
  1127 							break;
  1115 
  1128 
  1116 						default:
  1129 						default:
  1117 							$this->warning('Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"');
  1130 							$this->warning('Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.$thisfile_riff_RIFFsubtype_VHDR_0['sCompression'].'"');
  1118 							break;
  1131 							break;
  1119 					}
  1132 					}
  1120 				}
  1133 				}
  1121 
  1134 
  1122 				if (isset($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'])) {
  1135 				if (isset($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'])) {
  1157 
  1170 
  1158 				if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
  1171 				if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
  1159 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, true);
  1172 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, true);
  1160 
  1173 
  1161 					$getid3_temp = new getID3();
  1174 					$getid3_temp = new getID3();
  1162 					$getid3_temp->openfile($this->getid3->filename);
  1175 					$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1163 					$getid3_mpeg = new getid3_mpeg($getid3_temp);
  1176 					$getid3_mpeg = new getid3_mpeg($getid3_temp);
  1164 					$getid3_mpeg->Analyze();
  1177 					$getid3_mpeg->Analyze();
  1165 					if (empty($getid3_temp->info['error'])) {
  1178 					if (empty($getid3_temp->info['error'])) {
  1166 						$info['audio']   = $getid3_temp->info['audio'];
  1179 						$info['audio']   = $getid3_temp->info['audio'];
  1167 						$info['video']   = $getid3_temp->info['video'];
  1180 						$info['video']   = $getid3_temp->info['video'];
  1243 
  1256 
  1244 				if (isset($thisfile_riff[$RIFFsubtype]['id3 '])) {
  1257 				if (isset($thisfile_riff[$RIFFsubtype]['id3 '])) {
  1245 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
  1258 					getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
  1246 
  1259 
  1247 					$getid3_temp = new getID3();
  1260 					$getid3_temp = new getID3();
  1248 					$getid3_temp->openfile($this->getid3->filename);
  1261 					$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1249 					$getid3_id3v2 = new getid3_id3v2($getid3_temp);
  1262 					$getid3_id3v2 = new getid3_id3v2($getid3_temp);
  1250 					$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8;
  1263 					$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8;
  1251 					if ($thisfile_riff[$RIFFsubtype]['id3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
  1264 					if ($thisfile_riff[$RIFFsubtype]['id3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
  1252 						$info['id3v2'] = $getid3_temp->info['id3v2'];
  1265 						$info['id3v2'] = $getid3_temp->info['id3v2'];
  1253 					}
  1266 					}
  1370 		}
  1383 		}
  1371 
  1384 
  1372 		return true;
  1385 		return true;
  1373 	}
  1386 	}
  1374 
  1387 
       
  1388 	/**
       
  1389 	 * @param int $startoffset
       
  1390 	 * @param int $maxoffset
       
  1391 	 *
       
  1392 	 * @return array|false
       
  1393 	 *
       
  1394 	 * @throws Exception
       
  1395 	 * @throws getid3_exception
       
  1396 	 */
  1375 	public function ParseRIFFAMV($startoffset, $maxoffset) {
  1397 	public function ParseRIFFAMV($startoffset, $maxoffset) {
  1376 		// AMV files are RIFF-AVI files with parts of the spec deliberately broken, such as chunk size fields hardcoded to zero (because players known in hardware that these fields are always a certain size
  1398 		// AMV files are RIFF-AVI files with parts of the spec deliberately broken, such as chunk size fields hardcoded to zero (because players known in hardware that these fields are always a certain size
  1377 
  1399 
  1378 		// https://code.google.com/p/amv-codec-tools/wiki/AmvDocumentation
  1400 		// https://code.google.com/p/amv-codec-tools/wiki/AmvDocumentation
  1379 		//typedef struct _amvmainheader {
  1401 		//typedef struct _amvmainheader {
  1478 		}
  1500 		}
  1479 
  1501 
  1480 		return $RIFFchunk;
  1502 		return $RIFFchunk;
  1481 	}
  1503 	}
  1482 
  1504 
  1483 
  1505 	/**
       
  1506 	 * @param int $startoffset
       
  1507 	 * @param int $maxoffset
       
  1508 	 *
       
  1509 	 * @return array|false
       
  1510 	 * @throws getid3_exception
       
  1511 	 */
  1484 	public function ParseRIFF($startoffset, $maxoffset) {
  1512 	public function ParseRIFF($startoffset, $maxoffset) {
  1485 		$info = &$this->getid3->info;
  1513 		$info = &$this->getid3->info;
  1486 
  1514 
  1487 		$RIFFchunk = false;
  1515 		$RIFFchunk = false;
  1488 		$FoundAllChunksWeNeed = false;
  1516 		$FoundAllChunksWeNeed = false;
  1527 									$FirstFourBytes = substr($AudioChunkHeader, 8, 4);
  1555 									$FirstFourBytes = substr($AudioChunkHeader, 8, 4);
  1528 									if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
  1556 									if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
  1529 										// MP3
  1557 										// MP3
  1530 										if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
  1558 										if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
  1531 											$getid3_temp = new getID3();
  1559 											$getid3_temp = new getID3();
  1532 											$getid3_temp->openfile($this->getid3->filename);
  1560 											$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1533 											$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
  1561 											$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
  1534 											$getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
  1562 											$getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
  1535 											$getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
  1563 											$getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
  1536 											$getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
  1564 											$getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
  1537 											if (isset($getid3_temp->info['mpeg']['audio'])) {
  1565 											if (isset($getid3_temp->info['mpeg']['audio'])) {
  1549 
  1577 
  1550 									} elseif (strpos($FirstFourBytes, getid3_ac3::syncword) === 0) {
  1578 									} elseif (strpos($FirstFourBytes, getid3_ac3::syncword) === 0) {
  1551 
  1579 
  1552 										// AC3
  1580 										// AC3
  1553 										$getid3_temp = new getID3();
  1581 										$getid3_temp = new getID3();
  1554 										$getid3_temp->openfile($this->getid3->filename);
  1582 										$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1555 										$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
  1583 										$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
  1556 										$getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
  1584 										$getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
  1557 										$getid3_ac3 = new getid3_ac3($getid3_temp);
  1585 										$getid3_ac3 = new getid3_ac3($getid3_temp);
  1558 										$getid3_ac3->Analyze();
  1586 										$getid3_ac3->Analyze();
  1559 										if (empty($getid3_temp->info['error'])) {
  1587 										if (empty($getid3_temp->info['error'])) {
  1610 								if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($testData, 0, 4))) {
  1638 								if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($testData, 0, 4))) {
  1611 
  1639 
  1612 									// Probably is MP3 data
  1640 									// Probably is MP3 data
  1613 									if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) {
  1641 									if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) {
  1614 										$getid3_temp = new getID3();
  1642 										$getid3_temp = new getID3();
  1615 										$getid3_temp->openfile($this->getid3->filename);
  1643 										$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1616 										$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1644 										$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1617 										$getid3_temp->info['avdataend']    = $info['avdataend'];
  1645 										$getid3_temp->info['avdataend']    = $info['avdataend'];
  1618 										$getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
  1646 										$getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
  1619 										$getid3_mp3->getOnlyMPEGaudioInfo($info['avdataoffset'], false);
  1647 										$getid3_mp3->getOnlyMPEGaudioInfo($info['avdataoffset'], false);
  1620 										if (empty($getid3_temp->info['error'])) {
  1648 										if (empty($getid3_temp->info['error'])) {
  1627 								} elseif (($isRegularAC3 = (substr($testData, 0, 2) == getid3_ac3::syncword)) || substr($testData, 8, 2) == strrev(getid3_ac3::syncword)) {
  1655 								} elseif (($isRegularAC3 = (substr($testData, 0, 2) == getid3_ac3::syncword)) || substr($testData, 8, 2) == strrev(getid3_ac3::syncword)) {
  1628 
  1656 
  1629 									// This is probably AC-3 data
  1657 									// This is probably AC-3 data
  1630 									$getid3_temp = new getID3();
  1658 									$getid3_temp = new getID3();
  1631 									if ($isRegularAC3) {
  1659 									if ($isRegularAC3) {
  1632 										$getid3_temp->openfile($this->getid3->filename);
  1660 										$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1633 										$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1661 										$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1634 										$getid3_temp->info['avdataend']    = $info['avdataend'];
  1662 										$getid3_temp->info['avdataend']    = $info['avdataend'];
  1635 									}
  1663 									}
  1636 									$getid3_ac3 = new getid3_ac3($getid3_temp);
  1664 									$getid3_ac3 = new getid3_ac3($getid3_temp);
  1637 									if ($isRegularAC3) {
  1665 									if ($isRegularAC3) {
  1661 
  1689 
  1662 								} elseif (preg_match('/^('.implode('|', array_map('preg_quote', getid3_dts::$syncwords)).')/', $testData)) {
  1690 								} elseif (preg_match('/^('.implode('|', array_map('preg_quote', getid3_dts::$syncwords)).')/', $testData)) {
  1663 
  1691 
  1664 									// This is probably DTS data
  1692 									// This is probably DTS data
  1665 									$getid3_temp = new getID3();
  1693 									$getid3_temp = new getID3();
  1666 									$getid3_temp->openfile($this->getid3->filename);
  1694 									$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
  1667 									$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1695 									$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
  1668 									$getid3_dts = new getid3_dts($getid3_temp);
  1696 									$getid3_dts = new getid3_dts($getid3_temp);
  1669 									$getid3_dts->Analyze();
  1697 									$getid3_dts->Analyze();
  1670 									if (empty($getid3_temp->info['error'])) {
  1698 									if (empty($getid3_temp->info['error'])) {
  1671 										$info['audio']            = $getid3_temp->info['audio'];
  1699 										$info['audio']            = $getid3_temp->info['audio'];
  1729 
  1757 
  1730 							//case 'IDVX':
  1758 							//case 'IDVX':
  1731 							//	$info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunksize));
  1759 							//	$info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunksize));
  1732 							//	break;
  1760 							//	break;
  1733 
  1761 
       
  1762 							case 'scot':
       
  1763 								// https://cmsdk.com/node-js/adding-scot-chunk-to-wav-file.html
       
  1764 								$RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize);
       
  1765 								$RIFFchunk[$chunkname][$thisindex]['parsed']['alter']           =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],   0,   1);
       
  1766 								$RIFFchunk[$chunkname][$thisindex]['parsed']['attrib']          =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],   1,   1);
       
  1767 								$RIFFchunk[$chunkname][$thisindex]['parsed']['artnum']          = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'],   2,   2));
       
  1768 								$RIFFchunk[$chunkname][$thisindex]['parsed']['title']           =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],   4,  43);  // "name" in other documentation
       
  1769 								$RIFFchunk[$chunkname][$thisindex]['parsed']['copy']            =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],  47,   4);
       
  1770 								$RIFFchunk[$chunkname][$thisindex]['parsed']['padd']            =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],  51,   1);
       
  1771 								$RIFFchunk[$chunkname][$thisindex]['parsed']['asclen']          =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],  52,   5);
       
  1772 								$RIFFchunk[$chunkname][$thisindex]['parsed']['startseconds']    = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'],  57,   2));
       
  1773 								$RIFFchunk[$chunkname][$thisindex]['parsed']['starthundredths'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'],  59,   2));
       
  1774 								$RIFFchunk[$chunkname][$thisindex]['parsed']['endseconds']      = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'],  61,   2));
       
  1775 								$RIFFchunk[$chunkname][$thisindex]['parsed']['endhundreths']    = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'],  63,   2));
       
  1776 								$RIFFchunk[$chunkname][$thisindex]['parsed']['sdate']           =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],  65,   6);
       
  1777 								$RIFFchunk[$chunkname][$thisindex]['parsed']['kdate']           =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],  71,   6);
       
  1778 								$RIFFchunk[$chunkname][$thisindex]['parsed']['start_hr']        =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],  77,   1);
       
  1779 								$RIFFchunk[$chunkname][$thisindex]['parsed']['kill_hr']         =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],  78,   1);
       
  1780 								$RIFFchunk[$chunkname][$thisindex]['parsed']['digital']         =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],  79,   1);
       
  1781 								$RIFFchunk[$chunkname][$thisindex]['parsed']['sample_rate']     = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'],  80,   2));
       
  1782 								$RIFFchunk[$chunkname][$thisindex]['parsed']['stereo']          =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],  82,   1);
       
  1783 								$RIFFchunk[$chunkname][$thisindex]['parsed']['compress']        =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],  83,   1);
       
  1784 								$RIFFchunk[$chunkname][$thisindex]['parsed']['eomstrt']         = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'],  84,   4));
       
  1785 								$RIFFchunk[$chunkname][$thisindex]['parsed']['eomlen']          = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'],  88,   2));
       
  1786 								$RIFFchunk[$chunkname][$thisindex]['parsed']['attrib2']         = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'],  90,   4));
       
  1787 								$RIFFchunk[$chunkname][$thisindex]['parsed']['future1']         =                              substr($RIFFchunk[$chunkname][$thisindex]['data'],  94,  12);
       
  1788 								$RIFFchunk[$chunkname][$thisindex]['parsed']['catfontcolor']    = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 106,   4));
       
  1789 								$RIFFchunk[$chunkname][$thisindex]['parsed']['catcolor']        = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 110,   4));
       
  1790 								$RIFFchunk[$chunkname][$thisindex]['parsed']['segeompos']       = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 114,   4));
       
  1791 								$RIFFchunk[$chunkname][$thisindex]['parsed']['vt_startsecs']    = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 118,   2));
       
  1792 								$RIFFchunk[$chunkname][$thisindex]['parsed']['vt_starthunds']   = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 120,   2));
       
  1793 								$RIFFchunk[$chunkname][$thisindex]['parsed']['priorcat']        =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 122,   3);
       
  1794 								$RIFFchunk[$chunkname][$thisindex]['parsed']['priorcopy']       =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 125,   4);
       
  1795 								$RIFFchunk[$chunkname][$thisindex]['parsed']['priorpadd']       =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 129,   1);
       
  1796 								$RIFFchunk[$chunkname][$thisindex]['parsed']['postcat']         =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 130,   3);
       
  1797 								$RIFFchunk[$chunkname][$thisindex]['parsed']['postcopy']        =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 133,   4);
       
  1798 								$RIFFchunk[$chunkname][$thisindex]['parsed']['postpadd']        =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 137,   1);
       
  1799 								$RIFFchunk[$chunkname][$thisindex]['parsed']['hrcanplay']       =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 138,  21);
       
  1800 								$RIFFchunk[$chunkname][$thisindex]['parsed']['future2']         =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 159, 108);
       
  1801 								$RIFFchunk[$chunkname][$thisindex]['parsed']['artist']          =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 267,  34);
       
  1802 								$RIFFchunk[$chunkname][$thisindex]['parsed']['comment']         =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 301,  34); // "trivia" in other documentation
       
  1803 								$RIFFchunk[$chunkname][$thisindex]['parsed']['intro']           =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 335,   2);
       
  1804 								$RIFFchunk[$chunkname][$thisindex]['parsed']['end']             =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 337,   1);
       
  1805 								$RIFFchunk[$chunkname][$thisindex]['parsed']['year']            =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 338,   4);
       
  1806 								$RIFFchunk[$chunkname][$thisindex]['parsed']['obsolete2']       =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 342,   1);
       
  1807 								$RIFFchunk[$chunkname][$thisindex]['parsed']['rec_hr']          =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 343,   1);
       
  1808 								$RIFFchunk[$chunkname][$thisindex]['parsed']['rdate']           =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 344,   6);
       
  1809 								$RIFFchunk[$chunkname][$thisindex]['parsed']['mpeg_bitrate']    = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 350,   2));
       
  1810 								$RIFFchunk[$chunkname][$thisindex]['parsed']['pitch']           = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 352,   2));
       
  1811 								$RIFFchunk[$chunkname][$thisindex]['parsed']['playlevel']       = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 354,   2));
       
  1812 								$RIFFchunk[$chunkname][$thisindex]['parsed']['lenvalid']        =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 356,   1);
       
  1813 								$RIFFchunk[$chunkname][$thisindex]['parsed']['filelength']      = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 357,   4));
       
  1814 								$RIFFchunk[$chunkname][$thisindex]['parsed']['newplaylevel']    = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 361,   2));
       
  1815 								$RIFFchunk[$chunkname][$thisindex]['parsed']['chopsize']        = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 363,   4));
       
  1816 								$RIFFchunk[$chunkname][$thisindex]['parsed']['vteomovr']        = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 367,   4));
       
  1817 								$RIFFchunk[$chunkname][$thisindex]['parsed']['desiredlen']      = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 371,   4));
       
  1818 								$RIFFchunk[$chunkname][$thisindex]['parsed']['triggers']        = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 375,   4));
       
  1819 								$RIFFchunk[$chunkname][$thisindex]['parsed']['fillout']         =                              substr($RIFFchunk[$chunkname][$thisindex]['data'], 379,   33);
       
  1820 
       
  1821 								foreach (array('title', 'artist', 'comment') as $key) {
       
  1822 									if (trim($RIFFchunk[$chunkname][$thisindex]['parsed'][$key])) {
       
  1823 										$info['riff']['comments'][$key] = array($RIFFchunk[$chunkname][$thisindex]['parsed'][$key]);
       
  1824 									}
       
  1825 								}
       
  1826 								if ($RIFFchunk[$chunkname][$thisindex]['parsed']['filelength'] && !empty($info['filesize']) && ($RIFFchunk[$chunkname][$thisindex]['parsed']['filelength'] != $info['filesize'])) {
       
  1827 									$this->warning('RIFF.WAVE.scot.filelength ('.$RIFFchunk[$chunkname][$thisindex]['parsed']['filelength'].') different from actual filesize ('.$info['filesize'].')');
       
  1828 								}
       
  1829 								break;
       
  1830 
  1734 							default:
  1831 							default:
  1735 								if (!empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) {
  1832 								if (!empty($LISTchunkParent) && isset($LISTchunkMaxOffset) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) {
  1736 									$RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
  1833 									$RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
  1737 									$RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size']   = $RIFFchunk[$chunkname][$thisindex]['size'];
  1834 									$RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size']   = $RIFFchunk[$chunkname][$thisindex]['size'];
  1738 									unset($RIFFchunk[$chunkname][$thisindex]['offset']);
  1835 									unset($RIFFchunk[$chunkname][$thisindex]['offset']);
  1739 									unset($RIFFchunk[$chunkname][$thisindex]['size']);
  1836 									unset($RIFFchunk[$chunkname][$thisindex]['size']);
  1740 									if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) {
  1837 									if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) {
  1765 		}
  1862 		}
  1766 
  1863 
  1767 		return $RIFFchunk;
  1864 		return $RIFFchunk;
  1768 	}
  1865 	}
  1769 
  1866 
       
  1867 	/**
       
  1868 	 * @param string $RIFFdata
       
  1869 	 *
       
  1870 	 * @return bool
       
  1871 	 */
  1770 	public function ParseRIFFdata(&$RIFFdata) {
  1872 	public function ParseRIFFdata(&$RIFFdata) {
  1771 		$info = &$this->getid3->info;
  1873 		$info = &$this->getid3->info;
  1772 		if ($RIFFdata) {
  1874 		if ($RIFFdata) {
  1773 			$tempfile = tempnam(GETID3_TEMP_DIR, 'getID3');
  1875 			$tempfile = tempnam(GETID3_TEMP_DIR, 'getID3');
  1774 			$fp_temp  = fopen($tempfile, 'wb');
  1876 			$fp_temp  = fopen($tempfile, 'wb');
  1802 			unlink($tempfile);
  1904 			unlink($tempfile);
  1803 		}
  1905 		}
  1804 		return false;
  1906 		return false;
  1805 	}
  1907 	}
  1806 
  1908 
       
  1909 	/**
       
  1910 	 * @param array $RIFFinfoArray
       
  1911 	 * @param array $CommentsTargetArray
       
  1912 	 *
       
  1913 	 * @return bool
       
  1914 	 */
  1807 	public static function parseComments(&$RIFFinfoArray, &$CommentsTargetArray) {
  1915 	public static function parseComments(&$RIFFinfoArray, &$CommentsTargetArray) {
  1808 		$RIFFinfoKeyLookup = array(
  1916 		$RIFFinfoKeyLookup = array(
  1809 			'IARL'=>'archivallocation',
  1917 			'IARL'=>'archivallocation',
  1810 			'IART'=>'artist',
  1918 			'IART'=>'artist',
  1811 			'ICDS'=>'costumedesigner',
  1919 			'ICDS'=>'costumedesigner',
  1861 			}
  1969 			}
  1862 		}
  1970 		}
  1863 		return true;
  1971 		return true;
  1864 	}
  1972 	}
  1865 
  1973 
       
  1974 	/**
       
  1975 	 * @param string $WaveFormatExData
       
  1976 	 *
       
  1977 	 * @return array
       
  1978 	 */
  1866 	public static function parseWAVEFORMATex($WaveFormatExData) {
  1979 	public static function parseWAVEFORMATex($WaveFormatExData) {
  1867 		// shortcut
  1980 		// shortcut
       
  1981 		$WaveFormatEx        = array();
  1868 		$WaveFormatEx['raw'] = array();
  1982 		$WaveFormatEx['raw'] = array();
  1869 		$WaveFormatEx_raw    = &$WaveFormatEx['raw'];
  1983 		$WaveFormatEx_raw    = &$WaveFormatEx['raw'];
  1870 
  1984 
  1871 		$WaveFormatEx_raw['wFormatTag']      = substr($WaveFormatExData,  0, 2);
  1985 		$WaveFormatEx_raw['wFormatTag']      = substr($WaveFormatExData,  0, 2);
  1872 		$WaveFormatEx_raw['nChannels']       = substr($WaveFormatExData,  2, 2);
  1986 		$WaveFormatEx_raw['nChannels']       = substr($WaveFormatExData,  2, 2);
  1886 		$WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample'];
  2000 		$WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample'];
  1887 
  2001 
  1888 		return $WaveFormatEx;
  2002 		return $WaveFormatEx;
  1889 	}
  2003 	}
  1890 
  2004 
       
  2005 	/**
       
  2006 	 * @param string $WavPackChunkData
       
  2007 	 *
       
  2008 	 * @return bool
       
  2009 	 */
  1891 	public function parseWavPackHeader($WavPackChunkData) {
  2010 	public function parseWavPackHeader($WavPackChunkData) {
  1892 		// typedef struct {
  2011 		// typedef struct {
  1893 		//     char ckID [4];
  2012 		//     char ckID [4];
  1894 		//     long ckSize;
  2013 		//     long ckSize;
  1895 		//     short version;
  2014 		//     short version;
  1947 		}
  2066 		}
  1948 
  2067 
  1949 		return true;
  2068 		return true;
  1950 	}
  2069 	}
  1951 
  2070 
       
  2071 	/**
       
  2072 	 * @param string $BITMAPINFOHEADER
       
  2073 	 * @param bool   $littleEndian
       
  2074 	 *
       
  2075 	 * @return array
       
  2076 	 */
  1952 	public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
  2077 	public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
  1953 
  2078 
  1954 		$parsed['biSize']          = substr($BITMAPINFOHEADER,  0, 4); // number of bytes required by the BITMAPINFOHEADER structure
  2079 		$parsed['biSize']          = substr($BITMAPINFOHEADER,  0, 4); // number of bytes required by the BITMAPINFOHEADER structure
  1955 		$parsed['biWidth']         = substr($BITMAPINFOHEADER,  4, 4); // width of the bitmap in pixels
  2080 		$parsed['biWidth']         = substr($BITMAPINFOHEADER,  4, 4); // width of the bitmap in pixels
  1956 		$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
  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
  1966 		$parsed['fourcc']          = substr($BITMAPINFOHEADER, 16, 4);  // compression identifier
  2091 		$parsed['fourcc']          = substr($BITMAPINFOHEADER, 16, 4);  // compression identifier
  1967 
  2092 
  1968 		return $parsed;
  2093 		return $parsed;
  1969 	}
  2094 	}
  1970 
  2095 
       
  2096 	/**
       
  2097 	 * @param string $DIVXTAG
       
  2098 	 * @param bool   $raw
       
  2099 	 *
       
  2100 	 * @return array
       
  2101 	 */
  1971 	public static function ParseDIVXTAG($DIVXTAG, $raw=false) {
  2102 	public static function ParseDIVXTAG($DIVXTAG, $raw=false) {
  1972 		// structure from "IDivX" source, Form1.frm, by "Greg Frazier of Daemonic Software Group", email: gfrazier@icestorm.net, web: http://dsg.cjb.net/
  2103 		// structure from "IDivX" source, Form1.frm, by "Greg Frazier of Daemonic Software Group", email: gfrazier@icestorm.net, web: http://dsg.cjb.net/
  1973 		// source available at http://files.divx-digest.com/download/c663efe7ef8ad2e90bf4af4d3ea6188a/on0SWN2r/edit/IDivX.zip
  2104 		// source available at http://files.divx-digest.com/download/c663efe7ef8ad2e90bf4af4d3ea6188a/on0SWN2r/edit/IDivX.zip
  1974 		// 'Byte Layout:                   '1111111111111111
  2105 		// 'Byte Layout:                   '1111111111111111
  1975 		// '32 for Movie - 1               '1111111111111111
  2106 		// '32 for Movie - 1               '1111111111111111
  2012 			 3 => 'PG-13',
  2143 			 3 => 'PG-13',
  2013 			 4 => 'R',
  2144 			 4 => 'R',
  2014 			 5 => 'NC-17',
  2145 			 5 => 'NC-17',
  2015 		);
  2146 		);
  2016 
  2147 
       
  2148 		$parsed              = array();
  2017 		$parsed['title']     =        trim(substr($DIVXTAG,   0, 32));
  2149 		$parsed['title']     =        trim(substr($DIVXTAG,   0, 32));
  2018 		$parsed['artist']    =        trim(substr($DIVXTAG,  32, 28));
  2150 		$parsed['artist']    =        trim(substr($DIVXTAG,  32, 28));
  2019 		$parsed['year']      = intval(trim(substr($DIVXTAG,  60,  4)));
  2151 		$parsed['year']      = intval(trim(substr($DIVXTAG,  60,  4)));
  2020 		$parsed['comment']   =        trim(substr($DIVXTAG,  64, 48));
  2152 		$parsed['comment']   =        trim(substr($DIVXTAG,  64, 48));
  2021 		$parsed['genre_id']  = intval(trim(substr($DIVXTAG, 112,  3)));
  2153 		$parsed['genre_id']  = intval(trim(substr($DIVXTAG, 112,  3)));
  2027 		$parsed['rating'] = (isset($DIVXTAGrating[$parsed['rating_id']]) ? $DIVXTAGrating[$parsed['rating_id']] : $parsed['rating_id']);
  2159 		$parsed['rating'] = (isset($DIVXTAGrating[$parsed['rating_id']]) ? $DIVXTAGrating[$parsed['rating_id']] : $parsed['rating_id']);
  2028 
  2160 
  2029 		if (!$raw) {
  2161 		if (!$raw) {
  2030 			unset($parsed['genre_id'], $parsed['rating_id']);
  2162 			unset($parsed['genre_id'], $parsed['rating_id']);
  2031 			foreach ($parsed as $key => $value) {
  2163 			foreach ($parsed as $key => $value) {
  2032 				if (!$value === '') {
  2164 				if (empty($value)) {
  2033 					unset($parsed['key']);
  2165 					unset($parsed[$key]);
  2034 				}
  2166 				}
  2035 			}
  2167 			}
  2036 		}
  2168 		}
  2037 
  2169 
  2038 		foreach ($parsed as $tag => $value) {
  2170 		foreach ($parsed as $tag => $value) {
  2040 		}
  2172 		}
  2041 
  2173 
  2042 		return $parsed;
  2174 		return $parsed;
  2043 	}
  2175 	}
  2044 
  2176 
       
  2177 	/**
       
  2178 	 * @param string $tagshortname
       
  2179 	 *
       
  2180 	 * @return string
       
  2181 	 */
  2045 	public static function waveSNDMtagLookup($tagshortname) {
  2182 	public static function waveSNDMtagLookup($tagshortname) {
  2046 		$begin = __LINE__;
  2183 		$begin = __LINE__;
  2047 
  2184 
  2048 		/** This is not a comment!
  2185 		/** This is not a comment!
  2049 
  2186 
  2063 		*/
  2200 		*/
  2064 
  2201 
  2065 		return getid3_lib::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm');
  2202 		return getid3_lib::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm');
  2066 	}
  2203 	}
  2067 
  2204 
       
  2205 	/**
       
  2206 	 * @param int $wFormatTag
       
  2207 	 *
       
  2208 	 * @return string
       
  2209 	 */
  2068 	public static function wFormatTagLookup($wFormatTag) {
  2210 	public static function wFormatTagLookup($wFormatTag) {
  2069 
  2211 
  2070 		$begin = __LINE__;
  2212 		$begin = __LINE__;
  2071 
  2213 
  2072 		/** This is not a comment!
  2214 		/** This is not a comment!
  2232 		*/
  2374 		*/
  2233 
  2375 
  2234 		return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag');
  2376 		return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag');
  2235 	}
  2377 	}
  2236 
  2378 
       
  2379 	/**
       
  2380 	 * @param string $fourcc
       
  2381 	 *
       
  2382 	 * @return string
       
  2383 	 */
  2237 	public static function fourccLookup($fourcc) {
  2384 	public static function fourccLookup($fourcc) {
  2238 
  2385 
  2239 		$begin = __LINE__;
  2386 		$begin = __LINE__;
  2240 
  2387 
  2241 		/** This is not a comment!
  2388 		/** This is not a comment!
  2626 		*/
  2773 		*/
  2627 
  2774 
  2628 		return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
  2775 		return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
  2629 	}
  2776 	}
  2630 
  2777 
       
  2778 	/**
       
  2779 	 * @param string $byteword
       
  2780 	 * @param bool   $signed
       
  2781 	 *
       
  2782 	 * @return int|float|false
       
  2783 	 */
  2631 	private function EitherEndian2Int($byteword, $signed=false) {
  2784 	private function EitherEndian2Int($byteword, $signed=false) {
  2632 		if ($this->container == 'riff') {
  2785 		if ($this->container == 'riff') {
  2633 			return getid3_lib::LittleEndian2Int($byteword, $signed);
  2786 			return getid3_lib::LittleEndian2Int($byteword, $signed);
  2634 		}
  2787 		}
  2635 		return getid3_lib::BigEndian2Int($byteword, false, $signed);
  2788 		return getid3_lib::BigEndian2Int($byteword, false, $signed);