343 $this->warning('error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))). [Note: this particular error has been known to happen with tags edited by iTunes (versions "X v2.0.3", "v3.0.1", "v7.0.0.70" are known-guilty, probably others too)]. Translated frame name from "'.str_replace("\x00", ' ', $frame_name).'" to "'.$iTunesBrokenFrameNameFixed.'" for parsing.'); |
343 $this->warning('error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))). [Note: this particular error has been known to happen with tags edited by iTunes (versions "X v2.0.3", "v3.0.1", "v7.0.0.70" are known-guilty, probably others too)]. Translated frame name from "'.str_replace("\x00", ' ', $frame_name).'" to "'.$iTunesBrokenFrameNameFixed.'" for parsing.'); |
344 $frame_name = $iTunesBrokenFrameNameFixed; |
344 $frame_name = $iTunesBrokenFrameNameFixed; |
345 } |
345 } |
346 if (($frame_size <= strlen($framedata)) && ($this->IsValidID3v2FrameName($frame_name, $id3v2_majorversion))) { |
346 if (($frame_size <= strlen($framedata)) && ($this->IsValidID3v2FrameName($frame_name, $id3v2_majorversion))) { |
347 |
347 |
348 unset($parsedFrame); |
348 $parsedFrame = array(); |
349 $parsedFrame['frame_name'] = $frame_name; |
349 $parsedFrame['frame_name'] = $frame_name; |
350 $parsedFrame['frame_flags_raw'] = $frame_flags; |
350 $parsedFrame['frame_flags_raw'] = $frame_flags; |
351 $parsedFrame['data'] = substr($framedata, 0, $frame_size); |
351 $parsedFrame['data'] = substr($framedata, 0, $frame_size); |
352 $parsedFrame['datalength'] = getid3_lib::CastAsInt($frame_size); |
352 $parsedFrame['datalength'] = getid3_lib::CastAsInt($frame_size); |
353 $parsedFrame['dataoffset'] = $framedataoffset; |
353 $parsedFrame['dataoffset'] = $framedataoffset; |
976 } |
976 } |
977 unset($parsedFrame['data']); |
977 unset($parsedFrame['data']); |
978 |
978 |
979 |
979 |
980 } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'USLT')) || // 4.8 USLT Unsynchronised lyric/text transcription |
980 } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'USLT')) || // 4.8 USLT Unsynchronised lyric/text transcription |
981 (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'ULT'))) { // 4.9 ULT Unsynchronised lyric/text transcription |
981 (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'ULT'))) { // 4.9 ULT Unsynchronised lyric/text transcription |
982 // There may be more than one 'Unsynchronised lyrics/text transcription' frame |
982 // There may be more than one 'Unsynchronised lyrics/text transcription' frame |
983 // in each tag, but only one with the same language and content descriptor. |
983 // in each tag, but only one with the same language and content descriptor. |
984 // <Header for 'Unsynchronised lyrics/text transcription', ID: 'USLT'> |
984 // <Header for 'Unsynchronised lyrics/text transcription', ID: 'USLT'> |
985 // Text encoding $xx |
985 // Text encoding $xx |
986 // Language $xx xx xx |
986 // Language $xx xx xx |
992 $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding); |
992 $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding); |
993 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { |
993 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { |
994 $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'); |
994 $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'); |
995 $frame_textencoding_terminator = "\x00"; |
995 $frame_textencoding_terminator = "\x00"; |
996 } |
996 } |
997 $frame_language = substr($parsedFrame['data'], $frame_offset, 3); |
997 if (strlen($parsedFrame['data']) >= (4 + strlen($frame_textencoding_terminator))) { // shouldn't be an issue but badly-written files have been spotted in the wild with not only no contents but also missing the required language field, see https://github.com/JamesHeinrich/getID3/issues/315 |
998 $frame_offset += 3; |
998 $frame_language = substr($parsedFrame['data'], $frame_offset, 3); |
999 $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset); |
999 $frame_offset += 3; |
1000 if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) { |
1000 $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset); |
1001 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 |
1001 if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) { |
1002 } |
1002 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 |
1003 $parsedFrame['description'] = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); |
1003 } |
1004 $parsedFrame['description'] = $this->MakeUTF16emptyStringEmpty($parsedFrame['description']); |
1004 $parsedFrame['description'] = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); |
1005 $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator)); |
1005 $parsedFrame['description'] = $this->MakeUTF16emptyStringEmpty($parsedFrame['description']); |
1006 $parsedFrame['data'] = $this->RemoveStringTerminator($parsedFrame['data'], $frame_textencoding_terminator); |
1006 $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator)); |
1007 |
1007 $parsedFrame['data'] = $this->RemoveStringTerminator($parsedFrame['data'], $frame_textencoding_terminator); |
1008 $parsedFrame['encodingid'] = $frame_textencoding; |
1008 |
1009 $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); |
1009 $parsedFrame['encodingid'] = $frame_textencoding; |
1010 |
1010 $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); |
1011 $parsedFrame['language'] = $frame_language; |
1011 |
1012 $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false); |
1012 $parsedFrame['language'] = $frame_language; |
1013 if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { |
1013 $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false); |
1014 $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']); |
1014 if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { |
|
1015 $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']); |
|
1016 } |
|
1017 } else { |
|
1018 $this->warning('Invalid data in frame "'.$parsedFrame['frame_name'].'" at offset '.$parsedFrame['dataoffset']); |
1015 } |
1019 } |
1016 unset($parsedFrame['data']); |
1020 unset($parsedFrame['data']); |
1017 |
1021 |
1018 |
1022 |
1019 } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'SYLT')) || // 4.9 SYLT Synchronised lyric/text |
1023 } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'SYLT')) || // 4.9 SYLT Synchronised lyric/text |
1368 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { |
1372 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { |
1369 $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'); |
1373 $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'); |
1370 $frame_textencoding_terminator = "\x00"; |
1374 $frame_textencoding_terminator = "\x00"; |
1371 } |
1375 } |
1372 |
1376 |
|
1377 $frame_imagetype = null; |
|
1378 $frame_mimetype = null; |
1373 if ($id3v2_majorversion == 2 && strlen($parsedFrame['data']) > $frame_offset) { |
1379 if ($id3v2_majorversion == 2 && strlen($parsedFrame['data']) > $frame_offset) { |
1374 $frame_imagetype = substr($parsedFrame['data'], $frame_offset, 3); |
1380 $frame_imagetype = substr($parsedFrame['data'], $frame_offset, 3); |
1375 if (strtolower($frame_imagetype) == 'ima') { |
1381 if (strtolower($frame_imagetype) == 'ima') { |
1376 // complete hack for mp3Rage (www.chaoticsoftware.com) that puts ID3v2.3-formatted |
1382 // complete hack for mp3Rage (www.chaoticsoftware.com) that puts ID3v2.3-formatted |
1377 // MIME type instead of 3-char ID3v2.2-format image type (thanks xbhoffØpacbell*net) |
1383 // MIME type instead of 3-char ID3v2.2-format image type (thanks xbhoffØpacbell*net) |
1954 // d - replay gain adjustment |
1960 // d - replay gain adjustment |
1955 |
1961 |
1956 $frame_offset = 0; |
1962 $frame_offset = 0; |
1957 $parsedFrame['peakamplitude'] = getid3_lib::BigEndian2Float(substr($parsedFrame['data'], $frame_offset, 4)); |
1963 $parsedFrame['peakamplitude'] = getid3_lib::BigEndian2Float(substr($parsedFrame['data'], $frame_offset, 4)); |
1958 $frame_offset += 4; |
1964 $frame_offset += 4; |
1959 $rg_track_adjustment = getid3_lib::Dec2Bin(substr($parsedFrame['data'], $frame_offset, 2)); |
1965 foreach (array('track','album') as $rgad_entry_type) { |
1960 $frame_offset += 2; |
1966 $rg_adjustment_word = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2)); |
1961 $rg_album_adjustment = getid3_lib::Dec2Bin(substr($parsedFrame['data'], $frame_offset, 2)); |
1967 $frame_offset += 2; |
1962 $frame_offset += 2; |
1968 $parsedFrame['raw'][$rgad_entry_type]['name'] = ($rg_adjustment_word & 0xE000) >> 13; |
1963 $parsedFrame['raw']['track']['name'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 0, 3)); |
1969 $parsedFrame['raw'][$rgad_entry_type]['originator'] = ($rg_adjustment_word & 0x1C00) >> 10; |
1964 $parsedFrame['raw']['track']['originator'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 3, 3)); |
1970 $parsedFrame['raw'][$rgad_entry_type]['signbit'] = ($rg_adjustment_word & 0x0200) >> 9; |
1965 $parsedFrame['raw']['track']['signbit'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 6, 1)); |
1971 $parsedFrame['raw'][$rgad_entry_type]['adjustment'] = ($rg_adjustment_word & 0x0100); |
1966 $parsedFrame['raw']['track']['adjustment'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 7, 9)); |
1972 } |
1967 $parsedFrame['raw']['album']['name'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 0, 3)); |
|
1968 $parsedFrame['raw']['album']['originator'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 3, 3)); |
|
1969 $parsedFrame['raw']['album']['signbit'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 6, 1)); |
|
1970 $parsedFrame['raw']['album']['adjustment'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 7, 9)); |
|
1971 $parsedFrame['track']['name'] = getid3_lib::RGADnameLookup($parsedFrame['raw']['track']['name']); |
1973 $parsedFrame['track']['name'] = getid3_lib::RGADnameLookup($parsedFrame['raw']['track']['name']); |
1972 $parsedFrame['track']['originator'] = getid3_lib::RGADoriginatorLookup($parsedFrame['raw']['track']['originator']); |
1974 $parsedFrame['track']['originator'] = getid3_lib::RGADoriginatorLookup($parsedFrame['raw']['track']['originator']); |
1973 $parsedFrame['track']['adjustment'] = getid3_lib::RGADadjustmentLookup($parsedFrame['raw']['track']['adjustment'], $parsedFrame['raw']['track']['signbit']); |
1975 $parsedFrame['track']['adjustment'] = getid3_lib::RGADadjustmentLookup($parsedFrame['raw']['track']['adjustment'], $parsedFrame['raw']['track']['signbit']); |
1974 $parsedFrame['album']['name'] = getid3_lib::RGADnameLookup($parsedFrame['raw']['album']['name']); |
1976 $parsedFrame['album']['name'] = getid3_lib::RGADnameLookup($parsedFrame['raw']['album']['name']); |
1975 $parsedFrame['album']['originator'] = getid3_lib::RGADoriginatorLookup($parsedFrame['raw']['album']['originator']); |
1977 $parsedFrame['album']['originator'] = getid3_lib::RGADoriginatorLookup($parsedFrame['raw']['album']['originator']); |