summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormomo-i <momo-i@ampache>2009-03-11 07:47:25 +0000
committermomo-i <momo-i@ampache>2009-03-11 07:47:25 +0000
commitbb0405fc9caa97a8517807a1ea43767751734512 (patch)
treeee15b4e7838ab2787f42f4c87382cf9510066deb
parenta1dd62bf2d74362e5553d124df67eef766acc008 (diff)
downloadampache-bb0405fc9caa97a8517807a1ea43767751734512.tar.gz
ampache-bb0405fc9caa97a8517807a1ea43767751734512.tar.bz2
ampache-bb0405fc9caa97a8517807a1ea43767751734512.zip
Updated: getid3-2.0.0b5
-rw-r--r--modules/getid3/getid3.php310
-rw-r--r--modules/getid3/module.audio-video.quicktime.php235
-rw-r--r--modules/getid3/module.audio.aac_adts.php5
-rw-r--r--modules/getid3/module.audio.mpc7.php (renamed from modules/getid3/module.audio.mpc.php)98
-rw-r--r--modules/getid3/module.audio.mpc8.php324
-rw-r--r--modules/getid3/module.tag.id3v2.php239
-rw-r--r--modules/getid3/write.id3v2.php2
7 files changed, 821 insertions, 392 deletions
diff --git a/modules/getid3/getid3.php b/modules/getid3/getid3.php
index 7f6a8eb8..f6cb8532 100644
--- a/modules/getid3/getid3.php
+++ b/modules/getid3/getid3.php
@@ -61,7 +61,7 @@ class getid3
protected $iconv_present;
// Class constants
- const VERSION = '2.0.0b4';
+ const VERSION = '2.0.0b5';
const FREAD_BUFFER_SIZE = 16384; // Read buffer size in bytes.
const ICONV_TEST_STRING = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ';
@@ -286,7 +286,7 @@ class getid3
// Supported format signature pattern detected, but module deleted.
if (!file_exists($this->include_path.$determined_format['include'])) {
fclose($this->fp);
- throw new getid3_exception('Format not supported, module, '.$determined_format['include'].', was removed.');
+ throw new getid3_exception('Format not supported, module "'.$determined_format['include'].'" was removed.');
}
// Include module
@@ -295,7 +295,7 @@ class getid3
// Instantiate module class and analyze
$class_name = 'getid3_'.$determined_format['module'];
if (!class_exists($class_name)) {
- throw new getid3_exception('Format not supported, module, '.$determined_format['include'].', is corrupt.');
+ throw new getid3_exception('Format not supported, module "'.$determined_format['include'].'" is corrupt.');
}
$class = new $class_name($this);
@@ -320,95 +320,11 @@ class getid3
//// Optional - perform more calculations
if ($this->option_extra_info) {
-
- // Set channelmode on audio
- if (@$this->info['audio']['channels'] == '1') {
- $this->info['audio']['channelmode'] = 'mono';
- } elseif (@$this->info['audio']['channels'] == '2') {
- $this->info['audio']['channelmode'] = 'stereo';
- }
-
- // Calculate combined bitrate - audio + video
- $combined_bitrate = 0;
- $combined_bitrate += (isset($this->info['audio']['bitrate']) ? $this->info['audio']['bitrate'] : 0);
- $combined_bitrate += (isset($this->info['video']['bitrate']) ? $this->info['video']['bitrate'] : 0);
- if (($combined_bitrate > 0) && empty($this->info['bitrate'])) {
- $this->info['bitrate'] = $combined_bitrate;
- }
- if (!isset($this->info['playtime_seconds']) && !empty($this->info['bitrate'])) {
- $this->info['playtime_seconds'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['bitrate'];
- }
-
- // Set playtime string
- if (!empty($this->info['playtime_seconds']) && empty($this->info['playtime_string'])) {
- $this->info['playtime_string'] = floor(round($this->info['playtime_seconds']) / 60) . ':' . str_pad(floor(round($this->info['playtime_seconds']) % 60), 2, 0, STR_PAD_LEFT);;
- }
-
-
- // CalculateCompressionRatioVideo() {
- if (@$this->info['video'] && @$this->info['video']['resolution_x'] && @$this->info['video']['resolution_y'] && @$this->info['video']['bits_per_sample']) {
-
- // From static image formats
- if (in_array($this->info['video']['dataformat'], array ('bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff'))) {
- $frame_rate = 1;
- $bitrate_compressed = $this->info['filesize'] * 8;
- }
-
- // From video formats
- else {
- $frame_rate = @$this->info['video']['frame_rate'];
- $bitrate_compressed = @$this->info['video']['bitrate'];
- }
-
- if ($frame_rate && $bitrate_compressed) {
- $this->info['video']['compression_ratio'] = $bitrate_compressed / ($this->info['video']['resolution_x'] * $this->info['video']['resolution_y'] * $this->info['video']['bits_per_sample'] * $frame_rate);
- }
- }
-
-
- // CalculateCompressionRatioAudio() {
- if (@$this->info['audio']['bitrate'] && @$this->info['audio']['channels'] && @$this->info['audio']['sample_rate']) {
- $this->info['audio']['compression_ratio'] = $this->info['audio']['bitrate'] / ($this->info['audio']['channels'] * $this->info['audio']['sample_rate'] * (@$this->info['audio']['bits_per_sample'] ? $this->info['audio']['bits_per_sample'] : 16));
- }
-
- if (@$this->info['audio']['streams']) {
- foreach ($this->info['audio']['streams'] as $stream_number => $stream_data) {
- if (@$stream_data['bitrate'] && @$stream_data['channels'] && @$stream_data['sample_rate']) {
- $this->info['audio']['streams'][$stream_number]['compression_ratio'] = $stream_data['bitrate'] / ($stream_data['channels'] * $stream_data['sample_rate'] * (@$stream_data['bits_per_sample'] ? $stream_data['bits_per_sample'] : 16));
- }
- }
- }
-
-
- // CalculateReplayGain() {
- if (@$this->info['replay_gain']) {
- if (!@$this->info['replay_gain']['reference_volume']) {
- $this->info['replay_gain']['reference_volume'] = 89;
- }
- if (isset($this->info['replay_gain']['track']['adjustment'])) {
- $this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment'];
- }
- if (isset($this->info['replay_gain']['album']['adjustment'])) {
- $this->info['replay_gain']['album']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['album']['adjustment'];
- }
-
- if (isset($this->info['replay_gain']['track']['peak'])) {
- $this->info['replay_gain']['track']['max_noclip_gain'] = 0 - 20 * log10($this->info['replay_gain']['track']['peak']);
- }
- if (isset($this->info['replay_gain']['album']['peak'])) {
- $this->info['replay_gain']['album']['max_noclip_gain'] = 0 - 20 * log10($this->info['replay_gain']['album']['peak']);
- }
- }
-
-
- // ProcessAudioStreams() {
- if (@!$this->info['audio']['streams'] && (@$this->info['audio']['bitrate'] || @$this->info['audio']['channels'] || @$this->info['audio']['sample_rate'])) {
- foreach ($this->info['audio'] as $key => $value) {
- if ($key != 'streams') {
- $this->info['audio']['streams'][0][$key] = $value;
- }
- }
- }
+ $this->ChannelsBitratePlaytimeCalculations();
+ $this->CalculateCompressionRatioVideo();
+ $this->CalculateCompressionRatioAudio();
+ $this->CalculateReplayGain();
+ $this->ProcessAudioStreams();
}
@@ -662,11 +578,19 @@ class getid3
'mime_type' => 'audio/s3m',
),
- // MPC - audio - Musepack / MPEGplus SV7+
- 'mpc' => array (
+ // MPC - audio - Musepack SV7
+ 'mpc8' => array (
+ 'pattern' => '^(MPCK)',
+ 'group' => 'audio',
+ 'module' => 'mpc8',
+ 'mime_type' => 'audio/x-musepack',
+ ),
+
+ // MPC - audio - Musepack SV7
+ 'mpc7' => array (
'pattern' => '^(MP\+)',
'group' => 'audio',
- 'module' => 'mpc',
+ 'module' => 'mpc7',
'mime_type' => 'audio/x-musepack',
),
@@ -1035,6 +959,173 @@ class getid3
+ protected function ChannelsBitratePlaytimeCalculations() {
+
+ // set channelmode on audio
+ if (@$this->info['audio']['channels'] == '1') {
+ $this->info['audio']['channelmode'] = 'mono';
+ } elseif (@$this->info['audio']['channels'] == '2') {
+ $this->info['audio']['channelmode'] = 'stereo';
+ }
+
+ // Calculate combined bitrate - audio + video
+ $CombinedBitrate = 0;
+ $CombinedBitrate += (isset($this->info['audio']['bitrate']) ? $this->info['audio']['bitrate'] : 0);
+ $CombinedBitrate += (isset($this->info['video']['bitrate']) ? $this->info['video']['bitrate'] : 0);
+ if (($CombinedBitrate > 0) && empty($this->info['bitrate'])) {
+ $this->info['bitrate'] = $CombinedBitrate;
+ }
+ //if ((isset($this->info['video']) && !isset($this->info['video']['bitrate'])) || (isset($this->info['audio']) && !isset($this->info['audio']['bitrate']))) {
+ // // for example, VBR MPEG video files cannot determine video bitrate:
+ // // should not set overall bitrate and playtime from audio bitrate only
+ // unset($this->info['bitrate']);
+ //}
+
+ // video bitrate undetermined, but calculable
+ if (isset($this->info['video']['dataformat']) && $this->info['video']['dataformat'] && (!isset($this->info['video']['bitrate']) || ($this->info['video']['bitrate'] == 0))) {
+ // if video bitrate not set
+ if (isset($this->info['audio']['bitrate']) && ($this->info['audio']['bitrate'] > 0) && ($this->info['audio']['bitrate'] == $this->info['bitrate'])) {
+ // AND if audio bitrate is set to same as overall bitrate
+ if (isset($this->info['playtime_seconds']) && ($this->info['playtime_seconds'] > 0)) {
+ // AND if playtime is set
+ if (isset($this->info['avdataend']) && isset($this->info['avdataoffset'])) {
+ // AND if AV data offset start/end is known
+ // THEN we can calculate the video bitrate
+ $this->info['bitrate'] = round((($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['playtime_seconds']);
+ $this->info['video']['bitrate'] = $this->info['bitrate'] - $this->info['audio']['bitrate'];
+ }
+ }
+ }
+ }
+
+ if ((!isset($this->info['playtime_seconds']) || ($this->info['playtime_seconds'] <= 0)) && !empty($this->info['bitrate'])) {
+ $this->info['playtime_seconds'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['bitrate'];
+ }
+
+ if (!isset($this->info['bitrate']) && !empty($this->info['playtime_seconds'])) {
+ $this->info['bitrate'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['playtime_seconds'];
+ }
+//echo '<pre>';
+//var_dump($this->info['bitrate']);
+//var_dump($this->info['audio']['bitrate']);
+//var_dump($this->info['video']['bitrate']);
+//echo '</pre>';
+ if (isset($this->info['bitrate']) && empty($this->info['audio']['bitrate']) && empty($this->info['video']['bitrate'])) {
+ if (isset($this->info['audio']['dataformat']) && empty($this->info['video']['resolution_x'])) {
+ // audio only
+ $this->info['audio']['bitrate'] = $this->info['bitrate'];
+ } elseif (isset($this->info['video']['resolution_x']) && empty($this->info['audio']['dataformat'])) {
+ // video only
+ $this->info['video']['bitrate'] = $this->info['bitrate'];
+ }
+ }
+
+ // Set playtime string
+ if (!empty($this->info['playtime_seconds']) && empty($this->info['playtime_string'])) {
+ $this->info['playtime_string'] = getid3_lib::PlaytimeString($this->info['playtime_seconds']);
+ }
+ }
+
+
+ protected function CalculateCompressionRatioVideo() {
+ if (empty($this->info['video'])) {
+ return false;
+ }
+ if (empty($this->info['video']['resolution_x']) || empty($this->info['video']['resolution_y'])) {
+ return false;
+ }
+ if (empty($this->info['video']['bits_per_sample'])) {
+ return false;
+ }
+
+ switch ($this->info['video']['dataformat']) {
+ case 'bmp':
+ case 'gif':
+ case 'jpeg':
+ case 'jpg':
+ case 'png':
+ case 'tiff':
+ $FrameRate = 1;
+ $PlaytimeSeconds = 1;
+ $BitrateCompressed = $this->info['filesize'] * 8;
+ break;
+
+ default:
+ if (!empty($this->info['video']['frame_rate'])) {
+ $FrameRate = $this->info['video']['frame_rate'];
+ } else {
+ return false;
+ }
+ if (!empty($this->info['playtime_seconds'])) {
+ $PlaytimeSeconds = $this->info['playtime_seconds'];
+ } else {
+ return false;
+ }
+ if (!empty($this->info['video']['bitrate'])) {
+ $BitrateCompressed = $this->info['video']['bitrate'];
+ } else {
+ return false;
+ }
+ break;
+ }
+ $BitrateUncompressed = $this->info['video']['resolution_x'] * $this->info['video']['resolution_y'] * $this->info['video']['bits_per_sample'] * $FrameRate;
+
+ $this->info['video']['compression_ratio'] = $BitrateCompressed / $BitrateUncompressed;
+ return true;
+ }
+
+
+ protected function CalculateCompressionRatioAudio() {
+ if (empty($this->info['audio']['bitrate']) || empty($this->info['audio']['channels']) || empty($this->info['audio']['sample_rate'])) {
+ return false;
+ }
+ $this->info['audio']['compression_ratio'] = $this->info['audio']['bitrate'] / ($this->info['audio']['channels'] * $this->info['audio']['sample_rate'] * (!empty($this->info['audio']['bits_per_sample']) ? $this->info['audio']['bits_per_sample'] : 16));
+
+ if (!empty($this->info['audio']['streams'])) {
+ foreach ($this->info['audio']['streams'] as $streamnumber => $streamdata) {
+ if (!empty($streamdata['bitrate']) && !empty($streamdata['channels']) && !empty($streamdata['sample_rate'])) {
+ $this->info['audio']['streams'][$streamnumber]['compression_ratio'] = $streamdata['bitrate'] / ($streamdata['channels'] * $streamdata['sample_rate'] * (!empty($streamdata['bits_per_sample']) ? $streamdata['bits_per_sample'] : 16));
+ }
+ }
+ }
+ return true;
+ }
+
+
+ protected function CalculateReplayGain() {
+ if (isset($this->info['replay_gain'])) {
+ $this->info['replay_gain']['reference_volume'] = 89;
+ if (isset($this->info['replay_gain']['track']['adjustment'])) {
+ $this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment'];
+ }
+ if (isset($this->info['replay_gain']['album']['adjustment'])) {
+ $this->info['replay_gain']['album']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['album']['adjustment'];
+ }
+
+ if (isset($this->info['replay_gain']['track']['peak'])) {
+ $this->info['replay_gain']['track']['max_noclip_gain'] = 0 - getid3_lib::RGADamplitude2dB($this->info['replay_gain']['track']['peak']);
+ }
+ if (isset($this->info['replay_gain']['album']['peak'])) {
+ $this->info['replay_gain']['album']['max_noclip_gain'] = 0 - getid3_lib::RGADamplitude2dB($this->info['replay_gain']['album']['peak']);
+ }
+ }
+ return true;
+ }
+
+ protected function ProcessAudioStreams() {
+ if (!empty($this->info['audio']['bitrate']) || !empty($this->info['audio']['channels']) || !empty($this->info['audio']['sample_rate'])) {
+ if (!isset($this->info['audio']['streams'])) {
+ foreach ($this->info['audio'] as $key => $value) {
+ if ($key != 'streams') {
+ $this->info['audio']['streams'][0][$key] = $value;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+
// Convert and copy tags
protected function HandleAllTags() {
@@ -1275,18 +1366,18 @@ abstract class getid3_handler_write
ignore_user_abort($this->user_abort);
}
-
-
+
+
protected function save_permissions() {
-
+
$this->owner = fileowner($this->filename);
$this->group = filegroup($this->filename);
$this->perms = fileperms($this->filename);
}
-
-
+
+
protected function restore_permissions() {
-
+
@chown($this->filename, $this->owner);
@chgrp($this->filename, $this->group);
@chmod($this->filename, $this->perms);
@@ -1485,6 +1576,11 @@ class getid3_lib
}
+ public static function RGADamplitude2dB($amplitude) {
+ return 20 * log10($amplitude);
+ }
+
+
public static function PrintHexBytes($string, $hex=true, $spaces=true, $html_safe=true) {
$return_string = '';
@@ -1505,6 +1601,18 @@ class getid3_lib
}
+ public static function PlaytimeString($playtimeseconds) {
+ $sign = (($playtimeseconds < 0) ? '-' : '');
+ $playtimeseconds = abs($playtimeseconds);
+ $contentseconds = round((($playtimeseconds / 60) - floor($playtimeseconds / 60)) * 60);
+ $contentminutes = floor($playtimeseconds / 60);
+ if ($contentseconds >= 60) {
+ $contentseconds -= 60;
+ $contentminutes++;
+ }
+ return $sign.intval($contentminutes).':'.str_pad($contentseconds, 2, 0, STR_PAD_LEFT);
+ }
+
// Process header data string - read several values with algorithm and add to target
// algorithm is one one the getid3_lib::Something2Something() function names
diff --git a/modules/getid3/module.audio-video.quicktime.php b/modules/getid3/module.audio-video.quicktime.php
index 559c1065..3af2bccc 100644
--- a/modules/getid3/module.audio-video.quicktime.php
+++ b/modules/getid3/module.audio-video.quicktime.php
@@ -22,19 +22,19 @@
//
// $Id: module.audio-video.quicktime.php,v 1.7 2006/11/02 16:03:28 ah Exp $
-
-
+
+
class getid3_quicktime extends getid3_handler
{
public function Analyze() {
-
+
$getid3 = $this->getid3;
$info = &$getid3->info;
-
+
$getid3->include_module('audio.mp3');
-
+
$info['quicktime'] = array ();
$info_quicktime = &$info['quicktime'];
@@ -52,7 +52,7 @@ class getid3_quicktime extends getid3_handler
$atom_size = getid3_lib::BigEndian2Int(substr($atom_header, 0, 4));
$atom_name = substr($atom_header, 4, 4);
-
+
$info_quicktime[$atom_name]['name'] = $atom_name;
$info_quicktime[$atom_name]['size'] = $atom_size;
$info_quicktime[$atom_name]['offset'] = $offset;
@@ -67,9 +67,9 @@ class getid3_quicktime extends getid3_handler
// to read user data atoms, you should allow for the terminating 0.
break;
}
-
+
switch ($atom_name) {
-
+
case 'mdat': // Media DATa atom
// 'mdat' contains the actual data for the audio/video
if (($atom_size > 8) && (!isset($info['avdataend_tmp']) || ($info_quicktime[$atom_name]['size'] > ($info['avdataend_tmp'] - $info['avdataoffset'])))) {
@@ -78,28 +78,28 @@ class getid3_quicktime extends getid3_handler
$old_av_data_end = $info['avdataend'];
$info['avdataend'] = $info_quicktime[$atom_name]['offset'] + $info_quicktime[$atom_name]['size'];
-
+
//// MP3
-
+
if (!$getid3->include_module_optional('audio.mp3')) {
$getid3->warning('MP3 skipped because mpeg module is missing.');
}
-
+
else {
-
+
// Clone getid3 - messing with offsets - better safe than sorry
$clone = clone $getid3;
-
+
if (getid3_mp3::MPEGaudioHeaderValid(getid3_mp3::MPEGaudioHeaderDecode(fread($clone->fp, 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']['dataformat'] = 'mp3';
$info['audio']['codec'] = (!empty($info['mpeg']['audio']['encoder']) ? $info['mpeg']['audio']['encoder'] : (!empty($info['mpeg']['audio']['codec']) ? $info['mpeg']['audio']['codec'] : (!empty($info['mpeg']['audio']['LAME']) ? 'LAME' :'mp3')));
$info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate'];
@@ -107,19 +107,19 @@ class getid3_quicktime extends getid3_handler
$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);
}
}
}
-
+
$info['avdataend'] = $old_av_data_end;
unset($old_av_data_end);
}
break;
-
+
case 'free': // FREE space atom
case 'skip': // SKIP atom
@@ -148,11 +148,23 @@ class getid3_quicktime extends getid3_handler
if (!isset($info['bitrate']) && isset($info['playtime_seconds'])) {
$info['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
}
-
+
if (isset($info['bitrate']) && !isset($info['audio']['bitrate']) && !isset($info_quicktime['video'])) {
$info['audio']['bitrate'] = $info['bitrate'];
}
+ if (@$info['playtime_seconds'] && !isset($info['video']['frame_rate']) && !empty($info['quicktime']['stts_framecount'])) {
+ foreach ($info['quicktime']['stts_framecount'] as $key => $samples_count) {
+ $samples_per_second = $samples_count / $info['playtime_seconds'];
+ if ($samples_per_second > 240) {
+ // has to be audio samples
+ } else {
+ $info['video']['frame_rate'] = $samples_per_second;
+ break;
+ }
+ }
+ }
+
if ((@$info['audio']['dataformat'] == 'mp4') && empty($info['video']['resolution_x'])) {
$info['fileformat'] = 'mp4';
$info['mime_type'] = 'audio/mp4';
@@ -166,7 +178,7 @@ class getid3_quicktime extends getid3_handler
if (empty($info['audio']['dataformat']) && !empty($info_quicktime['audio'])) {
$info['audio']['dataformat'] = 'quicktime';
}
-
+
if (empty($info['video']['dataformat']) && !empty($info_quicktime['video'])) {
$info['video']['dataformat'] = 'quicktime';
}
@@ -177,11 +189,11 @@ class getid3_quicktime extends getid3_handler
private function QuicktimeParseAtom($atom_name, $atom_size, $atom_data, $base_offset, &$atom_hierarchy) {
-
+
// http://developer.apple.com/techpubs/quicktime/qtdevdocs/APIREF/INDEX/atomalphaindex.htm
-
+
$getid3 = $this->getid3;
-
+
$info = &$getid3->info;
$info_quicktime = &$info['quicktime'];
@@ -311,17 +323,17 @@ class getid3_quicktime extends getid3_handler
case 'rdrf': // Reference movie Data ReFerence atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
- 'version' => 1,
- 'flags_raw' => 3,
+ 'version' => 1,
+ 'flags_raw' => 3,
'reference_type_name' => -4,
- 'reference_length' => 4,
+ 'reference_length' => 4,
)
);
-
+
$atom_structure['flags']['internal_data'] = (bool)($atom_structure['flags_raw'] & 0x000001);
-
+
switch ($atom_structure['reference_type_name']) {
case 'url ':
$atom_structure['url'] = $this->NoNullString(substr($atom_data, 12));
@@ -348,7 +360,7 @@ class getid3_quicktime extends getid3_handler
case 'rmcs': // Reference Movie Cpu Speed atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
@@ -359,7 +371,7 @@ class getid3_quicktime extends getid3_handler
case 'rmvc': // Reference Movie Version Check atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
@@ -373,7 +385,7 @@ class getid3_quicktime extends getid3_handler
case 'rmcd': // Reference Movie Component check atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
@@ -389,7 +401,7 @@ class getid3_quicktime extends getid3_handler
case 'rmdr': // Reference Movie Data Rate atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
@@ -402,7 +414,7 @@ class getid3_quicktime extends getid3_handler
case 'rmla': // Reference Movie Language Atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
@@ -418,7 +430,7 @@ class getid3_quicktime extends getid3_handler
case 'rmla': // Reference Movie Language Atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
@@ -430,7 +442,7 @@ class getid3_quicktime extends getid3_handler
case 'ptv ': // Print To Video - defines a movie's full screen mode
// http://developer.apple.com/documentation/QuickTime/APIREF/SOURCESIV/at_ptv-_pg.htm
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'display_size_raw' => 2,
'reserved_1' => 2, // hardcoded: 0x0000
@@ -457,7 +469,7 @@ class getid3_quicktime extends getid3_handler
case 'stsd': // Sample Table Sample Description atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
@@ -466,8 +478,8 @@ class getid3_quicktime extends getid3_handler
);
$stsd_entries_data_offset = 8;
for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
-
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure['sample_description_table'][$i], $atom_data, $stsd_entries_data_offset,
+
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure['sample_description_table'][$i], $atom_data, $stsd_entries_data_offset,
array (
'size' => 4,
'data_format' => -4,
@@ -499,7 +511,7 @@ class getid3_quicktime extends getid3_handler
'audio_packet_size' => 2
)
);
-
+
$atom_structure['sample_description_table'][$i]['audio_sample_rate'] = getid3_quicktime::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 16, 4));
switch ($atom_structure['sample_description_table'][$i]['data_format']) {
@@ -554,7 +566,7 @@ class getid3_quicktime extends getid3_handler
$atom_structure['sample_description_table'][$i]['video_resolution_x'] = getid3_quicktime::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 20, 4));
$atom_structure['sample_description_table'][$i]['video_resolution_y'] = getid3_quicktime::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 24, 4));
getid3_lib::ReadSequence('BigEndian2Int', $atom_structure['sample_description_table'][$i], $atom_structure['sample_description_table'][$i]['data'], 28,
- array (
+ array (
'video_data_size' => 4,
'video_frame_count' => 2,
'video_encoder_name_len' => 1
@@ -622,53 +634,38 @@ class getid3_quicktime extends getid3_handler
case 'stts': // Sample Table Time-to-Sample atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
'number_entries' => 4
)
);
-
+
$stts_entries_data_offset = 8;
- $frame_rate_calculator_array = array ();
+ //$frame_rate_calculator_array = array ();
+ $frames_count = 0;
for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
-
+
$atom_structure['time_to_sample_table'][$i]['sample_count'] = getid3_lib::BigEndian2Int(substr($atom_data, $stts_entries_data_offset, 4));
$stts_entries_data_offset += 4;
-
+
$atom_structure['time_to_sample_table'][$i]['sample_duration'] = getid3_lib::BigEndian2Int(substr($atom_data, $stts_entries_data_offset, 4));
$stts_entries_data_offset += 4;
- if (!empty($info_quicktime['time_scale']) && (@$atoms_structure['time_to_sample_table'][$i]['sample_duration'] > 0)) {
+ $frames_count += $atom_structure['time_to_sample_table'][$i]['sample_count'];
- $stts_new_framerate = $info_quicktime['time_scale'] / $atom_structure['time_to_sample_table'][$i]['sample_duration'];
- if ($stts_new_framerate <= 60) {
- // some atoms have durations of "1" giving a very large framerate, which probably is not right
- $info['video']['frame_rate'] = max(@$info['video']['frame_rate'], $stts_new_framerate);
- }
- }
+ //if (!empty($info_quicktime['time_scale']) && (@$atoms_structure['time_to_sample_table'][$i]['sample_duration'] > 0)) {
+ //
+ // $stts_new_framerate = $info_quicktime['time_scale'] / $atom_structure['time_to_sample_table'][$i]['sample_duration'];
+ // if ($stts_new_framerate <= 60) {
+ // // some atoms have durations of "1" giving a very large framerate, which probably is not right
+ // $info['video']['frame_rate'] = max(@$info['video']['frame_rate'], $stts_new_framerate);
+ // }
+ //}
//@$frame_rate_calculator_array[($info_quicktime['time_scale'] / $atom_structure['time_to_sample_table'][$i]['sample_duration'])] += $atom_structure['time_to_sample_table'][$i]['sample_count'];
}
- /*
- $stts_frames_total = 0;
- $stts_seconds_total = 0;
- foreach ($frame_rate_calculator_array as $frames_per_second => $frame_count) {
- if (($frames_per_second > 60) || ($frames_per_second < 1)) {
- // not video FPS information, probably audio information
- $stts_frames_total = 0;
- $stts_seconds_total = 0;
- break;
- }
- $stts_frames_total += $frame_count;
- $stts_seconds_total += $frame_count / $frames_per_second;
- }
- if (($stts_frames_total > 0) && ($stts_seconds_total > 0)) {
- if (($stts_frames_total / $stts_seconds_total) > @$info['video']['frame_rate']) {
- $info['video']['frame_rate'] = $stts_frames_total / $stts_seconds_total;
- }
- }
- */
+ $info['quicktime']['stts_framecount'][] = $frames_count;
break;
@@ -736,18 +733,18 @@ class getid3_quicktime extends getid3_handler
case 'dref': // Data REFerence atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
'number_entries' => 4
)
);
-
+
$dref_data_offset = 8;
for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
-
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure['data_references'][$i], $atom_data, $dref_data_offset,
+
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure['data_references'][$i], $atom_data, $dref_data_offset,
array (
'size' => 4,
'type' => -4,
@@ -756,7 +753,7 @@ class getid3_quicktime extends getid3_handler
)
);
$dref_data_offset += 12;
-
+
$atom_structure['data_references'][$i]['data'] = substr($atom_data, $dref_data_offset, ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3));
$dref_data_offset += ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3);
@@ -766,7 +763,7 @@ class getid3_quicktime extends getid3_handler
case 'gmin': // base Media INformation atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
@@ -782,7 +779,7 @@ class getid3_quicktime extends getid3_handler
case 'smhd': // Sound Media information HeaDer atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
@@ -794,7 +791,7 @@ class getid3_quicktime extends getid3_handler
case 'vmhd': // Video Media information HeaDer atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3,
@@ -809,7 +806,7 @@ class getid3_quicktime extends getid3_handler
case 'hdlr': // HanDLeR reference atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
@@ -830,7 +827,7 @@ class getid3_quicktime extends getid3_handler
case 'mdhd': // MeDia HeaDer atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
@@ -847,7 +844,7 @@ class getid3_quicktime extends getid3_handler
throw new getid3_exception('Corrupt Quicktime file: mdhd.time_scale == zero');
}
$info_quicktime['time_scale'] = max(@$info['quicktime']['time_scale'], $atom_structure['time_scale']);
-
+
$atom_structure['creation_time_unix'] = (int)($atom_structure['creation_time'] - 2082844800); // DateMac2Unix()
$atom_structure['modify_time_unix'] = (int)($atom_structure['modify_time'] - 2082844800); // DateMac2Unix()
$atom_structure['playtime_seconds'] = $atom_structure['duration'] / $atom_structure['time_scale'];
@@ -859,7 +856,7 @@ class getid3_quicktime extends getid3_handler
case 'pnot': // Preview atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'modification_date' => 4, // "standard Macintosh format"
'version_number' => 2, // hardcoded: 0x00
@@ -879,7 +876,7 @@ class getid3_quicktime extends getid3_handler
case 'load': // track LOAD settings atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'preload_start_time' => 4,
'preload_duration' => 4,
@@ -905,14 +902,14 @@ class getid3_quicktime extends getid3_handler
case 'elst': // Edit LiST atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3, // hardcoded: 0x0000
'number_entries' => 4
)
- );
-
+ );
+
for ($i = 0; $i < $atom_structure['number_entries']; $i++ ) {
$atom_structure['edit_list'][$i]['track_duration'] = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($i * 12) + 0, 4));
$atom_structure['edit_list'][$i]['media_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($i * 12) + 4, 4));
@@ -942,7 +939,7 @@ class getid3_quicktime extends getid3_handler
case 'mvhd': // MoVie HeaDer atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3,
@@ -965,8 +962,8 @@ class getid3_quicktime extends getid3_handler
$atom_structure['matrix_x'] = getid3_quicktime::FixedPoint16_16(substr($atom_data, 60, 4));
$atom_structure['matrix_y'] = getid3_quicktime::FixedPoint16_16(substr($atom_data, 64, 4));
$atom_structure['matrix_w'] = getid3_quicktime::FixedPoint2_30(substr($atom_data, 68, 4));
-
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 72,
+
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 72,
array (
'preview_time' => 4,
'preview_duration' => 4,
@@ -981,7 +978,7 @@ class getid3_quicktime extends getid3_handler
if ($atom_structure['time_scale'] == 0) {
throw new getid3_exception('Corrupt Quicktime file: mvhd.time_scale == zero');
}
-
+
$atom_structure['creation_time_unix'] = (int)($atom_structure['creation_time'] - 2082844800); // DateMac2Unix()
$atom_structure['modify_time_unix'] = (int)($atom_structure['modify_time'] - 2082844800); // DateMac2Unix()
$info_quicktime['time_scale'] = max(@$info['quicktime']['time_scale'], $atom_structure['time_scale']);
@@ -991,7 +988,7 @@ class getid3_quicktime extends getid3_handler
case 'tkhd': // TracK HeaDer atom
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'version' => 1,
'flags_raw' => 3,
@@ -1005,7 +1002,7 @@ class getid3_quicktime extends getid3_handler
'alternate_group' => 2
)
);
-
+
$atom_structure['volume'] = getid3_quicktime::FixedPoint8_8(substr($atom_data, 36, 2));
$atom_structure['reserved3'] = getid3_lib::BigEndian2Int(substr($atom_data, 38, 2));
$atom_structure['matrix_a'] = getid3_quicktime::FixedPoint16_16(substr($atom_data, 40, 4));
@@ -1031,12 +1028,12 @@ class getid3_quicktime extends getid3_handler
$info['video']['resolution_x'] = $atom_structure['width'];
$info['video']['resolution_y'] = $atom_structure['height'];
}
-
+
if ($atom_structure['flags']['enabled'] == 1) {
$info['video']['resolution_x'] = max($info['video']['resolution_x'], $atom_structure['width']);
$info['video']['resolution_y'] = max($info['video']['resolution_y'], $atom_structure['height']);
}
-
+
if (!empty($info['video']['resolution_x']) && !empty($info['video']['resolution_y'])) {
$info_quicktime['video']['resolution_x'] = $info['video']['resolution_x'];
$info_quicktime['video']['resolution_y'] = $info['video']['resolution_y'];
@@ -1066,7 +1063,7 @@ class getid3_quicktime extends getid3_handler
break;
case 'ftyp': // FileTYPe (?) atom (for MP4 it seems)
- getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
+ getid3_lib::ReadSequence('BigEndian2Int', $atom_structure, $atom_data, 0,
array (
'signature' => -4,
'unknown_1' => 4,
@@ -1113,7 +1110,7 @@ class getid3_quicktime extends getid3_handler
case 'pano': // PANOrama track (seen on QTVR)
$atom_structure['pano'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4));
break;
-
+
case 'hint': // HINT track
case 'hinf': //
case 'hinv': //
@@ -1148,20 +1145,20 @@ class getid3_quicktime extends getid3_handler
private function QuicktimeParseContainerAtom($atom_data, $base_offset, &$atom_hierarchy) {
-
+
if ((strlen($atom_data) == 4) && (getid3_lib::BigEndian2Int($atom_data) == 0x00000000)) {
return false;
}
-
+
$atom_structure = false;
$subatom_offset = 0;
-
+
while ($subatom_offset < strlen($atom_data)) {
-
+
$subatom_size = getid3_lib::BigEndian2Int(substr($atom_data, $subatom_offset + 0, 4));
$subatom_name = substr($atom_data, $subatom_offset + 4, 4);
$subatom_data = substr($atom_data, $subatom_offset + 8, $subatom_size - 8);
-
+
if ($subatom_size == 0) {
// Furthermore, for historical reasons the list of atoms is optionally
// terminated by a 32-bit integer set to 0. If you are writing a program
@@ -1175,9 +1172,9 @@ class getid3_quicktime extends getid3_handler
}
return $atom_structure;
}
-
-
-
+
+
+
private function CopyToAppropriateCommentsSection($key_name, $data) {
// http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
@@ -1344,7 +1341,7 @@ class getid3_quicktime extends getid3_handler
137 => 'Dzongkha',
138 => 'JavaneseRom'
);
-
+
return (isset($lookup[$language_id]) ? $lookup[$language_id] : 'invalid');
}
@@ -1405,7 +1402,7 @@ class getid3_quicktime extends getid3_handler
'WRAW' => 'Windows RAW',
'y420' => 'YUV420'
);
-
+
return (isset($lookup[$codec_id]) ? $lookup[$codec_id] : '');
}
@@ -1453,7 +1450,7 @@ class getid3_quicktime extends getid3_handler
'twos' => 'signed/two\'s complement (Big Endian)',
'ulaw' => 'mu-law 2:1',
);
-
+
return (isset($lookup[$codec_id]) ? $lookup[$codec_id] : '');
}
@@ -1472,7 +1469,7 @@ class getid3_quicktime extends getid3_handler
public static function QuicktimeColorNameLookup($color_depth_id) {
-
+
static $lookup = array (
1 => '2-color (monochrome)',
2 => '4-color',
@@ -1486,7 +1483,7 @@ class getid3_quicktime extends getid3_handler
36 => '16-gray',
40 => '256-gray',
);
-
+
return (isset($lookup[$color_depth_id]) ? $lookup[$color_depth_id] : 'invalid');
}
@@ -1498,12 +1495,12 @@ class getid3_quicktime extends getid3_handler
if (substr($null_terminated_string, strlen($null_terminated_string) - 1, 1) === "\x00") {
return substr($null_terminated_string, 0, strlen($null_terminated_string) - 1);
}
-
+
return $null_terminated_string;
}
-
-
-
+
+
+
public static function FixedPoint8_8($raw_data) {
return getid3_lib::BigEndian2Int($raw_data{0}) + (float)(getid3_lib::BigEndian2Int($raw_data{1}) / 256);
@@ -1512,14 +1509,14 @@ class getid3_quicktime extends getid3_handler
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);
}
public static function FixedPoint2_30($raw_data) {
-
+
$binary_string = getid3_lib::BigEndian2Bin($raw_data);
return bindec(substr($binary_string, 0, 2)) + (float)(bindec(substr($binary_string, 2, 30)) / 1073741824);
}
diff --git a/modules/getid3/module.audio.aac_adts.php b/modules/getid3/module.audio.aac_adts.php
index 1a3f39f5..aa7f8f73 100644
--- a/modules/getid3/module.audio.aac_adts.php
+++ b/modules/getid3/module.audio.aac_adts.php
@@ -93,8 +93,7 @@ class getid3_aac_adts extends getid3_handler
$info_aac = &$getid3->info['aac'];
$info_aac_header = & $info_aac['header'];
- $byte_offset = $getid3->info['avdataoffset'];
- $frame_number = 0;
+ $byte_offset = $frame_number = 0;
while (true) {
@@ -280,4 +279,4 @@ class getid3_aac_adts extends getid3_handler
}
-?>
+?> \ No newline at end of file
diff --git a/modules/getid3/module.audio.mpc.php b/modules/getid3/module.audio.mpc7.php
index 59d2802e..2671c909 100644
--- a/modules/getid3/module.audio.mpc.php
+++ b/modules/getid3/module.audio.mpc7.php
@@ -1,35 +1,35 @@
<?php
-// +----------------------------------------------------------------------+
-// | PHP version 5 |
-// +----------------------------------------------------------------------+
-// | Copyright (c) 2002-2006 James Heinrich, Allan Hansen |
-// +----------------------------------------------------------------------+
-// | This source file is subject to version 2 of the GPL license, |
-// | that is bundled with this package in the file license.txt and is |
-// | available through the world-wide-web at the following url: |
+// +----------------------------------------------------------------------+
+// | PHP version 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 2002-2006 James Heinrich, Allan Hansen |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2 of the GPL license, |
+// | that is bundled with this package in the file license.txt and is |
+// | available through the world-wide-web at the following url: |
// | http://www.gnu.org/copyleft/gpl.html |
// +----------------------------------------------------------------------+
// | getID3() - http://getid3.sourceforge.net or http://www.getid3.org |
-// +----------------------------------------------------------------------+
-// | Authors: James Heinrich <infogetid3*org> |
-// | Allan Hansen <ahartemis*dk> |
+// +----------------------------------------------------------------------+
+// | Authors: James Heinrich <infoetid3*org> |
+// | Allan Hansen <ahartemis*dk> |
// +----------------------------------------------------------------------+
// | module.audio.mpc.php |
// | Module for analyzing Musepack/MPEG+ Audio files |
// | dependencies: NONE |
-// +----------------------------------------------------------------------+
-//
-// $Id: module.audio.mpc.php,v 1.3 2006/11/02 10:48:01 ah Exp $
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+
-
-
-class getid3_mpc extends getid3_handler
+class getid3_mpc7 extends getid3_handler
{
public function Analyze() {
$getid3 = $this->getid3;
-
+
// http://www.uni-jena.de/~pfk/mpp/sv8/header.html
$getid3->info['fileformat'] = 'mpc';
@@ -37,83 +37,83 @@ class getid3_mpc extends getid3_handler
$getid3->info['audio']['bitrate_mode'] = 'vbr';
$getid3->info['audio']['channels'] = 2; // the format appears to be hardcoded for stereo only
$getid3->info['audio']['lossless'] = false;
-
+
$getid3->info['mpc']['header'] = array ();
$info_mpc_header = &$getid3->info['mpc']['header'];
$info_mpc_header['size'] = 28;
$info_mpc_header['raw']['preamble'] = 'MP+'; // Magic bytes
-
+
fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET);
$mpc_header_data = fread($getid3->fp, 28);
-
+
$stream_version_byte = getid3_lib::LittleEndian2Int(substr($mpc_header_data, 3, 1));
$info_mpc_header['stream_major_version'] = ($stream_version_byte & 0x0F);
$info_mpc_header['stream_minor_version'] = ($stream_version_byte & 0xF0) >> 4;
if ($info_mpc_header['stream_major_version'] != 7) {
throw new getid3_exception('Only Musepack SV7 supported');
}
-
+
$info_mpc_header['frame_count'] = getid3_lib::LittleEndian2Int(substr($mpc_header_data, 4, 4));
-
+
$info_mpc_header['raw']['title_peak'] = getid3_lib::LittleEndian2Int(substr($mpc_header_data, 12, 2));
$info_mpc_header['raw']['title_gain'] = getid3_lib::LittleEndian2Int(substr($mpc_header_data, 14, 2), true);
$info_mpc_header['raw']['album_peak'] = getid3_lib::LittleEndian2Int(substr($mpc_header_data, 16, 2));
$info_mpc_header['raw']['album_gain'] = getid3_lib::LittleEndian2Int(substr($mpc_header_data, 18, 2), true);
-
+
$info_mpc_header['raw']['not_sure_what'] = getid3_lib::LittleEndian2Int(substr($mpc_header_data, 24, 3));
$info_mpc_header['raw']['encoder_version'] = getid3_lib::LittleEndian2Int(substr($mpc_header_data, 27, 1));
-
- $flags_dword1 = getid3_lib::LittleEndian2Int(substr($mpc_header_data, 8, 4));
+
+ $flags_dword1 = getid3_lib::LittleEndian2Int(substr($mpc_header_data, 8, 4));
$flags_dword2 = getid3_lib::LittleEndian2Int(substr($mpc_header_data, 20, 4));
-
- $info_mpc_header['intensity_stereo'] = (bool)(($flags_dword1 & 0x80000000) >> 31);
- $info_mpc_header['mid_side_stereo'] = (bool)(($flags_dword1 & 0x40000000) >> 30);
+
+ $info_mpc_header['intensity_stereo'] = (bool) (($flags_dword1 & 0x80000000) >> 31);
+ $info_mpc_header['mid_side_stereo'] = (bool) (($flags_dword1 & 0x40000000) >> 30);
$info_mpc_header['max_subband'] = ($flags_dword1 & 0x3F000000) >> 24;
$info_mpc_header['raw']['profile'] = ($flags_dword1 & 0x00F00000) >> 20;
- $info_mpc_header['begin_loud'] = (bool)(($flags_dword1 & 0x00080000) >> 19);
- $info_mpc_header['end_loud'] = (bool)(($flags_dword1 & 0x00040000) >> 18);
+ $info_mpc_header['begin_loud'] = (bool) (($flags_dword1 & 0x00080000) >> 19);
+ $info_mpc_header['end_loud'] = (bool) (($flags_dword1 & 0x00040000) >> 18);
$info_mpc_header['raw']['sample_rate'] = ($flags_dword1 & 0x00030000) >> 16;
$info_mpc_header['max_level'] = ($flags_dword1 & 0x0000FFFF);
-
- $info_mpc_header['true_gapless'] = (bool)(($flags_dword2 & 0x80000000) >> 31);
+
+ $info_mpc_header['true_gapless'] = (bool) (($flags_dword2 & 0x80000000) >> 31);
$info_mpc_header['last_frame_length'] = ($flags_dword2 & 0x7FF00000) >> 20;
-
- $info_mpc_header['profile'] = getid3_mpc::MPCprofileNameLookup($info_mpc_header['raw']['profile']);
- $info_mpc_header['sample_rate'] = getid3_mpc::MPCfrequencyLookup($info_mpc_header['raw']['sample_rate']);
+
+ $info_mpc_header['profile'] = getid3_mpc7::MPCprofileNameLookup($info_mpc_header['raw']['profile']);
+ $info_mpc_header['sample_rate'] = getid3_mpc7::MPCfrequencyLookup($info_mpc_header['raw']['sample_rate']);
$getid3->info['audio']['sample_rate'] = $info_mpc_header['sample_rate'];
$info_mpc_header['samples'] = ((($info_mpc_header['frame_count'] - 1) * 1152) + $info_mpc_header['last_frame_length']) * $getid3->info['audio']['channels'];
$getid3->info['playtime_seconds'] = ($info_mpc_header['samples'] / $getid3->info['audio']['channels']) / $getid3->info['audio']['sample_rate'];
$getid3->info['avdataoffset'] += $info_mpc_header['size'];
-
+
$getid3->info['audio']['bitrate'] = (($getid3->info['avdataend'] - $getid3->info['avdataoffset']) * 8) / $getid3->info['playtime_seconds'];
$info_mpc_header['title_peak'] = $info_mpc_header['raw']['title_peak'];
- $info_mpc_header['title_peak_db'] = getid3_mpc::MPCpeakDBLookup($info_mpc_header['title_peak']);
+ $info_mpc_header['title_peak_db'] = getid3_mpc7::MPCpeakDBLookup($info_mpc_header['title_peak']);
if ($info_mpc_header['raw']['title_gain'] < 0) {
$info_mpc_header['title_gain_db'] = (float)(32768 + $info_mpc_header['raw']['title_gain']) / -100;
- }
+ }
else {
$info_mpc_header['title_gain_db'] = (float)$info_mpc_header['raw']['title_gain'] / 100;
}
$info_mpc_header['album_peak'] = $info_mpc_header['raw']['album_peak'];
- $info_mpc_header['album_peak_db'] = getid3_mpc::MPCpeakDBLookup($info_mpc_header['album_peak']);
+ $info_mpc_header['album_peak_db'] = getid3_mpc7::MPCpeakDBLookup($info_mpc_header['album_peak']);
if ($info_mpc_header['raw']['album_gain'] < 0) {
$info_mpc_header['album_gain_db'] = (float)(32768 + $info_mpc_header['raw']['album_gain']) / -100;
- }
+ }
else {
$info_mpc_header['album_gain_db'] = (float)$info_mpc_header['raw']['album_gain'] / 100;;
}
- $info_mpc_header['encoder_version'] = getid3_mpc::MPCencoderVersionLookup($info_mpc_header['raw']['encoder_version']);
+ $info_mpc_header['encoder_version'] = getid3_mpc7::MPCencoderVersionLookup($info_mpc_header['raw']['encoder_version']);
$getid3->info['replay_gain']['track']['adjustment'] = $info_mpc_header['title_gain_db'];
$getid3->info['replay_gain']['album']['adjustment'] = $info_mpc_header['album_gain_db'];
if ($info_mpc_header['title_peak'] > 0) {
$getid3->info['replay_gain']['track']['peak'] = $info_mpc_header['title_peak'];
- }
+ }
elseif (round($info_mpc_header['max_level'] * 1.18) > 0) {
$getid3->info['replay_gain']['track']['peak'] = (int)(round($info_mpc_header['max_level'] * 1.18)); // why? I don't know - see mppdec.c
}
@@ -123,14 +123,14 @@ class getid3_mpc extends getid3_handler
$getid3->info['audio']['encoder'] = $info_mpc_header['encoder_version'];
$getid3->info['audio']['encoder_options'] = $info_mpc_header['profile'];
-
+
return true;
}
public static function MPCprofileNameLookup($profileid) {
-
+
static $lookup = array (
0 => 'no profile',
1 => 'Experimental',
@@ -155,7 +155,7 @@ class getid3_mpc extends getid3_handler
public static function MPCfrequencyLookup($frequencyid) {
-
+
static $lookup = array (
0 => 44100,
1 => 48000,
@@ -168,7 +168,7 @@ class getid3_mpc extends getid3_handler
public static function MPCpeakDBLookup($int_value) {
-
+
if ($int_value > 0) {
return ((log10($int_value) / log10(2)) - 15) * 6;
}
@@ -178,7 +178,7 @@ class getid3_mpc extends getid3_handler
public static function MPCencoderVersionLookup($encoder_version) {
-
+
//Encoder version * 100 (106 = 1.06)
//EncoderVersion % 10 == 0 Release (1.0)
//EncoderVersion % 2 == 0 Beta (1.06)
@@ -208,4 +208,4 @@ class getid3_mpc extends getid3_handler
}
-?> \ No newline at end of file
+?>
diff --git a/modules/getid3/module.audio.mpc8.php b/modules/getid3/module.audio.mpc8.php
new file mode 100644
index 00000000..8de44186
--- /dev/null
+++ b/modules/getid3/module.audio.mpc8.php
@@ -0,0 +1,324 @@
+<?php
+// +----------------------------------------------------------------------+
+// | PHP version 5 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 2002-2006 James Heinrich, Allan Hansen |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2 of the GPL license, |
+// | that is bundled with this package in the file license.txt and is |
+// | available through the world-wide-web at the following url: |
+// | http://www.gnu.org/copyleft/gpl.html |
+// +----------------------------------------------------------------------+
+// | getID3() - http://getid3.sourceforge.net or http://www.getid3.org |
+// +----------------------------------------------------------------------+
+// | Authors: James Heinrich <infoetid3*org> |
+// | Allan Hansen <ahartemis*dk> |
+// +----------------------------------------------------------------------+
+// | module.audio.mpc.php |
+// | Module for analyzing Musepack/MPEG+ Audio files |
+// | dependencies: NONE |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+
+
+class getid3_mpc8 extends getid3_handler
+{
+
+ public function Analyze() {
+ $getid3 = $this->getid3;
+
+ $getid3->info['fileformat'] = 'mpc';
+ $getid3->info['audio']['dataformat'] = 'mpc';
+ $getid3->info['audio']['bitrate_mode'] = 'vbr';
+ $getid3->info['audio']['lossless'] = false;
+
+ fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET);
+ $MPCheaderData = fread($getid3->fp, 4);
+ $getid3->info['mpc']['header']['preamble'] = substr($MPCheaderData, 0, 4); // should be 'MPCK' (SV8) or 'MP+' (SV7), otherwise possible stream data (SV4-SV6)
+ if (ereg('^MPCK', $getid3->info['mpc']['header']['preamble'])) {
+
+ // this is SV8
+ // http://trac.musepack.net/trac/wiki/SV8Specification
+
+ $thisfile_mpc_header = &$getid3->info['mpc']['header'];
+
+ $keyNameSize = 2;
+ $maxHandledPacketLength = 9; // specs say: "n*8; 0 < n < 10"
+
+ $offset = ftell($getid3->fp);
+ while ($offset < $getid3->info['avdataend']) {
+ $thisPacket = array();
+ $thisPacket['offset'] = $offset;
+ $packet_offset = 0;
+
+ // Size is a variable-size field, could be 1-4 bytes (possibly more?)
+ // read enough data in and figure out the exact size later
+ $MPCheaderData = fread($getid3->fp, $keyNameSize + $maxHandledPacketLength);
+ $packet_offset += $keyNameSize;
+ $thisPacket['key'] = substr($MPCheaderData, 0, $keyNameSize);
+ $thisPacket['key_name'] = $this->MPCsv8PacketName($thisPacket['key']);
+ if ($thisPacket['key'] == $thisPacket['key_name']) {
+ $getid3->info['error'][] = 'Found unexpected key value "'.$thisPacket['key'].'" at offset '.$thisPacket['offset'];
+ return false;
+ }
+ $packetLength = 0;
+ $thisPacket['packet_size'] = $this->SV8variableLengthInteger(substr($MPCheaderData, $keyNameSize), $packetLength); // includes keyname and packet_size field
+ if ($thisPacket['packet_size'] === false) {
+ $getid3->info['error'][] = 'Did not find expected packet length within '.$maxHandledPacketLength.' bytes at offset '.($thisPacket['offset'] + $keyNameSize);
+ return false;
+ }
+ $packet_offset += $packetLength;
+ $offset += $thisPacket['packet_size'];
+
+ switch ($thisPacket['key']) {
+ case 'SH': // Stream Header
+ $moreBytesToRead = $thisPacket['packet_size'] - $keyNameSize - $maxHandledPacketLength;
+ if ($moreBytesToRead > 0) {
+ $MPCheaderData .= fread($getid3->fp, $moreBytesToRead);
+ }
+ $thisPacket['crc'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 4));
+ $packet_offset += 4;
+ $thisPacket['stream_version'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
+ $packet_offset += 1;
+
+ $packetLength = 0;
+ $thisPacket['sample_count'] = $this->SV8variableLengthInteger(substr($MPCheaderData, $packet_offset, $maxHandledPacketLength), $packetLength);
+ $packet_offset += $packetLength;
+
+ $packetLength = 0;
+ $thisPacket['beginning_silence'] = $this->SV8variableLengthInteger(substr($MPCheaderData, $packet_offset, $maxHandledPacketLength), $packetLength);
+ $packet_offset += $packetLength;
+
+ $otherUsefulData = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 2));
+ $packet_offset += 2;
+ $thisPacket['sample_frequency_raw'] = (($otherUsefulData & 0xE000) >> 13);
+ $thisPacket['max_bands_used'] = (($otherUsefulData & 0x1F00) >> 8);
+ $thisPacket['channels'] = (($otherUsefulData & 0x00F0) >> 4) + 1;
+ $thisPacket['ms_used'] = (bool) (($otherUsefulData & 0x0008) >> 3);
+ $thisPacket['audio_block_frames'] = (($otherUsefulData & 0x0007) >> 0);
+ $thisPacket['sample_frequency'] = $this->MPCfrequencyLookup($thisPacket['sample_frequency_raw']);
+
+ $thisfile_mpc_header['mid_side_stereo'] = $thisPacket['ms_used'];
+ $thisfile_mpc_header['sample_rate'] = $thisPacket['sample_frequency'];
+ $thisfile_mpc_header['samples'] = $thisPacket['sample_count'];
+ $thisfile_mpc_header['stream_version_major'] = $thisPacket['stream_version'];
+
+ $getid3->info['audio']['channels'] = $thisPacket['channels'];
+ $getid3->info['audio']['sample_rate'] = $thisPacket['sample_frequency'];
+ $getid3->info['playtime_seconds'] = $thisPacket['sample_count'] / $thisPacket['sample_frequency'];
+ $getid3->info['audio']['bitrate'] = (($getid3->info['avdataend'] - $getid3->info['avdataoffset']) * 8) / $getid3->info['playtime_seconds'];
+ break;
+
+ case 'RG': // Replay Gain
+ $moreBytesToRead = $thisPacket['packet_size'] - $keyNameSize - $maxHandledPacketLength;
+ if ($moreBytesToRead > 0) {
+ $MPCheaderData .= fread($getid3->fp, $moreBytesToRead);
+ }
+ $thisPacket['replaygain_version'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
+ $packet_offset += 1;
+ $thisPacket['replaygain_title_gain'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 2));
+ $packet_offset += 2;
+ $thisPacket['replaygain_title_peak'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 2));
+ $packet_offset += 2;
+ $thisPacket['replaygain_album_gain'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 2));
+ $packet_offset += 2;
+ $thisPacket['replaygain_album_peak'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 2));
+ $packet_offset += 2;
+
+ if ($thisPacket['replaygain_title_gain']) { $getid3->info['replay_gain']['title']['gain'] = $thisPacket['replaygain_title_gain']; }
+ if ($thisPacket['replaygain_title_peak']) { $getid3->info['replay_gain']['title']['peak'] = $thisPacket['replaygain_title_peak']; }
+ if ($thisPacket['replaygain_album_gain']) { $getid3->info['replay_gain']['album']['gain'] = $thisPacket['replaygain_album_gain']; }
+ if ($thisPacket['replaygain_album_peak']) { $getid3->info['replay_gain']['album']['peak'] = $thisPacket['replaygain_album_peak']; }
+ break;
+
+ case 'EI': // Encoder Info
+ $moreBytesToRead = $thisPacket['packet_size'] - $keyNameSize - $maxHandledPacketLength;
+ if ($moreBytesToRead > 0) {
+ $MPCheaderData .= fread($getid3->fp, $moreBytesToRead);
+ }
+ $profile_pns = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
+ $packet_offset += 1;
+ $quality_int = (($profile_pns & 0xF0) >> 4);
+ $quality_dec = (($profile_pns & 0x0E) >> 3);
+ $thisPacket['quality'] = (float) $quality_int + ($quality_dec / 8);
+ $thisPacket['pns_tool'] = (bool) (($profile_pns & 0x01) >> 0);
+ $thisPacket['version_major'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
+ $packet_offset += 1;
+ $thisPacket['version_minor'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
+ $packet_offset += 1;
+ $thisPacket['version_build'] = getid3_lib::BigEndian2Int(substr($MPCheaderData, $packet_offset, 1));
+ $packet_offset += 1;
+ $thisPacket['version'] = $thisPacket['version_major'].'.'.$thisPacket['version_minor'].'.'.$thisPacket['version_build'];
+
+ $getid3->info['audio']['encoder'] = 'MPC v'.$thisPacket['version'].' ('.(($thisPacket['version_minor'] % 2) ? 'unstable' : 'stable').')';
+ $thisfile_mpc_header['encoder_version'] = $getid3->info['audio']['encoder'];
+ //$thisfile_mpc_header['quality'] = (float) ($thisPacket['quality'] / 1.5875); // values can range from 0.000 to 15.875, mapped to qualities of 0.0 to 10.0
+ $thisfile_mpc_header['quality'] = (float) ($thisPacket['quality'] - 5); // values can range from 0.000 to 15.875, of which 0..4 are "reserved/experimental", and 5..15 are mapped to qualities of 0.0 to 10.0
+ break;
+
+ case 'SO': // Seek Table Offset
+ $packetLength = 0;
+ $thisPacket['seek_table_offset'] = $thisPacket['offset'] + $this->SV8variableLengthInteger(substr($MPCheaderData, $packet_offset, $maxHandledPacketLength), $packetLength);
+ $packet_offset += $packetLength;
+ break;
+
+ case 'ST': // Seek Table
+ case 'SE': // Stream End
+ case 'AP': // Audio Data
+ // nothing useful here, just skip this packet
+ $thisPacket = array();
+ break;
+
+ default:
+ $getid3->info['error'][] = 'Found unhandled key type "'.$thisPacket['key'].'" at offset '.$thisPacket['offset'];
+ return false;
+ break;
+ }
+ if (!empty($thisPacket)) {
+ $getid3->info['mpc']['packets'][] = $thisPacket;
+ }
+ fseek($getid3->fp, $offset);
+ }
+ $thisfile_mpc_header['size'] = $offset;
+ return true;
+
+ } else {
+
+ $getid3->info['error'][] = 'Expecting "MP+" or "MPCK" at offset '.$getid3->info['avdataoffset'].', found "'.substr($MPCheaderData, 0, 4).'"';
+ unset($getid3->info['fileformat']);
+ unset($getid3->info['mpc']);
+ return false;
+
+ }
+ return false;
+ }
+
+
+
+ public static function MPCprofileNameLookup($profileid) {
+
+ static $lookup = array (
+ 0 => 'no profile',
+ 1 => 'Experimental',
+ 2 => 'unused',
+ 3 => 'unused',
+ 4 => 'unused',
+ 5 => 'below Telephone (q = 0.0)',
+ 6 => 'below Telephone (q = 1.0)',
+ 7 => 'Telephone (q = 2.0)',
+ 8 => 'Thumb (q = 3.0)',
+ 9 => 'Radio (q = 4.0)',
+ 10 => 'Standard (q = 5.0)',
+ 11 => 'Extreme (q = 6.0)',
+ 12 => 'Insane (q = 7.0)',
+ 13 => 'BrainDead (q = 8.0)',
+ 14 => 'above BrainDead (q = 9.0)',
+ 15 => 'above BrainDead (q = 10.0)'
+ );
+ return (isset($lookup[$profileid]) ? $lookup[$profileid] : 'invalid');
+ }
+
+
+
+ public static function MPCfrequencyLookup($frequencyid) {
+
+ static $lookup = array (
+ 0 => 44100,
+ 1 => 48000,
+ 2 => 37800,
+ 3 => 32000
+ );
+ return (isset($lookup[$frequencyid]) ? $lookup[$frequencyid] : 'invalid');
+ }
+
+
+
+ public static function MPCpeakDBLookup($int_value) {
+
+ if ($int_value > 0) {
+ return ((log10($int_value) / log10(2)) - 15) * 6;
+ }
+ return false;
+ }
+
+
+
+ public static function MPCencoderVersionLookup($encoder_version) {
+
+ //Encoder version * 100 (106 = 1.06)
+ //EncoderVersion % 10 == 0 Release (1.0)
+ //EncoderVersion % 2 == 0 Beta (1.06)
+ //EncoderVersion % 2 == 1 Alpha (1.05a...z)
+
+ if ($encoder_version == 0) {
+ // very old version, not known exactly which
+ return 'Buschmann v1.7.0-v1.7.9 or Klemm v0.90-v1.05';
+ }
+
+ if (($encoder_version % 10) == 0) {
+
+ // release version
+ return number_format($encoder_version / 100, 2);
+
+ } elseif (($encoder_version % 2) == 0) {
+
+ // beta version
+ return number_format($encoder_version / 100, 2).' beta';
+
+ }
+
+ // alpha version
+ return number_format($encoder_version / 100, 2).' alpha';
+ }
+
+
+
+ public static function SV8variableLengthInteger($data, &$packetLength, $maxHandledPacketLength=9) {
+ $packet_size = 0;
+ for ($packetLength = 1; $packetLength <= $maxHandledPacketLength; $packetLength++) {
+ // variable-length size field:
+ // bits, big-endian
+ // 0xxx xxxx - value 0 to 2^7-1
+ // 1xxx xxxx 0xxx xxxx - value 0 to 2^14-1
+ // 1xxx xxxx 1xxx xxxx 0xxx xxxx - value 0 to 2^21-1
+ // 1xxx xxxx 1xxx xxxx 1xxx xxxx 0xxx xxxx - value 0 to 2^28-1
+ // ...
+ $thisbyte = ord(substr($data, ($packetLength - 1), 1));
+ // look through bytes until find a byte with MSB==0
+ $packet_size = ($packet_size << 7);
+ $packet_size = ($packet_size | ($thisbyte & 0x7F));
+ if (($thisbyte & 0x80) === 0) {
+ break;
+ }
+ if ($packetLength >= $maxHandledPacketLength) {
+ return false;
+ }
+ }
+ return $packet_size;
+ }
+
+
+
+ public static function MPCsv8PacketName($packetKey) {
+ static $MPCsv8PacketName = array();
+ if (empty($MPCsv8PacketName)) {
+ $MPCsv8PacketName = array(
+ 'AP' => 'Audio Packet',
+ 'CT' => 'Chapter Tag',
+ 'EI' => 'Encoder Info',
+ 'RG' => 'Replay Gain',
+ 'SE' => 'Stream End',
+ 'SH' => 'Stream Header',
+ 'SO' => 'Seek Table Offset',
+ 'ST' => 'Seek Table',
+ );
+ }
+ return (isset($MPCsv8PacketName[$packetKey]) ? $MPCsv8PacketName[$packetKey] : $packetKey);
+ }
+
+}
+
+
+?>
diff --git a/modules/getid3/module.tag.id3v2.php b/modules/getid3/module.tag.id3v2.php
index deaa5abc..c1ee70ab 100644
--- a/modules/getid3/module.tag.id3v2.php
+++ b/modules/getid3/module.tag.id3v2.php
@@ -24,8 +24,8 @@
// $Id: module.tag.id3v2.php,v 1.15 2006/12/03 23:47:29 ah Exp $
-
-
+
+
class getid3_id3v2 extends getid3_handler
{
@@ -35,11 +35,11 @@ class getid3_id3v2 extends getid3_handler
public function Analyze() {
$getid3 = $this->getid3;
-
+
// dependency
$getid3->include_module('tag.id3v1');
-
- if ($getid3->option_tags_images) {
+
+ if ($getid3->option_tags_images) {
$getid3->include_module('lib.image_size');
}
@@ -124,7 +124,7 @@ class getid3_id3v2 extends getid3_handler
// Frames
-
+
// All ID3v2 frames consists of one frame header followed by one or more
// fields containing the actual information. The header is always 10
// bytes and laid out as follows:
@@ -137,11 +137,11 @@ class getid3_id3v2 extends getid3_handler
if (@$info_id3v2['exthead']['length']) {
$size_of_frames -= ($info_id3v2['exthead']['length'] + 4);
}
-
+
if (@$info_id3v2_flags['isfooter']) {
$size_of_frames -= 10; // footer takes last 10 bytes of ID3v2 header, after frame data, before audio
}
-
+
if ($size_of_frames > 0) {
$frame_data = $this->fread($size_of_frames); // read all frames from file into $frame_data variable
@@ -149,7 +149,7 @@ class getid3_id3v2 extends getid3_handler
if (@$info_id3v2_flags['unsynch'] && ($id3v2_major_version <= 3)) {
$frame_data = str_replace("\xFF\x00", "\xFF", $frame_data);
}
-
+
// [in ID3v2.4.0] Unsynchronisation [S:6.1] is done on frame level, instead
// of on tag level, making it easier to skip frames, increasing the streamability
// of the tag. The unsynchronisation flag in the header [S:3.1] indicates that
@@ -190,8 +190,8 @@ class getid3_id3v2 extends getid3_handler
}
$extended_header_offset += $info_id3v2['exthead']['padding_size'];
- }
-
+ }
+
elseif ($id3v2_major_version == 4) {
// v2.4 definition:
@@ -237,12 +237,12 @@ class getid3_id3v2 extends getid3_handler
$frame_data_offset += $extended_header_offset;
$frame_data = substr($frame_data, $extended_header_offset);
} // end extended header
-
-
-
-
-
-
+
+
+
+
+
+
while (isset($frame_data) && (strlen($frame_data) > 0)) { // cycle through until no more frame data is left to parse
if (strlen($frame_data) <= ($id3v2_major_version == 2 ? 6 : 10)) {
// insufficient room left in ID3v2 header for actual data - must be padding
@@ -259,7 +259,7 @@ class getid3_id3v2 extends getid3_handler
}
break; // skip rest of ID3v2 header
}
-
+
if ($id3v2_major_version == 2) {
// Frame ID $xx xx xx (three characters)
// Size $xx xx xx (24-bit integer)
@@ -313,7 +313,7 @@ class getid3_id3v2 extends getid3_handler
$info_id3v2['padding']['start'] = $frame_data_offset;
$info_id3v2['padding']['length'] = strlen($frame_header) + strlen($frame_data);
$info_id3v2['padding']['valid'] = true;
-
+
$len = strlen($frame_data);
for ($i = 0; $i < $len; $i++) {
if ($frame_data{$i} != "\x00") {
@@ -376,7 +376,7 @@ class getid3_id3v2 extends getid3_handler
if (!getid3_id3v2::IsValidID3v2FrameName($frame_name, $id3v2_major_version)) {
switch ($frame_name) {
-
+
case "\x00\x00".'MP':
case "\x00".'MP3':
case ' MP3':
@@ -411,7 +411,7 @@ class getid3_id3v2 extends getid3_handler
// Footer
-
+
// The footer is a copy of the header, but with a different identifier.
// ID3v2 identifier "3DI"
// ID3v2 version $04 00
@@ -450,9 +450,9 @@ class getid3_id3v2 extends getid3_handler
}
}
}
-
- // Use year from recording time if year is empty
- if (!strlen($info_id3v2['comments']['year']) && ereg('^([0-9]{4})', @$info_id3v2['comments']['recording_time'][0], $matches)) {
+
+ // Use year from recording time if year not set
+ if (!isset($info_id3v2['comments']['year']) && ereg('^([0-9]{4})', @$info_id3v2['comments']['recording_time'][0], $matches)) {
$info_id3v2['comments']['year'] = array ($matches[1]);
}
@@ -468,19 +468,19 @@ class getid3_id3v2 extends getid3_handler
private function ParseID3v2Frame(&$parsed_frame) {
-
+
$getid3 = $this->getid3;
$id3v2_major_version = $getid3->info['id3v2']['majorversion'];
$frame_name_long = getid3_id3v2::FrameNameLongLookup($parsed_frame['frame_name']);
if ($frame_name_long) {
- $parsed_frame['framenamelong'] = $frame_name_long;
+ $parsed_frame['framenamelong'] = $frame_name_long;
}
-
+
$frame_name_short = getid3_id3v2::FrameNameShortLookup($parsed_frame['frame_name']);
if ($frame_name_short) {
- $parsed_frame['framenameshort'] = $frame_name_short;
+ $parsed_frame['framenameshort'] = $frame_name_short;
}
if ($id3v2_major_version >= 3) { // frame flags are not part of the ID3v2.2 standard
@@ -521,7 +521,7 @@ class getid3_id3v2 extends getid3_handler
// Frame-level de-compression
if ($parsed_frame['flags']['compression']) {
$parsed_frame['decompressed_size'] = getid3_lib::BigEndian2Int(substr($parsed_frame['data'], 0, 4));
-
+
if (!function_exists('gzuncompress')) {
$getid3->warning('gzuncompress() support required to decompress ID3v2 frame "'.$parsed_frame['frame_name'].'"');
} elseif ($decompressed_data = @gzuncompress(substr($parsed_frame['data'], 4))) {
@@ -547,8 +547,8 @@ class getid3_id3v2 extends getid3_handler
$getid3->warning($warning);
return true;
}
-
-
+
+
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'UFID')) || // 4.1 UFID Unique file identifier
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'UFI'))) { // 4.1 UFI Unique file identifier
@@ -602,7 +602,7 @@ class getid3_id3v2 extends getid3_handler
unset($parsed_frame['data']);
return true;
}
-
+
if ($parsed_frame['frame_name']{0} == 'T') { // 4.2. T??[?] Text information frame
@@ -624,11 +624,11 @@ class getid3_id3v2 extends getid3_handler
$parsed_frame['encoding'] = $this->TextEncodingNameLookup($frame_text_encoding);
if (!empty($parsed_frame['framenameshort']) && !empty($parsed_frame['data'])) {
-
+
// remove possible terminating \x00 (put by encoding id or software bug)
$string = $getid3->iconv($parsed_frame['encoding'], 'UTF-8', $parsed_frame['data']);
- if ($string[strlen($string)-1] == "\x00") {
- $string = substr($string, 0, strlen($string)-1);
+ if ($string[strlen($string) - 1] == "\x00") {
+ $string = substr($string, 0, strlen($string) - 1);
}
$getid3->info['id3v2']['comments'][$parsed_frame['framenameshort']][] = $string;
unset($string);
@@ -639,7 +639,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'WXXX')) || // 4.3.2 WXXX User defined URL link frame
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'WXX'))) { // 4.3.2 WXX User defined URL link frame
-
+
// There may be more than one 'WXXX' frame in each tag,
// but only one with the same description
// <Header for 'User defined URL link frame', ID: 'WXXX'>
@@ -775,7 +775,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'MLLT')) || // 4.6 MLLT MPEG location lookup table
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'MLL'))) { // 4.7 MLL MPEG location lookup table
-
+
// There may only be one 'MLLT' frame in each tag
// <Header for 'Location lookup table', ID: 'MLLT'>
// MPEG frames between reference $xx xx
@@ -794,7 +794,7 @@ class getid3_id3v2 extends getid3_handler
$parsed_frame['bitsforbytesdeviation'] = getid3_lib::BigEndian2Int($parsed_frame['data'][8]);
$parsed_frame['bitsformsdeviation'] = getid3_lib::BigEndian2Int($parsed_frame['data'][9]);
$parsed_frame['data'] = substr($parsed_frame['data'], 10);
-
+
while ($frame_offset < strlen($parsed_frame['data'])) {
$deviation_bitstream .= getid3_lib::BigEndian2Bin($parsed_frame['data']{$frame_offset++});
}
@@ -812,7 +812,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'SYTC')) || // 4.7 SYTC Synchronised tempo codes
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'STC'))) { // 4.8 STC Synchronised tempo codes
-
+
// There may only be one 'SYTC' frame in each tag
// <Header for 'Synchronised tempo codes', ID: 'SYTC'>
// Time stamp format $xx
@@ -837,10 +837,10 @@ class getid3_id3v2 extends getid3_handler
return true;
}
-
+
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'USLT')) || // 4.8 USLT Unsynchronised lyric/text transcription
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'ULT'))) { // 4.9 ULT Unsynchronised lyric/text transcription
-
+
// There may be more than one 'Unsynchronised lyrics/text transcription' frame
// in each tag, but only one with the same language and content descriptor.
// <Header for 'Unsynchronised lyrics/text transcription', ID: 'USLT'>
@@ -886,7 +886,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'SYLT')) || // 4.9 SYLT Synchronised lyric/text
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'SLT'))) { // 4.10 SLT Synchronised lyric/text
-
+
// There may be more than one 'SYLT' frame in each tag,
// but only one with the same language and content descriptor.
// <Header for 'Synchronised lyrics/text', ID: 'SYLT'>
@@ -947,7 +947,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'COMM')) || // 4.10 COMM Comments
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'COM'))) { // 4.11 COM Comments
-
+
// There may be more than one comment frame in each tag,
// but only one with the same language and content descriptor.
// <Header for 'Comment', ID: 'COMM'>
@@ -991,10 +991,10 @@ class getid3_id3v2 extends getid3_handler
}
return true;
}
-
+
if (($id3v2_major_version >= 4) && ($parsed_frame['frame_name'] == 'RVA2')) { // 4.11 RVA2 Relative volume adjustment (2) (ID3v2.4+ only)
-
+
// There may be more than one 'RVA2' frame in each tag,
// but only one with the same identification string
// <Header for 'Relative volume adjustment (2)', ID: 'RVA2'>
@@ -1014,7 +1014,7 @@ class getid3_id3v2 extends getid3_handler
}
$frame_remaining_data = substr($parsed_frame['data'], $frame_terminator_pos + strlen("\x00"));
$parsed_frame['description'] = $frame_id_string;
-
+
while (strlen($frame_remaining_data)) {
$frame_offset = 0;
$frame_channeltypeid = ord(substr($frame_remaining_data, $frame_offset++, 1));
@@ -1030,11 +1030,11 @@ class getid3_id3v2 extends getid3_handler
unset($parsed_frame['data']);
return true;
}
-
+
if ((($id3v2_major_version == 3) && ($parsed_frame['frame_name'] == 'RVAD')) || // 4.12 RVAD Relative volume adjustment (ID3v2.3 only)
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'RVA'))) { // 4.12 RVA Relative volume adjustment (ID3v2.2 only)
-
+
// There may only be one 'RVA' frame in each tag
// <Header for 'Relative volume adjustment', ID: 'RVA'>
// ID3v2.2 => Increment/decrement %000000ba
@@ -1125,7 +1125,7 @@ class getid3_id3v2 extends getid3_handler
if (($id3v2_major_version >= 4) && ($parsed_frame['frame_name'] == 'EQU2')) { // 4.12 EQU2 Equalisation (2) (ID3v2.4+ only)
-
+
// There may be more than one 'EQU2' frame in each tag,
// but only one with the same identification string
// <Header of 'Equalisation (2)', ID: 'EQU2'>
@@ -1159,7 +1159,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version == 3) && ($parsed_frame['frame_name'] == 'EQUA')) || // 4.12 EQUA Equalisation (ID3v2.3 only)
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'EQU'))) { // 4.13 EQU Equalisation (ID3v2.2 only)
-
+
// There may only be one 'EQUA' frame in each tag
// <Header for 'Relative volume adjustment', ID: 'EQU'>
// Adjustment bits $xx
@@ -1193,7 +1193,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'RVRB')) || // 4.13 RVRB Reverb
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'REV'))) { // 4.14 REV Reverb
-
+
// There may only be one 'RVRB' frame in each tag.
// <Header for 'Reverb', ID: 'RVRB'>
// Reverb left (ms) $xx xx
@@ -1245,7 +1245,7 @@ class getid3_id3v2 extends getid3_handler
$getid3->warning('Invalid text encoding byte ('.$frame_text_encoding.') in frame "'.$parsed_frame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
}
- if ($id3v2_major_version == 2 && strlen($parsed_frame['data']) > $frame_offset) {
+ if ($id3v2_major_version == 2 && strlen($parsed_frame['data']) > $frame_offset) {
$frame_imagetype = substr($parsed_frame['data'], $frame_offset, 3);
if (strtolower($frame_imagetype) == 'ima') {
// complete hack for mp3Rage (www.chaoticsoftware.com) that puts ID3v2.3-formatted
@@ -1264,7 +1264,7 @@ class getid3_id3v2 extends getid3_handler
$frame_offset += 3;
}
}
-
+
if ($id3v2_major_version > 2 && strlen($parsed_frame['data']) > $frame_offset) {
$frame_terminator_pos = @strpos($parsed_frame['data'], "\x00", $frame_offset);
$frame_mimetype = substr($parsed_frame['data'], $frame_offset, $frame_terminator_pos - $frame_offset);
@@ -1298,19 +1298,19 @@ class getid3_id3v2 extends getid3_handler
$parsed_frame['data'] = substr($parsed_frame['data'], $frame_terminator_pos + strlen(getid3_id3v2::TextEncodingTerminatorLookup($frame_text_encoding)));
if ($getid3->option_tags_images) {
-
+
$image_chunk_check = getid3_lib_image_size::get($parsed_frame['data']);
if (($image_chunk_check[2] >= 1) && ($image_chunk_check[2] <= 3)) {
$parsed_frame['image_mime'] = image_type_to_mime_type($image_chunk_check[2]);
-
+
if ($image_chunk_check[0]) {
$parsed_frame['image_width'] = $image_chunk_check[0];
}
-
+
if ($image_chunk_check[1]) {
$parsed_frame['image_height'] = $image_chunk_check[1];
}
-
+
$parsed_frame['image_bytes'] = strlen($parsed_frame['data']);
}
}
@@ -1321,7 +1321,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'GEOB')) || // 4.15 GEOB General encapsulated object
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'GEO'))) { // 4.16 GEO General encapsulated object
-
+
// There may be more than one 'GEOB' frame in each tag,
// but only one with the same content descriptor
// <Header for 'General encapsulated object', ID: 'GEOB'>
@@ -1377,7 +1377,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'PCNT')) || // 4.16 PCNT Play counter
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'CNT'))) { // 4.17 CNT Play counter
-
+
// There may only be one 'PCNT' frame in each tag.
// When the counter reaches all one's, one byte is inserted in
// front of the counter thus making the counter eight bits bigger
@@ -1391,7 +1391,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'POPM')) || // 4.17 POPM Popularimeter
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'POP'))) { // 4.18 POP Popularimeter
-
+
// There may be more than one 'POPM' frame in each tag,
// but only one with the same email address
// <Header for 'Popularimeter', ID: 'POPM'>
@@ -1417,7 +1417,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'RBUF')) || // 4.18 RBUF Recommended buffer size
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'BUF'))) { // 4.19 BUF Recommended buffer size
-
+
// There may only be one 'RBUF' frame in each tag
// <Header for 'Recommended buffer size', ID: 'RBUF'>
// Buffer size $xx xx xx
@@ -1437,7 +1437,7 @@ class getid3_id3v2 extends getid3_handler
if (($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'CRM')) { // 4.20 Encrypted meta frame (ID3v2.2 only)
-
+
// There may be more than one 'CRM' frame in a tag,
// but only one with the same 'owner identifier'
// <Header for 'Encrypted meta frame', ID: 'CRM'>
@@ -1467,7 +1467,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'AENC')) || // 4.19 AENC Audio encryption
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'CRA'))) { // 4.21 CRA Audio encryption
-
+
// There may be more than one 'AENC' frames in a tag,
// but only one with the same 'Owner identifier'
// <Header for 'Audio encryption', ID: 'AENC'>
@@ -1496,7 +1496,7 @@ class getid3_id3v2 extends getid3_handler
if ((($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'LINK')) || // 4.20 LINK Linked information
(($id3v2_major_version == 2) && ($parsed_frame['frame_name'] == 'LNK'))) { // 4.22 LNK Linked information
-
+
// There may be more than one 'LINK' frame in a tag,
// but only one with the same contents
// <Header for 'Linked information', ID: 'LINK'>
@@ -1532,7 +1532,7 @@ class getid3_id3v2 extends getid3_handler
if (($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'POSS')) { // 4.21 POSS Position synchronisation frame (ID3v2.3+ only)
-
+
// There may only be one 'POSS' frame in each tag
// <Head for 'Position synchronisation', ID: 'POSS'>
// Time stamp format $xx
@@ -1547,7 +1547,7 @@ class getid3_id3v2 extends getid3_handler
if (($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'USER')) { // 4.22 USER Terms of use (ID3v2.3+ only)
-
+
// There may be more than one 'Terms of use' frame in a tag,
// but only one with the same 'Language'
// <Header for 'Terms of use frame', ID: 'USER'>
@@ -1577,7 +1577,7 @@ class getid3_id3v2 extends getid3_handler
if (($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'OWNE')) { // 4.23 OWNE Ownership frame (ID3v2.3+ only)
-
+
// There may only be one 'OWNE' frame in a tag
// <Header for 'Ownership frame', ID: 'OWNE'>
// Text encoding $xx
@@ -1614,7 +1614,7 @@ class getid3_id3v2 extends getid3_handler
if (($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'COMR')) { // 4.24 COMR Commercial frame (ID3v2.3+ only)
-
+
// There may be more than one 'commercial frame' in a tag,
// but no two may be identical
// <Header for 'Commercial frame', ID: 'COMR'>
@@ -1657,24 +1657,24 @@ class getid3_id3v2 extends getid3_handler
if (ord(substr($parsed_frame['data'], $frame_terminator_pos + strlen(getid3_id3v2::TextEncodingTerminatorLookup($frame_text_encoding)), 1)) === 0) {
$frame_terminator_pos++; // @strpos() fooled because 2nd byte of Unicode chars are often 0x00
}
-
+
$frame_sellername = substr($parsed_frame['data'], $frame_offset, $frame_terminator_pos - $frame_offset);
if (ord($frame_sellername) === 0) {
$frame_sellername = '';
}
-
+
$frame_offset = $frame_terminator_pos + strlen(getid3_id3v2::TextEncodingTerminatorLookup($frame_text_encoding));
$frame_terminator_pos = @strpos($parsed_frame['data'], getid3_id3v2::TextEncodingTerminatorLookup($frame_text_encoding), $frame_offset);
if (ord(substr($parsed_frame['data'], $frame_terminator_pos + strlen(getid3_id3v2::TextEncodingTerminatorLookup($frame_text_encoding)), 1)) === 0) {
$frame_terminator_pos++; // @strpos() fooled because 2nd byte of Unicode chars are often 0x00
}
-
+
$frame_description = substr($parsed_frame['data'], $frame_offset, $frame_terminator_pos - $frame_offset);
if (ord($frame_description) === 0) {
$frame_description = '';
}
-
+
$frame_offset = $frame_terminator_pos + strlen(getid3_id3v2::TextEncodingTerminatorLookup($frame_text_encoding));
$frame_terminator_pos = @strpos($parsed_frame['data'], "\x00", $frame_offset);
@@ -1699,7 +1699,7 @@ class getid3_id3v2 extends getid3_handler
if (($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'ENCR')) { // 4.25 ENCR Encryption method registration (ID3v2.3+ only)
-
+
// There may be several 'ENCR' frames in a tag,
// but only one containing the same symbol
// and only one containing the same owner identifier
@@ -1721,7 +1721,7 @@ class getid3_id3v2 extends getid3_handler
$parsed_frame['data'] = (string)substr($parsed_frame['data'], $frame_offset);
return true;
}
-
+
if (($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'GRID')) { // 4.26 GRID Group identification registration (ID3v2.3+ only)
@@ -1749,7 +1749,7 @@ class getid3_id3v2 extends getid3_handler
if (($id3v2_major_version >= 3) && ($parsed_frame['frame_name'] == 'PRIV')) { // 4.27 PRIV Private frame (ID3v2.3+ only)
-
+
// The tag may contain more than one 'PRIV' frame
// but only with different contents
// <Header for 'Private frame', ID: 'PRIV'>
@@ -1771,7 +1771,7 @@ class getid3_id3v2 extends getid3_handler
if (($id3v2_major_version >= 4) && ($parsed_frame['frame_name'] == 'SIGN')) { // 4.28 SIGN Signature frame (ID3v2.4+ only)
-
+
// There may be more than one 'signature frame' in a tag,
// but no two may be identical
// <Header for 'Signature frame', ID: 'SIGN'>
@@ -1786,7 +1786,7 @@ class getid3_id3v2 extends getid3_handler
if (($id3v2_major_version >= 4) && ($parsed_frame['frame_name'] == 'SEEK')) { // 4.29 SEEK Seek frame (ID3v2.4+ only)
-
+
// There may only be one 'seek frame' in a tag
// <Header for 'Seek frame', ID: 'SEEK'>
// Minimum offset to next tag $xx xx xx xx
@@ -1798,7 +1798,7 @@ class getid3_id3v2 extends getid3_handler
if (($id3v2_major_version >= 4) && ($parsed_frame['frame_name'] == 'ASPI')) { // 4.30 ASPI Audio seek point index (ID3v2.4+ only)
-
+
// There may only be one 'audio seek point index' frame in a tag
// <Header for 'Seek Point Index', ID: 'ASPI'>
// Indexed data start (S) $xx xx xx xx
@@ -1840,16 +1840,16 @@ class getid3_id3v2 extends getid3_handler
// d - replay gain adjustment
$frame_offset = 0;
-
+
$parsed_frame['peakamplitude'] = (float)getid3_lib::BigEndian2Int(substr($parsed_frame['data'], $frame_offset, 4));
$frame_offset += 4;
-
+
$rg_track_adjustment = decbin(substr($parsed_frame['data'], $frame_offset, 2));
$frame_offset += 2;
-
+
$rg_album_adjustment = decbin(substr($parsed_frame['data'], $frame_offset, 2));
$frame_offset += 2;
-
+
$parsed_frame['raw']['track']['name'] = bindec(substr($rg_track_adjustment, 0, 3));
$parsed_frame['raw']['track']['originator'] = bindec(substr($rg_track_adjustment, 3, 3));
$parsed_frame['raw']['track']['signbit'] = bindec($rg_track_adjustment[6]);
@@ -1877,32 +1877,32 @@ class getid3_id3v2 extends getid3_handler
return true;
}
-
-
-
+
+
+
private function TextEncodingNameLookup($encoding) {
-
+
// Override specification - BRAINDEAD taggers
if (!$encoding) {
return $this->getid3->encoding_id3v2;
}
-
+
// http://www.id3.org/id3v2.4.0-structure.txt
static $lookup = array (
- 0 => 'ISO-8859-1',
- 1 => 'UTF-16',
- 2 => 'UTF-16BE',
- 3 => 'UTF-8',
+ 0 => 'ISO-8859-1',
+ 1 => 'UTF-16',
+ 2 => 'UTF-16BE',
+ 3 => 'UTF-8',
255 => 'UTF-16BE'
);
-
+
return (isset($lookup[$encoding]) ? $lookup[$encoding] : 'ISO-8859-1');
}
public static function ParseID3v2GenreString($genre_string) {
-
+
// Parse genres into arrays of genreName and genreID
// ID3v2.2.x, ID3v2.3.x: '(21)' or '(4)Eurodisco' or '(51)(39)' or '(55)((I think...)'
// ID3v2.4.x: '21' $00 'Eurodisco' $00
@@ -1913,12 +1913,15 @@ class getid3_id3v2 extends getid3_handler
$unprocessed = trim($genre_string); // trailing nulls will cause an infinite loop.
$genre_string = '';
while (strpos($unprocessed, "\x00") !== false) {
- // convert null-seperated v2.4-format into v2.3 ()-seperated format
- $end_pos = strpos($unprocessed, "\x00");
- $genre_string .= '('.substr($unprocessed, 0, $end_pos).')';
- $unprocessed = substr($unprocessed, $end_pos + 1);
+ // convert null-seperated v2.4-format into v2.3 ()-seperated format
+ $end_pos = strpos($unprocessed, "\x00");
+ $genre_string .= '('.substr($unprocessed, 0, $end_pos).')';
+ $unprocessed = substr($unprocessed, $end_pos + 1);
}
unset($unprocessed);
+ } elseif (eregi('^([0-9]+|CR|RX)$', $genre_string)) {
+ // some tagging program (including some that use TagLib) fail to include null byte after numeric genre
+ $genre_string = '('.$genre_string.')';
}
if (getid3_id3v1::LookupGenreID($genre_string)) {
@@ -1936,7 +1939,7 @@ class getid3_id3v2 extends getid3_handler
}
$element = substr($genre_string, $start_pos + 1, $end_pos - ($start_pos + 1));
$genre_string = substr($genre_string, 0, $start_pos).substr($genre_string, $end_pos + 1);
-
+
if (getid3_id3v1::LookupGenreName($element)) { // $element is a valid genre id/abbreviation
if (empty($return_array['genre']) || !in_array(getid3_id3v1::LookupGenreName($element), $return_array['genre'])) { // avoid duplicate entires
@@ -1958,9 +1961,9 @@ class getid3_id3v2 extends getid3_handler
return $return_array;
}
-
-
-
+
+
+
public static function LookupCurrencyUnits($currency_id) {
static $lookup = array (
@@ -2341,7 +2344,7 @@ class getid3_id3v2 extends getid3_handler
'ZMK' => 'Zambia',
'ZWD' => 'Zimbabwe'
);
-
+
return @$lookup[$currency_id];
}
@@ -2793,15 +2796,15 @@ class getid3_id3v2 extends getid3_handler
'zho' => 'Chinese',
'zul' => 'Zulu',
'zun' => 'Zuni'
- );
+ );
return @$lookup[$language_code];
}
-
+
public static function ETCOEventLookup($index) {
-
+
if (($index >= 0x17) && ($index <= 0xDF)) {
return 'reserved for future use';
}
@@ -2890,7 +2893,7 @@ class getid3_id3v2 extends getid3_handler
0x13 => 'Band/artist logotype',
0x14 => 'Publisher/Studio logotype'
);
-
+
if ($return_array) {
return $lookup;
}
@@ -2919,7 +2922,7 @@ class getid3_id3v2 extends getid3_handler
public static function RVA2ChannelTypeLookup($index) {
-
+
static $lookup = array (
0x00 => 'Other',
0x01 => 'Master volume',
@@ -3098,8 +3101,8 @@ class getid3_id3v2 extends getid3_handler
'TFEA' => 'Featured Artist',
'TSTU' => 'Recording Studio',
'rgad' => 'Replay Gain Adjustment'
- );
-
+ );
+
return @$lookup[$frame_name];
// Last three:
@@ -3146,13 +3149,11 @@ class getid3_id3v2 extends getid3_handler
'TP2' => 'band',
'TP3' => 'conductor',
'TP4' => 'remixer',
- 'TPA' => 'pos',
'TPB' => 'publisher',
'TPE1' => 'artist',
'TPE2' => 'band',
'TPE3' => 'conductor',
'TPE4' => 'remixer',
- 'TPOS' => 'pos',
'TPUB' => 'publisher',
'TRC' => 'isrc',
'TRCK' => 'track',
@@ -3208,10 +3209,10 @@ class getid3_id3v2 extends getid3_handler
// $03 UTF-8 encoded Unicode. Terminated with $00.
static $lookup = array (
- 0 => "\x00",
- 1 => "\x00\x00",
- 2 => "\x00\x00",
- 3 => "\x00",
+ 0 => "\x00",
+ 1 => "\x00\x00",
+ 2 => "\x00\x00",
+ 3 => "\x00",
255 => "\x00\x00"
);
@@ -3243,7 +3244,7 @@ class getid3_id3v2 extends getid3_handler
if ((int)$date_stamp) {
return false;
}
-
+
$year = substr($date_stamp, 0, 4);
$month = substr($date_stamp, 4, 2);
$day = substr($date_stamp, 6, 2);
@@ -3258,8 +3259,8 @@ class getid3_id3v2 extends getid3_handler
}
return true;
}
-
-
+
+
public static function array_merge_noclobber($array1, $array2) {
if (!is_array($array1) || !is_array($array2)) {
@@ -3279,4 +3280,4 @@ class getid3_id3v2 extends getid3_handler
}
-?>
+?> \ No newline at end of file
diff --git a/modules/getid3/write.id3v2.php b/modules/getid3/write.id3v2.php
index 5c4ae4d7..f122b6b0 100644
--- a/modules/getid3/write.id3v2.php
+++ b/modules/getid3/write.id3v2.php
@@ -375,7 +375,7 @@ class getid3_write_id3v2 extends getid3_handler_write
// rewrite file - no tag present or new tag longer than old tag
else
- {
+
if (!$fp_source = @fopen($this->filename, 'rb')) {
throw new getid3_exception('Could not open '.$this->filename.' mode "rb"');
}