MP3-Info
view release on metacpan or search on metacpan
# JRF: I believe this should probably only be applied to the text frames
# and not every single frame.
if ($UNICODE) {
if ($encoding eq "\001" || $encoding eq "\002") { # UTF-16, UTF-16BE
# text fields can be null-separated lists;
# UTF-16 therefore needs special care
#
# foobar2000 encodes tags in UTF-16LE
# (which is apparently illegal)
# Encode dies on a bad BOM, so it is
# probably wise to wrap it in an eval
# anyway
$data = eval { Encode::decode('utf16', $data) } || Encode::decode('utf16le', $data);
} elsif ($encoding eq "\003") { # UTF-8
# make sure string is UTF8, and set flag appropriately
$data = Encode::decode('utf8', $data);
} elsif ($encoding eq "\000") {
# Best try
$data = Encode::decode('iso-8859-1', $data);
}
}
}
}
} else {
# If the string starts with an
# UTF-16 little endian BOM, use a hack to
# convert to ASCII per best-effort
my $pat;
if ($data =~ s/^\xFF\xFE//) {
# strip additional BOMs as seen in COM(M?) and TXX(X?)
$data = join ("",map { ( /^(..)$/ && ! /(\xFF\xFE)/ )? $_: "" } (split /(..)/, $data));
$pat = 'v';
} elsif ($data =~ s/^\xFE\xFF//) {
# strip additional BOMs as seen in COM(M?) and TXX(X?)
$data = join ("",map { ( /^(..)$/ && ! /(\xFF\xFE)/ )? $_: "" } (split /(..)/, $data));
$pat = 'n';
}
if ($pat) {
# strip additional 0s
$data = join ("",map { ( /^(..)$/ && ! /(\x00\x00)/ )? $_: "" } (split /(..)/, $data));
$data = pack 'C*', map {
(chr =~ /[[:ascii:]]/ && chr =~ /[[:print:]]/)
? $_
$info->{$hash->{$id}} = [ $info->{$hash->{$id}}, $data ];
}
} else {
# User defined frame
if ($id eq 'TXXX') {
my ($key, $val) = split(/\0/, $data);
# Some programs - such as FB2K leave a UTF-16 BOM on the value
if ($encoding eq "\001" || $encoding eq "\002") {
$val =~ s/^\x{feff}//;
}
$info->{uc($key)} = $val;
} elsif ($id eq 'PRIV') {
my ($key, $val) = split(/\0/, $data);
( run in 0.860 second using v1.01-cache-2.11-cpan-e9daa2b36ef )