changeset 16 | a86126ab1dd4 |
parent 7 | cf61fcea0001 |
child 19 | 3d72ae0968f4 |
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); |