diff options
Diffstat (limited to 'modules/getid3/module.audio-video.riff.php')
-rw-r--r-- | modules/getid3/module.audio-video.riff.php | 366 |
1 files changed, 183 insertions, 183 deletions
diff --git a/modules/getid3/module.audio-video.riff.php b/modules/getid3/module.audio-video.riff.php index 5cecd67c..6da6b3bf 100644 --- a/modules/getid3/module.audio-video.riff.php +++ b/modules/getid3/module.audio-video.riff.php @@ -26,8 +26,8 @@ // // $Id: module.audio-video.riff.php,v 1.10 2006/12/03 20:13:17 ah Exp $ - - + + class getid3_riff extends getid3_handler { @@ -35,7 +35,7 @@ class getid3_riff extends getid3_handler public function Analyze() { - + $getid3 = $this->getid3; $getid3->info['riff']['raw'] = array (); @@ -53,11 +53,11 @@ class getid3_riff extends getid3_handler $this->fseek($info_avdataoffset, SEEK_SET); $riff_header = $this->fread(12); - + $riff_sub_type = substr($riff_header, 8, 4); - + switch (substr($riff_header, 0, 4)) { - + case 'FORM': $getid3->info['fileformat'] = 'aiff'; $this->endian_function = 'BigEndian2Int'; @@ -89,18 +89,18 @@ class getid3_riff extends getid3_handler default: throw new getid3_exception('Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$riff_sub_type.'" instead'); } - + $endian_function = $this->endian_function; $stream_index = 0; switch ($riff_sub_type) { case 'WAVE': - + if (empty($info_audio['bitrate_mode'])) { $info_audio['bitrate_mode'] = 'cbr'; } - + if (empty($info_audio_dataformat)) { $info_audio_dataformat = 'wav'; } @@ -109,9 +109,9 @@ class getid3_riff extends getid3_handler $info_avdataoffset = $info_riff_wave['data'][0]['offset'] + 8; $info_avdataend = $info_avdataoffset + $info_riff_wave['data'][0]['size']; } - + if (isset($info_riff_wave['fmt '][0]['data'])) { - + $info_riff_audio[$stream_index] = getid3_riff::RIFFparseWAVEFORMATex($info_riff_wave['fmt '][0]['data']); $info_audio['wformattag'] = $info_riff_audio[$stream_index]['raw']['wFormatTag']; $info_riff_raw['fmt '] = $info_riff_audio[$stream_index]['raw']; @@ -125,11 +125,11 @@ class getid3_riff extends getid3_handler $info_audio['bitrate'] = $info_riff_audio[$stream_index]['bitrate']; $getid3->info['playtime_seconds'] = (float)((($info_avdataend - $info_avdataoffset) * 8) / $info_audio['bitrate']); - + $info_audio['lossless'] = false; if (isset($info_riff_wave['data'][0]['offset']) && isset($info_riff_raw['fmt ']['wFormatTag'])) { - + switch ($info_riff_raw['fmt ']['wFormatTag']) { case 0x0001: // PCM @@ -146,7 +146,7 @@ class getid3_riff extends getid3_handler } } - + $info_audio['streams'][$stream_index]['wformattag'] = $info_audio['wformattag']; $info_audio['streams'][$stream_index]['bitrate_mode'] = $info_audio['bitrate_mode']; $info_audio['streams'][$stream_index]['lossless'] = $info_audio['lossless']; @@ -169,7 +169,7 @@ class getid3_riff extends getid3_handler $n_track_rg_adjust_bit_string = str_pad(decbin($info_riff_raw_rgad['nRadioRgAdjust']), 16, '0', STR_PAD_LEFT); $n_album_rg_adjust_bit_string = str_pad(decbin($info_riff_raw_rgad['nAudiophileRgAdjust']), 16, '0', STR_PAD_LEFT); - + $info_riff_raw_rgad_track['name'] = bindec(substr($n_track_rg_adjust_bit_string, 0, 3)); $info_riff_raw_rgad_track['originator'] = bindec(substr($n_track_rg_adjust_bit_string, 3, 3)); $info_riff_raw_rgad_track['signbit'] = bindec($n_track_rg_adjust_bit_string[6]); @@ -185,7 +185,7 @@ class getid3_riff extends getid3_handler $info_riff['rgad']['track']['originator'] = getid3_lib_replaygain::OriginatorLookup($info_riff_raw_rgad_track['originator']); $info_riff['rgad']['track']['adjustment'] = getid3_lib_replaygain::AdjustmentLookup($info_riff_raw_rgad_track['adjustment'], $info_riff_raw_rgad_track['signbit']); } - + if (($info_riff_raw_rgad_album['name'] != 0) && ($info_riff_raw_rgad_album['originator'] != 0)) { $info_riff['rgad']['album']['name'] = getid3_lib_replaygain::NameLookup($info_riff_raw_rgad_album['name']); $info_riff['rgad']['album']['originator'] = getid3_lib_replaygain::OriginatorLookup($info_riff_raw_rgad_album['originator']); @@ -194,7 +194,7 @@ class getid3_riff extends getid3_handler } if (isset($info_riff_wave['fact'][0]['data'])) { - + $info_riff_raw['fact']['NumberOfSamples'] = getid3_lib::$endian_function(substr($info_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 @@ -202,14 +202,14 @@ class getid3_riff extends getid3_handler // $getid3->info['playtime_seconds'] = (float)$info_riff_raw['fact']['NumberOfSamples'] / $info_riff_raw['fmt ']['nSamplesPerSec']; // } } - - + + if (!empty($info_riff_raw['fmt ']['nAvgBytesPerSec'])) { $info_audio['bitrate'] = (int)$info_riff_raw['fmt ']['nAvgBytesPerSec'] * 8; } if (isset($info_riff_wave['bext'][0]['data'])) { - + $info_riff_wave_bext_0 = &$info_riff_wave['bext'][0]; getid3_lib::ReadSequence('LittleEndian2Int', $info_riff_wave_bext_0, $info_riff_wave_bext_0['data'], 0, @@ -224,11 +224,11 @@ class getid3_riff extends getid3_handler 'reserved' => 254 ) ); - + foreach (array ('title', 'author', 'reference') as $key) { $info_riff_wave_bext_0[$key] = trim($info_riff_wave_bext_0[$key]); } - + $info_riff_wave_bext_0['coding_history'] = explode("\r\n", trim(substr($info_riff_wave_bext_0['data'], 601))); $info_riff_wave_bext_0['origin_date_unix'] = gmmktime(substr($info_riff_wave_bext_0['origin_time'], 0, 2), @@ -243,7 +243,7 @@ class getid3_riff extends getid3_handler } if (isset($info_riff_wave['MEXT'][0]['data'])) { - + $info_riff_wave_mext_0 = &$info_riff_wave['MEXT'][0]; $info_riff_wave_mext_0['raw']['sound_information'] = getid3_lib::LittleEndian2Int(substr($info_riff_wave_mext_0['data'], 0, 2)); @@ -263,7 +263,7 @@ class getid3_riff extends getid3_handler } if (isset($info_riff_wave['cart'][0]['data'])) { - + $info_riff_wave_cart_0 = &$info_riff_wave['cart'][0]; getid3_lib::ReadSequence('LittleEndian2Int', $info_riff_wave_cart_0, $info_riff_wave_cart_0['data'], 0, @@ -285,23 +285,23 @@ class getid3_riff extends getid3_handler 'user_defined_text' => -64, ) ); - + foreach (array ('artist', 'cut_id', 'client_id', 'category', 'classification', 'out_cue', 'start_date', 'start_time', 'end_date', 'end_time', 'producer_app_id', 'producer_app_version', 'user_defined_text') as $key) { $info_riff_wave_cart_0[$key] = trim($info_riff_wave_cart_0[$key]); } - + $info_riff_wave_cart_0['zero_db_reference'] = getid3_lib::LittleEndian2Int(substr($info_riff_wave_cart_0['data'], 680, 4), true); - + for ($i = 0; $i < 8; $i++) { $info_riff_wave_cart_0['post_time'][$i]['usage_fourcc'] = substr($info_riff_wave_cart_0['data'], 684 + ($i * 8), 4); $info_riff_wave_cart_0['post_time'][$i]['timer_value'] = getid3_lib::LittleEndian2Int(substr($info_riff_wave_cart_0['data'], 684 + ($i * 8) + 4, 4)); - } + } $info_riff_wave_cart_0['url'] = trim(substr($info_riff_wave_cart_0['data'], 748, 1024)); $info_riff_wave_cart_0['tag_text'] = explode("\r\n", trim(substr($info_riff_wave_cart_0['data'], 1772))); - + $info_riff['comments']['artist'][] = $info_riff_wave_cart_0['artist']; $info_riff['comments']['title'][] = $info_riff_wave_cart_0['title']; - } + } if (!isset($info_audio['bitrate']) && isset($info_riff_audio[$stream_index]['bitrate'])) { $info_audio['bitrate'] = $info_riff_audio[$stream_index]['bitrate']; @@ -309,28 +309,28 @@ class getid3_riff extends getid3_handler } if (@$getid3->info['wavpack']) { - + if (!$this->data_string_flag) { - + $info_audio_dataformat = 'wavpack'; $info_audio['bitrate_mode'] = 'vbr'; $info_audio['encoder'] = 'WavPack v'.$getid3->info['wavpack']['version']; - + // Reset to the way it was - RIFF parsing will have messed this up $info_avdataend = $original['avdataend']; $info_audio['bitrate'] = (($info_avdataend - $info_avdataoffset) * 8) / $getid3->info['playtime_seconds']; - + $this->fseek($info_avdataoffset - 44, SEEK_SET); $riff_data = $this->fread(44); $orignal_riff_header_size = getid3_lib::LittleEndian2Int(substr($riff_data, 4, 4)) + 8; $orignal_riff_data_size = getid3_lib::LittleEndian2Int(substr($riff_data, 40, 4)) + 44; - + if ($orignal_riff_header_size > $orignal_riff_data_size) { $info_avdataend -= ($orignal_riff_header_size - $orignal_riff_data_size); $this->fseek($info_avdataend, SEEK_SET); $riff_data .= $this->fread($orignal_riff_header_size - $orignal_riff_data_size); } - + // 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 @@ -339,18 +339,18 @@ class getid3_riff extends getid3_handler // Save audio info key $saved_info_audio = $info_audio; - // Analyze riff_data + // Analyze riff_data $this->AnalyzeString($riff_data); - + // Restore info key $info_audio = $saved_info_audio; } } if (isset($info_riff_raw['fmt ']['wFormatTag'])) { - + switch ($info_riff_raw['fmt ']['wFormatTag']) { - + case 0x08AE: // ClearJump LiteWave $info_audio['bitrate_mode'] = 'vbr'; $info_audio_dataformat = 'litewave'; @@ -436,7 +436,7 @@ class getid3_riff extends getid3_handler $getid3->warning('File should probably be padded to nearest WORD boundary, but it is not (expecting '.$info_riff[$riff_sub_type]['data'][0]['size'].' bytes of data, only found '.($getid3->info['filesize'] - $info_avdataoffset).' therefore short by '.($info_riff[$riff_sub_type]['data'][0]['size'] - ($getid3->info['filesize'] - $info_avdataoffset)).' bytes)'); $info_avdataend = $getid3->info['filesize']; break; - + } // Short by more than one byte, throw warning $getid3->warning('Probably truncated file - expecting '.$info_riff[$riff_sub_type]['data'][0]['size'].' bytes of data, only found '.($getid3->info['filesize'] - $info_avdataoffset).' (short by '.($info_riff[$riff_sub_type]['data'][0]['size'] - ($getid3->info['filesize'] - $info_avdataoffset)).' bytes)'); @@ -444,14 +444,14 @@ class getid3_riff extends getid3_handler break; } } - + if (!empty($getid3->info['mpeg']['audio']['LAME']['audio_bytes'])) { if ((($info_avdataend - $info_avdataoffset) - $getid3->info['mpeg']['audio']['LAME']['audio_bytes']) == 1) { $info_avdataend--; $getid3->warning('Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored'); } } - + if (@$info_audio_dataformat == 'ac3') { unset($info_audio['bits_per_sample']); if (!empty($getid3->info['ac3']['bitrate']) && ($getid3->info['ac3']['bitrate'] != $info_audio['bitrate'])) { @@ -480,8 +480,8 @@ class getid3_riff extends getid3_handler $info_riff_raw['avih'] = array (); $info_riff_raw_avih = &$info_riff_raw['avih']; - - getid3_lib::ReadSequence($this->endian_function, $info_riff_raw_avih, $avihData, 0, + + getid3_lib::ReadSequence($this->endian_function, $info_riff_raw_avih, $avihData, 0, array ( 'dwMicroSecPerFrame' => 4, // frame display rate (or 0L) 'dwMaxBytesPerSec' => 4, // max. transfer rate @@ -514,12 +514,12 @@ class getid3_riff extends getid3_handler $info_riff_video_current['frame_width'] = $info_riff_raw_avih['dwWidth']; $info_video['resolution_x'] = $info_riff_video_current['frame_width']; } - + if ($info_riff_raw_avih['dwHeight'] > 0) { $info_riff_video_current['frame_height'] = $info_riff_raw_avih['dwHeight']; $info_video['resolution_y'] = $info_riff_video_current['frame_height']; } - + if ($info_riff_raw_avih['dwTotalFrames'] > 0) { $info_riff_video_current['total_frames'] = $info_riff_raw_avih['dwTotalFrames']; $info_video['total_frames'] = $info_riff_video_current['total_frames']; @@ -528,7 +528,7 @@ class getid3_riff extends getid3_handler $info_riff_video_current['frame_rate'] = round(1000000 / $info_riff_raw_avih['dwMicroSecPerFrame'], 3); $info_video['frame_rate'] = $info_riff_video_current['frame_rate']; } - + if (isset($info_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) { if (is_array($info_riff['AVI ']['hdrl']['strl']['strh'])) { for ($i = 0; $i < count($info_riff['AVI ']['hdrl']['strl']['strh']); $i++) { @@ -571,7 +571,7 @@ class getid3_riff extends getid3_handler $info_audio['lossless'] = false; switch ($info_riff_raw_strf_strh_fcc_type_stream_index['wFormatTag']) { - + case 0x0001: // PCM $info_audio_dataformat = 'wav'; $info_audio['lossless'] = true; @@ -618,8 +618,8 @@ class getid3_riff extends getid3_handler // shortcut $info_riff_raw['strh'][$i] = array (); $info_riff_raw_strh_current = &$info_riff_raw['strh'][$i]; - - getid3_lib::ReadSequence($this->endian_function, $info_riff_raw_strh_current, $strh_data, 0, + + getid3_lib::ReadSequence($this->endian_function, $info_riff_raw_strh_current, $strh_data, 0, array ( 'fccType' => -4, // same as $strh_fcc_type; 'fccHandler' => -4, @@ -640,17 +640,17 @@ class getid3_riff extends getid3_handler $info_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($info_riff_raw_strh_current['fccHandler']); $info_video['fourcc'] = $info_riff_raw_strh_current['fccHandler']; - + if (!$info_riff_video_current['codec'] && isset($info_riff_raw_strf_strh_fcc_type_stream_index['fourcc']) && getid3_riff::RIFFfourccLookup($info_riff_raw_strf_strh_fcc_type_stream_index['fourcc'])) { $info_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($info_riff_raw_strf_strh_fcc_type_stream_index['fourcc']); $info_video['fourcc'] = $info_riff_raw_strf_strh_fcc_type_stream_index['fourcc']; } - + $info_video['codec'] = $info_riff_video_current['codec']; $info_video['pixel_aspect_ratio'] = (float)1; - + switch ($info_riff_raw_strh_current['fccHandler']) { - + case 'HFYU': // Huffman Lossless Codec case 'IRAW': // Intel YUV Uncompressed case 'YUY2': // Uncompressed YUV 4:2:2 @@ -663,7 +663,7 @@ class getid3_riff extends getid3_handler } switch ($strh_fcc_type) { - + case 'vids': getid3_lib::ReadSequence($this->endian_function, $info_riff_raw_strf_strh_fcc_type_stream_index, $strf_data, 0, array ( @@ -709,7 +709,7 @@ class getid3_riff extends getid3_handler $info_video['fourcc'] = $info_riff_raw_strf_strh_fcc_type_stream_index['fourcc']; switch ($info_riff_raw_strf_strh_fcc_type_stream_index['fourcc']) { - + case 'HFYU': // Huffman Lossless Codec case 'IRAW': // Intel YUV Uncompressed case 'YUY2': // Uncompressed YUV 4:2:2 @@ -739,10 +739,10 @@ class getid3_riff extends getid3_handler $info_avdataoffset = 44; if (isset($info_riff['CDDA']['fmt '][0]['data'])) { - + $info_riff_cdda_fmt_0 = &$info_riff['CDDA']['fmt '][0]; - getid3_lib::ReadSequence($this->endian_function, $info_riff_cdda_fmt_0, $info_riff_cdda_fmt_0['data'], 0, + getid3_lib::ReadSequence($this->endian_function, $info_riff_cdda_fmt_0, $info_riff_cdda_fmt_0['data'], 0, array ( 'unknown1' => 2, 'track_num' => 2, @@ -804,9 +804,9 @@ class getid3_riff extends getid3_handler $info_riff_audio['codec_fourcc'] = substr($info_riff_RIFFsubtype_COMM_0_data, 18, 4); $codec_name_size = getid3_lib::BigEndian2Int(substr($info_riff_RIFFsubtype_COMM_0_data, 22, 1)); $info_riff_audio['codec_name'] = substr($info_riff_RIFFsubtype_COMM_0_data, 23, $codec_name_size); - + switch ($info_riff_audio['codec_name']) { - + case 'NONE': $info_audio['codec'] = 'Pulse Code Modulation (PCM)'; $info_audio['lossless'] = true; @@ -814,7 +814,7 @@ class getid3_riff extends getid3_handler case '': switch ($info_riff_audio['codec_fourcc']) { - + // http://developer.apple.com/qa/snd/snd07.html case 'sowt': $info_riff_audio['codec_name'] = 'Two\'s Compliment Little-Endian PCM'; @@ -839,31 +839,31 @@ class getid3_riff extends getid3_handler } $info_audio['channels'] = $info_riff_audio['channels']; - + if ($info_riff_audio['bits_per_sample'] > 0) { $info_audio['bits_per_sample'] = $info_riff_audio['bits_per_sample']; } - + $info_audio['sample_rate'] = $info_riff_audio['sample_rate']; $getid3->info['playtime_seconds'] = $info_riff_audio['total_samples'] / $info_audio['sample_rate']; } if (isset($info_riff[$riff_sub_type]['COMT'])) { - + $comment_count = getid3_lib::BigEndian2Int(substr($info_riff[$riff_sub_type]['COMT'][0]['data'], 0, 2)); $offset = 2; - + for ($i = 0; $i < $comment_count; $i++) { - + $getid3->info['comments_raw'][$i]['timestamp'] = getid3_lib::BigEndian2Int( substr($info_riff[$riff_sub_type]['COMT'][0]['data'], $offset, 4)); - $offset += 4; - + $offset += 4; + $getid3->info['comments_raw'][$i]['marker_id'] = getid3_lib::BigEndianSyncSafe2Int(substr($info_riff[$riff_sub_type]['COMT'][0]['data'], $offset, 2)); - $offset += 2; - + $offset += 2; + $comment_length = getid3_lib::BigEndian2Int( substr($info_riff[$riff_sub_type]['COMT'][0]['data'], $offset, 2)); - $offset += 2; - + $offset += 2; + $getid3->info['comments_raw'][$i]['comment'] = substr($info_riff[$riff_sub_type]['COMT'][0]['data'], $offset, $comment_length); $offset += $comment_length; @@ -899,7 +899,7 @@ class getid3_riff extends getid3_handler // shortcut $info_riff_riff_sub_type_vhdr_0 = &$info_riff[$riff_sub_type]['VHDR'][0]; - getid3_lib::ReadSequence('BigEndian2Int', $info_riff_riff_sub_type_vhdr_0, $info_riff_riff_sub_type_vhdr_0['data'], 0, + getid3_lib::ReadSequence('BigEndian2Int', $info_riff_riff_sub_type_vhdr_0, $info_riff_riff_sub_type_vhdr_0['data'], 0, array ( 'oneShotHiSamples' => 4, 'repeatHiSamples' => 4, @@ -910,7 +910,7 @@ class getid3_riff extends getid3_handler 'Volume' => -4 ) ); - + $info_riff_riff_sub_type_vhdr_0['Volume'] = getid3_riff::FixedPoint16_16($info_riff_riff_sub_type_vhdr_0['Volume']); $info_audio['sample_rate'] = $info_riff_riff_sub_type_vhdr_0['samplesPerSec']; @@ -967,25 +967,25 @@ class getid3_riff extends getid3_handler case 'CDXA': - + $getid3->info['mime_type'] = 'video/mpeg'; if (!empty($info_riff['CDXA']['data'][0]['size'])) { $GETID3_ERRORARRAY = &$getid3->info['warning']; - + if (!$getid3->include_module_optional('audio-video.mpeg')) { $getid3->warning('MPEG skipped because mpeg module is missing.'); } - + else { - + // Clone getid3 - messing with offsets - better safe than sorry $clone = clone $getid3; - + // Analyse $mpeg = new getid3_mpeg($clone); $mpeg->Analyze(); - // Import from clone and destroy + // Import from clone and destroy $getid3->info['audio'] = $clone->info['audio']; $getid3->info['video'] = $clone->info['video']; $getid3->info['mpeg'] = $clone->info['mpeg']; @@ -994,26 +994,26 @@ class getid3_riff extends getid3_handler unset($clone); } } - + break; default: throw new getid3_exception('Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$riff_sub_type.'" instead'); } - - + + if (@$info_riff_raw['fmt ']['wFormatTag'] == 1) { - + // http://www.mega-nerd.com/erikd/Blog/Windiots/dts.html $this->fseek($getid3->info['avdataoffset'], SEEK_SET); $bytes4 = $this->fread(4); - + // DTSWAV if (preg_match('/^\xFF\x1F\x00\xE8/s', $bytes4)) { $info_audio_dataformat = 'dts'; - } - + } + // DTS, but this probably shouldn't happen elseif (preg_match('/^\x7F\xFF\x80\x01/s', $bytes4)) { $info_audio_dataformat = 'dts'; @@ -1023,13 +1023,13 @@ class getid3_riff extends getid3_handler if (@is_array($info_riff_wave['DISP'])) { $info_riff['comments']['title'][] = trim(substr($info_riff_wave['DISP'][count($info_riff_wave['DISP']) - 1]['data'], 4)); } - + if (@is_array($info_riff_wave['INFO'])) { getid3_riff::RIFFCommentsParse($info_riff_wave['INFO'], $info_riff['comments']); } - + if (isset($info_riff_wave['INFO']) && is_array($info_riff_wave['INFO'])) { - + foreach (array ('IARL' => 'archivallocation', 'IART' => 'artist', 'ICDS' => 'costumedesigner', 'ICMS' => 'commissionedby', 'ICMT' => 'comment', 'ICNT' => 'country', 'ICOP' => 'copyright', 'ICRD' => 'creationdate', 'IDIM' => 'dimensions', 'IDIT' => 'digitizationdate', 'IDPI' => 'resolution', 'IDST' => 'distributor', 'IEDT' => 'editor', 'IENG' => 'engineers', 'IFRM' => 'accountofparts', 'IGNR' => 'genre', 'IKEY' => 'keywords', 'ILGT' => 'lightness', 'ILNG' => 'language', 'IMED' => 'orignalmedium', 'IMUS' => 'composer', 'INAM' => 'title', 'IPDS' => 'productiondesigner', 'IPLT' => 'palette', 'IPRD' => 'product', 'IPRO' => 'producer', 'IPRT' => 'part', 'IRTD' => 'rating', 'ISBJ' => 'subject', 'ISFT' => 'software', 'ISGN' => 'secondarygenre', 'ISHP' => 'sharpness', 'ISRC' => 'sourcesupplier', 'ISRF' => 'digitizationsource', 'ISTD' => 'productionstudio', 'ISTR' => 'starring', 'ITCH' => 'encoded_by', 'IWEB' => 'url', 'IWRI' => 'writer') as $key => $value) { if (isset($info_riff_wave['INFO'][$key])) { foreach ($info_riff_wave['INFO'][$key] as $comment_id => $comment_data) { @@ -1157,34 +1157,34 @@ class getid3_riff extends getid3_handler public function ParseRIFF($start_offset, $max_offset) { - + $getid3 = $this->getid3; - + $info = &$getid3->info; - + $endian_function = $this->endian_function; $max_offset = min($max_offset, $info['avdataend']); - + $riff_chunk = false; $this->fseek($start_offset, SEEK_SET); - + while ($this->ftell() < $max_offset) { - + $chunk_name = $this->fread(4); - + if (strlen($chunk_name) < 4) { throw new getid3_exception('Expecting chunk name at offset '.($this->ftell() - 4).' but found nothing. Aborting RIFF parsing.'); } - + $chunk_size = getid3_lib::$endian_function($this->fread(4)); - + if ($chunk_size == 0) { continue; throw new getid3_exception('Chunk size at offset '.($this->ftell() - 4).' is zero. Aborting RIFF parsing.'); } - + if (($chunk_size % 2) != 0) { // all structures are packed on word boundaries $chunk_size++; @@ -1194,16 +1194,16 @@ class getid3_riff extends getid3_handler case 'LIST': $list_name = $this->fread(4); - + switch ($list_name) { - + case 'movi': case 'rec ': $riff_chunk[$list_name]['offset'] = $this->ftell() - 4; $riff_chunk[$list_name]['size'] = $chunk_size; static $parsed_audio_stream = false; - + if (!$parsed_audio_stream) { $where_we_were = $this->ftell(); $audio_chunk_header = $this->fread(12); @@ -1214,62 +1214,62 @@ class getid3_riff extends getid3_handler if ($audio_chunk_stream_type == 'wb') { $first_four_bytes = substr($audio_chunk_header, 8, 4); - + //// MPEG - + if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $first_four_bytes)) { if (!$getid3->include_module_optional('audio.mp3')) { $getid3->warning('MP3 skipped because mp3 module is missing.'); } - + elseif (getid3_mp3::MPEGaudioHeaderBytesValid($first_four_bytes)) { - + // Clone getid3 - messing with offsets - better safe than sorry $clone = clone $getid3; $clone->info['avdataoffset'] = $this->ftell() - 4; $clone->info['avdataend'] = $this->ftell() + $audio_chunk_size; - + $mp3 = new getid3_mp3($clone); $mp3->AnalyzeMPEGaudioInfo(); - + // Import from clone and destroy if (isset($clone->info['mpeg']['audio'])) { - + $info['mpeg']['audio'] = $clone->info['mpeg']['audio']; - + $info['audio']['dataformat'] = 'mp'.$info['mpeg']['audio']['layer']; $info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate']; $info['audio']['channels'] = $info['mpeg']['audio']['channels']; $info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate']; $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']); $info['bitrate'] = $info['audio']['bitrate']; - + $getid3->warning($clone->warnings()); unset($clone); } } - } - + } + //// AC3-WAVE - + elseif (preg_match('/^\x0B\x77/s', $first_four_bytes)) { if (!$getid3->include_module_optional('audio.ac3')) { $getid3->warning('AC3 skipped because ac3 module is missing.'); } - + else { - + // Clone getid3 - messing with offsets - better safe than sorry $clone = clone $getid3; - $clone->info['avdataoffset'] = $this->ftell() - 4; + $clone->info['avdataoffset'] = $this->ftell() - 4; $clone->info['avdataend'] = $this->ftell() + $audio_chunk_size; - + // Analyze clone by fp $ac3 = new getid3_ac3($clone); $ac3->Analyze(); - + // Import from clone and destroy $info['audio'] = $clone->info['audio']; $info['ac3'] = $clone->info['ac3']; @@ -1301,7 +1301,7 @@ class getid3_riff extends getid3_handler default: - + $this_index = 0; if (isset($riff_chunk[$chunk_name]) && is_array($riff_chunk[$chunk_name])) { $this_index = count($riff_chunk[$chunk_name]); @@ -1319,33 +1319,33 @@ class getid3_riff extends getid3_handler //// This is probably MP3 data if ((strlen($riff_data_chunk_contents_test) > 0) && preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($riff_data_chunk_contents_test, 0, 4))) { - + try { - + if (!$getid3->include_module_optional('audio.mp3')) { $getid3->warning('MP3 skipped because mp3 module is missing.'); } - - + + // Clone getid3 - messing with offsets - better safe than sorry $clone = clone $getid3; - + if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($riff_data_chunk_contents_test, 0, 4))) { - + $mp3 = new getid3_mp3($clone); $mp3->AnalyzeMPEGaudioInfo(); - + // Import from clone and destroy if (isset($clone->info['mpeg']['audio'])) { - + $info['mpeg']['audio'] = $clone->info['mpeg']['audio']; - + $info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate']; $info['audio']['channels'] = $info['mpeg']['audio']['channels']; $info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate']; $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']); $info['bitrate'] = $info['audio']['bitrate']; - + $getid3->warning($clone->warnings()); unset($clone); } @@ -1354,66 +1354,66 @@ class getid3_riff extends getid3_handler catch (Exception $e) { // do nothing - not MP3 data } - } - - + } + + //// This is probably AC-3 data - + elseif ((strlen($riff_data_chunk_contents_test) > 0) && (substr($riff_data_chunk_contents_test, 0, 2) == "\x0B\x77")) { if (!$getid3->include_module_optional('audio.ac3')) { $getid3->warning('AC3 skipped because ac3 module is missing.'); } - + else { // Clone getid3 - messing with offsets - better safe than sorry $clone = clone $getid3; $clone->info['avdataoffset'] = $riff_chunk[$chunk_name][$this_index]['offset']; $clone->info['avdataend'] = $clone->info['avdataoffset'] + $riff_chunk[$chunk_name][$this_index]['size']; - + // Analyze clone by fp $ac3 = new getid3_ac3($clone); $ac3->Analyze(); - + // Import from clone and destroy $info['audio'] = $clone->info['audio']; $info['ac3'] = $clone->info['ac3']; $getid3->warning($clone->warnings()); unset($clone); } - } - - + } + + // Dolby Digital WAV // AC-3 content, but not encoded in same format as normal AC-3 file // For one thing, byte order is swapped - + elseif ((strlen($riff_data_chunk_contents_test) > 0) && (substr($riff_data_chunk_contents_test, 8, 2) == "\x77\x0B")) { if (!$getid3->include_module_optional('audio.ac3')) { $getid3->warning('AC3 skipped because ac3 module is missing.'); } - + else { - + // Extract ac3 data to string - $ac3_data = ''; + $ac3_data = ''; for ($i = 0; $i < 28; $i += 2) { // swap byte order $ac3_data .= substr($riff_data_chunk_contents_test, 8 + $i + 1, 1); $ac3_data .= substr($riff_data_chunk_contents_test, 8 + $i + 0, 1); } - + // Clone getid3 - messing with offsets - better safe than sorry $clone = clone $getid3; $clone->info['avdataoffset'] = 0; $clone->info['avdataend'] = 20; - + // Analyse clone by string $ac3 = new getid3_ac3($clone); $ac3->AnalyzeString($ac3_data); - + // Import from clone and destroy $info['audio'] = $clone->info['audio']; $info['ac3'] = $clone->info['ac3']; @@ -1422,7 +1422,7 @@ class getid3_riff extends getid3_handler } } - + if ((strlen($riff_data_chunk_contents_test) > 0) && (substr($riff_data_chunk_contents_test, 0, 4) == 'wvpk')) { // This is WavPack data @@ -1481,7 +1481,7 @@ class getid3_riff extends getid3_handler private function RIFFparseWavPackHeader($wavpack3_chunk_data) { - + // typedef struct { // char ckID [4]; // long ckSize; @@ -1496,13 +1496,13 @@ class getid3_riff extends getid3_handler $info_wavpack = &$this->getid3->info['wavpack']; $info_wavpack['version'] = getid3_lib::LittleEndian2Int(substr($wavpack3_chunk_data, 0, 2)); - + if ($info_wavpack['version'] >= 2) { $info_wavpack['bits'] = getid3_lib::LittleEndian2Int(substr($wavpack3_chunk_data, 2, 2)); } - + if ($info_wavpack['version'] >= 3) { - + getid3_lib::ReadSequence('LittleEndian2Int', $info_wavpack, $wavpack3_chunk_data, 4, array ( 'flags_raw' => 2, @@ -1514,7 +1514,7 @@ class getid3_riff extends getid3_handler 'extra_bc' => 1 ) ); - + for ($i = 0; $i < 3; $i++) { $info_wavpack['extras'][] = getid3_lib::LittleEndian2Int($wavpack3_chunk_data{25 + $i}); } @@ -1546,27 +1546,27 @@ class getid3_riff extends getid3_handler return true; } - - - + + + public function AnalyzeString(&$string) { - + // Rewrite header_size in header $new_header_size = getid3_lib::LittleEndian2String(strlen($string), 4); for ($i = 0; $i < 4; $i++) { $string{$i + 4} = $new_header_size{$i}; } - + return parent::AnalyzeString($string); } - + public static function RIFFparseWAVEFORMATex($wave_format_ex_data) { - + $wave_format_ex['raw'] = array (); $wave_format_ex_raw = &$wave_format_ex['raw']; - + getid3_lib::ReadSequence('LittleEndian2Int', $wave_format_ex_raw, $wave_format_ex_data, 0, array ( 'wFormatTag' => 2, @@ -1577,7 +1577,7 @@ class getid3_riff extends getid3_handler 'wBitsPerSample' => 2 ) ); - + if (strlen($wave_format_ex_data) > 16) { $wave_format_ex_raw['cbSize'] = getid3_lib::LittleEndian2Int(substr($wave_format_ex_data, 16, 2)); } @@ -1756,7 +1756,7 @@ class getid3_riff extends getid3_handler 0xFFFE => 'WAVE_FORMAT_EXTENSIBLE', 0xFFFF => 'WAVE_FORMAT_DEVELOPMENT' ); - + return @$lookup[$w_format_tag]; } @@ -2144,14 +2144,14 @@ class getid3_riff extends getid3_handler 'ZLIB' => 'Lossless Codec Library zlib compression (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)', 'ZPEG' => 'Metheus Video Zipper' ); - + return @$lookup[$four_cc]; } public static function RIFFcommentsParse(&$riff_info_aray, &$comments_target_array) { - + static $lookup = array( 'IARL' => 'archivallocation', 'IART' => 'artist', @@ -2193,7 +2193,7 @@ class getid3_riff extends getid3_handler 'IWEB' => 'url', 'IWRI' => 'writer' ); - + foreach ($lookup as $key => $value) { if (isset($riff_info_aray[$key])) { foreach ($riff_info_aray[$key] as $comment_id => $comment_data) { @@ -2205,9 +2205,9 @@ class getid3_riff extends getid3_handler } return true; } - - - + + + public static function array_merge_noclobber($array1, $array2) { if (!is_array($array1) || !is_array($array2)) { return false; @@ -2222,27 +2222,27 @@ class getid3_riff extends getid3_handler } return $new_array; } - - - + + + public static function DateMac2Unix($mac_date) { - + // Macintosh timestamp: seconds since 00:00h January 1, 1904 // UNIX timestamp: seconds since 00:00h January 1, 1970 return (int)($mac_date - 2082844800); } - - - + + + public static function FixedPoint16_16($raw_data) { - + return getid3_lib::BigEndian2Int(substr($raw_data, 0, 2)) + (float)(getid3_lib::BigEndian2Int(substr($raw_data, 2, 2)) / 65536); // pow(2, 16) = 65536 } - - - + + + function BigEndian2Float($byte_word) { - + // ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic // http://www.psc.edu/general/software/packages/ieee/ieee.html // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html |