summaryrefslogtreecommitdiff
path: root/lib/Image/ExifTool/ID3.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Image/ExifTool/ID3.pm')
-rw-r--r--lib/Image/ExifTool/ID3.pm77
1 files changed, 70 insertions, 7 deletions
diff --git a/lib/Image/ExifTool/ID3.pm b/lib/Image/ExifTool/ID3.pm
index 82efe710..b7697803 100644
--- a/lib/Image/ExifTool/ID3.pm
+++ b/lib/Image/ExifTool/ID3.pm
@@ -18,12 +18,13 @@ use strict;
use vars qw($VERSION);
use Image::ExifTool qw(:DataAccess :Utils);
-$VERSION = '1.58';
+$VERSION = '1.59';
sub ProcessID3v2($$$);
sub ProcessPrivate($$$);
sub ProcessSynText($$$);
sub ProcessID3Dir($$$);
+sub ProcessGEOB($$$);
sub ConvertID3v1Text($$);
sub ConvertTimeStamp($);
@@ -419,7 +420,7 @@ my %genre = (
# Tags for ID2v2.2
%Image::ExifTool::ID3::v2_2 = (
- PROCESS_PROC => \&Image::ExifTool::ID3::ProcessID3v2,
+ PROCESS_PROC => \&ProcessID3v2,
GROUPS => { 1 => 'ID3v2_2', 2 => 'Audio' },
NOTES => q{
ExifTool extracts mainly text-based tags from ID3v2 information. The tags
@@ -511,6 +512,9 @@ my %genre = (
TSC => 'ComposerSortOrder',
ITU => { Name => 'iTunesU', Description => 'iTunes U', Binary => 1, Unknown => 1 },
PCS => { Name => 'Podcast', Binary => 1, Unknown => 1 },
+ GP1 => 'Grouping', #github142 (NC)
+ MVN => 'MovementName', #github142 (NC)
+ MVI => 'MovementNumber', #github142 (NC)
);
# tags common to ID3v2.3 and ID3v2.4
@@ -534,7 +538,10 @@ my %id3v2_common = (
# COMR => 'Commercial',
# ENCR => 'EncryptionMethod',
# ETCO => 'EventTimingCodes',
- # GEOB => 'GeneralEncapsulatedObject',
+ GEOB => {
+ Name => 'GeneralEncapsulatedObject',
+ SubDirectory => { TagTable => 'Image::ExifTool::ID3::GEOB' },
+ },
# GRID => 'GroupIdentification',
# LINK => 'LinkedInformation',
MCDI => { Name => 'MusicCDIdentifier', Binary => 1 },
@@ -640,9 +647,25 @@ my %id3v2_common = (
MVIN => 'MovementNumber', # (NC)
);
+%Image::ExifTool::ID3::GEOB = (
+ GROUPS => { 1 => 'ID3v2_3', 2 => 'Other' },
+ PROCESS_PROC => \&ProcessGEOB,
+ 'application/x-c2pa-manifest-store' => {
+ Name => 'JUMBF',
+ SubDirectory => {
+ TagTable => 'Image::ExifTool::Jpeg2000::Main',
+ ByteOrder => 'BigEndian',
+ },
+ },
+ 'GEOB-Mime' => { },
+ 'GEOB-File' => { },
+ 'GEOB-Desc' => { },
+ 'GEOB-Data' => { },
+);
+
# Tags for ID3v2.3 (http://www.id3.org/id3v2.3.0)
%Image::ExifTool::ID3::v2_3 = (
- PROCESS_PROC => \&Image::ExifTool::ID3::ProcessID3v2,
+ PROCESS_PROC => \&ProcessID3v2,
GROUPS => { 1 => 'ID3v2_3', 2 => 'Audio' },
NOTES => q{
ID3 version 2.3 tags. Includes some non-standard tags written by other
@@ -662,7 +685,7 @@ my %id3v2_common = (
# Tags for ID3v2.4 (http://www.id3.org/id3v2.4.0-frames)
%Image::ExifTool::ID3::v2_4 = (
- PROCESS_PROC => \&Image::ExifTool::ID3::ProcessID3v2,
+ PROCESS_PROC => \&ProcessID3v2,
GROUPS => { 1 => 'ID3v2_4', 2 => 'Audio' },
NOTES => q{
ID3 version 2.4 tags. Includes some non-standard tags written by other
@@ -1101,7 +1124,11 @@ sub ProcessID3v2($$$)
my $oldLen = $len;
$len = UnSyncSafe($len);
if (not defined $len or $offset + $len + 10 > $size) {
- $et->Warn('Invalid ID3 frame size');
+ if ($offset + $len == $size) {
+ $et->Warn('Missing ID3 terminating frame', 1);
+ } else {
+ $et->Warn('Invalid ID3 frame size');
+ }
last;
}
# check next ID to see if it makes sense
@@ -1218,7 +1245,7 @@ sub ProcessID3v2($$$)
my @vals = DecodeString($et, $val);
foreach (0..1) { $vals[$_] = '' unless defined $vals[$_]; }
($val = "($vals[0]) $vals[1]") =~ s/^\(\) //;
- } elsif ($id =~ /^T/ or $id =~ /^(IPL|IPLS)$/) {
+ } elsif ($id =~ /^T/ or $id =~ /^(IPL|IPLS|GP1|MVI|MVN)$/) {
$val = DecodeString($et, $val);
} elsif ($id =~ /^(WXX|WXXX)$/) {
# one encoded string and one Latin string separated by a null
@@ -1583,6 +1610,42 @@ sub ProcessID3Dir($$$)
}
#------------------------------------------------------------------------------
+# Process ID3 General Encapsulated Object
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessGEOB($$$)
+{
+ my ($et, $dirInfo, $tagTablePtr) = @_;
+ $et->VerboseDir('GEOB', undef, length ${$$dirInfo{DataPt}});
+ my $dataPt = $$dirInfo{DataPt};
+ my $len = length $$dataPt;
+ $len >= 4 or $et->Warn("Short GEOB frame"), return 0;
+ my ($hdr, $attr);
+ my $enc = unpack('C', $$dataPt);
+ if ($enc == 1 or $enc == 2) {
+ $hdr = ".(.*?)\0((?:..)*?)\0\0((?:..)*?)\0\0";
+ } else {
+ $hdr = ".(.*?)\0(.*?)\0(.*?)\0";
+ }
+ # remove header (encoding, mime, filename, description)
+ $$dataPt =~ s/^$hdr//s or $et->Warn("Invalid GEOB frame"), return 0;
+ my ($mime, $file, $desc) = ($1, DecodeString($et, $2, $enc), DecodeString($et, $3, $enc));
+ $et->HandleTag($tagTablePtr, 'GEOB-Mime', $mime) if length $mime;
+ $et->HandleTag($tagTablePtr, 'GEOB-File', $file) if length $file;
+ $et->HandleTag($tagTablePtr, 'GEOB-Desc', $desc) if length $desc;
+ if ($$tagTablePtr{$mime}) {
+ $et->HandleTag($tagTablePtr, $mime, undef,
+ DataPt => $dataPt,
+ Start => 0,
+ Size => length($$dataPt),
+ );
+ } else {
+ $et->HandleTag($tagTablePtr, 'GEOB-Data', $dataPt);
+ }
+ return 1;
+}
+
+#------------------------------------------------------------------------------
# Extract ID3 information from an MP3 audio file
# Inputs: 0) ExifTool object reference, 1) dirInfo reference
# Returns: 1 on success, 0 if this wasn't a valid MP3 file