module.audio-video.riff.php 101 KB

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