[ Index ] |
WordPress Cross Reference |
[Summary view] [Print] [Text view]
1 <?php 2 ///////////////////////////////////////////////////////////////// 3 /// getID3() by James Heinrich <info@getid3.org> // 4 // available at http://getid3.sourceforge.net // 5 // or http://www.getid3.org // 6 ///////////////////////////////////////////////////////////////// 7 // See readme.txt for more details // 8 ///////////////////////////////////////////////////////////////// 9 // // 10 // module.audio-video.riff.php // 11 // module for analyzing RIFF files // 12 // multiple formats supported by this module: // 13 // Wave, AVI, AIFF/AIFC, (MP3,AC3)/RIFF, Wavpack v3, 8SVX // 14 // dependencies: module.audio.mp3.php // 15 // module.audio.ac3.php // 16 // module.audio.dts.php // 17 // /// 18 ///////////////////////////////////////////////////////////////// 19 20 /** 21 * @todo Parse AC-3/DTS audio inside WAVE correctly 22 * @todo Rewrite RIFF parser totally 23 */ 24 25 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true); 26 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, true); 27 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.dts.php', __FILE__, true); 28 29 class getid3_riff extends getid3_handler 30 { 31 32 public function Analyze() { 33 $info = &$this->getid3->info; 34 35 // initialize these values to an empty array, otherwise they default to NULL 36 // and you can't append array values to a NULL value 37 $info['riff'] = array('raw'=>array()); 38 39 // Shortcuts 40 $thisfile_riff = &$info['riff']; 41 $thisfile_riff_raw = &$thisfile_riff['raw']; 42 $thisfile_audio = &$info['audio']; 43 $thisfile_video = &$info['video']; 44 $thisfile_audio_dataformat = &$thisfile_audio['dataformat']; 45 $thisfile_riff_audio = &$thisfile_riff['audio']; 46 $thisfile_riff_video = &$thisfile_riff['video']; 47 48 $Original['avdataoffset'] = $info['avdataoffset']; 49 $Original['avdataend'] = $info['avdataend']; 50 51 $this->fseek($info['avdataoffset']); 52 $RIFFheader = $this->fread(12); 53 $offset = $this->ftell(); 54 $RIFFtype = substr($RIFFheader, 0, 4); 55 $RIFFsize = substr($RIFFheader, 4, 4); 56 $RIFFsubtype = substr($RIFFheader, 8, 4); 57 58 switch ($RIFFtype) { 59 60 case 'FORM': // AIFF, AIFC 61 $info['fileformat'] = 'aiff'; 62 $thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize); 63 $thisfile_riff[$RIFFsubtype] = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4)); 64 break; 65 66 case 'RIFF': // AVI, WAV, etc 67 case 'SDSS': // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com) 68 case 'RMP3': // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s 69 $info['fileformat'] = 'riff'; 70 $thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize); 71 if ($RIFFsubtype == 'RMP3') { 72 // RMP3 is identical to WAVE, just renamed. Used by [unknown program] when creating RIFF-MP3s 73 $RIFFsubtype = 'WAVE'; 74 } 75 $thisfile_riff[$RIFFsubtype] = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4)); 76 if (($info['avdataend'] - $info['filesize']) == 1) { 77 // LiteWave appears to incorrectly *not* pad actual output file 78 // to nearest WORD boundary so may appear to be short by one 79 // byte, in which case - skip warning 80 $info['avdataend'] = $info['filesize']; 81 } 82 83 $nextRIFFoffset = $Original['avdataoffset'] + 8 + $thisfile_riff['header_size']; // 8 = "RIFF" + 32-bit offset 84 while ($nextRIFFoffset < min($info['filesize'], $info['avdataend'])) { 85 try { 86 $this->fseek($nextRIFFoffset); 87 } catch (getid3_exception $e) { 88 if ($e->getCode() == 10) { 89 //$this->warning('RIFF parser: '.$e->getMessage()); 90 $this->error('AVI extends beyond '.round(PHP_INT_MAX / 1073741824).'GB and PHP filesystem functions cannot read that far, playtime may be wrong'); 91 $this->warning('[avdataend] value may be incorrect, multiple AVIX chunks may be present'); 92 break; 93 } else { 94 throw $e; 95 } 96 } 97 $nextRIFFheader = $this->fread(12); 98 if ($nextRIFFoffset == ($info['avdataend'] - 1)) { 99 if (substr($nextRIFFheader, 0, 1) == "\x00") { 100 // RIFF padded to WORD boundary, we're actually already at the end 101 break; 102 } 103 } 104 $nextRIFFheaderID = substr($nextRIFFheader, 0, 4); 105 $nextRIFFsize = $this->EitherEndian2Int(substr($nextRIFFheader, 4, 4)); 106 $nextRIFFtype = substr($nextRIFFheader, 8, 4); 107 $chunkdata = array(); 108 $chunkdata['offset'] = $nextRIFFoffset + 8; 109 $chunkdata['size'] = $nextRIFFsize; 110 $nextRIFFoffset = $chunkdata['offset'] + $chunkdata['size']; 111 112 switch ($nextRIFFheaderID) { 113 114 case 'RIFF': 115 $chunkdata['chunks'] = $this->ParseRIFF($chunkdata['offset'] + 4, $nextRIFFoffset); 116 117 if (!isset($thisfile_riff[$nextRIFFtype])) { 118 $thisfile_riff[$nextRIFFtype] = array(); 119 } 120 $thisfile_riff[$nextRIFFtype][] = $chunkdata; 121 break; 122 123 case 'JUNK': 124 // ignore 125 $thisfile_riff[$nextRIFFheaderID][] = $chunkdata; 126 break; 127 128 case 'IDVX': 129 $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunkdata['size'])); 130 break; 131 132 default: 133 if ($info['filesize'] == ($chunkdata['offset'] - 8 + 128)) { 134 $DIVXTAG = $nextRIFFheader.$this->fread(128 - 12); 135 if (substr($DIVXTAG, -7) == 'DIVXTAG') { 136 // DIVXTAG is supposed to be inside an IDVX chunk in a LIST chunk, but some bad encoders just slap it on the end of a file 137 $this->warning('Found wrongly-structured DIVXTAG at offset '.($this->ftell() - 128).', parsing anyway'); 138 $info['divxtag']['comments'] = self::ParseDIVXTAG($DIVXTAG); 139 break 2; 140 } 141 } 142 $this->warning('Expecting "RIFF|JUNK|IDVX" at '.$nextRIFFoffset.', found "'.$nextRIFFheaderID.'" ('.getid3_lib::PrintHexBytes($nextRIFFheaderID).') - skipping rest of file'); 143 break 2; 144 145 } 146 147 } 148 if ($RIFFsubtype == 'WAVE') { 149 $thisfile_riff_WAVE = &$thisfile_riff['WAVE']; 150 } 151 break; 152 153 default: 154 $this->error('Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$RIFFsubtype.'" instead'); 155 unset($info['fileformat']); 156 return false; 157 } 158 159 $streamindex = 0; 160 switch ($RIFFsubtype) { 161 case 'WAVE': 162 if (empty($thisfile_audio['bitrate_mode'])) { 163 $thisfile_audio['bitrate_mode'] = 'cbr'; 164 } 165 if (empty($thisfile_audio_dataformat)) { 166 $thisfile_audio_dataformat = 'wav'; 167 } 168 169 if (isset($thisfile_riff_WAVE['data'][0]['offset'])) { 170 $info['avdataoffset'] = $thisfile_riff_WAVE['data'][0]['offset'] + 8; 171 $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff_WAVE['data'][0]['size']; 172 } 173 if (isset($thisfile_riff_WAVE['fmt '][0]['data'])) { 174 175 $thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($thisfile_riff_WAVE['fmt '][0]['data']); 176 $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag']; 177 if (!isset($thisfile_riff_audio[$streamindex]['bitrate']) || ($thisfile_riff_audio[$streamindex]['bitrate'] == 0)) { 178 $info['error'][] = 'Corrupt RIFF file: bitrate_audio == zero'; 179 return false; 180 } 181 $thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw']; 182 unset($thisfile_riff_audio[$streamindex]['raw']); 183 $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex]; 184 185 $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]); 186 if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') { 187 $info['warning'][] = 'Audio codec = '.$thisfile_audio['codec']; 188 } 189 $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate']; 190 191 if (empty($info['playtime_seconds'])) { // may already be set (e.g. DTS-WAV) 192 $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']); 193 } 194 195 $thisfile_audio['lossless'] = false; 196 if (isset($thisfile_riff_WAVE['data'][0]['offset']) && isset($thisfile_riff_raw['fmt ']['wFormatTag'])) { 197 switch ($thisfile_riff_raw['fmt ']['wFormatTag']) { 198 199 case 0x0001: // PCM 200 $thisfile_audio['lossless'] = true; 201 break; 202 203 case 0x2000: // AC-3 204 $thisfile_audio_dataformat = 'ac3'; 205 break; 206 207 default: 208 // do nothing 209 break; 210 211 } 212 } 213 $thisfile_audio['streams'][$streamindex]['wformattag'] = $thisfile_audio['wformattag']; 214 $thisfile_audio['streams'][$streamindex]['bitrate_mode'] = $thisfile_audio['bitrate_mode']; 215 $thisfile_audio['streams'][$streamindex]['lossless'] = $thisfile_audio['lossless']; 216 $thisfile_audio['streams'][$streamindex]['dataformat'] = $thisfile_audio_dataformat; 217 } 218 219 if (isset($thisfile_riff_WAVE['rgad'][0]['data'])) { 220 221 // shortcuts 222 $rgadData = &$thisfile_riff_WAVE['rgad'][0]['data']; 223 $thisfile_riff_raw['rgad'] = array('track'=>array(), 'album'=>array()); 224 $thisfile_riff_raw_rgad = &$thisfile_riff_raw['rgad']; 225 $thisfile_riff_raw_rgad_track = &$thisfile_riff_raw_rgad['track']; 226 $thisfile_riff_raw_rgad_album = &$thisfile_riff_raw_rgad['album']; 227 228 $thisfile_riff_raw_rgad['fPeakAmplitude'] = getid3_lib::LittleEndian2Float(substr($rgadData, 0, 4)); 229 $thisfile_riff_raw_rgad['nRadioRgAdjust'] = $this->EitherEndian2Int(substr($rgadData, 4, 2)); 230 $thisfile_riff_raw_rgad['nAudiophileRgAdjust'] = $this->EitherEndian2Int(substr($rgadData, 6, 2)); 231 232 $nRadioRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nRadioRgAdjust']), 16, '0', STR_PAD_LEFT); 233 $nAudiophileRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nAudiophileRgAdjust']), 16, '0', STR_PAD_LEFT); 234 $thisfile_riff_raw_rgad_track['name'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 0, 3)); 235 $thisfile_riff_raw_rgad_track['originator'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 3, 3)); 236 $thisfile_riff_raw_rgad_track['signbit'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 6, 1)); 237 $thisfile_riff_raw_rgad_track['adjustment'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 7, 9)); 238 $thisfile_riff_raw_rgad_album['name'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 0, 3)); 239 $thisfile_riff_raw_rgad_album['originator'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 3, 3)); 240 $thisfile_riff_raw_rgad_album['signbit'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 6, 1)); 241 $thisfile_riff_raw_rgad_album['adjustment'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 7, 9)); 242 243 $thisfile_riff['rgad']['peakamplitude'] = $thisfile_riff_raw_rgad['fPeakAmplitude']; 244 if (($thisfile_riff_raw_rgad_track['name'] != 0) && ($thisfile_riff_raw_rgad_track['originator'] != 0)) { 245 $thisfile_riff['rgad']['track']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_track['name']); 246 $thisfile_riff['rgad']['track']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_track['originator']); 247 $thisfile_riff['rgad']['track']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_track['adjustment'], $thisfile_riff_raw_rgad_track['signbit']); 248 } 249 if (($thisfile_riff_raw_rgad_album['name'] != 0) && ($thisfile_riff_raw_rgad_album['originator'] != 0)) { 250 $thisfile_riff['rgad']['album']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_album['name']); 251 $thisfile_riff['rgad']['album']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_album['originator']); 252 $thisfile_riff['rgad']['album']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_album['adjustment'], $thisfile_riff_raw_rgad_album['signbit']); 253 } 254 } 255 256 if (isset($thisfile_riff_WAVE['fact'][0]['data'])) { 257 $thisfile_riff_raw['fact']['NumberOfSamples'] = $this->EitherEndian2Int(substr($thisfile_riff_WAVE['fact'][0]['data'], 0, 4)); 258 259 // This should be a good way of calculating exact playtime, 260 // but some sample files have had incorrect number of samples, 261 // so cannot use this method 262 263 // if (!empty($thisfile_riff_raw['fmt ']['nSamplesPerSec'])) { 264 // $info['playtime_seconds'] = (float) $thisfile_riff_raw['fact']['NumberOfSamples'] / $thisfile_riff_raw['fmt ']['nSamplesPerSec']; 265 // } 266 } 267 if (!empty($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'])) { 268 $thisfile_audio['bitrate'] = getid3_lib::CastAsInt($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'] * 8); 269 } 270 271 if (isset($thisfile_riff_WAVE['bext'][0]['data'])) { 272 // shortcut 273 $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0]; 274 275 $thisfile_riff_WAVE_bext_0['title'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 0, 256)); 276 $thisfile_riff_WAVE_bext_0['author'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 256, 32)); 277 $thisfile_riff_WAVE_bext_0['reference'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 288, 32)); 278 $thisfile_riff_WAVE_bext_0['origin_date'] = substr($thisfile_riff_WAVE_bext_0['data'], 320, 10); 279 $thisfile_riff_WAVE_bext_0['origin_time'] = substr($thisfile_riff_WAVE_bext_0['data'], 330, 8); 280 $thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338, 8)); 281 $thisfile_riff_WAVE_bext_0['bwf_version'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 346, 1)); 282 $thisfile_riff_WAVE_bext_0['reserved'] = substr($thisfile_riff_WAVE_bext_0['data'], 347, 254); 283 $thisfile_riff_WAVE_bext_0['coding_history'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601))); 284 if (preg_match('#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_date'], $matches_bext_date)) { 285 if (preg_match('#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_time'], $matches_bext_time)) { 286 list($dummy, $bext_timestamp['year'], $bext_timestamp['month'], $bext_timestamp['day']) = $matches_bext_date; 287 list($dummy, $bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second']) = $matches_bext_time; 288 $thisfile_riff_WAVE_bext_0['origin_date_unix'] = gmmktime($bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second'], $bext_timestamp['month'], $bext_timestamp['day'], $bext_timestamp['year']); 289 } else { 290 $info['warning'][] = 'RIFF.WAVE.BEXT.origin_time is invalid'; 291 } 292 } else { 293 $info['warning'][] = 'RIFF.WAVE.BEXT.origin_date is invalid'; 294 } 295 $thisfile_riff['comments']['author'][] = $thisfile_riff_WAVE_bext_0['author']; 296 $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_bext_0['title']; 297 } 298 299 if (isset($thisfile_riff_WAVE['MEXT'][0]['data'])) { 300 // shortcut 301 $thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE['MEXT'][0]; 302 303 $thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 0, 2)); 304 $thisfile_riff_WAVE_MEXT_0['flags']['homogenous'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0001); 305 if ($thisfile_riff_WAVE_MEXT_0['flags']['homogenous']) { 306 $thisfile_riff_WAVE_MEXT_0['flags']['padding'] = ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0002) ? false : true; 307 $thisfile_riff_WAVE_MEXT_0['flags']['22_or_44'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0004); 308 $thisfile_riff_WAVE_MEXT_0['flags']['free_format'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0008); 309 310 $thisfile_riff_WAVE_MEXT_0['nominal_frame_size'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 2, 2)); 311 } 312 $thisfile_riff_WAVE_MEXT_0['anciliary_data_length'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 6, 2)); 313 $thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 8, 2)); 314 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_left'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0001); 315 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_free'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0002); 316 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_right'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0004); 317 } 318 319 if (isset($thisfile_riff_WAVE['cart'][0]['data'])) { 320 // shortcut 321 $thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE['cart'][0]; 322 323 $thisfile_riff_WAVE_cart_0['version'] = substr($thisfile_riff_WAVE_cart_0['data'], 0, 4); 324 $thisfile_riff_WAVE_cart_0['title'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 4, 64)); 325 $thisfile_riff_WAVE_cart_0['artist'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 68, 64)); 326 $thisfile_riff_WAVE_cart_0['cut_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 132, 64)); 327 $thisfile_riff_WAVE_cart_0['client_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 196, 64)); 328 $thisfile_riff_WAVE_cart_0['category'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 260, 64)); 329 $thisfile_riff_WAVE_cart_0['classification'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 324, 64)); 330 $thisfile_riff_WAVE_cart_0['out_cue'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 388, 64)); 331 $thisfile_riff_WAVE_cart_0['start_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 452, 10)); 332 $thisfile_riff_WAVE_cart_0['start_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 462, 8)); 333 $thisfile_riff_WAVE_cart_0['end_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 470, 10)); 334 $thisfile_riff_WAVE_cart_0['end_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 480, 8)); 335 $thisfile_riff_WAVE_cart_0['producer_app_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 488, 64)); 336 $thisfile_riff_WAVE_cart_0['producer_app_version'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 552, 64)); 337 $thisfile_riff_WAVE_cart_0['user_defined_text'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 616, 64)); 338 $thisfile_riff_WAVE_cart_0['zero_db_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 680, 4), true); 339 for ($i = 0; $i < 8; $i++) { 340 $thisfile_riff_WAVE_cart_0['post_time'][$i]['usage_fourcc'] = substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8), 4); 341 $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)); 342 } 343 $thisfile_riff_WAVE_cart_0['url'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 748, 1024)); 344 $thisfile_riff_WAVE_cart_0['tag_text'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_cart_0['data'], 1772))); 345 346 $thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist']; 347 $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_cart_0['title']; 348 } 349 350 if (isset($thisfile_riff_WAVE['SNDM'][0]['data'])) { 351 // SoundMiner metadata 352 353 // shortcuts 354 $thisfile_riff_WAVE_SNDM_0 = &$thisfile_riff_WAVE['SNDM'][0]; 355 $thisfile_riff_WAVE_SNDM_0_data = &$thisfile_riff_WAVE_SNDM_0['data']; 356 $SNDM_startoffset = 0; 357 $SNDM_endoffset = $thisfile_riff_WAVE_SNDM_0['size']; 358 359 while ($SNDM_startoffset < $SNDM_endoffset) { 360 $SNDM_thisTagOffset = 0; 361 $SNDM_thisTagSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4)); 362 $SNDM_thisTagOffset += 4; 363 $SNDM_thisTagKey = substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4); 364 $SNDM_thisTagOffset += 4; 365 $SNDM_thisTagDataSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2)); 366 $SNDM_thisTagOffset += 2; 367 $SNDM_thisTagDataFlags = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2)); 368 $SNDM_thisTagOffset += 2; 369 $SNDM_thisTagDataText = substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, $SNDM_thisTagDataSize); 370 $SNDM_thisTagOffset += $SNDM_thisTagDataSize; 371 372 if ($SNDM_thisTagSize != (4 + 4 + 2 + 2 + $SNDM_thisTagDataSize)) { 373 $info['warning'][] = 'RIFF.WAVE.SNDM.data contains tag not expected length (expected: '.$SNDM_thisTagSize.', found: '.(4 + 4 + 2 + 2 + $SNDM_thisTagDataSize).') at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')'; 374 break; 375 } elseif ($SNDM_thisTagSize <= 0) { 376 $info['warning'][] = 'RIFF.WAVE.SNDM.data contains zero-size tag at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')'; 377 break; 378 } 379 $SNDM_startoffset += $SNDM_thisTagSize; 380 381 $thisfile_riff_WAVE_SNDM_0['parsed_raw'][$SNDM_thisTagKey] = $SNDM_thisTagDataText; 382 if ($parsedkey = self::waveSNDMtagLookup($SNDM_thisTagKey)) { 383 $thisfile_riff_WAVE_SNDM_0['parsed'][$parsedkey] = $SNDM_thisTagDataText; 384 } else { 385 $info['warning'][] = 'RIFF.WAVE.SNDM contains unknown tag "'.$SNDM_thisTagKey.'" at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')'; 386 } 387 } 388 389 $tagmapping = array( 390 'tracktitle'=>'title', 391 'category' =>'genre', 392 'cdtitle' =>'album', 393 'tracktitle'=>'title', 394 ); 395 foreach ($tagmapping as $fromkey => $tokey) { 396 if (isset($thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey])) { 397 $thisfile_riff['comments'][$tokey][] = $thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey]; 398 } 399 } 400 } 401 402 if (isset($thisfile_riff_WAVE['iXML'][0]['data'])) { 403 // requires functions simplexml_load_string and get_object_vars 404 if ($parsedXML = getid3_lib::XML2array($thisfile_riff_WAVE['iXML'][0]['data'])) { 405 $thisfile_riff_WAVE['iXML'][0]['parsed'] = $parsedXML; 406 if (isset($parsedXML['SPEED']['MASTER_SPEED'])) { 407 @list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['MASTER_SPEED']); 408 $thisfile_riff_WAVE['iXML'][0]['master_speed'] = $numerator / ($denominator ? $denominator : 1000); 409 } 410 if (isset($parsedXML['SPEED']['TIMECODE_RATE'])) { 411 @list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['TIMECODE_RATE']); 412 $thisfile_riff_WAVE['iXML'][0]['timecode_rate'] = $numerator / ($denominator ? $denominator : 1000); 413 } 414 if (isset($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO']) && !empty($parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']) && !empty($thisfile_riff_WAVE['iXML'][0]['timecode_rate'])) { 415 $samples_since_midnight = floatval(ltrim($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI'].$parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO'], '0')); 416 $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] = $samples_since_midnight / $parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']; 417 $h = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] / 3600); 418 $m = floor(($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600)) / 60); 419 $s = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60)); 420 $f = ($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60) - $s) * $thisfile_riff_WAVE['iXML'][0]['timecode_rate']; 421 $thisfile_riff_WAVE['iXML'][0]['timecode_string'] = sprintf('%02d:%02d:%02d:%05.2f', $h, $m, $s, $f); 422 $thisfile_riff_WAVE['iXML'][0]['timecode_string_round'] = sprintf('%02d:%02d:%02d:%02d', $h, $m, $s, round($f)); 423 } 424 unset($parsedXML); 425 } 426 } 427 428 429 430 if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) { 431 $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate']; 432 $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']); 433 } 434 435 if (!empty($info['wavpack'])) { 436 $thisfile_audio_dataformat = 'wavpack'; 437 $thisfile_audio['bitrate_mode'] = 'vbr'; 438 $thisfile_audio['encoder'] = 'WavPack v'.$info['wavpack']['version']; 439 440 // Reset to the way it was - RIFF parsing will have messed this up 441 $info['avdataend'] = $Original['avdataend']; 442 $thisfile_audio['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds']; 443 444 $this->fseek($info['avdataoffset'] - 44); 445 $RIFFdata = $this->fread(44); 446 $OrignalRIFFheaderSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 4, 4)) + 8; 447 $OrignalRIFFdataSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 40, 4)) + 44; 448 449 if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) { 450 $info['avdataend'] -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize); 451 $this->fseek($info['avdataend']); 452 $RIFFdata .= $this->fread($OrignalRIFFheaderSize - $OrignalRIFFdataSize); 453 } 454 455 // move the data chunk after all other chunks (if any) 456 // so that the RIFF parser doesn't see EOF when trying 457 // to skip over the data chunk 458 $RIFFdata = substr($RIFFdata, 0, 36).substr($RIFFdata, 44).substr($RIFFdata, 36, 8); 459 $getid3_riff = new getid3_riff($this->getid3); 460 $getid3_riff->ParseRIFFdata($RIFFdata); 461 unset($getid3_riff); 462 } 463 464 if (isset($thisfile_riff_raw['fmt ']['wFormatTag'])) { 465 switch ($thisfile_riff_raw['fmt ']['wFormatTag']) { 466 case 0x0001: // PCM 467 if (!empty($info['ac3'])) { 468 // Dolby Digital WAV files masquerade as PCM-WAV, but they're not 469 $thisfile_audio['wformattag'] = 0x2000; 470 $thisfile_audio['codec'] = self::wFormatTagLookup($thisfile_audio['wformattag']); 471 $thisfile_audio['lossless'] = false; 472 $thisfile_audio['bitrate'] = $info['ac3']['bitrate']; 473 $thisfile_audio['sample_rate'] = $info['ac3']['sample_rate']; 474 } 475 if (!empty($info['dts'])) { 476 // Dolby DTS files masquerade as PCM-WAV, but they're not 477 $thisfile_audio['wformattag'] = 0x2001; 478 $thisfile_audio['codec'] = self::wFormatTagLookup($thisfile_audio['wformattag']); 479 $thisfile_audio['lossless'] = false; 480 $thisfile_audio['bitrate'] = $info['dts']['bitrate']; 481 $thisfile_audio['sample_rate'] = $info['dts']['sample_rate']; 482 } 483 break; 484 case 0x08AE: // ClearJump LiteWave 485 $thisfile_audio['bitrate_mode'] = 'vbr'; 486 $thisfile_audio_dataformat = 'litewave'; 487 488 //typedef struct tagSLwFormat { 489 // WORD m_wCompFormat; // low byte defines compression method, high byte is compression flags 490 // DWORD m_dwScale; // scale factor for lossy compression 491 // DWORD m_dwBlockSize; // number of samples in encoded blocks 492 // WORD m_wQuality; // alias for the scale factor 493 // WORD m_wMarkDistance; // distance between marks in bytes 494 // WORD m_wReserved; 495 // 496 // //following paramters are ignored if CF_FILESRC is not set 497 // DWORD m_dwOrgSize; // original file size in bytes 498 // WORD m_bFactExists; // indicates if 'fact' chunk exists in the original file 499 // DWORD m_dwRiffChunkSize; // riff chunk size in the original file 500 // 501 // PCMWAVEFORMAT m_OrgWf; // original wave format 502 // }SLwFormat, *PSLwFormat; 503 504 // shortcut 505 $thisfile_riff['litewave']['raw'] = array(); 506 $riff_litewave = &$thisfile_riff['litewave']; 507 $riff_litewave_raw = &$riff_litewave['raw']; 508 509 $flags = array( 510 'compression_method' => 1, 511 'compression_flags' => 1, 512 'm_dwScale' => 4, 513 'm_dwBlockSize' => 4, 514 'm_wQuality' => 2, 515 'm_wMarkDistance' => 2, 516 'm_wReserved' => 2, 517 'm_dwOrgSize' => 4, 518 'm_bFactExists' => 2, 519 'm_dwRiffChunkSize' => 4, 520 ); 521 $litewave_offset = 18; 522 foreach ($flags as $flag => $length) { 523 $riff_litewave_raw[$flag] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], $litewave_offset, $length)); 524 $litewave_offset += $length; 525 } 526 527 //$riff_litewave['quality_factor'] = intval(round((2000 - $riff_litewave_raw['m_dwScale']) / 20)); 528 $riff_litewave['quality_factor'] = $riff_litewave_raw['m_wQuality']; 529 530 $riff_litewave['flags']['raw_source'] = ($riff_litewave_raw['compression_flags'] & 0x01) ? false : true; 531 $riff_litewave['flags']['vbr_blocksize'] = ($riff_litewave_raw['compression_flags'] & 0x02) ? false : true; 532 $riff_litewave['flags']['seekpoints'] = (bool) ($riff_litewave_raw['compression_flags'] & 0x04); 533 534 $thisfile_audio['lossless'] = (($riff_litewave_raw['m_wQuality'] == 100) ? true : false); 535 $thisfile_audio['encoder_options'] = '-q'.$riff_litewave['quality_factor']; 536 break; 537 538 default: 539 break; 540 } 541 } 542 if ($info['avdataend'] > $info['filesize']) { 543 switch (!empty($thisfile_audio_dataformat) ? $thisfile_audio_dataformat : '') { 544 case 'wavpack': // WavPack 545 case 'lpac': // LPAC 546 case 'ofr': // OptimFROG 547 case 'ofs': // OptimFROG DualStream 548 // lossless compressed audio formats that keep original RIFF headers - skip warning 549 break; 550 551 case 'litewave': 552 if (($info['avdataend'] - $info['filesize']) == 1) { 553 // LiteWave appears to incorrectly *not* pad actual output file 554 // to nearest WORD boundary so may appear to be short by one 555 // byte, in which case - skip warning 556 } else { 557 // Short by more than one byte, throw warning 558 $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)'; 559 $info['avdataend'] = $info['filesize']; 560 } 561 break; 562 563 default: 564 if ((($info['avdataend'] - $info['filesize']) == 1) && (($thisfile_riff[$RIFFsubtype]['data'][0]['size'] % 2) == 0) && ((($info['filesize'] - $info['avdataoffset']) % 2) == 1)) { 565 // output file appears to be incorrectly *not* padded to nearest WORD boundary 566 // Output less severe warning 567 $info['warning'][] = 'File should probably be padded to nearest WORD boundary, but it is not (expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' therefore short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)'; 568 $info['avdataend'] = $info['filesize']; 569 } else { 570 // Short by more than one byte, throw warning 571 $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)'; 572 $info['avdataend'] = $info['filesize']; 573 } 574 break; 575 } 576 } 577 if (!empty($info['mpeg']['audio']['LAME']['audio_bytes'])) { 578 if ((($info['avdataend'] - $info['avdataoffset']) - $info['mpeg']['audio']['LAME']['audio_bytes']) == 1) { 579 $info['avdataend']--; 580 $info['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored'; 581 } 582 } 583 if (isset($thisfile_audio_dataformat) && ($thisfile_audio_dataformat == 'ac3')) { 584 unset($thisfile_audio['bits_per_sample']); 585 if (!empty($info['ac3']['bitrate']) && ($info['ac3']['bitrate'] != $thisfile_audio['bitrate'])) { 586 $thisfile_audio['bitrate'] = $info['ac3']['bitrate']; 587 } 588 } 589 break; 590 591 case 'AVI ': 592 $thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably 593 $thisfile_video['dataformat'] = 'avi'; 594 $info['mime_type'] = 'video/avi'; 595 596 if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) { 597 $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['movi']['offset'] + 8; 598 if (isset($thisfile_riff['AVIX'])) { 599 $info['avdataend'] = $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['offset'] + $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['size']; 600 } else { 601 $info['avdataend'] = $thisfile_riff['AVI ']['movi']['offset'] + $thisfile_riff['AVI ']['movi']['size']; 602 } 603 if ($info['avdataend'] > $info['filesize']) { 604 $info['warning'][] = 'Probably truncated file - expecting '.($info['avdataend'] - $info['avdataoffset']).' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($info['avdataend'] - $info['filesize']).' bytes)'; 605 $info['avdataend'] = $info['filesize']; 606 } 607 } 608 609 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['indx'])) { 610 //$bIndexType = array( 611 // 0x00 => 'AVI_INDEX_OF_INDEXES', 612 // 0x01 => 'AVI_INDEX_OF_CHUNKS', 613 // 0x80 => 'AVI_INDEX_IS_DATA', 614 //); 615 //$bIndexSubtype = array( 616 // 0x01 => array( 617 // 0x01 => 'AVI_INDEX_2FIELD', 618 // ), 619 //); 620 foreach ($thisfile_riff['AVI ']['hdrl']['strl']['indx'] as $streamnumber => $steamdataarray) { 621 $ahsisd = &$thisfile_riff['AVI ']['hdrl']['strl']['indx'][$streamnumber]['data']; 622 623 $thisfile_riff_raw['indx'][$streamnumber]['wLongsPerEntry'] = $this->EitherEndian2Int(substr($ahsisd, 0, 2)); 624 $thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType'] = $this->EitherEndian2Int(substr($ahsisd, 2, 1)); 625 $thisfile_riff_raw['indx'][$streamnumber]['bIndexType'] = $this->EitherEndian2Int(substr($ahsisd, 3, 1)); 626 $thisfile_riff_raw['indx'][$streamnumber]['nEntriesInUse'] = $this->EitherEndian2Int(substr($ahsisd, 4, 4)); 627 $thisfile_riff_raw['indx'][$streamnumber]['dwChunkId'] = substr($ahsisd, 8, 4); 628 $thisfile_riff_raw['indx'][$streamnumber]['dwReserved'] = $this->EitherEndian2Int(substr($ahsisd, 12, 4)); 629 630 //$thisfile_riff_raw['indx'][$streamnumber]['bIndexType_name'] = $bIndexType[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']]; 631 //$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType_name'] = $bIndexSubtype[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']][$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType']]; 632 633 unset($ahsisd); 634 } 635 } 636 if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) { 637 $avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data']; 638 639 // shortcut 640 $thisfile_riff_raw['avih'] = array(); 641 $thisfile_riff_raw_avih = &$thisfile_riff_raw['avih']; 642 643 $thisfile_riff_raw_avih['dwMicroSecPerFrame'] = $this->EitherEndian2Int(substr($avihData, 0, 4)); // frame display rate (or 0L) 644 if ($thisfile_riff_raw_avih['dwMicroSecPerFrame'] == 0) { 645 $info['error'][] = 'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero'; 646 return false; 647 } 648 649 $flags = array( 650 'dwMaxBytesPerSec', // max. transfer rate 651 'dwPaddingGranularity', // pad to multiples of this size; normally 2K. 652 'dwFlags', // the ever-present flags 653 'dwTotalFrames', // # frames in file 654 'dwInitialFrames', // 655 'dwStreams', // 656 'dwSuggestedBufferSize', // 657 'dwWidth', // 658 'dwHeight', // 659 'dwScale', // 660 'dwRate', // 661 'dwStart', // 662 'dwLength', // 663 ); 664 $avih_offset = 4; 665 foreach ($flags as $flag) { 666 $thisfile_riff_raw_avih[$flag] = $this->EitherEndian2Int(substr($avihData, $avih_offset, 4)); 667 $avih_offset += 4; 668 } 669 670 $flags = array( 671 'hasindex' => 0x00000010, 672 'mustuseindex' => 0x00000020, 673 'interleaved' => 0x00000100, 674 'trustcktype' => 0x00000800, 675 'capturedfile' => 0x00010000, 676 'copyrighted' => 0x00020010, 677 ); 678 foreach ($flags as $flag => $value) { 679 $thisfile_riff_raw_avih['flags'][$flag] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & $value); 680 } 681 682 // shortcut 683 $thisfile_riff_video[$streamindex] = array(); 684 $thisfile_riff_video_current = &$thisfile_riff_video[$streamindex]; 685 686 if ($thisfile_riff_raw_avih['dwWidth'] > 0) { 687 $thisfile_riff_video_current['frame_width'] = $thisfile_riff_raw_avih['dwWidth']; 688 $thisfile_video['resolution_x'] = $thisfile_riff_video_current['frame_width']; 689 } 690 if ($thisfile_riff_raw_avih['dwHeight'] > 0) { 691 $thisfile_riff_video_current['frame_height'] = $thisfile_riff_raw_avih['dwHeight']; 692 $thisfile_video['resolution_y'] = $thisfile_riff_video_current['frame_height']; 693 } 694 if ($thisfile_riff_raw_avih['dwTotalFrames'] > 0) { 695 $thisfile_riff_video_current['total_frames'] = $thisfile_riff_raw_avih['dwTotalFrames']; 696 $thisfile_video['total_frames'] = $thisfile_riff_video_current['total_frames']; 697 } 698 699 $thisfile_riff_video_current['frame_rate'] = round(1000000 / $thisfile_riff_raw_avih['dwMicroSecPerFrame'], 3); 700 $thisfile_video['frame_rate'] = $thisfile_riff_video_current['frame_rate']; 701 } 702 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) { 703 if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) { 704 for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) { 705 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) { 706 $strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data']; 707 $strhfccType = substr($strhData, 0, 4); 708 709 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'])) { 710 $strfData = $thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data']; 711 712 // shortcut 713 $thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw['strf'][$strhfccType][$streamindex]; 714 715 switch ($strhfccType) { 716 case 'auds': 717 $thisfile_audio['bitrate_mode'] = 'cbr'; 718 $thisfile_audio_dataformat = 'wav'; 719 if (isset($thisfile_riff_audio) && is_array($thisfile_riff_audio)) { 720 $streamindex = count($thisfile_riff_audio); 721 } 722 723 $thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($strfData); 724 $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag']; 725 726 // shortcut 727 $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex]; 728 $thisfile_audio_streams_currentstream = &$thisfile_audio['streams'][$streamindex]; 729 730 if ($thisfile_audio_streams_currentstream['bits_per_sample'] == 0) { 731 unset($thisfile_audio_streams_currentstream['bits_per_sample']); 732 } 733 $thisfile_audio_streams_currentstream['wformattag'] = $thisfile_audio_streams_currentstream['raw']['wFormatTag']; 734 unset($thisfile_audio_streams_currentstream['raw']); 735 736 // shortcut 737 $thisfile_riff_raw['strf'][$strhfccType][$streamindex] = $thisfile_riff_audio[$streamindex]['raw']; 738 739 unset($thisfile_riff_audio[$streamindex]['raw']); 740 $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]); 741 742 $thisfile_audio['lossless'] = false; 743 switch ($thisfile_riff_raw_strf_strhfccType_streamindex['wFormatTag']) { 744 case 0x0001: // PCM 745 $thisfile_audio_dataformat = 'wav'; 746 $thisfile_audio['lossless'] = true; 747 break; 748 749 case 0x0050: // MPEG Layer 2 or Layer 1 750 $thisfile_audio_dataformat = 'mp2'; // Assume Layer-2 751 break; 752 753 case 0x0055: // MPEG Layer 3 754 $thisfile_audio_dataformat = 'mp3'; 755 break; 756 757 case 0x00FF: // AAC 758 $thisfile_audio_dataformat = 'aac'; 759 break; 760 761 case 0x0161: // Windows Media v7 / v8 / v9 762 case 0x0162: // Windows Media Professional v9 763 case 0x0163: // Windows Media Lossess v9 764 $thisfile_audio_dataformat = 'wma'; 765 break; 766 767 case 0x2000: // AC-3 768 $thisfile_audio_dataformat = 'ac3'; 769 break; 770 771 case 0x2001: // DTS 772 $thisfile_audio_dataformat = 'dts'; 773 break; 774 775 default: 776 $thisfile_audio_dataformat = 'wav'; 777 break; 778 } 779 $thisfile_audio_streams_currentstream['dataformat'] = $thisfile_audio_dataformat; 780 $thisfile_audio_streams_currentstream['lossless'] = $thisfile_audio['lossless']; 781 $thisfile_audio_streams_currentstream['bitrate_mode'] = $thisfile_audio['bitrate_mode']; 782 break; 783 784 785 case 'iavs': 786 case 'vids': 787 // shortcut 788 $thisfile_riff_raw['strh'][$i] = array(); 789 $thisfile_riff_raw_strh_current = &$thisfile_riff_raw['strh'][$i]; 790 791 $thisfile_riff_raw_strh_current['fccType'] = substr($strhData, 0, 4); // same as $strhfccType; 792 $thisfile_riff_raw_strh_current['fccHandler'] = substr($strhData, 4, 4); 793 $thisfile_riff_raw_strh_current['dwFlags'] = $this->EitherEndian2Int(substr($strhData, 8, 4)); // Contains AVITF_* flags 794 $thisfile_riff_raw_strh_current['wPriority'] = $this->EitherEndian2Int(substr($strhData, 12, 2)); 795 $thisfile_riff_raw_strh_current['wLanguage'] = $this->EitherEndian2Int(substr($strhData, 14, 2)); 796 $thisfile_riff_raw_strh_current['dwInitialFrames'] = $this->EitherEndian2Int(substr($strhData, 16, 4)); 797 $thisfile_riff_raw_strh_current['dwScale'] = $this->EitherEndian2Int(substr($strhData, 20, 4)); 798 $thisfile_riff_raw_strh_current['dwRate'] = $this->EitherEndian2Int(substr($strhData, 24, 4)); 799 $thisfile_riff_raw_strh_current['dwStart'] = $this->EitherEndian2Int(substr($strhData, 28, 4)); 800 $thisfile_riff_raw_strh_current['dwLength'] = $this->EitherEndian2Int(substr($strhData, 32, 4)); 801 $thisfile_riff_raw_strh_current['dwSuggestedBufferSize'] = $this->EitherEndian2Int(substr($strhData, 36, 4)); 802 $thisfile_riff_raw_strh_current['dwQuality'] = $this->EitherEndian2Int(substr($strhData, 40, 4)); 803 $thisfile_riff_raw_strh_current['dwSampleSize'] = $this->EitherEndian2Int(substr($strhData, 44, 4)); 804 $thisfile_riff_raw_strh_current['rcFrame'] = $this->EitherEndian2Int(substr($strhData, 48, 4)); 805 806 $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_riff_raw_strh_current['fccHandler']); 807 $thisfile_video['fourcc'] = $thisfile_riff_raw_strh_current['fccHandler']; 808 if (!$thisfile_riff_video_current['codec'] && isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && self::fourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) { 809 $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']); 810 $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']; 811 } 812 $thisfile_video['codec'] = $thisfile_riff_video_current['codec']; 813 $thisfile_video['pixel_aspect_ratio'] = (float) 1; 814 switch ($thisfile_riff_raw_strh_current['fccHandler']) { 815 case 'HFYU': // Huffman Lossless Codec 816 case 'IRAW': // Intel YUV Uncompressed 817 case 'YUY2': // Uncompressed YUV 4:2:2 818 $thisfile_video['lossless'] = true; 819 break; 820 821 default: 822 $thisfile_video['lossless'] = false; 823 break; 824 } 825 826 switch ($strhfccType) { 827 case 'vids': 828 $thisfile_riff_raw_strf_strhfccType_streamindex = self::ParseBITMAPINFOHEADER(substr($strfData, 0, 40), ($info['fileformat'] == 'riff')); 829 $thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount']; 830 831 if ($thisfile_riff_video_current['codec'] == 'DV') { 832 $thisfile_riff_video_current['dv_type'] = 2; 833 } 834 break; 835 836 case 'iavs': 837 $thisfile_riff_video_current['dv_type'] = 1; 838 break; 839 } 840 break; 841 842 default: 843 $info['warning'][] = 'Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"'; 844 break; 845 846 } 847 } 848 } 849 850 if (isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) { 851 852 $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']; 853 if (self::fourccLookup($thisfile_video['fourcc'])) { 854 $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_video['fourcc']); 855 $thisfile_video['codec'] = $thisfile_riff_video_current['codec']; 856 } 857 858 switch ($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) { 859 case 'HFYU': // Huffman Lossless Codec 860 case 'IRAW': // Intel YUV Uncompressed 861 case 'YUY2': // Uncompressed YUV 4:2:2 862 $thisfile_video['lossless'] = true; 863 //$thisfile_video['bits_per_sample'] = 24; 864 break; 865 866 default: 867 $thisfile_video['lossless'] = false; 868 //$thisfile_video['bits_per_sample'] = 24; 869 break; 870 } 871 872 } 873 } 874 } 875 } 876 break; 877 878 case 'CDDA': 879 $thisfile_audio['bitrate_mode'] = 'cbr'; 880 $thisfile_audio_dataformat = 'cda'; 881 $thisfile_audio['lossless'] = true; 882 unset($info['mime_type']); 883 884 $info['avdataoffset'] = 44; 885 886 if (isset($thisfile_riff['CDDA']['fmt '][0]['data'])) { 887 // shortcut 888 $thisfile_riff_CDDA_fmt_0 = &$thisfile_riff['CDDA']['fmt '][0]; 889 890 $thisfile_riff_CDDA_fmt_0['unknown1'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 0, 2)); 891 $thisfile_riff_CDDA_fmt_0['track_num'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 2, 2)); 892 $thisfile_riff_CDDA_fmt_0['disc_id'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 4, 4)); 893 $thisfile_riff_CDDA_fmt_0['start_offset_frame'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 8, 4)); 894 $thisfile_riff_CDDA_fmt_0['playtime_frames'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 12, 4)); 895 $thisfile_riff_CDDA_fmt_0['unknown6'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 16, 4)); 896 $thisfile_riff_CDDA_fmt_0['unknown7'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 20, 4)); 897 898 $thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75; 899 $thisfile_riff_CDDA_fmt_0['playtime_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75; 900 $info['comments']['track'] = $thisfile_riff_CDDA_fmt_0['track_num']; 901 $info['playtime_seconds'] = $thisfile_riff_CDDA_fmt_0['playtime_seconds']; 902 903 // hardcoded data for CD-audio 904 $thisfile_audio['sample_rate'] = 44100; 905 $thisfile_audio['channels'] = 2; 906 $thisfile_audio['bits_per_sample'] = 16; 907 $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $thisfile_audio['channels'] * $thisfile_audio['bits_per_sample']; 908 $thisfile_audio['bitrate_mode'] = 'cbr'; 909 } 910 break; 911 912 913 case 'AIFF': 914 case 'AIFC': 915 $thisfile_audio['bitrate_mode'] = 'cbr'; 916 $thisfile_audio_dataformat = 'aiff'; 917 $thisfile_audio['lossless'] = true; 918 $info['mime_type'] = 'audio/x-aiff'; 919 920 if (isset($thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'])) { 921 $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'] + 8; 922 $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['SSND'][0]['size']; 923 if ($info['avdataend'] > $info['filesize']) { 924 if (($info['avdataend'] == ($info['filesize'] + 1)) && (($info['filesize'] % 2) == 1)) { 925 // structures rounded to 2-byte boundary, but dumb encoders 926 // forget to pad end of file to make this actually work 927 } else { 928 $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['SSND'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found'; 929 } 930 $info['avdataend'] = $info['filesize']; 931 } 932 } 933 934 if (isset($thisfile_riff[$RIFFsubtype]['COMM'][0]['data'])) { 935 936 // shortcut 937 $thisfile_riff_RIFFsubtype_COMM_0_data = &$thisfile_riff[$RIFFsubtype]['COMM'][0]['data']; 938 939 $thisfile_riff_audio['channels'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 0, 2), true); 940 $thisfile_riff_audio['total_samples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 2, 4), false); 941 $thisfile_riff_audio['bits_per_sample'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 6, 2), true); 942 $thisfile_riff_audio['sample_rate'] = (int) getid3_lib::BigEndian2Float(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 8, 10)); 943 944 if ($thisfile_riff[$RIFFsubtype]['COMM'][0]['size'] > 18) { 945 $thisfile_riff_audio['codec_fourcc'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 18, 4); 946 $CodecNameSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 22, 1), false); 947 $thisfile_riff_audio['codec_name'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 23, $CodecNameSize); 948 switch ($thisfile_riff_audio['codec_name']) { 949 case 'NONE': 950 $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)'; 951 $thisfile_audio['lossless'] = true; 952 break; 953 954 case '': 955 switch ($thisfile_riff_audio['codec_fourcc']) { 956 // http://developer.apple.com/qa/snd/snd07.html 957 case 'sowt': 958 $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Little-Endian PCM'; 959 $thisfile_audio['lossless'] = true; 960 break; 961 962 case 'twos': 963 $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Big-Endian PCM'; 964 $thisfile_audio['lossless'] = true; 965 break; 966 967 default: 968 break; 969 } 970 break; 971 972 default: 973 $thisfile_audio['codec'] = $thisfile_riff_audio['codec_name']; 974 $thisfile_audio['lossless'] = false; 975 break; 976 } 977 } 978 979 $thisfile_audio['channels'] = $thisfile_riff_audio['channels']; 980 if ($thisfile_riff_audio['bits_per_sample'] > 0) { 981 $thisfile_audio['bits_per_sample'] = $thisfile_riff_audio['bits_per_sample']; 982 } 983 $thisfile_audio['sample_rate'] = $thisfile_riff_audio['sample_rate']; 984 if ($thisfile_audio['sample_rate'] == 0) { 985 $info['error'][] = 'Corrupted AIFF file: sample_rate == zero'; 986 return false; 987 } 988 $info['playtime_seconds'] = $thisfile_riff_audio['total_samples'] / $thisfile_audio['sample_rate']; 989 } 990 991 if (isset($thisfile_riff[$RIFFsubtype]['COMT'])) { 992 $offset = 0; 993 $CommentCount = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false); 994 $offset += 2; 995 for ($i = 0; $i < $CommentCount; $i++) { 996 $info['comments_raw'][$i]['timestamp'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 4), false); 997 $offset += 4; 998 $info['comments_raw'][$i]['marker_id'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), true); 999 $offset += 2; 1000 $CommentLength = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false); 1001 $offset += 2; 1002 $info['comments_raw'][$i]['comment'] = substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, $CommentLength); 1003 $offset += $CommentLength; 1004 1005 $info['comments_raw'][$i]['timestamp_unix'] = getid3_lib::DateMac2Unix($info['comments_raw'][$i]['timestamp']); 1006 $thisfile_riff['comments']['comment'][] = $info['comments_raw'][$i]['comment']; 1007 } 1008 } 1009 1010 $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment'); 1011 foreach ($CommentsChunkNames as $key => $value) { 1012 if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) { 1013 $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data']; 1014 } 1015 } 1016 /* 1017 if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) { 1018 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); 1019 $getid3_temp = new getID3(); 1020 $getid3_temp->openfile($this->getid3->filename); 1021 $getid3_id3v2 = new getid3_id3v2($getid3_temp); 1022 $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8; 1023 if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) { 1024 $info['id3v2'] = $getid3_temp->info['id3v2']; 1025 } 1026 unset($getid3_temp, $getid3_id3v2); 1027 } 1028 */ 1029 break; 1030 1031 case '8SVX': 1032 $thisfile_audio['bitrate_mode'] = 'cbr'; 1033 $thisfile_audio_dataformat = '8svx'; 1034 $thisfile_audio['bits_per_sample'] = 8; 1035 $thisfile_audio['channels'] = 1; // overridden below, if need be 1036 $info['mime_type'] = 'audio/x-aiff'; 1037 1038 if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) { 1039 $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8; 1040 $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size']; 1041 if ($info['avdataend'] > $info['filesize']) { 1042 $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['BODY'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found'; 1043 } 1044 } 1045 1046 if (isset($thisfile_riff[$RIFFsubtype]['VHDR'][0]['offset'])) { 1047 // shortcut 1048 $thisfile_riff_RIFFsubtype_VHDR_0 = &$thisfile_riff[$RIFFsubtype]['VHDR'][0]; 1049 1050 $thisfile_riff_RIFFsubtype_VHDR_0['oneShotHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 0, 4)); 1051 $thisfile_riff_RIFFsubtype_VHDR_0['repeatHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 4, 4)); 1052 $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerHiCycle'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 8, 4)); 1053 $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 12, 2)); 1054 $thisfile_riff_RIFFsubtype_VHDR_0['ctOctave'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 14, 1)); 1055 $thisfile_riff_RIFFsubtype_VHDR_0['sCompression'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 15, 1)); 1056 $thisfile_riff_RIFFsubtype_VHDR_0['Volume'] = getid3_lib::FixedPoint16_16(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 16, 4)); 1057 1058 $thisfile_audio['sample_rate'] = $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec']; 1059 1060 switch ($thisfile_riff_RIFFsubtype_VHDR_0['sCompression']) { 1061 case 0: 1062 $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)'; 1063 $thisfile_audio['lossless'] = true; 1064 $ActualBitsPerSample = 8; 1065 break; 1066 1067 case 1: 1068 $thisfile_audio['codec'] = 'Fibonacci-delta encoding'; 1069 $thisfile_audio['lossless'] = false; 1070 $ActualBitsPerSample = 4; 1071 break; 1072 1073 default: 1074 $info['warning'][] = 'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"'; 1075 break; 1076 } 1077 } 1078 1079 if (isset($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'])) { 1080 $ChannelsIndex = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'], 0, 4)); 1081 switch ($ChannelsIndex) { 1082 case 6: // Stereo 1083 $thisfile_audio['channels'] = 2; 1084 break; 1085 1086 case 2: // Left channel only 1087 case 4: // Right channel only 1088 $thisfile_audio['channels'] = 1; 1089 break; 1090 1091 default: 1092 $info['warning'][] = 'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"'; 1093 break; 1094 } 1095 1096 } 1097 1098 $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment'); 1099 foreach ($CommentsChunkNames as $key => $value) { 1100 if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) { 1101 $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data']; 1102 } 1103 } 1104 1105 $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $ActualBitsPerSample * $thisfile_audio['channels']; 1106 if (!empty($thisfile_audio['bitrate'])) { 1107 $info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) / ($thisfile_audio['bitrate'] / 8); 1108 } 1109 break; 1110 1111 1112 case 'CDXA': 1113 $info['mime_type'] = 'video/mpeg'; 1114 if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) { 1115 if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, false)) { 1116 $getid3_temp = new getID3(); 1117 $getid3_temp->openfile($this->getid3->filename); 1118 $getid3_mpeg = new getid3_mpeg($getid3_temp); 1119 $getid3_mpeg->Analyze(); 1120 if (empty($getid3_temp->info['error'])) { 1121 $info['audio'] = $getid3_temp->info['audio']; 1122 $info['video'] = $getid3_temp->info['video']; 1123 $info['mpeg'] = $getid3_temp->info['mpeg']; 1124 $info['warning'] = $getid3_temp->info['warning']; 1125 } 1126 unset($getid3_temp, $getid3_mpeg); 1127 } 1128 } 1129 break; 1130 1131 1132 default: 1133 $info['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead'; 1134 unset($info['fileformat']); 1135 break; 1136 } 1137 1138 switch ($RIFFsubtype) { 1139 case 'WAVE': 1140 case 'AIFF': 1141 case 'AIFC': 1142 $ID3v2_key_good = 'id3 '; 1143 $ID3v2_keys_bad = array('ID3 ', 'tag '); 1144 foreach ($ID3v2_keys_bad as $ID3v2_key_bad) { 1145 if (isset($thisfile_riff[$RIFFsubtype][$ID3v2_key_bad]) && !array_key_exists($ID3v2_key_good, $thisfile_riff[$RIFFsubtype])) { 1146 $thisfile_riff[$RIFFsubtype][$ID3v2_key_good] = $thisfile_riff[$RIFFsubtype][$ID3v2_key_bad]; 1147 $info['warning'][] = 'mapping "'.$ID3v2_key_bad.'" chunk to "'.$ID3v2_key_good.'"'; 1148 } 1149 } 1150 1151 if (isset($thisfile_riff[$RIFFsubtype]['id3 '])) { 1152 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); 1153 $getid3_temp = new getID3(); 1154 $getid3_temp->openfile($this->getid3->filename); 1155 $getid3_id3v2 = new getid3_id3v2($getid3_temp); 1156 $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8; 1157 if ($thisfile_riff[$RIFFsubtype]['id3 '][0]['valid'] = $getid3_id3v2->Analyze()) { 1158 $info['id3v2'] = $getid3_temp->info['id3v2']; 1159 } 1160 unset($getid3_temp, $getid3_id3v2); 1161 } 1162 break; 1163 } 1164 1165 if (isset($thisfile_riff_WAVE['DISP']) && is_array($thisfile_riff_WAVE['DISP'])) { 1166 $thisfile_riff['comments']['title'][] = trim(substr($thisfile_riff_WAVE['DISP'][count($thisfile_riff_WAVE['DISP']) - 1]['data'], 4)); 1167 } 1168 if (isset($thisfile_riff_WAVE['INFO']) && is_array($thisfile_riff_WAVE['INFO'])) { 1169 self::parseComments($thisfile_riff_WAVE['INFO'], $thisfile_riff['comments']); 1170 } 1171 if (isset($thisfile_riff['AVI ']['INFO']) && is_array($thisfile_riff['AVI ']['INFO'])) { 1172 self::parseComments($thisfile_riff['AVI ']['INFO'], $thisfile_riff['comments']); 1173 } 1174 1175 if (empty($thisfile_audio['encoder']) && !empty($info['mpeg']['audio']['LAME']['short_version'])) { 1176 $thisfile_audio['encoder'] = $info['mpeg']['audio']['LAME']['short_version']; 1177 } 1178 1179 if (!isset($info['playtime_seconds'])) { 1180 $info['playtime_seconds'] = 0; 1181 } 1182 if (isset($thisfile_riff_raw['strh'][0]['dwLength']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) { 1183 // needed for >2GB AVIs where 'avih' chunk only lists number of frames in that chunk, not entire movie 1184 $info['playtime_seconds'] = $thisfile_riff_raw['strh'][0]['dwLength'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000); 1185 } elseif (isset($thisfile_riff_raw['avih']['dwTotalFrames']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) { 1186 $info['playtime_seconds'] = $thisfile_riff_raw['avih']['dwTotalFrames'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000); 1187 } 1188 1189 if ($info['playtime_seconds'] > 0) { 1190 if (isset($thisfile_riff_audio) && isset($thisfile_riff_video)) { 1191 1192 if (!isset($info['bitrate'])) { 1193 $info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8); 1194 } 1195 1196 } elseif (isset($thisfile_riff_audio) && !isset($thisfile_riff_video)) { 1197 1198 if (!isset($thisfile_audio['bitrate'])) { 1199 $thisfile_audio['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8); 1200 } 1201 1202 } elseif (!isset($thisfile_riff_audio) && isset($thisfile_riff_video)) { 1203 1204 if (!isset($thisfile_video['bitrate'])) { 1205 $thisfile_video['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8); 1206 } 1207 1208 } 1209 } 1210 1211 1212 if (isset($thisfile_riff_video) && isset($thisfile_audio['bitrate']) && ($thisfile_audio['bitrate'] > 0) && ($info['playtime_seconds'] > 0)) { 1213 1214 $info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8); 1215 $thisfile_audio['bitrate'] = 0; 1216 $thisfile_video['bitrate'] = $info['bitrate']; 1217 foreach ($thisfile_riff_audio as $channelnumber => $audioinfoarray) { 1218 $thisfile_video['bitrate'] -= $audioinfoarray['bitrate']; 1219 $thisfile_audio['bitrate'] += $audioinfoarray['bitrate']; 1220 } 1221 if ($thisfile_video['bitrate'] <= 0) { 1222 unset($thisfile_video['bitrate']); 1223 } 1224 if ($thisfile_audio['bitrate'] <= 0) { 1225 unset($thisfile_audio['bitrate']); 1226 } 1227 } 1228 1229 if (isset($info['mpeg']['audio'])) { 1230 $thisfile_audio_dataformat = 'mp'.$info['mpeg']['audio']['layer']; 1231 $thisfile_audio['sample_rate'] = $info['mpeg']['audio']['sample_rate']; 1232 $thisfile_audio['channels'] = $info['mpeg']['audio']['channels']; 1233 $thisfile_audio['bitrate'] = $info['mpeg']['audio']['bitrate']; 1234 $thisfile_audio['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']); 1235 if (!empty($info['mpeg']['audio']['codec'])) { 1236 $thisfile_audio['codec'] = $info['mpeg']['audio']['codec'].' '.$thisfile_audio['codec']; 1237 } 1238 if (!empty($thisfile_audio['streams'])) { 1239 foreach ($thisfile_audio['streams'] as $streamnumber => $streamdata) { 1240 if ($streamdata['dataformat'] == $thisfile_audio_dataformat) { 1241 $thisfile_audio['streams'][$streamnumber]['sample_rate'] = $thisfile_audio['sample_rate']; 1242 $thisfile_audio['streams'][$streamnumber]['channels'] = $thisfile_audio['channels']; 1243 $thisfile_audio['streams'][$streamnumber]['bitrate'] = $thisfile_audio['bitrate']; 1244 $thisfile_audio['streams'][$streamnumber]['bitrate_mode'] = $thisfile_audio['bitrate_mode']; 1245 $thisfile_audio['streams'][$streamnumber]['codec'] = $thisfile_audio['codec']; 1246 } 1247 } 1248 } 1249 $getid3_mp3 = new getid3_mp3($this->getid3); 1250 $thisfile_audio['encoder_options'] = $getid3_mp3->GuessEncoderOptions(); 1251 unset($getid3_mp3); 1252 } 1253 1254 1255 if (!empty($thisfile_riff_raw['fmt ']['wBitsPerSample']) && ($thisfile_riff_raw['fmt ']['wBitsPerSample'] > 0)) { 1256 switch ($thisfile_audio_dataformat) { 1257 case 'ac3': 1258 // ignore bits_per_sample 1259 break; 1260 1261 default: 1262 $thisfile_audio['bits_per_sample'] = $thisfile_riff_raw['fmt ']['wBitsPerSample']; 1263 break; 1264 } 1265 } 1266 1267 1268 if (empty($thisfile_riff_raw)) { 1269 unset($thisfile_riff['raw']); 1270 } 1271 if (empty($thisfile_riff_audio)) { 1272 unset($thisfile_riff['audio']); 1273 } 1274 if (empty($thisfile_riff_video)) { 1275 unset($thisfile_riff['video']); 1276 } 1277 1278 return true; 1279 } 1280 1281 public function ParseRIFF($startoffset, $maxoffset) { 1282 $info = &$this->getid3->info; 1283 1284 $RIFFchunk = false; 1285 $FoundAllChunksWeNeed = false; 1286 1287 try { 1288 $this->fseek($startoffset); 1289 $maxoffset = min($maxoffset, $info['avdataend']); 1290 while ($this->ftell() < $maxoffset) { 1291 $chunknamesize = $this->fread(8); 1292 //$chunkname = substr($chunknamesize, 0, 4); 1293 $chunkname = str_replace("\x00", '_', substr($chunknamesize, 0, 4)); // note: chunk names of 4 null bytes do appear to be legal (has been observed inside INFO and PRMI chunks, for example), but makes traversing array keys more difficult 1294 $chunksize = $this->EitherEndian2Int(substr($chunknamesize, 4, 4)); 1295 //if (strlen(trim($chunkname, "\x00")) < 4) { 1296 if (strlen($chunkname) < 4) { 1297 $this->error('Expecting chunk name at offset '.($this->ftell() - 8).' but found nothing. Aborting RIFF parsing.'); 1298 break; 1299 } 1300 if (($chunksize == 0) && ($chunkname != 'JUNK')) { 1301 $this->warning('Chunk ('.$chunkname.') size at offset '.($this->ftell() - 4).' is zero. Aborting RIFF parsing.'); 1302 break; 1303 } 1304 if (($chunksize % 2) != 0) { 1305 // all structures are packed on word boundaries 1306 $chunksize++; 1307 } 1308 1309 switch ($chunkname) { 1310 case 'LIST': 1311 $listname = $this->fread(4); 1312 if (preg_match('#^(movi|rec )$#i', $listname)) { 1313 $RIFFchunk[$listname]['offset'] = $this->ftell() - 4; 1314 $RIFFchunk[$listname]['size'] = $chunksize; 1315 1316 if (!$FoundAllChunksWeNeed) { 1317 $WhereWeWere = $this->ftell(); 1318 $AudioChunkHeader = $this->fread(12); 1319 $AudioChunkStreamNum = substr($AudioChunkHeader, 0, 2); 1320 $AudioChunkStreamType = substr($AudioChunkHeader, 2, 2); 1321 $AudioChunkSize = getid3_lib::LittleEndian2Int(substr($AudioChunkHeader, 4, 4)); 1322 1323 if ($AudioChunkStreamType == 'wb') { 1324 $FirstFourBytes = substr($AudioChunkHeader, 8, 4); 1325 if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) { 1326 // MP3 1327 if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) { 1328 $getid3_temp = new getID3(); 1329 $getid3_temp->openfile($this->getid3->filename); 1330 $getid3_temp->info['avdataoffset'] = $this->ftell() - 4; 1331 $getid3_temp->info['avdataend'] = $this->ftell() + $AudioChunkSize; 1332 $getid3_mp3 = new getid3_mp3($getid3_temp); 1333 $getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false); 1334 if (isset($getid3_temp->info['mpeg']['audio'])) { 1335 $info['mpeg']['audio'] = $getid3_temp->info['mpeg']['audio']; 1336 $info['audio'] = $getid3_temp->info['audio']; 1337 $info['audio']['dataformat'] = 'mp'.$info['mpeg']['audio']['layer']; 1338 $info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate']; 1339 $info['audio']['channels'] = $info['mpeg']['audio']['channels']; 1340 $info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate']; 1341 $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']); 1342 //$info['bitrate'] = $info['audio']['bitrate']; 1343 } 1344 unset($getid3_temp, $getid3_mp3); 1345 } 1346 1347 } elseif (strpos($FirstFourBytes, getid3_ac3::syncword) === 0) { 1348 1349 // AC3 1350 $getid3_temp = new getID3(); 1351 $getid3_temp->openfile($this->getid3->filename); 1352 $getid3_temp->info['avdataoffset'] = $this->ftell() - 4; 1353 $getid3_temp->info['avdataend'] = $this->ftell() + $AudioChunkSize; 1354 $getid3_ac3 = new getid3_ac3($getid3_temp); 1355 $getid3_ac3->Analyze(); 1356 if (empty($getid3_temp->info['error'])) { 1357 $info['audio'] = $getid3_temp->info['audio']; 1358 $info['ac3'] = $getid3_temp->info['ac3']; 1359 if (!empty($getid3_temp->info['warning'])) { 1360 foreach ($getid3_temp->info['warning'] as $key => $value) { 1361 $info['warning'][] = $value; 1362 } 1363 } 1364 } 1365 unset($getid3_temp, $getid3_ac3); 1366 } 1367 } 1368 $FoundAllChunksWeNeed = true; 1369 $this->fseek($WhereWeWere); 1370 } 1371 $this->fseek($chunksize - 4, SEEK_CUR); 1372 1373 } else { 1374 1375 if (!isset($RIFFchunk[$listname])) { 1376 $RIFFchunk[$listname] = array(); 1377 } 1378 $LISTchunkParent = $listname; 1379 $LISTchunkMaxOffset = $this->ftell() - 4 + $chunksize; 1380 if ($parsedChunk = $this->ParseRIFF($this->ftell(), $LISTchunkMaxOffset)) { 1381 $RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk); 1382 } 1383 1384 } 1385 break; 1386 1387 default: 1388 if (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname)) { 1389 $this->fseek($chunksize, SEEK_CUR); 1390 break; 1391 } 1392 $thisindex = 0; 1393 if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) { 1394 $thisindex = count($RIFFchunk[$chunkname]); 1395 } 1396 $RIFFchunk[$chunkname][$thisindex]['offset'] = $this->ftell() - 8; 1397 $RIFFchunk[$chunkname][$thisindex]['size'] = $chunksize; 1398 switch ($chunkname) { 1399 case 'data': 1400 $info['avdataoffset'] = $this->ftell(); 1401 $info['avdataend'] = $info['avdataoffset'] + $chunksize; 1402 1403 $testData = $this->fread(36); 1404 if ($testData === '') { 1405 break; 1406 } 1407 if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($testData, 0, 4))) { 1408 1409 // Probably is MP3 data 1410 if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) { 1411 $getid3_temp = new getID3(); 1412 $getid3_temp->openfile($this->getid3->filename); 1413 $getid3_temp->info['avdataoffset'] = $info['avdataoffset']; 1414 $getid3_temp->info['avdataend'] = $info['avdataend']; 1415 $getid3_mp3 = new getid3_mp3($getid3_temp); 1416 $getid3_mp3->getOnlyMPEGaudioInfo($info['avdataoffset'], false); 1417 if (empty($getid3_temp->info['error'])) { 1418 $info['audio'] = $getid3_temp->info['audio']; 1419 $info['mpeg'] = $getid3_temp->info['mpeg']; 1420 } 1421 unset($getid3_temp, $getid3_mp3); 1422 } 1423 1424 } elseif (($isRegularAC3 = (substr($testData, 0, 2) == getid3_ac3::syncword)) || substr($testData, 8, 2) == strrev(getid3_ac3::syncword)) { 1425 1426 // This is probably AC-3 data 1427 $getid3_temp = new getID3(); 1428 if ($isRegularAC3) { 1429 $getid3_temp->openfile($this->getid3->filename); 1430 $getid3_temp->info['avdataoffset'] = $info['avdataoffset']; 1431 $getid3_temp->info['avdataend'] = $info['avdataend']; 1432 } 1433 $getid3_ac3 = new getid3_ac3($getid3_temp); 1434 if ($isRegularAC3) { 1435 $getid3_ac3->Analyze(); 1436 } else { 1437 // Dolby Digital WAV 1438 // AC-3 content, but not encoded in same format as normal AC-3 file 1439 // For one thing, byte order is swapped 1440 $ac3_data = ''; 1441 for ($i = 0; $i < 28; $i += 2) { 1442 $ac3_data .= substr($testData, 8 + $i + 1, 1); 1443 $ac3_data .= substr($testData, 8 + $i + 0, 1); 1444 } 1445 $getid3_ac3->AnalyzeString($ac3_data); 1446 } 1447 1448 if (empty($getid3_temp->info['error'])) { 1449 $info['audio'] = $getid3_temp->info['audio']; 1450 $info['ac3'] = $getid3_temp->info['ac3']; 1451 if (!empty($getid3_temp->info['warning'])) { 1452 foreach ($getid3_temp->info['warning'] as $newerror) { 1453 $this->warning('getid3_ac3() says: ['.$newerror.']'); 1454 } 1455 } 1456 } 1457 unset($getid3_temp, $getid3_ac3); 1458 1459 } elseif (preg_match('/^('.implode('|', array_map('preg_quote', getid3_dts::$syncwords)).')/', $testData)) { 1460 1461 // This is probably DTS data 1462 $getid3_temp = new getID3(); 1463 $getid3_temp->openfile($this->getid3->filename); 1464 $getid3_temp->info['avdataoffset'] = $info['avdataoffset']; 1465 $getid3_dts = new getid3_dts($getid3_temp); 1466 $getid3_dts->Analyze(); 1467 if (empty($getid3_temp->info['error'])) { 1468 $info['audio'] = $getid3_temp->info['audio']; 1469 $info['dts'] = $getid3_temp->info['dts']; 1470 $info['playtime_seconds'] = $getid3_temp->info['playtime_seconds']; // may not match RIFF calculations since DTS-WAV often used 14/16 bit-word packing 1471 if (!empty($getid3_temp->info['warning'])) { 1472 foreach ($getid3_temp->info['warning'] as $newerror) { 1473 $this->warning('getid3_dts() says: ['.$newerror.']'); 1474 } 1475 } 1476 } 1477 1478 unset($getid3_temp, $getid3_dts); 1479 1480 } elseif (substr($testData, 0, 4) == 'wvpk') { 1481 1482 // This is WavPack data 1483 $info['wavpack']['offset'] = $info['avdataoffset']; 1484 $info['wavpack']['size'] = getid3_lib::LittleEndian2Int(substr($testData, 4, 4)); 1485 $this->parseWavPackHeader(substr($testData, 8, 28)); 1486 1487 } else { 1488 // This is some other kind of data (quite possibly just PCM) 1489 // do nothing special, just skip it 1490 } 1491 $nextoffset = $info['avdataend']; 1492 $this->fseek($nextoffset); 1493 break; 1494 1495 case 'iXML': 1496 case 'bext': 1497 case 'cart': 1498 case 'fmt ': 1499 case 'strh': 1500 case 'strf': 1501 case 'indx': 1502 case 'MEXT': 1503 case 'DISP': 1504 // always read data in 1505 case 'JUNK': 1506 // should be: never read data in 1507 // but some programs write their version strings in a JUNK chunk (e.g. VirtualDub, AVIdemux, etc) 1508 if ($chunksize < 1048576) { 1509 if ($chunksize > 0) { 1510 $RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize); 1511 if ($chunkname == 'JUNK') { 1512 if (preg_match('#^([\\x20-\\x7F]+)#', $RIFFchunk[$chunkname][$thisindex]['data'], $matches)) { 1513 // only keep text characters [chr(32)-chr(127)] 1514 $info['riff']['comments']['junk'][] = trim($matches[1]); 1515 } 1516 // but if nothing there, ignore 1517 // remove the key in either case 1518 unset($RIFFchunk[$chunkname][$thisindex]['data']); 1519 } 1520 } 1521 } else { 1522 $this->warning('Chunk "'.$chunkname.'" at offset '.$this->ftell().' is unexpectedly larger than 1MB (claims to be '.number_format($chunksize).' bytes), skipping data'); 1523 $this->fseek($chunksize, SEEK_CUR); 1524 } 1525 break; 1526 1527 //case 'IDVX': 1528 // $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunksize)); 1529 // break; 1530 1531 default: 1532 if (!empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) { 1533 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset']; 1534 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size'] = $RIFFchunk[$chunkname][$thisindex]['size']; 1535 unset($RIFFchunk[$chunkname][$thisindex]['offset']); 1536 unset($RIFFchunk[$chunkname][$thisindex]['size']); 1537 if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) { 1538 unset($RIFFchunk[$chunkname][$thisindex]); 1539 } 1540 if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) { 1541 unset($RIFFchunk[$chunkname]); 1542 } 1543 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['data'] = $this->fread($chunksize); 1544 } elseif ($chunksize < 2048) { 1545 // only read data in if smaller than 2kB 1546 $RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize); 1547 } else { 1548 $this->fseek($chunksize, SEEK_CUR); 1549 } 1550 break; 1551 } 1552 break; 1553 } 1554 } 1555 1556 } catch (getid3_exception $e) { 1557 if ($e->getCode() == 10) { 1558 $this->warning('RIFF parser: '.$e->getMessage()); 1559 } else { 1560 throw $e; 1561 } 1562 } 1563 1564 return $RIFFchunk; 1565 } 1566 1567 public function ParseRIFFdata(&$RIFFdata) { 1568 $info = &$this->getid3->info; 1569 if ($RIFFdata) { 1570 $tempfile = tempnam(GETID3_TEMP_DIR, 'getID3'); 1571 $fp_temp = fopen($tempfile, 'wb'); 1572 $RIFFdataLength = strlen($RIFFdata); 1573 $NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4); 1574 for ($i = 0; $i < 4; $i++) { 1575 $RIFFdata[($i + 4)] = $NewLengthString[$i]; 1576 } 1577 fwrite($fp_temp, $RIFFdata); 1578 fclose($fp_temp); 1579 1580 $getid3_temp = new getID3(); 1581 $getid3_temp->openfile($tempfile); 1582 $getid3_temp->info['filesize'] = $RIFFdataLength; 1583 $getid3_temp->info['filenamepath'] = $info['filenamepath']; 1584 $getid3_temp->info['tags'] = $info['tags']; 1585 $getid3_temp->info['warning'] = $info['warning']; 1586 $getid3_temp->info['error'] = $info['error']; 1587 $getid3_temp->info['comments'] = $info['comments']; 1588 $getid3_temp->info['audio'] = (isset($info['audio']) ? $info['audio'] : array()); 1589 $getid3_temp->info['video'] = (isset($info['video']) ? $info['video'] : array()); 1590 $getid3_riff = new getid3_riff($getid3_temp); 1591 $getid3_riff->Analyze(); 1592 1593 $info['riff'] = $getid3_temp->info['riff']; 1594 $info['warning'] = $getid3_temp->info['warning']; 1595 $info['error'] = $getid3_temp->info['error']; 1596 $info['tags'] = $getid3_temp->info['tags']; 1597 $info['comments'] = $getid3_temp->info['comments']; 1598 unset($getid3_riff, $getid3_temp); 1599 unlink($tempfile); 1600 } 1601 return false; 1602 } 1603 1604 public static function parseComments(&$RIFFinfoArray, &$CommentsTargetArray) { 1605 $RIFFinfoKeyLookup = array( 1606 'IARL'=>'archivallocation', 1607 'IART'=>'artist', 1608 'ICDS'=>'costumedesigner', 1609 'ICMS'=>'commissionedby', 1610 'ICMT'=>'comment', 1611 'ICNT'=>'country', 1612 'ICOP'=>'copyright', 1613 'ICRD'=>'creationdate', 1614 'IDIM'=>'dimensions', 1615 'IDIT'=>'digitizationdate', 1616 'IDPI'=>'resolution', 1617 'IDST'=>'distributor', 1618 'IEDT'=>'editor', 1619 'IENG'=>'engineers', 1620 'IFRM'=>'accountofparts', 1621 'IGNR'=>'genre', 1622 'IKEY'=>'keywords', 1623 'ILGT'=>'lightness', 1624 'ILNG'=>'language', 1625 'IMED'=>'orignalmedium', 1626 'IMUS'=>'composer', 1627 'INAM'=>'title', 1628 'IPDS'=>'productiondesigner', 1629 'IPLT'=>'palette', 1630 'IPRD'=>'product', 1631 'IPRO'=>'producer', 1632 'IPRT'=>'part', 1633 'IRTD'=>'rating', 1634 'ISBJ'=>'subject', 1635 'ISFT'=>'software', 1636 'ISGN'=>'secondarygenre', 1637 'ISHP'=>'sharpness', 1638 'ISRC'=>'sourcesupplier', 1639 'ISRF'=>'digitizationsource', 1640 'ISTD'=>'productionstudio', 1641 'ISTR'=>'starring', 1642 'ITCH'=>'encoded_by', 1643 'IWEB'=>'url', 1644 'IWRI'=>'writer', 1645 '____'=>'comment', 1646 ); 1647 foreach ($RIFFinfoKeyLookup as $key => $value) { 1648 if (isset($RIFFinfoArray[$key])) { 1649 foreach ($RIFFinfoArray[$key] as $commentid => $commentdata) { 1650 if (trim($commentdata['data']) != '') { 1651 if (isset($CommentsTargetArray[$value])) { 1652 $CommentsTargetArray[$value][] = trim($commentdata['data']); 1653 } else { 1654 $CommentsTargetArray[$value] = array(trim($commentdata['data'])); 1655 } 1656 } 1657 } 1658 } 1659 } 1660 return true; 1661 } 1662 1663 public static function parseWAVEFORMATex($WaveFormatExData) { 1664 // shortcut 1665 $WaveFormatEx['raw'] = array(); 1666 $WaveFormatEx_raw = &$WaveFormatEx['raw']; 1667 1668 $WaveFormatEx_raw['wFormatTag'] = substr($WaveFormatExData, 0, 2); 1669 $WaveFormatEx_raw['nChannels'] = substr($WaveFormatExData, 2, 2); 1670 $WaveFormatEx_raw['nSamplesPerSec'] = substr($WaveFormatExData, 4, 4); 1671 $WaveFormatEx_raw['nAvgBytesPerSec'] = substr($WaveFormatExData, 8, 4); 1672 $WaveFormatEx_raw['nBlockAlign'] = substr($WaveFormatExData, 12, 2); 1673 $WaveFormatEx_raw['wBitsPerSample'] = substr($WaveFormatExData, 14, 2); 1674 if (strlen($WaveFormatExData) > 16) { 1675 $WaveFormatEx_raw['cbSize'] = substr($WaveFormatExData, 16, 2); 1676 } 1677 $WaveFormatEx_raw = array_map('getid3_lib::LittleEndian2Int', $WaveFormatEx_raw); 1678 1679 $WaveFormatEx['codec'] = self::wFormatTagLookup($WaveFormatEx_raw['wFormatTag']); 1680 $WaveFormatEx['channels'] = $WaveFormatEx_raw['nChannels']; 1681 $WaveFormatEx['sample_rate'] = $WaveFormatEx_raw['nSamplesPerSec']; 1682 $WaveFormatEx['bitrate'] = $WaveFormatEx_raw['nAvgBytesPerSec'] * 8; 1683 $WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample']; 1684 1685 return $WaveFormatEx; 1686 } 1687 1688 public function parseWavPackHeader($WavPackChunkData) { 1689 // typedef struct { 1690 // char ckID [4]; 1691 // long ckSize; 1692 // short version; 1693 // short bits; // added for version 2.00 1694 // short flags, shift; // added for version 3.00 1695 // long total_samples, crc, crc2; 1696 // char extension [4], extra_bc, extras [3]; 1697 // } WavpackHeader; 1698 1699 // shortcut 1700 $info = &$this->getid3->info; 1701 $info['wavpack'] = array(); 1702 $thisfile_wavpack = &$info['wavpack']; 1703 1704 $thisfile_wavpack['version'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 0, 2)); 1705 if ($thisfile_wavpack['version'] >= 2) { 1706 $thisfile_wavpack['bits'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 2, 2)); 1707 } 1708 if ($thisfile_wavpack['version'] >= 3) { 1709 $thisfile_wavpack['flags_raw'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 4, 2)); 1710 $thisfile_wavpack['shift'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 6, 2)); 1711 $thisfile_wavpack['total_samples'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 8, 4)); 1712 $thisfile_wavpack['crc1'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 12, 4)); 1713 $thisfile_wavpack['crc2'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 16, 4)); 1714 $thisfile_wavpack['extension'] = substr($WavPackChunkData, 20, 4); 1715 $thisfile_wavpack['extra_bc'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 24, 1)); 1716 for ($i = 0; $i <= 2; $i++) { 1717 $thisfile_wavpack['extras'][] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 25 + $i, 1)); 1718 } 1719 1720 // shortcut 1721 $thisfile_wavpack['flags'] = array(); 1722 $thisfile_wavpack_flags = &$thisfile_wavpack['flags']; 1723 1724 $thisfile_wavpack_flags['mono'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000001); 1725 $thisfile_wavpack_flags['fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000002); 1726 $thisfile_wavpack_flags['raw_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000004); 1727 $thisfile_wavpack_flags['calc_noise'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000008); 1728 $thisfile_wavpack_flags['high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000010); 1729 $thisfile_wavpack_flags['3_byte_samples'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000020); 1730 $thisfile_wavpack_flags['over_20_bits'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000040); 1731 $thisfile_wavpack_flags['use_wvc'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000080); 1732 $thisfile_wavpack_flags['noiseshaping'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000100); 1733 $thisfile_wavpack_flags['very_fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000200); 1734 $thisfile_wavpack_flags['new_high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000400); 1735 $thisfile_wavpack_flags['cancel_extreme'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000800); 1736 $thisfile_wavpack_flags['cross_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x001000); 1737 $thisfile_wavpack_flags['new_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x002000); 1738 $thisfile_wavpack_flags['joint_stereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x004000); 1739 $thisfile_wavpack_flags['extra_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x008000); 1740 $thisfile_wavpack_flags['override_noiseshape'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x010000); 1741 $thisfile_wavpack_flags['override_jointstereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x020000); 1742 $thisfile_wavpack_flags['copy_source_filetime'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x040000); 1743 $thisfile_wavpack_flags['create_exe'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x080000); 1744 } 1745 1746 return true; 1747 } 1748 1749 public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) { 1750 1751 $parsed['biSize'] = substr($BITMAPINFOHEADER, 0, 4); // number of bytes required by the BITMAPINFOHEADER structure 1752 $parsed['biWidth'] = substr($BITMAPINFOHEADER, 4, 4); // width of the bitmap in pixels 1753 $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 1754 $parsed['biPlanes'] = substr($BITMAPINFOHEADER, 12, 2); // number of color planes on the target device. In most cases this value must be set to 1 1755 $parsed['biBitCount'] = substr($BITMAPINFOHEADER, 14, 2); // Specifies the number of bits per pixels 1756 $parsed['biSizeImage'] = substr($BITMAPINFOHEADER, 20, 4); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures) 1757 $parsed['biXPelsPerMeter'] = substr($BITMAPINFOHEADER, 24, 4); // horizontal resolution, in pixels per metre, of the target device 1758 $parsed['biYPelsPerMeter'] = substr($BITMAPINFOHEADER, 28, 4); // vertical resolution, in pixels per metre, of the target device 1759 $parsed['biClrUsed'] = substr($BITMAPINFOHEADER, 32, 4); // actual number of color indices in the color table used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression 1760 $parsed['biClrImportant'] = substr($BITMAPINFOHEADER, 36, 4); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important 1761 $parsed = array_map('getid3_lib::'.($littleEndian ? 'Little' : 'Big').'Endian2Int', $parsed); 1762 1763 $parsed['fourcc'] = substr($BITMAPINFOHEADER, 16, 4); // compression identifier 1764 1765 return $parsed; 1766 } 1767 1768 public static function ParseDIVXTAG($DIVXTAG, $raw=false) { 1769 // structure from "IDivX" source, Form1.frm, by "Greg Frazier of Daemonic Software Group", email: gfrazier@icestorm.net, web: http://dsg.cjb.net/ 1770 // source available at http://files.divx-digest.com/download/c663efe7ef8ad2e90bf4af4d3ea6188a/on0SWN2r/edit/IDivX.zip 1771 // 'Byte Layout: '1111111111111111 1772 // '32 for Movie - 1 '1111111111111111 1773 // '28 for Author - 6 '6666666666666666 1774 // '4 for year - 2 '6666666666662222 1775 // '3 for genre - 3 '7777777777777777 1776 // '48 for Comments - 7 '7777777777777777 1777 // '1 for Rating - 4 '7777777777777777 1778 // '5 for Future Additions - 0 '333400000DIVXTAG 1779 // '128 bytes total 1780 1781 static $DIVXTAGgenre = array( 1782 0 => 'Action', 1783 1 => 'Action/Adventure', 1784 2 => 'Adventure', 1785 3 => 'Adult', 1786 4 => 'Anime', 1787 5 => 'Cartoon', 1788 6 => 'Claymation', 1789 7 => 'Comedy', 1790 8 => 'Commercial', 1791 9 => 'Documentary', 1792 10 => 'Drama', 1793 11 => 'Home Video', 1794 12 => 'Horror', 1795 13 => 'Infomercial', 1796 14 => 'Interactive', 1797 15 => 'Mystery', 1798 16 => 'Music Video', 1799 17 => 'Other', 1800 18 => 'Religion', 1801 19 => 'Sci Fi', 1802 20 => 'Thriller', 1803 21 => 'Western', 1804 ), 1805 $DIVXTAGrating = array( 1806 0 => 'Unrated', 1807 1 => 'G', 1808 2 => 'PG', 1809 3 => 'PG-13', 1810 4 => 'R', 1811 5 => 'NC-17', 1812 ); 1813 1814 $parsed['title'] = trim(substr($DIVXTAG, 0, 32)); 1815 $parsed['artist'] = trim(substr($DIVXTAG, 32, 28)); 1816 $parsed['year'] = intval(trim(substr($DIVXTAG, 60, 4))); 1817 $parsed['comment'] = trim(substr($DIVXTAG, 64, 48)); 1818 $parsed['genre_id'] = intval(trim(substr($DIVXTAG, 112, 3))); 1819 $parsed['rating_id'] = ord(substr($DIVXTAG, 115, 1)); 1820 //$parsed['padding'] = substr($DIVXTAG, 116, 5); // 5-byte null 1821 //$parsed['magic'] = substr($DIVXTAG, 121, 7); // "DIVXTAG" 1822 1823 $parsed['genre'] = (isset($DIVXTAGgenre[$parsed['genre_id']]) ? $DIVXTAGgenre[$parsed['genre_id']] : $parsed['genre_id']); 1824 $parsed['rating'] = (isset($DIVXTAGrating[$parsed['rating_id']]) ? $DIVXTAGrating[$parsed['rating_id']] : $parsed['rating_id']); 1825 1826 if (!$raw) { 1827 unset($parsed['genre_id'], $parsed['rating_id']); 1828 foreach ($parsed as $key => $value) { 1829 if (!$value === '') { 1830 unset($parsed['key']); 1831 } 1832 } 1833 } 1834 1835 foreach ($parsed as $tag => $value) { 1836 $parsed[$tag] = array($value); 1837 } 1838 1839 return $parsed; 1840 } 1841 1842 public static function waveSNDMtagLookup($tagshortname) { 1843 $begin = __LINE__; 1844 1845 /** This is not a comment! 1846 1847 ©kwd keywords 1848 ©BPM bpm 1849 ©trt tracktitle 1850 ©des description 1851 ©gen category 1852 ©fin featuredinstrument 1853 ©LID longid 1854 ©bex bwdescription 1855 ©pub publisher 1856 ©cdt cdtitle 1857 ©alb library 1858 ©com composer 1859 1860 */ 1861 1862 return getid3_lib::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm'); 1863 } 1864 1865 public static function wFormatTagLookup($wFormatTag) { 1866 1867 $begin = __LINE__; 1868 1869 /** This is not a comment! 1870 1871 0x0000 Microsoft Unknown Wave Format 1872 0x0001 Pulse Code Modulation (PCM) 1873 0x0002 Microsoft ADPCM 1874 0x0003 IEEE Float 1875 0x0004 Compaq Computer VSELP 1876 0x0005 IBM CVSD 1877 0x0006 Microsoft A-Law 1878 0x0007 Microsoft mu-Law 1879 0x0008 Microsoft DTS 1880 0x0010 OKI ADPCM 1881 0x0011 Intel DVI/IMA ADPCM 1882 0x0012 Videologic MediaSpace ADPCM 1883 0x0013 Sierra Semiconductor ADPCM 1884 0x0014 Antex Electronics G.723 ADPCM 1885 0x0015 DSP Solutions DigiSTD 1886 0x0016 DSP Solutions DigiFIX 1887 0x0017 Dialogic OKI ADPCM 1888 0x0018 MediaVision ADPCM 1889 0x0019 Hewlett-Packard CU 1890 0x0020 Yamaha ADPCM 1891 0x0021 Speech Compression Sonarc 1892 0x0022 DSP Group TrueSpeech 1893 0x0023 Echo Speech EchoSC1 1894 0x0024 Audiofile AF36 1895 0x0025 Audio Processing Technology APTX 1896 0x0026 AudioFile AF10 1897 0x0027 Prosody 1612 1898 0x0028 LRC 1899 0x0030 Dolby AC2 1900 0x0031 Microsoft GSM 6.10 1901 0x0032 MSNAudio 1902 0x0033 Antex Electronics ADPCME 1903 0x0034 Control Resources VQLPC 1904 0x0035 DSP Solutions DigiREAL 1905 0x0036 DSP Solutions DigiADPCM 1906 0x0037 Control Resources CR10 1907 0x0038 Natural MicroSystems VBXADPCM 1908 0x0039 Crystal Semiconductor IMA ADPCM 1909 0x003A EchoSC3 1910 0x003B Rockwell ADPCM 1911 0x003C Rockwell Digit LK 1912 0x003D Xebec 1913 0x0040 Antex Electronics G.721 ADPCM 1914 0x0041 G.728 CELP 1915 0x0042 MSG723 1916 0x0050 MPEG Layer-2 or Layer-1 1917 0x0052 RT24 1918 0x0053 PAC 1919 0x0055 MPEG Layer-3 1920 0x0059 Lucent G.723 1921 0x0060 Cirrus 1922 0x0061 ESPCM 1923 0x0062 Voxware 1924 0x0063 Canopus Atrac 1925 0x0064 G.726 ADPCM 1926 0x0065 G.722 ADPCM 1927 0x0066 DSAT 1928 0x0067 DSAT Display 1929 0x0069 Voxware Byte Aligned 1930 0x0070 Voxware AC8 1931 0x0071 Voxware AC10 1932 0x0072 Voxware AC16 1933 0x0073 Voxware AC20 1934 0x0074 Voxware MetaVoice 1935 0x0075 Voxware MetaSound 1936 0x0076 Voxware RT29HW 1937 0x0077 Voxware VR12 1938 0x0078 Voxware VR18 1939 0x0079 Voxware TQ40 1940 0x0080 Softsound 1941 0x0081 Voxware TQ60 1942 0x0082 MSRT24 1943 0x0083 G.729A 1944 0x0084 MVI MV12 1945 0x0085 DF G.726 1946 0x0086 DF GSM610 1947 0x0088 ISIAudio 1948 0x0089 Onlive 1949 0x0091 SBC24 1950 0x0092 Dolby AC3 SPDIF 1951 0x0093 MediaSonic G.723 1952 0x0094 Aculab PLC Prosody 8kbps 1953 0x0097 ZyXEL ADPCM 1954 0x0098 Philips LPCBB 1955 0x0099 Packed 1956 0x00FF AAC 1957 0x0100 Rhetorex ADPCM 1958 0x0101 IBM mu-law 1959 0x0102 IBM A-law 1960 0x0103 IBM AVC Adaptive Differential Pulse Code Modulation (ADPCM) 1961 0x0111 Vivo G.723 1962 0x0112 Vivo Siren 1963 0x0123 Digital G.723 1964 0x0125 Sanyo LD ADPCM 1965 0x0130 Sipro Lab Telecom ACELP NET 1966 0x0131 Sipro Lab Telecom ACELP 4800 1967 0x0132 Sipro Lab Telecom ACELP 8V3 1968 0x0133 Sipro Lab Telecom G.729 1969 0x0134 Sipro Lab Telecom G.729A 1970 0x0135 Sipro Lab Telecom Kelvin 1971 0x0140 Windows Media Video V8 1972 0x0150 Qualcomm PureVoice 1973 0x0151 Qualcomm HalfRate 1974 0x0155 Ring Zero Systems TUB GSM 1975 0x0160 Microsoft Audio 1 1976 0x0161 Windows Media Audio V7 / V8 / V9 1977 0x0162 Windows Media Audio Professional V9 1978 0x0163 Windows Media Audio Lossless V9 1979 0x0200 Creative Labs ADPCM 1980 0x0202 Creative Labs Fastspeech8 1981 0x0203 Creative Labs Fastspeech10 1982 0x0210 UHER Informatic GmbH ADPCM 1983 0x0220 Quarterdeck 1984 0x0230 I-link Worldwide VC 1985 0x0240 Aureal RAW Sport 1986 0x0250 Interactive Products HSX 1987 0x0251 Interactive Products RPELP 1988 0x0260 Consistent Software CS2 1989 0x0270 Sony SCX 1990 0x0300 Fujitsu FM Towns Snd 1991 0x0400 BTV Digital 1992 0x0401 Intel Music Coder 1993 0x0450 QDesign Music 1994 0x0680 VME VMPCM 1995 0x0681 AT&T Labs TPC 1996 0x08AE ClearJump LiteWave 1997 0x1000 Olivetti GSM 1998 0x1001 Olivetti ADPCM 1999 0x1002 Olivetti CELP 2000 0x1003 Olivetti SBC 2001 0x1004 Olivetti OPR 2002 0x1100 Lernout & Hauspie Codec (0x1100) 2003 0x1101 Lernout & Hauspie CELP Codec (0x1101) 2004 0x1102 Lernout & Hauspie SBC Codec (0x1102) 2005 0x1103 Lernout & Hauspie SBC Codec (0x1103) 2006 0x1104 Lernout & Hauspie SBC Codec (0x1104) 2007 0x1400 Norris 2008 0x1401 AT&T ISIAudio 2009 0x1500 Soundspace Music Compression 2010 0x181C VoxWare RT24 Speech 2011 0x1FC4 NCT Soft ALF2CD (www.nctsoft.com) 2012 0x2000 Dolby AC3 2013 0x2001 Dolby DTS 2014 0x2002 WAVE_FORMAT_14_4 2015 0x2003 WAVE_FORMAT_28_8 2016 0x2004 WAVE_FORMAT_COOK 2017 0x2005 WAVE_FORMAT_DNET 2018 0x674F Ogg Vorbis 1 2019 0x6750 Ogg Vorbis 2 2020 0x6751 Ogg Vorbis 3 2021 0x676F Ogg Vorbis 1+ 2022 0x6770 Ogg Vorbis 2+ 2023 0x6771 Ogg Vorbis 3+ 2024 0x7A21 GSM-AMR (CBR, no SID) 2025 0x7A22 GSM-AMR (VBR, including SID) 2026 0xFFFE WAVE_FORMAT_EXTENSIBLE 2027 0xFFFF WAVE_FORMAT_DEVELOPMENT 2028 2029 */ 2030 2031 return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag'); 2032 } 2033 2034 public static function fourccLookup($fourcc) { 2035 2036 $begin = __LINE__; 2037 2038 /** This is not a comment! 2039 2040 swot http://developer.apple.com/qa/snd/snd07.html 2041 ____ No Codec (____) 2042 _BIT BI_BITFIELDS (Raw RGB) 2043 _JPG JPEG compressed 2044 _PNG PNG compressed W3C/ISO/IEC (RFC-2083) 2045 _RAW Full Frames (Uncompressed) 2046 _RGB Raw RGB Bitmap 2047 _RL4 RLE 4bpp RGB 2048 _RL8 RLE 8bpp RGB 2049 3IV1 3ivx MPEG-4 v1 2050 3IV2 3ivx MPEG-4 v2 2051 3IVX 3ivx MPEG-4 2052 AASC Autodesk Animator 2053 ABYR Kensington ?ABYR? 2054 AEMI Array Microsystems VideoONE MPEG1-I Capture 2055 AFLC Autodesk Animator FLC 2056 AFLI Autodesk Animator FLI 2057 AMPG Array Microsystems VideoONE MPEG 2058 ANIM Intel RDX (ANIM) 2059 AP41 AngelPotion Definitive 2060 ASV1 Asus Video v1 2061 ASV2 Asus Video v2 2062 ASVX Asus Video 2.0 (audio) 2063 AUR2 AuraVision Aura 2 Codec - YUV 4:2:2 2064 AURA AuraVision Aura 1 Codec - YUV 4:1:1 2065 AVDJ Independent JPEG Group\'s codec (AVDJ) 2066 AVRN Independent JPEG Group\'s codec (AVRN) 2067 AYUV 4:4:4 YUV (AYUV) 2068 AZPR Quicktime Apple Video (AZPR) 2069 BGR Raw RGB32 2070 BLZ0 Blizzard DivX MPEG-4 2071 BTVC Conexant Composite Video 2072 BINK RAD Game Tools Bink Video 2073 BT20 Conexant Prosumer Video 2074 BTCV Conexant Composite Video Codec 2075 BW10 Data Translation Broadway MPEG Capture 2076 CC12 Intel YUV12 2077 CDVC Canopus DV 2078 CFCC Digital Processing Systems DPS Perception 2079 CGDI Microsoft Office 97 Camcorder Video 2080 CHAM Winnov Caviara Champagne 2081 CJPG Creative WebCam JPEG 2082 CLJR Cirrus Logic YUV 4:1:1 2083 CMYK Common Data Format in Printing (Colorgraph) 2084 CPLA Weitek 4:2:0 YUV Planar 2085 CRAM Microsoft Video 1 (CRAM) 2086 cvid Radius Cinepak 2087 CVID Radius Cinepak 2088 CWLT Microsoft Color WLT DIB 2089 CYUV Creative Labs YUV 2090 CYUY ATI YUV 2091 D261 H.261 2092 D263 H.263 2093 DIB Device Independent Bitmap 2094 DIV1 FFmpeg OpenDivX 2095 DIV2 Microsoft MPEG-4 v1/v2 2096 DIV3 DivX ;-) MPEG-4 v3.x Low-Motion 2097 DIV4 DivX ;-) MPEG-4 v3.x Fast-Motion 2098 DIV5 DivX MPEG-4 v5.x 2099 DIV6 DivX ;-) (MS MPEG-4 v3.x) 2100 DIVX DivX MPEG-4 v4 (OpenDivX / Project Mayo) 2101 divx DivX MPEG-4 2102 DMB1 Matrox Rainbow Runner hardware MJPEG 2103 DMB2 Paradigm MJPEG 2104 DSVD ?DSVD? 2105 DUCK Duck TrueMotion 1.0 2106 DPS0 DPS/Leitch Reality Motion JPEG 2107 DPSC DPS/Leitch PAR Motion JPEG 2108 DV25 Matrox DVCPRO codec 2109 DV50 Matrox DVCPRO50 codec 2110 DVC IEC 61834 and SMPTE 314M (DVC/DV Video) 2111 DVCP IEC 61834 and SMPTE 314M (DVC/DV Video) 2112 DVHD IEC Standard DV 1125 lines @ 30fps / 1250 lines @ 25fps 2113 DVMA Darim Vision DVMPEG (dummy for MPEG compressor) (www.darvision.com) 2114 DVSL IEC Standard DV compressed in SD (SDL) 2115 DVAN ?DVAN? 2116 DVE2 InSoft DVE-2 Videoconferencing 2117 dvsd IEC 61834 and SMPTE 314M DVC/DV Video 2118 DVSD IEC 61834 and SMPTE 314M DVC/DV Video 2119 DVX1 Lucent DVX1000SP Video Decoder 2120 DVX2 Lucent DVX2000S Video Decoder 2121 DVX3 Lucent DVX3000S Video Decoder 2122 DX50 DivX v5 2123 DXT1 Microsoft DirectX Compressed Texture (DXT1) 2124 DXT2 Microsoft DirectX Compressed Texture (DXT2) 2125 DXT3 Microsoft DirectX Compressed Texture (DXT3) 2126 DXT4 Microsoft DirectX Compressed Texture (DXT4) 2127 DXT5 Microsoft DirectX Compressed Texture (DXT5) 2128 DXTC Microsoft DirectX Compressed Texture (DXTC) 2129 DXTn Microsoft DirectX Compressed Texture (DXTn) 2130 EM2V Etymonix MPEG-2 I-frame (www.etymonix.com) 2131 EKQ0 Elsa ?EKQ0? 2132 ELK0 Elsa ?ELK0? 2133 ESCP Eidos Escape 2134 ETV1 eTreppid Video ETV1 2135 ETV2 eTreppid Video ETV2 2136 ETVC eTreppid Video ETVC 2137 FLIC Autodesk FLI/FLC Animation 2138 FLV1 Sorenson Spark 2139 FLV4 On2 TrueMotion VP6 2140 FRWT Darim Vision Forward Motion JPEG (www.darvision.com) 2141 FRWU Darim Vision Forward Uncompressed (www.darvision.com) 2142 FLJP D-Vision Field Encoded Motion JPEG 2143 FPS1 FRAPS v1 2144 FRWA SoftLab-Nsk Forward Motion JPEG w/ alpha channel 2145 FRWD SoftLab-Nsk Forward Motion JPEG 2146 FVF1 Iterated Systems Fractal Video Frame 2147 GLZW Motion LZW (gabest@freemail.hu) 2148 GPEG Motion JPEG (gabest@freemail.hu) 2149 GWLT Microsoft Greyscale WLT DIB 2150 H260 Intel ITU H.260 Videoconferencing 2151 H261 Intel ITU H.261 Videoconferencing 2152 H262 Intel ITU H.262 Videoconferencing 2153 H263 Intel ITU H.263 Videoconferencing 2154 H264 Intel ITU H.264 Videoconferencing 2155 H265 Intel ITU H.265 Videoconferencing 2156 H266 Intel ITU H.266 Videoconferencing 2157 H267 Intel ITU H.267 Videoconferencing 2158 H268 Intel ITU H.268 Videoconferencing 2159 H269 Intel ITU H.269 Videoconferencing 2160 HFYU Huffman Lossless Codec 2161 HMCR Rendition Motion Compensation Format (HMCR) 2162 HMRR Rendition Motion Compensation Format (HMRR) 2163 I263 FFmpeg I263 decoder 2164 IF09 Indeo YVU9 ("YVU9 with additional delta-frame info after the U plane") 2165 IUYV Interlaced version of UYVY (www.leadtools.com) 2166 IY41 Interlaced version of Y41P (www.leadtools.com) 2167 IYU1 12 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec IEEE standard 2168 IYU2 24 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec IEEE standard 2169 IYUV Planar YUV format (8-bpp Y plane, followed by 8-bpp 2×2 U and V planes) 2170 i263 Intel ITU H.263 Videoconferencing (i263) 2171 I420 Intel Indeo 4 2172 IAN Intel Indeo 4 (RDX) 2173 ICLB InSoft CellB Videoconferencing 2174 IGOR Power DVD 2175 IJPG Intergraph JPEG 2176 ILVC Intel Layered Video 2177 ILVR ITU-T H.263+ 2178 IPDV I-O Data Device Giga AVI DV Codec 2179 IR21 Intel Indeo 2.1 2180 IRAW Intel YUV Uncompressed 2181 IV30 Intel Indeo 3.0 2182 IV31 Intel Indeo 3.1 2183 IV32 Ligos Indeo 3.2 2184 IV33 Ligos Indeo 3.3 2185 IV34 Ligos Indeo 3.4 2186 IV35 Ligos Indeo 3.5 2187 IV36 Ligos Indeo 3.6 2188 IV37 Ligos Indeo 3.7 2189 IV38 Ligos Indeo 3.8 2190 IV39 Ligos Indeo 3.9 2191 IV40 Ligos Indeo Interactive 4.0 2192 IV41 Ligos Indeo Interactive 4.1 2193 IV42 Ligos Indeo Interactive 4.2 2194 IV43 Ligos Indeo Interactive 4.3 2195 IV44 Ligos Indeo Interactive 4.4 2196 IV45 Ligos Indeo Interactive 4.5 2197 IV46 Ligos Indeo Interactive 4.6 2198 IV47 Ligos Indeo Interactive 4.7 2199 IV48 Ligos Indeo Interactive 4.8 2200 IV49 Ligos Indeo Interactive 4.9 2201 IV50 Ligos Indeo Interactive 5.0 2202 JBYR Kensington ?JBYR? 2203 JPEG Still Image JPEG DIB 2204 JPGL Pegasus Lossless Motion JPEG 2205 KMVC Team17 Software Karl Morton\'s Video Codec 2206 LSVM Vianet Lighting Strike Vmail (Streaming) (www.vianet.com) 2207 LEAD LEAD Video Codec 2208 Ljpg LEAD MJPEG Codec 2209 MDVD Alex MicroDVD Video (hacked MS MPEG-4) (www.tiasoft.de) 2210 MJPA Morgan Motion JPEG (MJPA) (www.morgan-multimedia.com) 2211 MJPB Morgan Motion JPEG (MJPB) (www.morgan-multimedia.com) 2212 MMES Matrox MPEG-2 I-frame 2213 MP2v Microsoft S-Mpeg 4 version 1 (MP2v) 2214 MP42 Microsoft S-Mpeg 4 version 2 (MP42) 2215 MP43 Microsoft S-Mpeg 4 version 3 (MP43) 2216 MP4S Microsoft S-Mpeg 4 version 3 (MP4S) 2217 MP4V FFmpeg MPEG-4 2218 MPG1 FFmpeg MPEG 1/2 2219 MPG2 FFmpeg MPEG 1/2 2220 MPG3 FFmpeg DivX ;-) (MS MPEG-4 v3) 2221 MPG4 Microsoft MPEG-4 2222 MPGI Sigma Designs MPEG 2223 MPNG PNG images decoder 2224 MSS1 Microsoft Windows Screen Video 2225 MSZH LCL (Lossless Codec Library) (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm) 2226 M261 Microsoft H.261 2227 M263 Microsoft H.263 2228 M4S2 Microsoft Fully Compliant MPEG-4 v2 simple profile (M4S2) 2229 m4s2 Microsoft Fully Compliant MPEG-4 v2 simple profile (m4s2) 2230 MC12 ATI Motion Compensation Format (MC12) 2231 MCAM ATI Motion Compensation Format (MCAM) 2232 MJ2C Morgan Multimedia Motion JPEG2000 2233 mJPG IBM Motion JPEG w/ Huffman Tables 2234 MJPG Microsoft Motion JPEG DIB 2235 MP42 Microsoft MPEG-4 (low-motion) 2236 MP43 Microsoft MPEG-4 (fast-motion) 2237 MP4S Microsoft MPEG-4 (MP4S) 2238 mp4s Microsoft MPEG-4 (mp4s) 2239 MPEG Chromatic Research MPEG-1 Video I-Frame 2240 MPG4 Microsoft MPEG-4 Video High Speed Compressor 2241 MPGI Sigma Designs MPEG 2242 MRCA FAST Multimedia Martin Regen Codec 2243 MRLE Microsoft Run Length Encoding 2244 MSVC Microsoft Video 1 2245 MTX1 Matrox ?MTX1? 2246 MTX2 Matrox ?MTX2? 2247 MTX3 Matrox ?MTX3? 2248 MTX4 Matrox ?MTX4? 2249 MTX5 Matrox ?MTX5? 2250 MTX6 Matrox ?MTX6? 2251 MTX7 Matrox ?MTX7? 2252 MTX8 Matrox ?MTX8? 2253 MTX9 Matrox ?MTX9? 2254 MV12 Motion Pixels Codec (old) 2255 MWV1 Aware Motion Wavelets 2256 nAVI SMR Codec (hack of Microsoft MPEG-4) (IRC #shadowrealm) 2257 NT00 NewTek LightWave HDTV YUV w/ Alpha (www.newtek.com) 2258 NUV1 NuppelVideo 2259 NTN1 Nogatech Video Compression 1 2260 NVS0 nVidia GeForce Texture (NVS0) 2261 NVS1 nVidia GeForce Texture (NVS1) 2262 NVS2 nVidia GeForce Texture (NVS2) 2263 NVS3 nVidia GeForce Texture (NVS3) 2264 NVS4 nVidia GeForce Texture (NVS4) 2265 NVS5 nVidia GeForce Texture (NVS5) 2266 NVT0 nVidia GeForce Texture (NVT0) 2267 NVT1 nVidia GeForce Texture (NVT1) 2268 NVT2 nVidia GeForce Texture (NVT2) 2269 NVT3 nVidia GeForce Texture (NVT3) 2270 NVT4 nVidia GeForce Texture (NVT4) 2271 NVT5 nVidia GeForce Texture (NVT5) 2272 PIXL MiroXL, Pinnacle PCTV 2273 PDVC I-O Data Device Digital Video Capture DV codec 2274 PGVV Radius Video Vision 2275 PHMO IBM Photomotion 2276 PIM1 MPEG Realtime (Pinnacle Cards) 2277 PIM2 Pegasus Imaging ?PIM2? 2278 PIMJ Pegasus Imaging Lossless JPEG 2279 PVEZ Horizons Technology PowerEZ 2280 PVMM PacketVideo Corporation MPEG-4 2281 PVW2 Pegasus Imaging Wavelet Compression 2282 Q1.0 Q-Team\'s QPEG 1.0 (www.q-team.de) 2283 Q1.1 Q-Team\'s QPEG 1.1 (www.q-team.de) 2284 QPEG Q-Team QPEG 1.0 2285 qpeq Q-Team QPEG 1.1 2286 RGB Raw BGR32 2287 RGBA Raw RGB w/ Alpha 2288 RMP4 REALmagic MPEG-4 (unauthorized XVID copy) (www.sigmadesigns.com) 2289 ROQV Id RoQ File Video Decoder 2290 RPZA Quicktime Apple Video (RPZA) 2291 RUD0 Rududu video codec (http://rududu.ifrance.com/rududu/) 2292 RV10 RealVideo 1.0 (aka RealVideo 5.0) 2293 RV13 RealVideo 1.0 (RV13) 2294 RV20 RealVideo G2 2295 RV30 RealVideo 8 2296 RV40 RealVideo 9 2297 RGBT Raw RGB w/ Transparency 2298 RLE Microsoft Run Length Encoder 2299 RLE4 Run Length Encoded (4bpp, 16-color) 2300 RLE8 Run Length Encoded (8bpp, 256-color) 2301 RT21 Intel Indeo RealTime Video 2.1 2302 rv20 RealVideo G2 2303 rv30 RealVideo 8 2304 RVX Intel RDX (RVX ) 2305 SMC Apple Graphics (SMC ) 2306 SP54 Logitech Sunplus Sp54 Codec for Mustek GSmart Mini 2 2307 SPIG Radius Spigot 2308 SVQ3 Sorenson Video 3 (Apple Quicktime 5) 2309 s422 Tekram VideoCap C210 YUV 4:2:2 2310 SDCC Sun Communication Digital Camera Codec 2311 SFMC CrystalNet Surface Fitting Method 2312 SMSC Radius SMSC 2313 SMSD Radius SMSD 2314 smsv WorldConnect Wavelet Video 2315 SPIG Radius Spigot 2316 SPLC Splash Studios ACM Audio Codec (www.splashstudios.net) 2317 SQZ2 Microsoft VXTreme Video Codec V2 2318 STVA ST Microelectronics CMOS Imager Data (Bayer) 2319 STVB ST Microelectronics CMOS Imager Data (Nudged Bayer) 2320 STVC ST Microelectronics CMOS Imager Data (Bunched) 2321 STVX ST Microelectronics CMOS Imager Data (Extended CODEC Data Format) 2322 STVY ST Microelectronics CMOS Imager Data (Extended CODEC Data Format with Correction Data) 2323 SV10 Sorenson Video R1 2324 SVQ1 Sorenson Video 2325 T420 Toshiba YUV 4:2:0 2326 TM2A Duck TrueMotion Archiver 2.0 (www.duck.com) 2327 TVJP Pinnacle/Truevision Targa 2000 board (TVJP) 2328 TVMJ Pinnacle/Truevision Targa 2000 board (TVMJ) 2329 TY0N Tecomac Low-Bit Rate Codec (www.tecomac.com) 2330 TY2C Trident Decompression Driver 2331 TLMS TeraLogic Motion Intraframe Codec (TLMS) 2332 TLST TeraLogic Motion Intraframe Codec (TLST) 2333 TM20 Duck TrueMotion 2.0 2334 TM2X Duck TrueMotion 2X 2335 TMIC TeraLogic Motion Intraframe Codec (TMIC) 2336 TMOT Horizons Technology TrueMotion S 2337 tmot Horizons TrueMotion Video Compression 2338 TR20 Duck TrueMotion RealTime 2.0 2339 TSCC TechSmith Screen Capture Codec 2340 TV10 Tecomac Low-Bit Rate Codec 2341 TY2N Trident ?TY2N? 2342 U263 UB Video H.263/H.263+/H.263++ Decoder 2343 UMP4 UB Video MPEG 4 (www.ubvideo.com) 2344 UYNV Nvidia UYVY packed 4:2:2 2345 UYVP Evans & Sutherland YCbCr 4:2:2 extended precision 2346 UCOD eMajix.com ClearVideo 2347 ULTI IBM Ultimotion 2348 UYVY UYVY packed 4:2:2 2349 V261 Lucent VX2000S 2350 VIFP VFAPI Reader Codec (www.yks.ne.jp/~hori/) 2351 VIV1 FFmpeg H263+ decoder 2352 VIV2 Vivo H.263 2353 VQC2 Vector-quantised codec 2 (research) http://eprints.ecs.soton.ac.uk/archive/00001310/01/VTC97-js.pdf) 2354 VTLP Alaris VideoGramPiX 2355 VYU9 ATI YUV (VYU9) 2356 VYUY ATI YUV (VYUY) 2357 V261 Lucent VX2000S 2358 V422 Vitec Multimedia 24-bit YUV 4:2:2 Format 2359 V655 Vitec Multimedia 16-bit YUV 4:2:2 Format 2360 VCR1 ATI Video Codec 1 2361 VCR2 ATI Video Codec 2 2362 VCR3 ATI VCR 3.0 2363 VCR4 ATI VCR 4.0 2364 VCR5 ATI VCR 5.0 2365 VCR6 ATI VCR 6.0 2366 VCR7 ATI VCR 7.0 2367 VCR8 ATI VCR 8.0 2368 VCR9 ATI VCR 9.0 2369 VDCT Vitec Multimedia Video Maker Pro DIB 2370 VDOM VDOnet VDOWave 2371 VDOW VDOnet VDOLive (H.263) 2372 VDTZ Darim Vison VideoTizer YUV 2373 VGPX Alaris VideoGramPiX 2374 VIDS Vitec Multimedia YUV 4:2:2 CCIR 601 for V422 2375 VIVO Vivo H.263 v2.00 2376 vivo Vivo H.263 2377 VIXL Miro/Pinnacle Video XL 2378 VLV1 VideoLogic/PURE Digital Videologic Capture 2379 VP30 On2 VP3.0 2380 VP31 On2 VP3.1 2381 VP6F On2 TrueMotion VP6 2382 VX1K Lucent VX1000S Video Codec 2383 VX2K Lucent VX2000S Video Codec 2384 VXSP Lucent VX1000SP Video Codec 2385 WBVC Winbond W9960 2386 WHAM Microsoft Video 1 (WHAM) 2387 WINX Winnov Software Compression 2388 WJPG AverMedia Winbond JPEG 2389 WMV1 Windows Media Video V7 2390 WMV2 Windows Media Video V8 2391 WMV3 Windows Media Video V9 2392 WNV1 Winnov Hardware Compression 2393 XYZP Extended PAL format XYZ palette (www.riff.org) 2394 x263 Xirlink H.263 2395 XLV0 NetXL Video Decoder 2396 XMPG Xing MPEG (I-Frame only) 2397 XVID XviD MPEG-4 (www.xvid.org) 2398 XXAN ?XXAN? 2399 YU92 Intel YUV (YU92) 2400 YUNV Nvidia Uncompressed YUV 4:2:2 2401 YUVP Extended PAL format YUV palette (www.riff.org) 2402 Y211 YUV 2:1:1 Packed 2403 Y411 YUV 4:1:1 Packed 2404 Y41B Weitek YUV 4:1:1 Planar 2405 Y41P Brooktree PC1 YUV 4:1:1 Packed 2406 Y41T Brooktree PC1 YUV 4:1:1 with transparency 2407 Y42B Weitek YUV 4:2:2 Planar 2408 Y42T Brooktree UYUV 4:2:2 with transparency 2409 Y422 ADS Technologies Copy of UYVY used in Pyro WebCam firewire camera 2410 Y800 Simple, single Y plane for monochrome images 2411 Y8 Grayscale video 2412 YC12 Intel YUV 12 codec 2413 YUV8 Winnov Caviar YUV8 2414 YUV9 Intel YUV9 2415 YUY2 Uncompressed YUV 4:2:2 2416 YUYV Canopus YUV 2417 YV12 YVU12 Planar 2418 YVU9 Intel YVU9 Planar (8-bpp Y plane, followed by 8-bpp 4x4 U and V planes) 2419 YVYU YVYU 4:2:2 Packed 2420 ZLIB Lossless Codec Library zlib compression (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm) 2421 ZPEG Metheus Video Zipper 2422 2423 */ 2424 2425 return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc'); 2426 } 2427 2428 private function EitherEndian2Int($byteword, $signed=false) { 2429 if ($this->getid3->info['fileformat'] == 'riff') { 2430 return getid3_lib::LittleEndian2Int($byteword, $signed); 2431 } 2432 return getid3_lib::BigEndian2Int($byteword, false, $signed); 2433 } 2434 2435 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 25 01:41:18 2014 | WordPress honlapkészítés: online1.hu |