/getid3/module.audio-video.riff.php
PHP | 2410 lines | 1442 code | 248 blank | 720 comment | 298 complexity | ea51b9b326e29ec6aeb499bc6d871067 MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- <?php
- /////////////////////////////////////////////////////////////////
- /// getID3() by James Heinrich <info@getid3.org> //
- // available at http://getid3.sourceforge.net //
- // or http://www.getid3.org //
- /////////////////////////////////////////////////////////////////
- // See readme.txt for more details //
- /////////////////////////////////////////////////////////////////
- // //
- // module.audio-video.riff.php //
- // module for analyzing RIFF files //
- // multiple formats supported by this module: //
- // Wave, AVI, AIFF/AIFC, (MP3,AC3)/RIFF, Wavpack v3, 8SVX //
- // dependencies: module.audio.mp3.php //
- // module.audio.ac3.php (optional) //
- // module.audio.dts.php (optional) //
- // ///
- /////////////////////////////////////////////////////////////////
- getid3_lib::IncludeDependency ( GETID3_INCLUDEPATH . 'module.audio.mp3.php', __FILE__, true );
- class getid3_riff extends getid3_handler {
-
- function Analyze() {
- $info = &$this->getid3->info;
-
- // initialize these values to an empty array, otherwise they default to NULL
- // and you can't append array values to a NULL value
- $info ['riff'] = array (
- 'raw' => array () );
-
- // Shortcuts
- $thisfile_riff = &$info ['riff'];
- $thisfile_riff_raw = &$thisfile_riff ['raw'];
- $thisfile_audio = &$info ['audio'];
- $thisfile_video = &$info ['video'];
- $thisfile_audio_dataformat = &$thisfile_audio ['dataformat'];
- $thisfile_riff_audio = &$thisfile_riff ['audio'];
- $thisfile_riff_video = &$thisfile_riff ['video'];
-
- $Original ['avdataoffset'] = $info ['avdataoffset'];
- $Original ['avdataend'] = $info ['avdataend'];
-
- fseek ( $this->getid3->fp, $info ['avdataoffset'], SEEK_SET );
- $RIFFheader = fread ( $this->getid3->fp, 12 );
- $RIFFsubtype = substr ( $RIFFheader, 8, 4 );
- switch (substr ( $RIFFheader, 0, 4 )) {
- case 'FORM' :
- $info ['fileformat'] = 'aiff';
- $thisfile_riff ['header_size'] = $this->EitherEndian2Int ( substr ( $RIFFheader, 4, 4 ) );
- $thisfile_riff [$RIFFsubtype] = $this->ParseRIFF ( $info ['avdataoffset'] + 12, $info ['avdataoffset'] + $thisfile_riff ['header_size'] );
- break;
-
- case 'RIFF' : // AVI, WAV, etc
- case 'SDSS' : // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com)
- case 'RMP3' : // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s
- $info ['fileformat'] = 'riff';
- $thisfile_riff ['header_size'] = $this->EitherEndian2Int ( substr ( $RIFFheader, 4, 4 ) );
- if ($RIFFsubtype == 'RMP3') {
- // RMP3 is identical to WAVE, just renamed. Used by [unknown program] when creating RIFF-MP3s
- $RIFFsubtype = 'WAVE';
- }
- $thisfile_riff [$RIFFsubtype] = $this->ParseRIFF ( $info ['avdataoffset'] + 12, $info ['avdataoffset'] + $thisfile_riff ['header_size'] );
- if (($info ['avdataend'] - $info ['filesize']) == 1) {
- // LiteWave appears to incorrectly *not* pad actual output file
- // to nearest WORD boundary so may appear to be short by one
- // byte, in which case - skip warning
- $info ['avdataend'] = $info ['filesize'];
- }
-
- $nextRIFFoffset = $Original ['avdataoffset'] + 8 + $thisfile_riff ['header_size']; // 8 = "RIFF" + 32-bit offset
- while ( $nextRIFFoffset < min ( $info ['filesize'], $info ['avdataend'] ) ) {
- if (! getid3_lib::intValueSupported ( $nextRIFFoffset + 1024 )) {
- $info ['error'] [] = 'AVI extends beyond ' . round ( PHP_INT_MAX / 1073741824 ) . 'GB and PHP filesystem functions cannot read that far, playtime is probably wrong';
- $info ['warning'] [] = '[avdataend] value may be incorrect, multiple AVIX chunks may be present';
- break;
- } else {
- fseek ( $this->getid3->fp, $nextRIFFoffset, SEEK_SET );
- $nextRIFFheader = fread ( $this->getid3->fp, 12 );
- if ($nextRIFFoffset == ($info ['avdataend'] - 1)) {
- if (substr ( $nextRIFFheader, 0, 1 ) == "\x00") {
- // RIFF padded to WORD boundary, we're actually already at the end
- break;
- }
- }
- $nextRIFFheaderID = substr ( $nextRIFFheader, 0, 4 );
- $nextRIFFsize = $this->EitherEndian2Int ( substr ( $nextRIFFheader, 4, 4 ) );
- $nextRIFFtype = substr ( $nextRIFFheader, 8, 4 );
- $chunkdata = array ();
- $chunkdata ['offset'] = $nextRIFFoffset + 8;
- $chunkdata ['size'] = $nextRIFFsize;
- $nextRIFFoffset = $chunkdata ['offset'] + $chunkdata ['size'];
- switch ($nextRIFFheaderID) {
- case 'RIFF' :
- $info ['avdataend'] = $nextRIFFoffset;
- if (! getid3_lib::intValueSupported ( $info ['avdataend'] )) {
- $info ['error'] [] = 'AVI extends beyond ' . round ( PHP_INT_MAX / 1073741824 ) . 'GB and PHP filesystem functions cannot read that far, playtime is probably wrong';
- $info ['warning'] [] = '[avdataend] value may be incorrect, multiple AVIX chunks may be present';
- }
- $chunkdata ['chunks'] = $this->ParseRIFF ( $chunkdata ['offset'] + 4, $chunkdata ['offset'] + $chunkdata ['size'] );
-
- if (! isset ( $thisfile_riff [$nextRIFFtype] )) {
- $thisfile_riff [$nextRIFFtype] = array ();
- }
- $thisfile_riff [$nextRIFFtype] [] = $chunkdata;
- break;
- case 'JUNK' :
- // ignore
- $thisfile_riff [$nextRIFFheaderID] [] = $chunkdata;
- break;
- default :
- if ($info ['filesize'] == ($chunkdata ['offset'] - 8 + 128)) {
- $DIVXTAG = $nextRIFFheader . fread ( $this->getid3->fp, 128 - 12 );
- if (substr ( $DIVXTAG, - 7 ) == 'DIVXTAG') {
- // DIVXTAG is supposed to be inside an IDVX chunk in a LIST chunk, but some bad encoders just slap it on the end of a file
- $info ['warning'] [] = 'Found wrongly-structured DIVXTAG at offset ' . (ftell ( $this->getid3->fp ) - 128 + 12) . ', parsing anyway';
- $thisfile_riff ['DIVXTAG'] = $this->ParseDIVXTAG ( $DIVXTAG );
- foreach ( $thisfile_riff ['DIVXTAG'] as $key => $value ) {
- if ($value && ! preg_match ( '#_id$#', $key )) {
- $thisfile_riff ['comments'] [$key] [] = $value;
- }
- }
- break 2;
- }
- }
- $info ['warning'] [] = 'expecting "RIFF" or "JUNK" at ' . $nextRIFFoffset . ', found ' . getid3_lib::PrintHexBytes ( substr ( $nextRIFFheader, 0, 4 ) ) . ' - skipping rest of file';
- break 2;
- }
- }
- }
- if ($RIFFsubtype == 'WAVE') {
- $thisfile_riff_WAVE = &$thisfile_riff ['WAVE'];
- }
- break;
-
- default :
- $info ['error'] [] = 'Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "' . $RIFFsubtype . '" instead';
- unset ( $info ['fileformat'] );
- return false;
- break;
- }
-
- $streamindex = 0;
- switch ($RIFFsubtype) {
- case 'WAVE' :
- if (empty ( $thisfile_audio ['bitrate_mode'] )) {
- $thisfile_audio ['bitrate_mode'] = 'cbr';
- }
- if (empty ( $thisfile_audio_dataformat )) {
- $thisfile_audio_dataformat = 'wav';
- }
-
- if (isset ( $thisfile_riff_WAVE ['data'] [0] ['offset'] )) {
- $info ['avdataoffset'] = $thisfile_riff_WAVE ['data'] [0] ['offset'] + 8;
- $info ['avdataend'] = $info ['avdataoffset'] + $thisfile_riff_WAVE ['data'] [0] ['size'];
- }
- if (isset ( $thisfile_riff_WAVE ['fmt '] [0] ['data'] )) {
-
- $thisfile_riff_audio [$streamindex] = getid3_riff::RIFFparseWAVEFORMATex ( $thisfile_riff_WAVE ['fmt '] [0] ['data'] );
- $thisfile_audio ['wformattag'] = $thisfile_riff_audio [$streamindex] ['raw'] ['wFormatTag'];
- if (! isset ( $thisfile_riff_audio [$streamindex] ['bitrate'] ) || ($thisfile_riff_audio [$streamindex] ['bitrate'] == 0)) {
- $info ['error'] [] = 'Corrupt RIFF file: bitrate_audio == zero';
- return false;
- }
- $thisfile_riff_raw ['fmt '] = $thisfile_riff_audio [$streamindex] ['raw'];
- unset ( $thisfile_riff_audio [$streamindex] ['raw'] );
- $thisfile_audio ['streams'] [$streamindex] = $thisfile_riff_audio [$streamindex];
-
- $thisfile_audio = getid3_lib::array_merge_noclobber ( $thisfile_audio, $thisfile_riff_audio [$streamindex] );
- if (substr ( $thisfile_audio ['codec'], 0, strlen ( 'unknown: 0x' ) ) == 'unknown: 0x') {
- $info ['warning'] [] = 'Audio codec = ' . $thisfile_audio ['codec'];
- }
- $thisfile_audio ['bitrate'] = $thisfile_riff_audio [$streamindex] ['bitrate'];
-
- $info ['playtime_seconds'] = ( float ) ((($info ['avdataend'] - $info ['avdataoffset']) * 8) / $thisfile_audio ['bitrate']);
-
- $thisfile_audio ['lossless'] = false;
- if (isset ( $thisfile_riff_WAVE ['data'] [0] ['offset'] ) && isset ( $thisfile_riff_raw ['fmt '] ['wFormatTag'] )) {
- switch ($thisfile_riff_raw ['fmt '] ['wFormatTag']) {
-
- case 0x0001 : // PCM
- $thisfile_audio ['lossless'] = true;
- break;
-
- case 0x2000 : // AC-3
- $thisfile_audio_dataformat = 'ac3';
- break;
-
- default :
- // do nothing
- break;
-
- }
- }
- $thisfile_audio ['streams'] [$streamindex] ['wformattag'] = $thisfile_audio ['wformattag'];
- $thisfile_audio ['streams'] [$streamindex] ['bitrate_mode'] = $thisfile_audio ['bitrate_mode'];
- $thisfile_audio ['streams'] [$streamindex] ['lossless'] = $thisfile_audio ['lossless'];
- $thisfile_audio ['streams'] [$streamindex] ['dataformat'] = $thisfile_audio_dataformat;
- }
-
- if (isset ( $thisfile_riff_WAVE ['rgad'] [0] ['data'] )) {
-
- // shortcuts
- $rgadData = &$thisfile_riff_WAVE ['rgad'] [0] ['data'];
- $thisfile_riff_raw ['rgad'] = array (
- 'track' => array (),
- 'album' => array () );
- $thisfile_riff_raw_rgad = &$thisfile_riff_raw ['rgad'];
- $thisfile_riff_raw_rgad_track = &$thisfile_riff_raw_rgad ['track'];
- $thisfile_riff_raw_rgad_album = &$thisfile_riff_raw_rgad ['album'];
-
- $thisfile_riff_raw_rgad ['fPeakAmplitude'] = getid3_lib::LittleEndian2Float ( substr ( $rgadData, 0, 4 ) );
- $thisfile_riff_raw_rgad ['nRadioRgAdjust'] = $this->EitherEndian2Int ( substr ( $rgadData, 4, 2 ) );
- $thisfile_riff_raw_rgad ['nAudiophileRgAdjust'] = $this->EitherEndian2Int ( substr ( $rgadData, 6, 2 ) );
-
- $nRadioRgAdjustBitstring = str_pad ( getid3_lib::Dec2Bin ( $thisfile_riff_raw_rgad ['nRadioRgAdjust'] ), 16, '0', STR_PAD_LEFT );
- $nAudiophileRgAdjustBitstring = str_pad ( getid3_lib::Dec2Bin ( $thisfile_riff_raw_rgad ['nAudiophileRgAdjust'] ), 16, '0', STR_PAD_LEFT );
- $thisfile_riff_raw_rgad_track ['name'] = getid3_lib::Bin2Dec ( substr ( $nRadioRgAdjustBitstring, 0, 3 ) );
- $thisfile_riff_raw_rgad_track ['originator'] = getid3_lib::Bin2Dec ( substr ( $nRadioRgAdjustBitstring, 3, 3 ) );
- $thisfile_riff_raw_rgad_track ['signbit'] = getid3_lib::Bin2Dec ( substr ( $nRadioRgAdjustBitstring, 6, 1 ) );
- $thisfile_riff_raw_rgad_track ['adjustment'] = getid3_lib::Bin2Dec ( substr ( $nRadioRgAdjustBitstring, 7, 9 ) );
- $thisfile_riff_raw_rgad_album ['name'] = getid3_lib::Bin2Dec ( substr ( $nAudiophileRgAdjustBitstring, 0, 3 ) );
- $thisfile_riff_raw_rgad_album ['originator'] = getid3_lib::Bin2Dec ( substr ( $nAudiophileRgAdjustBitstring, 3, 3 ) );
- $thisfile_riff_raw_rgad_album ['signbit'] = getid3_lib::Bin2Dec ( substr ( $nAudiophileRgAdjustBitstring, 6, 1 ) );
- $thisfile_riff_raw_rgad_album ['adjustment'] = getid3_lib::Bin2Dec ( substr ( $nAudiophileRgAdjustBitstring, 7, 9 ) );
-
- $thisfile_riff ['rgad'] ['peakamplitude'] = $thisfile_riff_raw_rgad ['fPeakAmplitude'];
- if (($thisfile_riff_raw_rgad_track ['name'] != 0) && ($thisfile_riff_raw_rgad_track ['originator'] != 0)) {
- $thisfile_riff ['rgad'] ['track'] ['name'] = getid3_lib::RGADnameLookup ( $thisfile_riff_raw_rgad_track ['name'] );
- $thisfile_riff ['rgad'] ['track'] ['originator'] = getid3_lib::RGADoriginatorLookup ( $thisfile_riff_raw_rgad_track ['originator'] );
- $thisfile_riff ['rgad'] ['track'] ['adjustment'] = getid3_lib::RGADadjustmentLookup ( $thisfile_riff_raw_rgad_track ['adjustment'], $thisfile_riff_raw_rgad_track ['signbit'] );
- }
- if (($thisfile_riff_raw_rgad_album ['name'] != 0) && ($thisfile_riff_raw_rgad_album ['originator'] != 0)) {
- $thisfile_riff ['rgad'] ['album'] ['name'] = getid3_lib::RGADnameLookup ( $thisfile_riff_raw_rgad_album ['name'] );
- $thisfile_riff ['rgad'] ['album'] ['originator'] = getid3_lib::RGADoriginatorLookup ( $thisfile_riff_raw_rgad_album ['originator'] );
- $thisfile_riff ['rgad'] ['album'] ['adjustment'] = getid3_lib::RGADadjustmentLookup ( $thisfile_riff_raw_rgad_album ['adjustment'], $thisfile_riff_raw_rgad_album ['signbit'] );
- }
- }
-
- if (isset ( $thisfile_riff_WAVE ['fact'] [0] ['data'] )) {
- $thisfile_riff_raw ['fact'] ['NumberOfSamples'] = $this->EitherEndian2Int ( substr ( $thisfile_riff_WAVE ['fact'] [0] ['data'], 0, 4 ) );
-
- // This should be a good way of calculating exact playtime,
- // but some sample files have had incorrect number of samples,
- // so cannot use this method
-
- // if (!empty($thisfile_riff_raw['fmt ']['nSamplesPerSec'])) {
- // $info['playtime_seconds'] = (float) $thisfile_riff_raw['fact']['NumberOfSamples'] / $thisfile_riff_raw['fmt ']['nSamplesPerSec'];
- // }
- }
- if (! empty ( $thisfile_riff_raw ['fmt '] ['nAvgBytesPerSec'] )) {
- $thisfile_audio ['bitrate'] = getid3_lib::CastAsInt ( $thisfile_riff_raw ['fmt '] ['nAvgBytesPerSec'] * 8 );
- }
-
- if (isset ( $thisfile_riff_WAVE ['bext'] [0] ['data'] )) {
- // shortcut
- $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE ['bext'] [0];
-
- $thisfile_riff_WAVE_bext_0 ['title'] = trim ( substr ( $thisfile_riff_WAVE_bext_0 ['data'], 0, 256 ) );
- $thisfile_riff_WAVE_bext_0 ['author'] = trim ( substr ( $thisfile_riff_WAVE_bext_0 ['data'], 256, 32 ) );
- $thisfile_riff_WAVE_bext_0 ['reference'] = trim ( substr ( $thisfile_riff_WAVE_bext_0 ['data'], 288, 32 ) );
- $thisfile_riff_WAVE_bext_0 ['origin_date'] = substr ( $thisfile_riff_WAVE_bext_0 ['data'], 320, 10 );
- $thisfile_riff_WAVE_bext_0 ['origin_time'] = substr ( $thisfile_riff_WAVE_bext_0 ['data'], 330, 8 );
- $thisfile_riff_WAVE_bext_0 ['time_reference'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE_bext_0 ['data'], 338, 8 ) );
- $thisfile_riff_WAVE_bext_0 ['bwf_version'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE_bext_0 ['data'], 346, 1 ) );
- $thisfile_riff_WAVE_bext_0 ['reserved'] = substr ( $thisfile_riff_WAVE_bext_0 ['data'], 347, 254 );
- $thisfile_riff_WAVE_bext_0 ['coding_history'] = explode ( "\r\n", trim ( substr ( $thisfile_riff_WAVE_bext_0 ['data'], 601 ) ) );
- if (preg_match ( '#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0 ['origin_date'], $matches_bext_date )) {
- if (preg_match ( '#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0 ['origin_time'], $matches_bext_time )) {
- list ( $dummy, $bext_timestamp ['year'], $bext_timestamp ['month'], $bext_timestamp ['day'] ) = $matches_bext_date;
- list ( $dummy, $bext_timestamp ['hour'], $bext_timestamp ['minute'], $bext_timestamp ['second'] ) = $matches_bext_time;
- $thisfile_riff_WAVE_bext_0 ['origin_date_unix'] = gmmktime ( $bext_timestamp ['hour'], $bext_timestamp ['minute'], $bext_timestamp ['second'], $bext_timestamp ['month'], $bext_timestamp ['day'], $bext_timestamp ['year'] );
- } else {
- $info ['warning'] [] = 'RIFF.WAVE.BEXT.origin_time is invalid';
- }
- } else {
- $info ['warning'] [] = 'RIFF.WAVE.BEXT.origin_date is invalid';
- }
- $thisfile_riff ['comments'] ['author'] [] = $thisfile_riff_WAVE_bext_0 ['author'];
- $thisfile_riff ['comments'] ['title'] [] = $thisfile_riff_WAVE_bext_0 ['title'];
- }
-
- if (isset ( $thisfile_riff_WAVE ['MEXT'] [0] ['data'] )) {
- // shortcut
- $thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE ['MEXT'] [0];
-
- $thisfile_riff_WAVE_MEXT_0 ['raw'] ['sound_information'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE_MEXT_0 ['data'], 0, 2 ) );
- $thisfile_riff_WAVE_MEXT_0 ['flags'] ['homogenous'] = ( bool ) ($thisfile_riff_WAVE_MEXT_0 ['raw'] ['sound_information'] & 0x0001);
- if ($thisfile_riff_WAVE_MEXT_0 ['flags'] ['homogenous']) {
- $thisfile_riff_WAVE_MEXT_0 ['flags'] ['padding'] = ($thisfile_riff_WAVE_MEXT_0 ['raw'] ['sound_information'] & 0x0002) ? false : true;
- $thisfile_riff_WAVE_MEXT_0 ['flags'] ['22_or_44'] = ( bool ) ($thisfile_riff_WAVE_MEXT_0 ['raw'] ['sound_information'] & 0x0004);
- $thisfile_riff_WAVE_MEXT_0 ['flags'] ['free_format'] = ( bool ) ($thisfile_riff_WAVE_MEXT_0 ['raw'] ['sound_information'] & 0x0008);
-
- $thisfile_riff_WAVE_MEXT_0 ['nominal_frame_size'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE_MEXT_0 ['data'], 2, 2 ) );
- }
- $thisfile_riff_WAVE_MEXT_0 ['anciliary_data_length'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE_MEXT_0 ['data'], 6, 2 ) );
- $thisfile_riff_WAVE_MEXT_0 ['raw'] ['anciliary_data_def'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE_MEXT_0 ['data'], 8, 2 ) );
- $thisfile_riff_WAVE_MEXT_0 ['flags'] ['anciliary_data_left'] = ( bool ) ($thisfile_riff_WAVE_MEXT_0 ['raw'] ['anciliary_data_def'] & 0x0001);
- $thisfile_riff_WAVE_MEXT_0 ['flags'] ['anciliary_data_free'] = ( bool ) ($thisfile_riff_WAVE_MEXT_0 ['raw'] ['anciliary_data_def'] & 0x0002);
- $thisfile_riff_WAVE_MEXT_0 ['flags'] ['anciliary_data_right'] = ( bool ) ($thisfile_riff_WAVE_MEXT_0 ['raw'] ['anciliary_data_def'] & 0x0004);
- }
-
- if (isset ( $thisfile_riff_WAVE ['cart'] [0] ['data'] )) {
- // shortcut
- $thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE ['cart'] [0];
-
- $thisfile_riff_WAVE_cart_0 ['version'] = substr ( $thisfile_riff_WAVE_cart_0 ['data'], 0, 4 );
- $thisfile_riff_WAVE_cart_0 ['title'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 4, 64 ) );
- $thisfile_riff_WAVE_cart_0 ['artist'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 68, 64 ) );
- $thisfile_riff_WAVE_cart_0 ['cut_id'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 132, 64 ) );
- $thisfile_riff_WAVE_cart_0 ['client_id'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 196, 64 ) );
- $thisfile_riff_WAVE_cart_0 ['category'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 260, 64 ) );
- $thisfile_riff_WAVE_cart_0 ['classification'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 324, 64 ) );
- $thisfile_riff_WAVE_cart_0 ['out_cue'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 388, 64 ) );
- $thisfile_riff_WAVE_cart_0 ['start_date'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 452, 10 ) );
- $thisfile_riff_WAVE_cart_0 ['start_time'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 462, 8 ) );
- $thisfile_riff_WAVE_cart_0 ['end_date'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 470, 10 ) );
- $thisfile_riff_WAVE_cart_0 ['end_time'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 480, 8 ) );
- $thisfile_riff_WAVE_cart_0 ['producer_app_id'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 488, 64 ) );
- $thisfile_riff_WAVE_cart_0 ['producer_app_version'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 552, 64 ) );
- $thisfile_riff_WAVE_cart_0 ['user_defined_text'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 616, 64 ) );
- $thisfile_riff_WAVE_cart_0 ['zero_db_reference'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 680, 4 ), true );
- for($i = 0; $i < 8; $i ++) {
- $thisfile_riff_WAVE_cart_0 ['post_time'] [$i] ['usage_fourcc'] = substr ( $thisfile_riff_WAVE_cart_0 ['data'], 684 + ($i * 8), 4 );
- $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 ) );
- }
- $thisfile_riff_WAVE_cart_0 ['url'] = trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 748, 1024 ) );
- $thisfile_riff_WAVE_cart_0 ['tag_text'] = explode ( "\r\n", trim ( substr ( $thisfile_riff_WAVE_cart_0 ['data'], 1772 ) ) );
-
- $thisfile_riff ['comments'] ['artist'] [] = $thisfile_riff_WAVE_cart_0 ['artist'];
- $thisfile_riff ['comments'] ['title'] [] = $thisfile_riff_WAVE_cart_0 ['title'];
- }
-
- if (isset ( $thisfile_riff_WAVE ['SNDM'] [0] ['data'] )) {
- // SoundMiner metadata
-
- // shortcuts
- $thisfile_riff_WAVE_SNDM_0 = &$thisfile_riff_WAVE ['SNDM'] [0];
- $thisfile_riff_WAVE_SNDM_0_data = &$thisfile_riff_WAVE_SNDM_0 ['data'];
- $SNDM_startoffset = 0;
- $SNDM_endoffset = $thisfile_riff_WAVE_SNDM_0 ['size'];
-
- while ( $SNDM_startoffset < $SNDM_endoffset ) {
- $SNDM_thisTagOffset = 0;
- $SNDM_thisTagSize = getid3_lib::BigEndian2Int ( substr ( $thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4 ) );
- $SNDM_thisTagOffset += 4;
- $SNDM_thisTagKey = substr ( $thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4 );
- $SNDM_thisTagOffset += 4;
- $SNDM_thisTagDataSize = getid3_lib::BigEndian2Int ( substr ( $thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2 ) );
- $SNDM_thisTagOffset += 2;
- $SNDM_thisTagDataFlags = getid3_lib::BigEndian2Int ( substr ( $thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2 ) );
- $SNDM_thisTagOffset += 2;
- $SNDM_thisTagDataText = substr ( $thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, $SNDM_thisTagDataSize );
- $SNDM_thisTagOffset += $SNDM_thisTagDataSize;
-
- if ($SNDM_thisTagSize != (4 + 4 + 2 + 2 + $SNDM_thisTagDataSize)) {
- $info ['warning'] [] = 'RIFF.WAVE.SNDM.data contains tag not expected length (expected: ' . $SNDM_thisTagSize . ', found: ' . (4 + 4 + 2 + 2 + $SNDM_thisTagDataSize) . ') at offset ' . $SNDM_startoffset . ' (file offset ' . ($thisfile_riff_WAVE_SNDM_0 ['offset'] + $SNDM_startoffset) . ')';
- break;
- } elseif ($SNDM_thisTagSize <= 0) {
- $info ['warning'] [] = 'RIFF.WAVE.SNDM.data contains zero-size tag at offset ' . $SNDM_startoffset . ' (file offset ' . ($thisfile_riff_WAVE_SNDM_0 ['offset'] + $SNDM_startoffset) . ')';
- break;
- }
- $SNDM_startoffset += $SNDM_thisTagSize;
-
- $thisfile_riff_WAVE_SNDM_0 ['parsed_raw'] [$SNDM_thisTagKey] = $SNDM_thisTagDataText;
- if (($parsedkey = $this->RIFFwaveSNDMtagLookup ( $SNDM_thisTagKey )) != false) {
- $thisfile_riff_WAVE_SNDM_0 ['parsed'] [$parsedkey] = $SNDM_thisTagDataText;
- } else {
- $info ['warning'] [] = 'RIFF.WAVE.SNDM contains unknown tag "' . $SNDM_thisTagKey . '" at offset ' . $SNDM_startoffset . ' (file offset ' . ($thisfile_riff_WAVE_SNDM_0 ['offset'] + $SNDM_startoffset) . ')';
- }
- }
-
- $tagmapping = array (
- 'tracktitle' => 'title',
- 'category' => 'genre',
- 'cdtitle' => 'album',
- 'tracktitle' => 'title' );
- foreach ( $tagmapping as $fromkey => $tokey ) {
- if (isset ( $thisfile_riff_WAVE_SNDM_0 ['parsed'] [$fromkey] )) {
- $thisfile_riff ['comments'] [$tokey] [] = $thisfile_riff_WAVE_SNDM_0 ['parsed'] [$fromkey];
- }
- }
- }
-
- if (isset ( $thisfile_riff_WAVE ['iXML'] [0] ['data'] )) {
- // requires functions simplexml_load_string and get_object_vars
- if (($parsedXML = getid3_lib::XML2array ( $thisfile_riff_WAVE ['iXML'] [0] ['data'] )) != false) {
- $thisfile_riff_WAVE ['iXML'] [0] ['parsed'] = $parsedXML;
- if (isset ( $parsedXML ['SPEED'] ['MASTER_SPEED'] )) {
- @list ( $numerator, $denominator ) = explode ( '/', $parsedXML ['SPEED'] ['MASTER_SPEED'] );
- $thisfile_riff_WAVE ['iXML'] [0] ['master_speed'] = $numerator / ($denominator ? $denominator : 1000);
- }
- if (isset ( $parsedXML ['SPEED'] ['TIMECODE_RATE'] )) {
- @list ( $numerator, $denominator ) = explode ( '/', $parsedXML ['SPEED'] ['TIMECODE_RATE'] );
- $thisfile_riff_WAVE ['iXML'] [0] ['timecode_rate'] = $numerator / ($denominator ? $denominator : 1000);
- }
- if (isset ( $parsedXML ['SPEED'] ['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO'] ) && ! empty ( $parsedXML ['SPEED'] ['TIMESTAMP_SAMPLE_RATE'] ) && ! empty ( $thisfile_riff_WAVE ['iXML'] [0] ['timecode_rate'] )) {
- $samples_since_midnight = floatval ( ltrim ( $parsedXML ['SPEED'] ['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI'] . $parsedXML ['SPEED'] ['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO'], '0' ) );
- $thisfile_riff_WAVE ['iXML'] [0] ['timecode_seconds'] = $samples_since_midnight / $parsedXML ['SPEED'] ['TIMESTAMP_SAMPLE_RATE'];
- $h = floor ( $thisfile_riff_WAVE ['iXML'] [0] ['timecode_seconds'] / 3600 );
- $m = floor ( ($thisfile_riff_WAVE ['iXML'] [0] ['timecode_seconds'] - ($h * 3600)) / 60 );
- $s = floor ( $thisfile_riff_WAVE ['iXML'] [0] ['timecode_seconds'] - ($h * 3600) - ($m * 60) );
- $f = ($thisfile_riff_WAVE ['iXML'] [0] ['timecode_seconds'] - ($h * 3600) - ($m * 60) - $s) * $thisfile_riff_WAVE ['iXML'] [0] ['timecode_rate'];
- $thisfile_riff_WAVE ['iXML'] [0] ['timecode_string'] = sprintf ( '%02d:%02d:%02d:%05.2f', $h, $m, $s, $f );
- $thisfile_riff_WAVE ['iXML'] [0] ['timecode_string_round'] = sprintf ( '%02d:%02d:%02d:%02d', $h, $m, $s, round ( $f ) );
- }
- unset ( $parsedXML );
- }
- }
-
- if (! isset ( $thisfile_audio ['bitrate'] ) && isset ( $thisfile_riff_audio [$streamindex] ['bitrate'] )) {
- $thisfile_audio ['bitrate'] = $thisfile_riff_audio [$streamindex] ['bitrate'];
- $info ['playtime_seconds'] = ( float ) ((($info ['avdataend'] - $info ['avdataoffset']) * 8) / $thisfile_audio ['bitrate']);
- }
-
- if (! empty ( $info ['wavpack'] )) {
- $thisfile_audio_dataformat = 'wavpack';
- $thisfile_audio ['bitrate_mode'] = 'vbr';
- $thisfile_audio ['encoder'] = 'WavPack v' . $info ['wavpack'] ['version'];
-
- // Reset to the way it was - RIFF parsing will have messed this up
- $info ['avdataend'] = $Original ['avdataend'];
- $thisfile_audio ['bitrate'] = (($info ['avdataend'] - $info ['avdataoffset']) * 8) / $info ['playtime_seconds'];
-
- fseek ( $this->getid3->fp, $info ['avdataoffset'] - 44, SEEK_SET );
- $RIFFdata = fread ( $this->getid3->fp, 44 );
- $OrignalRIFFheaderSize = getid3_lib::LittleEndian2Int ( substr ( $RIFFdata, 4, 4 ) ) + 8;
- $OrignalRIFFdataSize = getid3_lib::LittleEndian2Int ( substr ( $RIFFdata, 40, 4 ) ) + 44;
-
- if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) {
- $info ['avdataend'] -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
- fseek ( $this->getid3->fp, $info ['avdataend'], SEEK_SET );
- $RIFFdata .= fread ( $this->getid3->fp, $OrignalRIFFheaderSize - $OrignalRIFFdataSize );
- }
-
- // move the data chunk after all other chunks (if any)
- // so that the RIFF parser doesn't see EOF when trying
- // to skip over the data chunk
- $RIFFdata = substr ( $RIFFdata, 0, 36 ) . substr ( $RIFFdata, 44 ) . substr ( $RIFFdata, 36, 8 );
- $getid3_riff = new getid3_riff ( $this->getid3 );
- $getid3_riff->ParseRIFFdata ( $RIFFdata );
- unset ( $getid3_riff );
- }
-
- if (isset ( $thisfile_riff_raw ['fmt '] ['wFormatTag'] )) {
- switch ($thisfile_riff_raw ['fmt '] ['wFormatTag']) {
- case 0x0001 : // PCM
- if (! empty ( $info ['ac3'] )) {
- // Dolby Digital WAV files masquerade as PCM-WAV, but they're not
- $thisfile_audio ['wformattag'] = 0x2000;
- $thisfile_audio ['codec'] = $this->RIFFwFormatTagLookup ( $thisfile_audio ['wformattag'] );
- $thisfile_audio ['lossless'] = false;
- $thisfile_audio ['bitrate'] = $info ['ac3'] ['bitrate'];
- $thisfile_audio ['sample_rate'] = $info ['ac3'] ['sample_rate'];
- }
- break;
- case 0x08AE : // ClearJump LiteWave
- $thisfile_audio ['bitrate_mode'] = 'vbr';
- $thisfile_audio_dataformat = 'litewave';
-
- //typedef struct tagSLwFormat {
- // WORD m_wCompFormat; // low byte defines compression method, high byte is compression flags
- // DWORD m_dwScale; // scale factor for lossy compression
- // DWORD m_dwBlockSize; // number of samples in encoded blocks
- // WORD m_wQuality; // alias for the scale factor
- // WORD m_wMarkDistance; // distance between marks in bytes
- // WORD m_wReserved;
- //
- // //following paramters are ignored if CF_FILESRC is not set
- // DWORD m_dwOrgSize; // original file size in bytes
- // WORD m_bFactExists; // indicates if 'fact' chunk exists in the original file
- // DWORD m_dwRiffChunkSize; // riff chunk size in the original file
- //
- // PCMWAVEFORMAT m_OrgWf; // original wave format
- // }SLwFormat, *PSLwFormat;
-
- // shortcut
- $thisfile_riff ['litewave'] ['raw'] = array ();
- $thisfile_riff_litewave = &$thisfile_riff ['litewave'];
- $thisfile_riff_litewave_raw = &$thisfile_riff_litewave ['raw'];
-
- $thisfile_riff_litewave_raw ['compression_method'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE ['fmt '] [0] ['data'], 18, 1 ) );
- $thisfile_riff_litewave_raw ['compression_flags'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE ['fmt '] [0] ['data'], 19, 1 ) );
- $thisfile_riff_litewave_raw ['m_dwScale'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE ['fmt '] [0] ['data'], 20, 4 ) );
- $thisfile_riff_litewave_raw ['m_dwBlockSize'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE ['fmt '] [0] ['data'], 24, 4 ) );
- $thisfile_riff_litewave_raw ['m_wQuality'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE ['fmt '] [0] ['data'], 28, 2 ) );
- $thisfile_riff_litewave_raw ['m_wMarkDistance'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE ['fmt '] [0] ['data'], 30, 2 ) );
- $thisfile_riff_litewave_raw ['m_wReserved'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE ['fmt '] [0] ['data'], 32, 2 ) );
- $thisfile_riff_litewave_raw ['m_dwOrgSize'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE ['fmt '] [0] ['data'], 34, 4 ) );
- $thisfile_riff_litewave_raw ['m_bFactExists'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE ['fmt '] [0] ['data'], 38, 2 ) );
- $thisfile_riff_litewave_raw ['m_dwRiffChunkSize'] = getid3_lib::LittleEndian2Int ( substr ( $thisfile_riff_WAVE ['fmt '] [0] ['data'], 40, 4 ) );
-
- //$thisfile_riff_litewave['quality_factor'] = intval(round((2000 - $thisfile_riff_litewave_raw['m_dwScale']) / 20));
- $thisfile_riff_litewave ['quality_factor'] = $thisfile_riff_litewave_raw ['m_wQuality'];
-
- $thisfile_riff_litewave ['flags'] ['raw_source'] = ($thisfile_riff_litewave_raw ['compression_flags'] & 0x01) ? false : true;
- $thisfile_riff_litewave ['flags'] ['vbr_blocksize'] = ($thisfile_riff_litewave_raw ['compression_flags'] & 0x02) ? false : true;
- $thisfile_riff_litewave ['flags'] ['seekpoints'] = ( bool ) ($thisfile_riff_litewave_raw ['compression_flags'] & 0x04);
-
- $thisfile_audio ['lossless'] = (($thisfile_riff_litewave_raw ['m_wQuality'] == 100) ? true : false);
- $thisfile_audio ['encoder_options'] = '-q' . $thisfile_riff_litewave ['quality_factor'];
- break;
-
- default :
- break;
- }
- }
- if ($info ['avdataend'] > $info ['filesize']) {
- switch (! empty ( $thisfile_audio_dataformat ) ? $thisfile_audio_dataformat : '') {
- case 'wavpack' : // WavPack
- case 'lpac' : // LPAC
- case 'ofr' : // OptimFROG
- case 'ofs' : // OptimFROG DualStream
- // lossless compressed audio formats that keep original RIFF headers - skip warning
- break;
-
- case 'litewave' :
- if (($info ['avdataend'] - $info ['filesize']) == 1) {
- // LiteWave appears to incorrectly *not* pad actual output file
- // to nearest WORD boundary so may appear to be short by one
- // byte, in which case - skip warning
- } else {
- // Short by more than one byte, throw warning
- $info ['warning'] [] = 'Probably truncated file - expecting ' . $thisfile_riff [$RIFFsubtype] ['data'] [0] ['size'] . ' bytes of data, only found ' . ($info ['filesize'] - $info ['avdataoffset']) . ' (short by ' . ($thisfile_riff [$RIFFsubtype] ['data'] [0] ['size'] - ($info ['filesize'] - $info ['avdataoffset'])) . ' bytes)';
- $info ['avdataend'] = $info ['filesize'];
- }
- break;
-
- default :
- if ((($info ['avdataend'] - $info ['filesize']) == 1) && (($thisfile_riff [$RIFFsubtype] ['data'] [0] ['size'] % 2) == 0) && ((($info ['filesize'] - $info ['avdataoffset']) % 2) == 1)) {
- // output file appears to be incorrectly *not* padded to nearest WORD boundary
- // Output less severe warning
- $info ['warning'] [] = 'File should probably be padded to nearest WORD boundary, but it is not (expecting ' . $thisfile_riff [$RIFFsubtype] ['data'] [0] ['size'] . ' bytes of data, only found ' . ($info ['filesize'] - $info ['avdataoffset']) . ' therefore short by ' . ($thisfile_riff [$RIFFsubtype] ['data'] [0] ['size'] - ($info ['filesize'] - $info ['avdataoffset'])) . ' bytes)';
- $info ['avdataend'] = $info ['filesize'];
- } else {
- // Short by more than one byte, throw warning
- $info ['warning'] [] = 'Probably truncated file - expecting ' . $thisfile_riff [$RIFFsubtype] ['data'] [0] ['size'] . ' bytes of data, only found ' . ($info ['filesize'] - $info ['avdataoffset']) . ' (short by ' . ($thisfile_riff [$RIFFsubtype] ['data'] [0] ['size'] - ($info ['filesize'] - $info ['avdataoffset'])) . ' bytes)';
- $info ['avdataend'] = $info ['filesize'];
- }
- break;
- }
- }
- if (! empty ( $info ['mpeg'] ['audio'] ['LAME'] ['audio_bytes'] )) {
- if ((($info ['avdataend'] - $info ['avdataoffset']) - $info ['mpeg'] ['audio'] ['LAME'] ['audio_bytes']) == 1) {
- $info ['avdataend'] --;
- $info ['warning'] [] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored';
- }
- }
- if (isset ( $thisfile_audio_dataformat ) && ($thisfile_audio_dataformat == 'ac3')) {
- unset ( $thisfile_audio ['bits_per_sample'] );
- if (! empty ( $info ['ac3'] ['bitrate'] ) && ($info ['ac3'] ['bitrate'] != $thisfile_audio ['bitrate'])) {
- $thisfile_audio ['bitrate'] = $info ['ac3'] ['bitrate'];
- }
- }
- break;
-
- case 'AVI ' :
- $thisfile_video ['bitrate_mode'] = 'vbr'; // maybe not, but probably
- $thisfile_video ['dataformat'] = 'avi';
- $info ['mime_type'] = 'video/avi';
-
- if (isset ( $thisfile_riff [$RIFFsubtype] ['movi'] ['offset'] )) {
- $info ['avdataoffset'] = $thisfile_riff [$RIFFsubtype] ['movi'] ['offset'] + 8;
- if (isset ( $thisfile_riff ['AVIX'] )) {
- $info ['avdataend'] = $thisfile_riff ['AVIX'] [(count ( $thisfile_riff ['AVIX'] ) - 1)] ['chunks'] ['movi'] ['offset'] + $thisfile_riff ['AVIX'] [(count ( $thisfile_riff ['AVIX'] ) - 1)] ['chunks'] ['movi'] ['size'];
- } else {
- $info ['avdataend'] = $thisfile_riff ['AVI '] ['movi'] ['offset'] + $thisfile_riff ['AVI '] ['movi'] ['size'];
- }
- if ($info ['avdataend'] > $info ['filesize']) {
- $info ['warning'] [] = 'Probably truncated file - expecting ' . ($info ['avdataend'] - $info ['avdataoffset']) . ' bytes of data, only found ' . ($info ['filesize'] - $info ['avdataoffset']) . ' (short by ' . ($info ['avdataend'] - $info ['filesize']) . ' bytes)';
- $info ['avdataend'] = $info ['filesize'];
- }
- }
-
- if (isset ( $thisfile_riff ['AVI '] ['hdrl'] ['strl'] ['indx'] )) {
- //$bIndexType = array(
- // 0x00 => 'AVI_INDEX_OF_INDEXES',
- // 0x01 => 'AVI_INDEX_OF_CHUNKS',
- // 0x80 => 'AVI_INDEX_IS_DATA',
- //);
- //$bIndexSubtype = array(
- // 0x01 => array(
- // 0x01 => 'AVI_INDEX_2FIELD',
- // ),
- //);
- foreach ( $thisfile_riff ['AVI '] ['hdrl'] ['strl'] ['indx'] as $streamnumber => $steamdataarray ) {
- $thisfile_riff_avi_hdrl_strl_indx_stream_data = &$thisfile_riff ['AVI '] ['hdrl'] ['strl'] ['indx'] [$streamnumber] ['data'];
-
- $thisfile_riff_raw ['indx'] [$streamnumber] ['wLongsPerEntry'] = $this->EitherEndian2Int ( substr ( $thisfile_riff_avi_hdrl_strl_indx_stream_data, 0, 2 ) );
- $thisfile_riff_raw ['indx'] [$streamnumber] ['bIndexSubType'] = $this->EitherEndian2Int ( substr ( $thisfile_riff_avi_hdrl_strl_indx_stream_data, 2, 1 ) );
- $thisfile_riff_raw ['indx'] [$streamnumber] ['bIndexType'] = $this->EitherEndian2Int ( substr ( $thisfile_riff_avi_hdrl_strl_indx_stream_data, 3, 1 ) );
- $thisfile_riff_raw ['indx'] [$streamnumber] ['nEntriesInUse'] = $this->EitherEndian2Int ( substr ( $thisfile_riff_avi_hdrl_strl_indx_stream_data, 4, 4 ) );
- $thisfile_riff_raw ['indx'] [$streamnumber] ['dwChunkId'] = substr ( $thisfile_riff_avi_hdrl_strl_indx_stream_data, 8, 4 );
- $thisfile_riff_raw ['indx'] [$streamnumber] ['dwReserved'] = $this->EitherEndian2Int ( substr ( $thisfile_riff_avi_hdrl_strl_indx_stream_data, 12, 4 ) );
-
- //$thisfile_riff_raw['indx'][$streamnumber]['bIndexType_name'] = $bIndexType[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']];
- //$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType_name'] = $bIndexSubtype[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']][$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType']];
-
- unset ( $thisfile_riff_avi_hdrl_strl_indx_stream_data );
- }
- }
- if (isset ( $thisfile_riff ['AVI '] ['hdrl'] ['avih'] [$streamindex] ['data'] )) {
- $avihData = $thisfile_riff ['AVI '] ['hdrl'] ['avih'] [$streamindex] ['data'];
-
- // shortcut
- $thisfile_riff_raw ['avih'] = array ();
- $thisfile_riff_raw_avih = &$thisfile_riff_raw ['avih'];
-
- $thisfile_riff_raw_avih ['dwMicroSecPerFrame'] = $this->EitherEndian2Int ( substr ( $avihData, 0, 4 ) ); // frame display rate (or 0L)
- if ($thisfile_riff_raw_avih ['dwMicroSecPerFrame'] == 0) {
- $info ['error'] [] = 'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero';
- return false;
- }
- $thisfile_riff_raw_avih ['dwMaxBytesPerSec'] = $this->EitherEndian2Int ( substr ( $avihData, 4, 4 ) ); // max. transfer rate
- $thisfile_riff_raw_avih ['dwPaddingGranularity'] = $this->EitherEndian2Int ( substr ( $avihData, 8, 4 ) ); // pad to multiples of this size; normally 2K.
- $thisfile_riff_raw_avih ['dwFlags'] = $this->EitherEndian2Int ( substr ( $avihData, 12, 4 ) ); // the ever-present flags
- $thisfile_riff_raw_avih ['dwTotalFrames'] = $this->EitherEndian2Int ( substr ( $avihData, 16, 4 ) ); // # frames in file
- $thisfile_riff_raw_avih ['dwInitialFrames'] = $this->EitherEndian2Int ( substr ( $avihData, 20, 4 ) );
- $thisfile_riff_raw_avih ['dwStreams'] = $this->EitherEndian2Int ( substr ( $avihData, 24, 4 ) );
- $thisfile_riff_raw_avih ['dwSuggestedBufferSize'] = $this->EitherEndian2Int ( substr ( $avihData, 28, 4 ) );
- $thisfile_riff_raw_avih ['dwWidth'] = $this->EitherEndian2Int ( substr ( $avihData, 32, 4 ) );
- $thisfile_riff_raw_avih ['dwHeight'] = $this->EitherEndian2Int ( substr ( $avihData, 36, 4 ) );
- $thisfile_riff_raw_avih ['dwScale'] = $this->EitherEndian2Int ( substr ( $avihData, 40, 4 ) );
- $thisfile_riff_raw_avih ['dwRate'] = $this->EitherEndian2Int ( substr ( $avihData, 44, 4 ) );
- $thisfile_riff_raw_avih ['dwStart'] = $this->EitherEndian2Int ( substr ( $avihData, 48, 4 ) );
- $thisfile_riff_raw_avih ['dwLength'] = $this->EitherEndian2Int ( substr ( $avihData, 52, 4 ) );
-
- $thisfile_riff_raw_avih ['flags'] ['hasindex'] = ( bool ) ($thisfile_riff_raw_avih ['dwFlags'] & 0x00000010);
- $thisfile_riff_raw_avih ['flags'] ['mustuseindex'] = ( bool ) ($thisfile_riff_raw_avih ['dwFlags'] & 0x00000020);
- $thisfile_riff_raw_avih ['flags'] ['interleaved'] = ( bool ) ($thisfile_riff_raw_avih ['dwFlags'] & 0x00000100);
- $thisfile_riff_raw_avih ['flags'] ['trustcktype'] = ( bool ) ($thisfile_riff_raw_avih ['dwFlags'] & 0x00000800);
- $thisfile_riff_raw_avih ['flags'] ['capturedfile'] = ( bool ) ($thisfile_riff_raw_avih ['dwFlags'] & 0x00010000);
- $thisfile_riff_raw_avih ['flags'] ['copyrighted'] = ( bool ) ($thisfile_riff_raw_avih ['dwFlags'] & 0x00020010);
-
- // shortcut
- $thisfile_riff_video [$streamindex] = array ();
- $thisfile_riff_video_current = &$thisfile_riff_video [$streamindex];
-
- if ($thisfile_riff_raw_avih ['dwWidth'] > 0) {
- $thisfile_riff_video_current ['frame_width'] = $thisfile_riff_raw_avih ['dwWidth'];
- $thisfile_video ['resolution_x'] = $thisfile_riff_video_current ['frame_width'];
- }
- if ($thisfile_riff_raw_avih ['dwHeight'] > 0) {
- $thisfile_riff_video_current ['frame_height'] = $thisfile_riff_raw_avih ['dwHeight'];
- $thisfile_video ['resolution_y'] = $thisfile_riff_video_current ['frame_height'];
- }
- if ($thisfile_riff_raw_avih ['dwTotalFrames'] > 0) {
- $thisfile_riff_video_current ['total_frames'] = $thisfile_riff_raw_avih ['dwTotalFrames'];
- $thisfile_video ['total_frames'] = $thisfile_riff_video_current ['total_frames'];
- }
-
- $thisfile_riff_video_current ['frame_rate'] = round ( 1000000 / $thisfile_riff_raw_avih ['dwMicroSecPerFrame'], 3 );
- $thisfile_video ['frame_rate'] = $thisfile_riff_video_current ['frame_rate'];
- }
- if (isset ( $thisfile_riff ['AVI '] ['hdrl'] ['strl'] ['strh'] [0] ['data'] )) {
- if (is_array ( $thisfile_riff ['AVI '] ['hdrl'] ['strl'] ['strh'] )) {
- for($i = 0; $i < count ( $thisfile_riff ['AVI '] ['hdrl'] ['strl'] ['strh'] ); $i ++) {
- if (isset ( $thisfile_riff ['AVI '] ['hdrl'] ['strl'] ['strh'] [$i] ['data'] )) {
- $strhData = $thisfile_riff ['AVI '] ['hdrl'] ['strl'] ['strh'] [$i] ['data'];
- $strhfccType = substr ( $strhData, 0, 4 );
-
- if (isset ( $thisfile_riff ['AVI '] ['hdrl'] ['strl'] ['strf'] [$i] ['data'] )) {
- $strfData = $thisfile_riff ['AVI '] ['hdrl'] ['strl'] ['strf'] [$i] ['data'];
-
- // shortcut
- $thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw ['strf'] [$strhfccType] [$streamindex];
-
- switch ($strhfccType) {
- case 'auds' :
- $thisfile_audio ['bitrate_mode'] = 'cbr';
- $thisfile_audio_dataformat = 'wav';
- if (isset ( $thisfile_riff_audio ) && is_array ( $thisfile_riff_audio )) {
- $streamindex = count ( $thisfile_riff_audio );
- }
-
- $thisfile_riff_audio [$streamindex] = getid3_riff::RIFFparseWAVEFORMATex ( $strfData );
- $thisfile_audio ['wformattag'] = $thisfile_riff_audio [$streamindex] ['raw'] ['wFormatTag'];
-
- // shortcut
- $thisfile_audio ['streams'] [$streamindex] = $thisfile_riff_audio [$streamindex];
- $thisfile_audio_streams_currentstream = &$thisfile_audio ['streams'] [$streamindex];
-
- if ($thisfile_audio_streams_currentstream ['bits_per_sample'] == 0) {
- unset ( $thisfile_audio_streams_currentstream ['bits_per_sample'] );
- }
- $thisfile_audio_streams_currentstream ['wformattag'] = $thisfile_audio_streams_currentstream ['raw'] ['wFormatTag'];
- unset ( $thisfile_audio_streams_currentstream ['raw'] );
-
- // shortcut
- $thisfile_riff_raw ['strf'] [$strhfccType] [$streamindex] = $thisfile_riff_audio [$streamindex] ['raw'];
-
- unset ( $thisfile_riff_audio [$streamindex] ['raw'] );
- $thisfile_audio = getid3_lib::array_merge_noclobber ( $thisfile_audio, $thisfile_riff_audio [$streamindex] );
-
- $thisfile_audio ['lossless'] = false;
- switch ($thisfile_riff_raw_strf_strhfccType_streamindex ['wFormatTag']) {
- case 0x0001 : // PCM
- $thisfile_audio_dataformat = 'wav';
- $thisfile_audio ['lossless'] = true;
- break;
-
- case 0x0050 : // MPEG Layer 2 or Layer 1
- $thisfile_audio_dataformat = 'mp2'; // Assume Layer-2
- break;
-
- case 0x0055 : // MPEG Layer 3
- $thisfile_audio_dataformat = 'mp3';
- break;
-
- case 0x00FF : // AAC
- $thisfile_audio_dataformat = 'aac';
- break;
-
- case 0x0161 : // Windows Media v7 / v8 / v9
- case 0x0162 : // Windows Media Professional v9
- case 0x0163 : // Windows Media Lossess v9
- $thisfile_audio_dataformat = 'wma';
- break;
-
- case 0x2000 : // AC-3
- $thisfile_audio_dataformat = 'ac3';
- break;
-
- case 0x2001 : // DTS
- $thisfile_audio_dataformat = 'dts';
- break;
-
- default :
- $thisfile_audio_dataformat = 'wav';
- break;
- }
- $thisfile_audio_streams_currentstream ['dataformat'] = $thisfile_audio_dataformat;
- $thisfile_audio_streams_currentstream ['lossless'] = $thisfile_audio ['lossless'];
- $thisfile_audio_streams_currentstream ['bitrate_mode'] = $thisfile_audio ['bitrate_mode'];
- break;
-
- case 'iavs' :
- case 'vids' :
- // shortcut
- $thisfile_riff_raw ['strh'] [$i] = array ();
- $thisfile_riff_raw_strh_current = &$thisfile_riff_raw ['strh'] [$i];
-
- $thisfile_riff_raw_strh_current ['fccType'] = substr ( $strhData, 0, 4 ); // same as $strhfccType;
- $thisfile_riff_raw_strh_current ['fccHandler'] = substr ( $strhData, 4, 4 );
- $thisfile_riff_raw_strh_current ['dwFlags'] = $this->EitherEndian2Int ( substr ( $strhData, 8, 4 ) ); // Contains AVITF_* flags
- $thisfile_riff_raw_strh_current ['wPriority'] = $this->EitherEndian2Int ( substr ( $strhData, 12, 2 ) );
- $thisfile_riff_raw_strh_current ['wLanguage'] = $this->EitherEndian2Int ( substr ( $strhData, 14, 2 ) );
- $thisfile_riff_raw_strh_current ['dwInitialFrames'] = $this->EitherEndian2Int ( substr ( $strhData, 16, 4 ) );
- $thisfile_riff_raw_strh_current ['dwScale'] = $this->EitherEndian2Int ( substr ( $strhData, 20, 4 ) );
- $thisfile_riff_raw_strh_current ['dwRate'] = $this->EitherEndian2Int ( substr ( $strhData, 24, 4 ) );
- $thisfile_riff_raw_strh_current ['dwStart'] = $this->EitherEndian2Int ( substr ( $strhData, 28, 4 ) );
- $thisfile_riff_raw_strh_current ['dwLength'] = $this->EitherEndian2Int ( substr ( $strhData, 32, 4 ) );
- $thisfile_riff_raw_strh_current ['dwSuggestedBufferSize'] = $this->EitherEndian2Int ( substr ( $strhData, 36, 4 ) );
- $thisfile_riff_raw_strh_current ['dwQuality'] = $this->EitherEndian2Int ( substr ( $strhData, 40, 4 ) );
- $thisfile_riff_raw_strh_current ['dwSampleSize'] = $this->EitherEndian2Int ( substr ( $strhData, 44, 4 ) );
- $thisfile_riff_raw_strh_current ['rcFrame'] = $this->EitherEndian2Int ( substr ( $strhData, 48, 4 ) );
-
- $thisfile_riff_video_current ['codec'] = getid3_riff::RIFFfourccLookup ( $thisfile_riff_raw_strh_current ['fccHandler'] );
- $thisfile_video ['fourcc'] = $thisfile_riff_raw_strh_current ['fccHandler'];
- if (! $thisfile_riff_video_current ['codec'] && isset ( $thisfile_riff_raw_strf_strhfccType_streamindex ['fourcc'] ) && getid3_riff::RIFFfourccLookup ( $thisfile_riff_raw_strf_strhfccType_streamindex ['fourcc'] )) {
- $thisfile_riff_video_current ['codec'] = getid3_riff::RIFFfourccLookup ( $thisfile_riff_raw_strf_strhfccType_streamindex ['fourcc'] );
- $thisfile_video ['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex ['fourcc'];
- }
- $thisfile_video ['codec'] = $thisfile_riff_video_current ['codec'];
- $thisfile_video ['pixel_aspect_ratio'] = ( float ) 1;
- switch ($thisfile_riff_raw_strh_current ['fccHandler']) {
- case 'HFYU' : // Huffman Lossless Codec
- case 'IRAW' : // Intel YUV Uncompressed
- case 'YUY2' : // Uncompressed YUV 4:2:2
- $thisfile_video ['lossless'] = true;
- break;
-
- default :
- $thisfile_video ['lossless'] = false;
- break;
- }
-
- switch ($strhfccType) {
- case 'vids' :
- $thisfile_riff_raw_strf_strhfccType_streamindex = getid3_riff::ParseBITMAPINFOHEADER ( substr ( $strfData, 0, 40 ), ($info ['fileformat'] == 'riff') );
- //echo '<pre>'.print_r($thisfile_riff_raw_strf_strhfccType_streamindex, true).'</pre>';
- $thisfile_video ['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex ['biBitCount'];
-
- if ($thisfile_riff_video_current ['codec'] == 'DV') {
- $thisfile_riff_video_current ['dv_type'] = 2;
- }
- break;
-
- case 'iavs' :
- $thisfile_riff_video_current ['dv_type'] = 1;
- break;
- }
- break;
-
- defa…
Large files files are truncated, but you can click here to view the full file