public function Analyze()
 {
     $info =& $this->getid3->info;
     // http://www.volweb.cz/str/tags.htm
     if (!getid3_lib::intValueSupported($info['filesize'])) {
         $info['warning'][] = 'Unable to check for Lyrics3 because file is larger than ' . round(PHP_INT_MAX / 1073741824) . 'GB';
         return false;
     }
     $this->fseek(0 - 128 - 9 - 6, SEEK_END);
     // end - ID3v1 - "LYRICSEND" - [Lyrics3size]
     $lyrics3_id3v1 = $this->fread(128 + 9 + 6);
     $lyrics3lsz = substr($lyrics3_id3v1, 0, 6);
     // Lyrics3size
     $lyrics3end = substr($lyrics3_id3v1, 6, 9);
     // LYRICSEND or LYRICS200
     $id3v1tag = substr($lyrics3_id3v1, 15, 128);
     // ID3v1
     if ($lyrics3end == 'LYRICSEND') {
         // Lyrics3v1, ID3v1, no APE
         $lyrics3size = 5100;
         $lyrics3offset = $info['filesize'] - 128 - $lyrics3size;
         $lyrics3version = 1;
     } elseif ($lyrics3end == 'LYRICS200') {
         // Lyrics3v2, ID3v1, no APE
         // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
         $lyrics3size = $lyrics3lsz + 6 + strlen('LYRICS200');
         $lyrics3offset = $info['filesize'] - 128 - $lyrics3size;
         $lyrics3version = 2;
     } elseif (substr(strrev($lyrics3_id3v1), 0, 9) == strrev('LYRICSEND')) {
         // Lyrics3v1, no ID3v1, no APE
         $lyrics3size = 5100;
         $lyrics3offset = $info['filesize'] - $lyrics3size;
         $lyrics3version = 1;
         $lyrics3offset = $info['filesize'] - $lyrics3size;
     } elseif (substr(strrev($lyrics3_id3v1), 0, 9) == strrev('LYRICS200')) {
         // Lyrics3v2, no ID3v1, no APE
         $lyrics3size = strrev(substr(strrev($lyrics3_id3v1), 9, 6)) + 6 + strlen('LYRICS200');
         // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
         $lyrics3offset = $info['filesize'] - $lyrics3size;
         $lyrics3version = 2;
     } else {
         if (isset($info['ape']['tag_offset_start']) && $info['ape']['tag_offset_start'] > 15) {
             $this->fseek($info['ape']['tag_offset_start'] - 15);
             $lyrics3lsz = $this->fread(6);
             $lyrics3end = $this->fread(9);
             if ($lyrics3end == 'LYRICSEND') {
                 // Lyrics3v1, APE, maybe ID3v1
                 $lyrics3size = 5100;
                 $lyrics3offset = $info['ape']['tag_offset_start'] - $lyrics3size;
                 $info['avdataend'] = $lyrics3offset;
                 $lyrics3version = 1;
                 $info['warning'][] = 'APE tag located after Lyrics3, will probably break Lyrics3 compatability';
             } elseif ($lyrics3end == 'LYRICS200') {
                 // Lyrics3v2, APE, maybe ID3v1
                 $lyrics3size = $lyrics3lsz + 6 + strlen('LYRICS200');
                 // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
                 $lyrics3offset = $info['ape']['tag_offset_start'] - $lyrics3size;
                 $lyrics3version = 2;
                 $info['warning'][] = 'APE tag located after Lyrics3, will probably break Lyrics3 compatability';
             }
         }
     }
     if (isset($lyrics3offset)) {
         $info['avdataend'] = $lyrics3offset;
         $this->getLyrics3Data($lyrics3offset, $lyrics3version, $lyrics3size);
         if (!isset($info['ape'])) {
             $GETID3_ERRORARRAY =& $info['warning'];
             getid3_lib::IncludeDependency(GETID3_INCLUDEPATH . 'module.tag.apetag.php', __FILE__, true);
             $getid3_temp = new getID3();
             $getid3_temp->openfile($this->getid3->filename);
             $getid3_apetag = new getid3_apetag($getid3_temp);
             $getid3_apetag->overrideendoffset = $info['lyrics3']['tag_offset_start'];
             $getid3_apetag->Analyze();
             if (!empty($getid3_temp->info['ape'])) {
                 $info['ape'] = $getid3_temp->info['ape'];
             }
             if (!empty($getid3_temp->info['replay_gain'])) {
                 $info['replay_gain'] = $getid3_temp->info['replay_gain'];
             }
             unset($getid3_temp, $getid3_apetag);
         }
     }
     return true;
 }
 protected function ParseAPEtagFlags($raw_flag_int)
 {
     // "Note: APE Tags 1.0 do not use any of the APE Tag flags.
     // All are set to zero on creation and ignored on reading."
     // http://www.uni-jena.de/~pfk/mpp/sv8/apetagflags.html
     $target['header'] = (bool) ($raw_flag_int & 2147483648.0);
     $target['footer'] = (bool) ($raw_flag_int & 0x40000000);
     $target['this_is_header'] = (bool) ($raw_flag_int & 0x20000000);
     $target['item_contents_raw'] = ($raw_flag_int & 0x6) >> 1;
     $target['read_only'] = (bool) ($raw_flag_int & 0x1);
     $target['item_contents'] = getid3_apetag::APEcontentTypeFlagLookup($target['item_contents_raw']);
     return $target;
 }
 public function Analyze()
 {
     $getid3 = $this->getid3;
     fseek($getid3->fp, 0 - 128 - 9 - 6, SEEK_END);
     // end - ID3v1 - LYRICSEND - [Lyrics3size]
     $lyrics3_id3v1 = fread($getid3->fp, 128 + 9 + 6);
     $lyrics3_lsz = substr($lyrics3_id3v1, 0, 6);
     // Lyrics3size
     $lyrics3_end = substr($lyrics3_id3v1, 6, 9);
     // LYRICSEND or LYRICS200
     $id3v1_tag = substr($lyrics3_id3v1, 15, 128);
     // ID3v1
     // Lyrics3v1, ID3v1, no APE
     if ($lyrics3_end == 'LYRICSEND') {
         $lyrics3_size = 5100;
         $lyrics3_offset = filesize($getid3->filename) - 128 - $lyrics3_size;
         $lyrics3_version = 1;
     } elseif ($lyrics3_end == 'LYRICS200') {
         // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
         $lyrics3_size = $lyrics3_lsz + 6 + strlen('LYRICS200');
         $lyrics3_offset = filesize($getid3->filename) - 128 - $lyrics3_size;
         $lyrics3_version = 2;
     } elseif (substr(strrev($lyrics3_id3v1), 0, 9) == 'DNESCIRYL') {
         // strrev('LYRICSEND') = 'DNESCIRYL'
         $lyrics3_size = 5100;
         $lyrics3_offset = filesize($getid3->filename) - $lyrics3_size;
         $lyrics3_version = 1;
         $lyrics3_offset = filesize($getid3->filename) - $lyrics3_size;
     } elseif (substr(strrev($lyrics3_id3v1), 0, 9) == '002SCIRYL') {
         // strrev('LYRICS200') = '002SCIRYL'
         $lyrics3_size = strrev(substr(strrev($lyrics3_id3v1), 9, 6)) + 15;
         // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'  // 15 = 6 + strlen('LYRICS200')
         $lyrics3_offset = filesize($getid3->filename) - $lyrics3_size;
         $lyrics3_version = 2;
     } elseif (isset($getid3->info['ape']['tag_offset_start']) && $getid3->info['ape']['tag_offset_start'] > 15) {
         fseek($getid3->fp, $getid3->info['ape']['tag_offset_start'] - 15, SEEK_SET);
         $lyrics3_lsz = fread($getid3->fp, 6);
         $lyrics3_end = fread($getid3->fp, 9);
         // Lyrics3v1, APE, maybe ID3v1
         if ($lyrics3_end == 'LYRICSEND') {
             $lyrics3_size = 5100;
             $lyrics3_offset = $getid3->info['ape']['tag_offset_start'] - $lyrics3_size;
             $getid3->info['avdataend'] = $lyrics3_offset;
             $lyrics3_version = 1;
             $getid3->warning('APE tag located after Lyrics3, will probably break Lyrics3 compatability');
         } elseif ($lyrics3_end == 'LYRICS200') {
             $lyrics3_size = $lyrics3_lsz + 15;
             // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
             $lyrics3_offset = $getid3->info['ape']['tag_offset_start'] - $lyrics3_size;
             $lyrics3_version = 2;
             $getid3->warning('APE tag located after Lyrics3, will probably break Lyrics3 compatability');
         }
     }
     //// GetLyrics3Data()
     if (isset($lyrics3_offset)) {
         $getid3->info['avdataend'] = $lyrics3_offset;
         if ($lyrics3_size <= 0) {
             return false;
         }
         fseek($getid3->fp, $lyrics3_offset, SEEK_SET);
         $raw_data = fread($getid3->fp, $lyrics3_size);
         if (substr($raw_data, 0, 11) != 'LYRICSBEGIN') {
             if (strpos($raw_data, 'LYRICSBEGIN') !== false) {
                 $getid3->warning('"LYRICSBEGIN" expected at ' . $lyrics3_offset . ' but actually found at ' . ($lyrics3_offset + strpos($raw_data, 'LYRICSBEGIN')) . ' - this is invalid for Lyrics3 v' . $lyrics3_version);
                 $getid3->info['avdataend'] = $lyrics3_offset + strpos($raw_data, 'LYRICSBEGIN');
                 $parsed_lyrics3['tag_offset_start'] = $getid3->info['avdataend'];
                 $raw_data = substr($raw_data, strpos($raw_data, 'LYRICSBEGIN'));
                 $lyrics3_size = strlen($raw_data);
             } else {
                 throw new getid3_exception('"LYRICSBEGIN" expected at ' . $lyrics3_offset . ' but found "' . substr($raw_data, 0, 11) . '" instead.');
             }
         }
         $parsed_lyrics3['raw']['lyrics3version'] = $lyrics3_version;
         $parsed_lyrics3['raw']['lyrics3tagsize'] = $lyrics3_size;
         $parsed_lyrics3['tag_offset_start'] = $lyrics3_offset;
         $parsed_lyrics3['tag_offset_end'] = $lyrics3_offset + $lyrics3_size;
         switch ($lyrics3_version) {
             case 1:
                 if (substr($raw_data, strlen($raw_data) - 9, 9) == 'LYRICSEND') {
                     $parsed_lyrics3['raw']['LYR'] = trim(substr($raw_data, 11, strlen($raw_data) - 11 - 9));
                     getid3_lyrics3::Lyrics3LyricsTimestampParse($parsed_lyrics3);
                 } else {
                     throw new getid3_exception('"LYRICSEND" expected at ' . (ftell($getid3->fp) - 11 + $lyrics3_size - 9) . ' but found "' . substr($raw_data, strlen($raw_data) - 9, 9) . '" instead.');
                 }
                 break;
             case 2:
                 if (substr($raw_data, strlen($raw_data) - 9, 9) == 'LYRICS200') {
                     $parsed_lyrics3['raw']['unparsed'] = substr($raw_data, 11, strlen($raw_data) - 11 - 9 - 6);
                     // LYRICSBEGIN + LYRICS200 + LSZ
                     $raw_data = $parsed_lyrics3['raw']['unparsed'];
                     while (strlen($raw_data) > 0) {
                         $fieldname = substr($raw_data, 0, 3);
                         $fieldsize = (int) substr($raw_data, 3, 5);
                         $parsed_lyrics3['raw'][$fieldname] = substr($raw_data, 8, $fieldsize);
                         $raw_data = substr($raw_data, 3 + 5 + $fieldsize);
                     }
                     if (isset($parsed_lyrics3['raw']['IND'])) {
                         $i = 0;
                         foreach (array('lyrics', 'timestamps', 'inhibitrandom') as $flagname) {
                             if (strlen($parsed_lyrics3['raw']['IND']) > ++$i) {
                                 $parsed_lyrics3['flags'][$flagname] = getid3_lyrics3::IntString2Bool(substr($parsed_lyrics3['raw']['IND'], $i, 1));
                             }
                         }
                     }
                     foreach (array('ETT' => 'title', 'EAR' => 'artist', 'EAL' => 'album', 'INF' => 'comment', 'AUT' => 'author') as $key => $value) {
                         if (isset($parsed_lyrics3['raw'][$key])) {
                             $parsed_lyrics3['comments'][$value][] = trim($parsed_lyrics3['raw'][$key]);
                         }
                     }
                     if (isset($parsed_lyrics3['raw']['IMG'])) {
                         foreach (explode("\r\n", $parsed_lyrics3['raw']['IMG']) as $key => $image_string) {
                             if (strpos($image_string, '||') !== false) {
                                 $imagearray = explode('||', $image_string);
                                 $parsed_lyrics3['images'][$key]['filename'] = @$imagearray[0];
                                 $parsed_lyrics3['images'][$key]['description'] = @$imagearray[1];
                                 $parsed_lyrics3['images'][$key]['timestamp'] = getid3_lyrics3::Lyrics3Timestamp2Seconds(@$imagearray[2]);
                             }
                         }
                     }
                     if (isset($parsed_lyrics3['raw']['LYR'])) {
                         getid3_lyrics3::Lyrics3LyricsTimestampParse($parsed_lyrics3);
                     }
                 } else {
                     throw new getid3_exception('"LYRICS200" expected at ' . (ftell($getid3->fp) - 11 + $lyrics3_size - 9) . ' but found "' . substr($raw_data, strlen($raw_data) - 9, 9) . '" instead.');
                 }
                 break;
             default:
                 throw new getid3_exception('Cannot process Lyrics3 version ' . $lyrics3_version . ' (only v1 and v2)');
         }
         if (isset($getid3->info['id3v1']['tag_offset_start']) && $getid3->info['id3v1']['tag_offset_start'] < $parsed_lyrics3['tag_offset_end']) {
             $getid3->warning('ID3v1 tag information ignored since it appears to be a false synch in Lyrics3 tag data');
             unset($getid3->info['id3v1']);
         }
         $getid3->info['lyrics3'] = $parsed_lyrics3;
         // Check for APE tag after lyrics3
         if (!@$getid3->info['ape'] && $getid3->option_tag_apetag && class_exists('getid3_apetag')) {
             $apetag = new getid3_apetag($getid3);
             $apetag->option_override_end_offset = $getid3->info['lyrics3']['tag_offset_start'];
             $apetag->Analyze();
         }
     }
     return true;
 }
Example #4
0
 public function remove()
 {
     $engine = new getid3();
     $engine->filename = $this->filename;
     $engine->fp = fopen($this->filename, 'rb');
     $engine->include_module('tag.apetag');
     $tag = new getid3_apetag($engine);
     $tag->Analyze();
     if (isset($engine->info['ape']['tag_offset_start']) && isset($engine->info['ape']['tag_offset_end'])) {
         if (!($fp = @fopen($this->filename, 'a+b'))) {
             throw new getid3_exception('Could not open a+b: ' . $this->filename);
         }
         // get data after apetag
         if (filesize($this->filename) > $engine->info['ape']['tag_offset_end']) {
             fseek($fp, $engine->info['ape']['tag_offset_end'], SEEK_SET);
             $data_after_ape = fread($fp, filesize($this->filename) - $engine->info['ape']['tag_offset_end']);
         }
         // truncate file before start of apetag
         ftruncate($fp, $engine->info['ape']['tag_offset_start']);
         // rewrite data after apetag
         if (isset($data_after_ape)) {
             fseek($fp, $engine->info['ape']['tag_offset_start'], SEEK_SET);
             fwrite($fp, $data_after_ape, strlen($data_after_ape));
         }
         fclose($fp);
         clearstatcache();
     }
     // success when removing non-existant tag
     return true;
 }