getid3_riff

The WordPress Core getid3 riff class.

Defined (1)

The class is defined in the following location(s).

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