exiftool_vendored 12.18.0 → 12.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/Changes +236 -4
- data/bin/MANIFEST +23 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +45 -43
- data/bin/arg_files/xmp2exif.args +2 -1
- data/bin/config_files/acdsee.config +193 -6
- data/bin/config_files/convert_regions.config +25 -14
- data/bin/config_files/cuepointlist.config +70 -0
- data/bin/config_files/example.config +2 -9
- data/bin/exiftool +152 -97
- data/bin/fmt_files/gpx.fmt +2 -2
- data/bin/fmt_files/gpx_wpt.fmt +2 -2
- data/bin/fmt_files/kml.fmt +1 -1
- data/bin/fmt_files/kml_track.fmt +1 -1
- data/bin/lib/Image/ExifTool/Apple.pm +3 -2
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +31 -13
- data/bin/lib/Image/ExifTool/CBOR.pm +331 -0
- data/bin/lib/Image/ExifTool/Canon.pm +44 -19
- data/bin/lib/Image/ExifTool/DJI.pm +6 -6
- data/bin/lib/Image/ExifTool/DPX.pm +13 -2
- data/bin/lib/Image/ExifTool/DjVu.pm +6 -5
- data/bin/lib/Image/ExifTool/Exif.pm +124 -13
- data/bin/lib/Image/ExifTool/FITS.pm +13 -2
- data/bin/lib/Image/ExifTool/FlashPix.pm +35 -10
- data/bin/lib/Image/ExifTool/FujiFilm.pm +19 -8
- data/bin/lib/Image/ExifTool/GPS.pm +22 -11
- data/bin/lib/Image/ExifTool/Geotag.pm +13 -2
- data/bin/lib/Image/ExifTool/GoPro.pm +16 -1
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +2 -2
- data/bin/lib/Image/ExifTool/ID3.pm +15 -3
- data/bin/lib/Image/ExifTool/JPEG.pm +74 -4
- data/bin/lib/Image/ExifTool/JSON.pm +30 -5
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +395 -16
- data/bin/lib/Image/ExifTool/LIF.pm +153 -0
- data/bin/lib/Image/ExifTool/Lang/nl.pm +60 -59
- data/bin/lib/Image/ExifTool/M2TS.pm +137 -5
- data/bin/lib/Image/ExifTool/MIE.pm +4 -3
- data/bin/lib/Image/ExifTool/MRC.pm +341 -0
- data/bin/lib/Image/ExifTool/MWG.pm +3 -3
- data/bin/lib/Image/ExifTool/MXF.pm +1 -1
- data/bin/lib/Image/ExifTool/MacOS.pm +3 -3
- data/bin/lib/Image/ExifTool/Microsoft.pm +298 -82
- data/bin/lib/Image/ExifTool/Nikon.pm +18 -5
- data/bin/lib/Image/ExifTool/NikonSettings.pm +19 -2
- data/bin/lib/Image/ExifTool/Olympus.pm +10 -3
- data/bin/lib/Image/ExifTool/Other.pm +93 -0
- data/bin/lib/Image/ExifTool/PDF.pm +9 -12
- data/bin/lib/Image/ExifTool/PNG.pm +8 -7
- data/bin/lib/Image/ExifTool/Panasonic.pm +28 -3
- data/bin/lib/Image/ExifTool/Pentax.pm +28 -5
- data/bin/lib/Image/ExifTool/PhaseOne.pm +4 -3
- data/bin/lib/Image/ExifTool/Photoshop.pm +6 -0
- data/bin/lib/Image/ExifTool/QuickTime.pm +234 -75
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +283 -141
- data/bin/lib/Image/ExifTool/README +5 -2
- data/bin/lib/Image/ExifTool/RIFF.pm +89 -12
- data/bin/lib/Image/ExifTool/Samsung.pm +48 -10
- data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -0
- data/bin/lib/Image/ExifTool/Sony.pm +230 -69
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +1 -0
- data/bin/lib/Image/ExifTool/TagLookup.pm +4145 -4029
- data/bin/lib/Image/ExifTool/TagNames.pod +671 -287
- data/bin/lib/Image/ExifTool/Torrent.pm +18 -11
- data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePDF.pl +1 -0
- data/bin/lib/Image/ExifTool/WritePNG.pl +2 -0
- data/bin/lib/Image/ExifTool/WritePostScript.pl +1 -0
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +55 -21
- data/bin/lib/Image/ExifTool/WriteXMP.pl +7 -3
- data/bin/lib/Image/ExifTool/Writer.pl +47 -10
- data/bin/lib/Image/ExifTool/XMP.pm +45 -15
- data/bin/lib/Image/ExifTool/XMP2.pl +3 -1
- data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
- data/bin/lib/Image/ExifTool/ZISRAW.pm +121 -2
- data/bin/lib/Image/ExifTool.pm +233 -81
- data/bin/lib/Image/ExifTool.pod +114 -93
- data/bin/perl-Image-ExifTool.spec +43 -42
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +28 -13
|
@@ -47,7 +47,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
47
47
|
use Image::ExifTool::Exif;
|
|
48
48
|
use Image::ExifTool::GPS;
|
|
49
49
|
|
|
50
|
-
$VERSION = '2.
|
|
50
|
+
$VERSION = '2.70';
|
|
51
51
|
|
|
52
52
|
sub ProcessMOV($$;$);
|
|
53
53
|
sub ProcessKeys($$$);
|
|
@@ -65,6 +65,7 @@ sub Process_gsen($$$);
|
|
|
65
65
|
sub ProcessRIFFTrailer($$$);
|
|
66
66
|
sub ProcessTTAD($$$);
|
|
67
67
|
sub ProcessNMEA($$$);
|
|
68
|
+
sub ProcessGPSLog($$$);
|
|
68
69
|
sub SaveMetaKeys($$$);
|
|
69
70
|
# ++^^^^^^^^^^^^++
|
|
70
71
|
sub ParseItemLocation($$);
|
|
@@ -160,8 +161,15 @@ my %ftypLookup = (
|
|
|
160
161
|
'F4P ' => 'Protected Video for Adobe Flash Player 9+ (.F4P)', # video/mp4
|
|
161
162
|
'F4V ' => 'Video for Adobe Flash Player 9+ (.F4V)', # video/mp4
|
|
162
163
|
'isc2' => 'ISMACryp 2.0 Encrypted File', # ?/enc-isoff-generic
|
|
163
|
-
'iso2' => 'MP4 Base Media v2 [ISO 14496-12:2005]', # video/mp4
|
|
164
|
-
'
|
|
164
|
+
'iso2' => 'MP4 Base Media v2 [ISO 14496-12:2005]', # video/mp4 (or audio)
|
|
165
|
+
'iso3' => 'MP4 Base Media v3', # video/mp4 (or audio)
|
|
166
|
+
'iso4' => 'MP4 Base Media v4', # video/mp4 (or audio)
|
|
167
|
+
'iso5' => 'MP4 Base Media v5', # video/mp4 (or audio)
|
|
168
|
+
'iso6' => 'MP4 Base Media v6', # video/mp4 (or audio)
|
|
169
|
+
'iso7' => 'MP4 Base Media v7', # video/mp4 (or audio)
|
|
170
|
+
'iso8' => 'MP4 Base Media v8', # video/mp4 (or audio)
|
|
171
|
+
'iso9' => 'MP4 Base Media v9', # video/mp4 (or audio)
|
|
172
|
+
'isom' => 'MP4 Base Media v1 [IS0 14496-12:2003]', # video/mp4 (or audio)
|
|
165
173
|
'JP2 ' => 'JPEG 2000 Image (.JP2) [ISO 15444-1 ?]', # image/jp2
|
|
166
174
|
'JP20' => 'Unknown, from GPAC samples (prob non-existent)',
|
|
167
175
|
'jpm ' => 'JPEG 2000 Compound Image (.JPM) [ISO 15444-6]', # image/jpm
|
|
@@ -221,9 +229,10 @@ my %timeInfo = (
|
|
|
221
229
|
Writable => 1,
|
|
222
230
|
Permanent => 1,
|
|
223
231
|
DelValue => 0,
|
|
224
|
-
# It is not uncommon for brain-dead software to use the wrong time zero,
|
|
225
|
-
# so assume a time zero of Jan 1, 1970 if the date is before this
|
|
232
|
+
# It is not uncommon for brain-dead software to use the wrong time zero, it should be
|
|
233
|
+
# Jan 1, 1904, so assume a time zero of Jan 1, 1970 if the date is before this
|
|
226
234
|
# Note: This value will be in UTC if generated by a system that is aware of the time zone
|
|
235
|
+
# (also note: this code is duplicated for the CreateDate tag)
|
|
227
236
|
RawConv => q{
|
|
228
237
|
my $offset = (66 * 365 + 17) * 24 * 3600;
|
|
229
238
|
return $val - $offset if $val >= $offset or $$self{OPTIONS}{QuickTimeUTC};
|
|
@@ -243,7 +252,11 @@ my %timeInfo = (
|
|
|
243
252
|
},
|
|
244
253
|
# (all CR3 files store UTC times - PH)
|
|
245
254
|
ValueConv => 'ConvertUnixTime($val, $self->Options("QuickTimeUTC") || $$self{FileType} eq "CR3")',
|
|
246
|
-
ValueConvInv =>
|
|
255
|
+
ValueConvInv => q{
|
|
256
|
+
$val = GetUnixTime($val, $self->Options("QuickTimeUTC"));
|
|
257
|
+
return undef unless defined $val;
|
|
258
|
+
return $val + (66 * 365 + 17) * 24 * 3600;
|
|
259
|
+
},
|
|
247
260
|
PrintConv => '$self->ConvertDateTime($val)',
|
|
248
261
|
PrintConvInv => '$self->InverseDateTime($val)',
|
|
249
262
|
# (can't put Groups here because they aren't constant!)
|
|
@@ -674,6 +687,15 @@ my %eeBox2 = (
|
|
|
674
687
|
udat => { #PH (GPS NMEA-format log written by Datakam Player software)
|
|
675
688
|
Name => 'GPSLog',
|
|
676
689
|
Binary => 1, # (actually ASCII, but very lengthy)
|
|
690
|
+
Notes => 'parsed to extract GPS separately when ExtractEmbedded is used',
|
|
691
|
+
RawConv => q{
|
|
692
|
+
$val =~ s/\0+$//; # remove trailing nulls
|
|
693
|
+
if (length $val and $$self{OPTIONS}{ExtractEmbedded}) {
|
|
694
|
+
my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
|
695
|
+
Image::ExifTool::QuickTime::ProcessGPSLog($self, { DataPt => \$val }, $tagTbl);
|
|
696
|
+
}
|
|
697
|
+
return $val;
|
|
698
|
+
},
|
|
677
699
|
},
|
|
678
700
|
# meta - proprietary XML information written by some Flip cameras - PH
|
|
679
701
|
# beam - 16 bytes found in an iPhone video
|
|
@@ -712,6 +734,11 @@ my %eeBox2 = (
|
|
|
712
734
|
Unknown => 1,
|
|
713
735
|
Binary => 1,
|
|
714
736
|
},
|
|
737
|
+
sefd => {
|
|
738
|
+
Name => 'SamsungTrailer',
|
|
739
|
+
SubDirectory => { TagTable => 'Image::ExifTool::Samsung::Trailer' },
|
|
740
|
+
},
|
|
741
|
+
# 'samn'? - seen in Vantrue N2S sample video
|
|
715
742
|
);
|
|
716
743
|
|
|
717
744
|
# MPEG-4 'ftyp' atom
|
|
@@ -1173,6 +1200,15 @@ my %eeBox2 = (
|
|
|
1173
1200
|
Name => 'CreateDate',
|
|
1174
1201
|
Groups => { 2 => 'Time' },
|
|
1175
1202
|
%timeInfo,
|
|
1203
|
+
RawConv => q{
|
|
1204
|
+
my $offset = (66 * 365 + 17) * 24 * 3600;
|
|
1205
|
+
if ($val >= $offset or $$self{OPTIONS}{QuickTimeUTC}) {
|
|
1206
|
+
$val -= $offset;
|
|
1207
|
+
} elsif ($val and not $$self{IsWriting}) {
|
|
1208
|
+
$self->WarnOnce('Patched incorrect time zero for QuickTime date/time tag',1);
|
|
1209
|
+
}
|
|
1210
|
+
return $$self{CreateDate} = $val;
|
|
1211
|
+
},
|
|
1176
1212
|
# this is int64u if MovieHeaderVersion == 1 (ref 13)
|
|
1177
1213
|
Hook => '$$self{MovieHeaderVersion} and $format = "int64u", $varSize += 4',
|
|
1178
1214
|
},
|
|
@@ -1560,36 +1596,29 @@ my %eeBox2 = (
|
|
|
1560
1596
|
coll => { Name => 'CollectionName', %langText3gp }, #17
|
|
1561
1597
|
rtng => {
|
|
1562
1598
|
Name => 'Rating',
|
|
1599
|
+
Writable => 'undef',
|
|
1600
|
+
Avoid => 1,
|
|
1563
1601
|
# (4-byte flags, 4-char entity, 4-char criteria, 2-byte lang, string)
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 12));
|
|
1569
|
-
$lang = $lang ? "($lang) " : '';
|
|
1570
|
-
$val = substr($val, 14);
|
|
1571
|
-
$val = $self->Decode($val, 'UCS2') if $val =~ /^\xfe\xff/;
|
|
1572
|
-
return $lang . $str . ' ' . $val;
|
|
1573
|
-
},
|
|
1602
|
+
IText => 14, # (14 bytes before string)
|
|
1603
|
+
Notes => 'string in the form "Entity=XXXX Criteria=XXXX XXXXX", used in 3gp videos',
|
|
1604
|
+
ValueConv => '$val=~s/^(.{4})(.{4})/Entity=$1 Criteria=$2 /i; $val',
|
|
1605
|
+
ValueConvInv => '$val=~s/Entity=(.{4}) Criteria=(.{4}) ?/$1$2/i; $val',
|
|
1574
1606
|
},
|
|
1575
1607
|
clsf => {
|
|
1576
1608
|
Name => 'Classification',
|
|
1609
|
+
Writable => 'undef',
|
|
1610
|
+
Avoid => 1,
|
|
1577
1611
|
# (4-byte flags, 4-char entity, 2-byte index, 2-byte lang, string)
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 10));
|
|
1583
|
-
$lang = $lang ? "($lang) " : '';
|
|
1584
|
-
$val = substr($val, 12);
|
|
1585
|
-
$val = $self->Decode($val, 'UCS2') if $val =~ /^\xfe\xff/;
|
|
1586
|
-
return $lang . $str . ' ' . $val;
|
|
1587
|
-
},
|
|
1612
|
+
IText => 12,
|
|
1613
|
+
Notes => 'string in the form "Entity=XXXX Index=### XXXXX", used in 3gp videos',
|
|
1614
|
+
ValueConv => '$val=~s/^(.{4})(.{2})/"Entity=$1 Index=".unpack("n",$2)." "/ie; $val',
|
|
1615
|
+
ValueConvInv => '$val=~s/Entity=(.{4}) Index=(\d+) ?/$1.pack("n",$2)/ie; $val',
|
|
1588
1616
|
},
|
|
1589
1617
|
kywd => {
|
|
1590
1618
|
Name => 'Keywords',
|
|
1591
1619
|
# (4 byte flags, 2-byte lang, 1-byte count, count x pascal strings, ref 17)
|
|
1592
|
-
# (but I have also seen a simple string written by iPhone)
|
|
1620
|
+
# (but I have also seen a simple string written by iPhone, so don't make writable yet)
|
|
1621
|
+
Notes => "not writable because Apple doesn't follow the 3gp specification",
|
|
1593
1622
|
RawConv => q{
|
|
1594
1623
|
my $sep = $self->Options('ListSep');
|
|
1595
1624
|
return join($sep, split /\0+/, $val) unless $val =~ /^\0/; # (iPhone)
|
|
@@ -1614,20 +1643,24 @@ my %eeBox2 = (
|
|
|
1614
1643
|
loci => {
|
|
1615
1644
|
Name => 'LocationInformation',
|
|
1616
1645
|
Groups => { 2 => 'Location' },
|
|
1646
|
+
Writable => 'undef',
|
|
1647
|
+
IText => 6,
|
|
1648
|
+
Avoid => 1,
|
|
1649
|
+
NoDecode => 1, # (we'll decode the data ourself)
|
|
1650
|
+
Notes => q{
|
|
1651
|
+
string in the form "XXXXX Role=XXX Lat=XXX Lon=XXX Alt=XXX Body=XXX
|
|
1652
|
+
Notes=XXX", used in 3gp videos
|
|
1653
|
+
},
|
|
1617
1654
|
# (4-byte flags, 2-byte lang, location string, 1-byte role, 4-byte fixed longitude,
|
|
1618
1655
|
# 4-byte fixed latitude, 4-byte fixed altitude, body string, notes string)
|
|
1619
1656
|
RawConv => q{
|
|
1620
|
-
return '<err>' unless length $val >= 6;
|
|
1621
|
-
my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 4));
|
|
1622
|
-
$lang = $lang ? "($lang) " : '';
|
|
1623
|
-
$val = substr($val, 6);
|
|
1624
1657
|
my $str;
|
|
1625
1658
|
if ($val =~ /^\xfe\xff/) {
|
|
1626
1659
|
$val =~ s/^(\xfe\xff(.{2})*?)\0\0//s or return '<err>';
|
|
1627
1660
|
$str = $self->Decode($1, 'UCS2');
|
|
1628
1661
|
} else {
|
|
1629
1662
|
$val =~ s/^(.*?)\0//s or return '<err>';
|
|
1630
|
-
$str = $1;
|
|
1663
|
+
$str = $self->Decode($1, 'UTF8');
|
|
1631
1664
|
}
|
|
1632
1665
|
$str = '(none)' unless length $str;
|
|
1633
1666
|
return '<err>' if length $val < 13;
|
|
@@ -1642,27 +1675,52 @@ my %eeBox2 = (
|
|
|
1642
1675
|
if ($val =~ s/^(\xfe\xff(.{2})*?)\0\0//s) {
|
|
1643
1676
|
$str .= ' Body=' . $self->Decode($1, 'UCS2');
|
|
1644
1677
|
} elsif ($val =~ s/^(.*?)\0//s) {
|
|
1645
|
-
$str .=
|
|
1678
|
+
$str .= ' Body=' . $self->Decode($1, 'UTF8');
|
|
1646
1679
|
}
|
|
1647
1680
|
if ($val =~ s/^(\xfe\xff(.{2})*?)\0\0//s) {
|
|
1648
1681
|
$str .= ' Notes=' . $self->Decode($1, 'UCS2');
|
|
1649
1682
|
} elsif ($val =~ s/^(.*?)\0//s) {
|
|
1650
|
-
$str .=
|
|
1683
|
+
$str .= ' Notes=' . $self->Decode($1, 'UTF8');
|
|
1651
1684
|
}
|
|
1652
|
-
return $
|
|
1685
|
+
return $str;
|
|
1686
|
+
},
|
|
1687
|
+
RawConvInv => q{
|
|
1688
|
+
my ($role, $lat, $lon, $alt, $body, $note);
|
|
1689
|
+
$lat = $1 if $val =~ s/ Lat=([-+]?[.\d]+)//i;
|
|
1690
|
+
$lon = $1 if $val =~ s/ Lon=([-+]?[.\d]+)//i;
|
|
1691
|
+
$alt = $1 if $val =~ s/ Alt=([-+]?[.\d]+)//i;
|
|
1692
|
+
$note = $val =~ s/ Notes=(.*)//i ? $1 : '';
|
|
1693
|
+
$body = $val =~ s/ Body=(.*)//i ? $1 : '';
|
|
1694
|
+
$role = $val =~ s/ Role=(.*)//i ? $1 : '';
|
|
1695
|
+
$val = '' if $val eq '(none)';
|
|
1696
|
+
$role = {shooting=>0,real=>1,fictional=>2}->{lc $role} || 0;
|
|
1697
|
+
return $self->Encode($val, 'UTF8') . "\0" . Set8u($role) .
|
|
1698
|
+
SetFixed32s(defined $lon ? $lon : 999) .
|
|
1699
|
+
SetFixed32s(defined $lat ? $lat : 999) .
|
|
1700
|
+
SetFixed32s(defined $alt ? $alt : 0) .
|
|
1701
|
+
$self->Encode($body) . "\0" .
|
|
1702
|
+
$self->Encode($note) . "\0";
|
|
1653
1703
|
},
|
|
1654
1704
|
},
|
|
1655
1705
|
yrrc => {
|
|
1656
1706
|
Name => 'Year',
|
|
1707
|
+
Writable => 'undef',
|
|
1657
1708
|
Groups => { 2 => 'Time' },
|
|
1658
|
-
|
|
1709
|
+
Avoid => 1,
|
|
1710
|
+
Notes => 'used in 3gp videos',
|
|
1711
|
+
ValueConv => 'length($val) >= 6 ? unpack("x4n",$val) : "<err>"',
|
|
1712
|
+
ValueConvInv => 'pack("Nn",0,$val)',
|
|
1659
1713
|
},
|
|
1660
1714
|
urat => { #17
|
|
1661
1715
|
Name => 'UserRating',
|
|
1662
|
-
|
|
1716
|
+
Writable => 'undef',
|
|
1717
|
+
Notes => 'used in 3gp videos',
|
|
1718
|
+
Avoid => 1,
|
|
1719
|
+
ValueConv => q{
|
|
1663
1720
|
return '<err>' unless length $val >= 8;
|
|
1664
|
-
|
|
1721
|
+
unpack('x7C', $val);
|
|
1665
1722
|
},
|
|
1723
|
+
ValueConvInv => 'pack("N2",0,$val)',
|
|
1666
1724
|
},
|
|
1667
1725
|
# tsel - TrackSelection (ref 17)
|
|
1668
1726
|
# Apple tags (ref 16[dead] -- see ref 25 instead)
|
|
@@ -1994,7 +2052,11 @@ my %eeBox2 = (
|
|
|
1994
2052
|
# ---- Microsoft ----
|
|
1995
2053
|
Xtra => { #PH (microsoft)
|
|
1996
2054
|
Name => 'MicrosoftXtra',
|
|
1997
|
-
|
|
2055
|
+
WriteGroup => 'Microsoft',
|
|
2056
|
+
SubDirectory => {
|
|
2057
|
+
DirName => 'Microsoft',
|
|
2058
|
+
TagTable => 'Image::ExifTool::Microsoft::Xtra',
|
|
2059
|
+
},
|
|
1998
2060
|
},
|
|
1999
2061
|
# ---- Minolta ----
|
|
2000
2062
|
MMA0 => { #PH (DiMage 7Hi)
|
|
@@ -2207,6 +2269,12 @@ my %eeBox2 = (
|
|
|
2207
2269
|
# opax - 164 bytes unknown (center and affine arrays? ref 26)
|
|
2208
2270
|
# opai - 32 bytes (maybe contains a serial number starting at byte 16? - PH) (rgb gains, degamma, gamma? ref 26)
|
|
2209
2271
|
# intv - 16 bytes all zero
|
|
2272
|
+
# ---- Xaiomi ----
|
|
2273
|
+
mcvr => {
|
|
2274
|
+
Name => 'PreviewImage',
|
|
2275
|
+
Groups => { 2 => 'Preview' },
|
|
2276
|
+
Binary => 1,
|
|
2277
|
+
},
|
|
2210
2278
|
# ---- Unknown ----
|
|
2211
2279
|
# CDET - 128 bytes (unknown origin)
|
|
2212
2280
|
# mtyp - 4 bytes all zero (some drone video)
|
|
@@ -2644,6 +2712,7 @@ my %eeBox2 = (
|
|
|
2644
2712
|
colr => [{
|
|
2645
2713
|
Name => 'ICC_Profile',
|
|
2646
2714
|
Condition => '$$valPt =~ /^(prof|rICC)/',
|
|
2715
|
+
Permanent => 0, # (in QuickTime, this writes a zero-length box instead of deleting)
|
|
2647
2716
|
SubDirectory => {
|
|
2648
2717
|
TagTable => 'Image::ExifTool::ICC_Profile::Main',
|
|
2649
2718
|
Start => 4,
|
|
@@ -3000,9 +3069,9 @@ my %eeBox2 = (
|
|
|
3000
3069
|
3-character ISO 639-2 language code and an optional ISO 3166-1 alpha 2
|
|
3001
3070
|
country code to the tag name (eg. "ItemList:Title-fra" or
|
|
3002
3071
|
"ItemList::Title-fra-FR"). When creating a new Meta box to contain the
|
|
3003
|
-
ItemList directory, by default ExifTool
|
|
3004
|
-
|
|
3005
|
-
|
|
3072
|
+
ItemList directory, by default ExifTool adds an 'mdir' (Metadata) Handler
|
|
3073
|
+
box because Apple software may ignore ItemList tags otherwise, but the API
|
|
3074
|
+
L<QuickTimeHandler|../ExifTool.html#QuickTimeHandler> option may be set to 0 to avoid this.
|
|
3006
3075
|
},
|
|
3007
3076
|
# in this table, binary 1 and 2-byte "data"-type tags are interpreted as
|
|
3008
3077
|
# int8u and int16u. Multi-byte binary "data" tags are extracted as binary data.
|
|
@@ -6163,13 +6232,12 @@ my %eeBox2 = (
|
|
|
6163
6232
|
PROCESS_PROC => \&ProcessKeys,
|
|
6164
6233
|
WRITE_PROC => \&WriteKeys,
|
|
6165
6234
|
CHECK_PROC => \&CheckQTValue,
|
|
6166
|
-
VARS => { LONG_TAGS =>
|
|
6235
|
+
VARS => { LONG_TAGS => 7 },
|
|
6167
6236
|
WRITABLE => 1,
|
|
6168
6237
|
# (not PREFERRED when writing)
|
|
6169
6238
|
GROUPS => { 1 => 'Keys' },
|
|
6170
6239
|
WRITE_GROUP => 'Keys',
|
|
6171
6240
|
LANG_INFO => \&GetLangInfo,
|
|
6172
|
-
FORMAT => 'string',
|
|
6173
6241
|
NOTES => q{
|
|
6174
6242
|
This directory contains a list of key names which are used to decode tags
|
|
6175
6243
|
written by the "mdta" handler. Also in this table are a few tags found in
|
|
@@ -6235,6 +6303,10 @@ my %eeBox2 = (
|
|
|
6235
6303
|
'location.ISO6709' => {
|
|
6236
6304
|
Name => 'GPSCoordinates',
|
|
6237
6305
|
Groups => { 2 => 'Location' },
|
|
6306
|
+
Notes => q{
|
|
6307
|
+
Google Photos may ignore this if the coorinates have more than 5 digits
|
|
6308
|
+
after the decimal
|
|
6309
|
+
},
|
|
6238
6310
|
ValueConv => \&ConvertISO6709,
|
|
6239
6311
|
ValueConvInv => \&ConvInvISO6709,
|
|
6240
6312
|
PrintConv => \&PrintGPSCoordinates,
|
|
@@ -6271,6 +6343,11 @@ my %eeBox2 = (
|
|
|
6271
6343
|
PrintConv => '$self->ConvertDateTime($val)',
|
|
6272
6344
|
PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
|
|
6273
6345
|
},
|
|
6346
|
+
'location.accuracy.horizontal' => { Name => 'LocationAccuracyHorizontal' },
|
|
6347
|
+
'live-photo.auto' => { Name => 'LivePhotoAuto', Writable => 'int8u' },
|
|
6348
|
+
'live-photo.vitality-score' => { Name => 'LivePhotoVitalityScore', Writable => 'float' },
|
|
6349
|
+
'live-photo.vitality-scoring-version' => { Name => 'LivePhotoVitalityScoringVersion', Writable => 'int64s' },
|
|
6350
|
+
'apple.photos.variation-identifier' => { Name => 'ApplePhotosVariationIdentifier', Writable => 'int64s' },
|
|
6274
6351
|
'direction.facing' => { Name => 'CameraDirection', Groups => { 2 => 'Location' } },
|
|
6275
6352
|
'direction.motion' => { Name => 'CameraMotion', Groups => { 2 => 'Location' } },
|
|
6276
6353
|
'location.body' => { Name => 'LocationBody', Groups => { 2 => 'Location' } },
|
|
@@ -6306,11 +6383,15 @@ my %eeBox2 = (
|
|
|
6306
6383
|
# com.divergentmedia.clipwrap.manufacturer ('Sony')
|
|
6307
6384
|
# com.divergentmedia.clipwrap.originalDateTime ('2013/2/6 10:30:40+0200')
|
|
6308
6385
|
#
|
|
6309
|
-
# seen in timed metadata (mebx), and added dynamically to the table
|
|
6310
|
-
#
|
|
6386
|
+
# seen in timed metadata (mebx), and added dynamically to the table via SaveMetaKeys()
|
|
6387
|
+
# NOTE: these tags are not writable! (timed metadata cannot yet be written)
|
|
6311
6388
|
#
|
|
6312
6389
|
# (mdta)com.apple.quicktime.video-orientation (dtyp=66, int16s)
|
|
6313
|
-
'video-orientation' => {
|
|
6390
|
+
'video-orientation' => {
|
|
6391
|
+
Name => 'VideoOrientation',
|
|
6392
|
+
Writable => 0,
|
|
6393
|
+
PrintConv => \%Image::ExifTool::Exif::orientation, #PH (NC)
|
|
6394
|
+
},
|
|
6314
6395
|
# (mdta)com.apple.quicktime.live-photo-info (dtyp=com.apple.quicktime.com.apple.quicktime.live-photo-info)
|
|
6315
6396
|
'live-photo-info' => {
|
|
6316
6397
|
Name => 'LivePhotoInfo',
|
|
@@ -6370,10 +6451,11 @@ my %eeBox2 = (
|
|
|
6370
6451
|
# iTunes info ('----') atoms
|
|
6371
6452
|
%Image::ExifTool::QuickTime::iTunesInfo = (
|
|
6372
6453
|
PROCESS_PROC => \&ProcessMOV,
|
|
6373
|
-
GROUPS => { 2 => 'Audio' },
|
|
6454
|
+
GROUPS => { 1 => 'iTunes', 2 => 'Audio' },
|
|
6374
6455
|
NOTES => q{
|
|
6375
6456
|
ExifTool will extract any iTunesInfo tags that exist, even if they are not
|
|
6376
|
-
defined in this table.
|
|
6457
|
+
defined in this table. These tags belong to the family 1 "iTunes" group,
|
|
6458
|
+
and are not currently writable.
|
|
6377
6459
|
},
|
|
6378
6460
|
# 'mean'/'name'/'data' atoms form a triplet, but unfortunately
|
|
6379
6461
|
# I haven't been able to find any documentation on this.
|
|
@@ -6434,9 +6516,45 @@ my %eeBox2 = (
|
|
|
6434
6516
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::EncodingParams' },
|
|
6435
6517
|
},
|
|
6436
6518
|
# also heard about 'iTunPGAP', but I haven't seen a sample
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6519
|
+
# all tags below were added based on samples I have seen - PH
|
|
6520
|
+
DISCNUMBER => 'DiscNumber',
|
|
6521
|
+
TRACKNUMBER => 'TrackNumber',
|
|
6522
|
+
ARTISTS => 'Artists',
|
|
6523
|
+
CATALOGNUMBER => 'CatalogNumber',
|
|
6524
|
+
RATING => 'Rating',
|
|
6525
|
+
MEDIA => 'Media',
|
|
6526
|
+
SCRIPT => 'Script', # character set? (seen 'Latn')
|
|
6527
|
+
BARCODE => 'Barcode',
|
|
6528
|
+
LABEL => 'Label',
|
|
6529
|
+
MOOD => 'Mood',
|
|
6530
|
+
popularimeter => 'Popularimeter',
|
|
6531
|
+
'Dynamic Range (DR)'=> 'DynamicRange',
|
|
6532
|
+
initialkey => 'InitialKey',
|
|
6533
|
+
originalyear => 'OriginalYear',
|
|
6534
|
+
originaldate => 'OriginalDate',
|
|
6535
|
+
'~length' => 'Length', # play length? (ie. duration?)
|
|
6536
|
+
replaygain_track_gain=>'ReplayTrackGain',
|
|
6537
|
+
replaygain_track_peak=>'ReplayTrackPeak',
|
|
6538
|
+
'Volume Level (ReplayGain)'=> 'ReplayVolumeLevel',
|
|
6539
|
+
'Dynamic Range (R128)'=> 'DynamicRangeR128',
|
|
6540
|
+
'Volume Level (R128)' => 'VolumeLevelR128',
|
|
6541
|
+
'Peak Level (Sample)' => 'PeakLevelSample',
|
|
6542
|
+
'Peak Level (R128)' => 'PeakLevelR128',
|
|
6543
|
+
# also seen (many from forum12777):
|
|
6544
|
+
# 'MusicBrainz Album Release Country'
|
|
6545
|
+
# 'MusicBrainz Album Type'
|
|
6546
|
+
# 'MusicBrainz Album Status'
|
|
6547
|
+
# 'MusicBrainz Track Id'
|
|
6548
|
+
# 'MusicBrainz Release Track Id'
|
|
6549
|
+
# 'MusicBrainz Album Id'
|
|
6550
|
+
# 'MusicBrainz Album Artist Id'
|
|
6551
|
+
# 'MusicBrainz Artist Id'
|
|
6552
|
+
# 'Acoustid Id' (sic)
|
|
6553
|
+
# 'Tool Version'
|
|
6554
|
+
# 'Tool Name'
|
|
6555
|
+
# 'ISRC'
|
|
6556
|
+
# 'HDCD'
|
|
6557
|
+
# 'Waveform'
|
|
6440
6558
|
);
|
|
6441
6559
|
|
|
6442
6560
|
# iTunes audio encoding parameters
|
|
@@ -7595,7 +7713,11 @@ my %eeBox2 = (
|
|
|
7595
7713
|
8 => {
|
|
7596
7714
|
Name => 'HandlerType',
|
|
7597
7715
|
Format => 'undef[4]',
|
|
7598
|
-
RawConv =>
|
|
7716
|
+
RawConv => q{
|
|
7717
|
+
$$self{HandlerType} = $val unless $val eq 'alis' or $val eq 'url ';
|
|
7718
|
+
$$self{HasHandler}{$val} = 1; # remember all our handlers
|
|
7719
|
+
return $val;
|
|
7720
|
+
},
|
|
7599
7721
|
PrintConvColumns => 2,
|
|
7600
7722
|
PrintConv => {
|
|
7601
7723
|
alis => 'Alias Data', #PH
|
|
@@ -7700,7 +7822,7 @@ my %eeBox2 = (
|
|
|
7700
7822
|
$val =~ s/\0+$//; # remove trailing nulls
|
|
7701
7823
|
if (length $val and $$self{OPTIONS}{ExtractEmbedded}) {
|
|
7702
7824
|
my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
|
7703
|
-
Image::ExifTool::QuickTime::
|
|
7825
|
+
Image::ExifTool::QuickTime::ProcessGPSLog($self, { DataPt => \$val }, $tagTbl);
|
|
7704
7826
|
}
|
|
7705
7827
|
return $val;
|
|
7706
7828
|
},
|
|
@@ -8580,7 +8702,7 @@ sub QuickTimeFormat($$)
|
|
|
8580
8702
|
my ($flags, $len) = @_;
|
|
8581
8703
|
my $format;
|
|
8582
8704
|
if ($flags == 0x15 or $flags == 0x16) {
|
|
8583
|
-
$format = { 1=>'int8', 2=>'int16', 4=>'int32' }->{$len};
|
|
8705
|
+
$format = { 1=>'int8', 2=>'int16', 4=>'int32', 8=>'int64' }->{$len};
|
|
8584
8706
|
$format .= $flags == 0x15 ? 's' : 'u' if $format;
|
|
8585
8707
|
} elsif ($flags == 0x17) {
|
|
8586
8708
|
$format = 'float';
|
|
@@ -8801,20 +8923,28 @@ sub ProcessKeys($$$)
|
|
|
8801
8923
|
my $ns = substr($$dataPt, $pos + 4, 4);
|
|
8802
8924
|
my $tag = substr($$dataPt, $pos + 8, $len - 8);
|
|
8803
8925
|
$tag =~ s/\0.*//s; # truncate at null
|
|
8926
|
+
my $full = $tag;
|
|
8804
8927
|
$tag =~ s/^com\.(apple\.quicktime\.)?// if $ns eq 'mdta'; # remove apple quicktime domain
|
|
8805
8928
|
$tag = "Tag_$ns" unless $tag;
|
|
8806
|
-
|
|
8807
|
-
my $tagInfo
|
|
8808
|
-
|
|
8809
|
-
$tagInfo = $et->GetTagInfo($
|
|
8810
|
-
|
|
8929
|
+
my $short = $tag;
|
|
8930
|
+
my $tagInfo;
|
|
8931
|
+
for (;;) {
|
|
8932
|
+
$tagInfo = $et->GetTagInfo($tagTablePtr, $tag) and last;
|
|
8933
|
+
# also try ItemList and UserData tables
|
|
8934
|
+
$tagInfo = $et->GetTagInfo($itemList, $tag) and last;
|
|
8935
|
+
$tagInfo = $et->GetTagInfo($userData, $tag) and last;
|
|
8936
|
+
# (I have some samples where the tag is a reversed ItemList or UserData tag ID)
|
|
8937
|
+
if ($tag =~ /^\w{3}\xa9$/) {
|
|
8938
|
+
$tag = pack('N', unpack('V', $tag));
|
|
8939
|
+
$tagInfo = $et->GetTagInfo($itemList, $tag) and last;
|
|
8811
8940
|
$tagInfo = $et->GetTagInfo($userData, $tag);
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
|
|
8941
|
+
last;
|
|
8942
|
+
}
|
|
8943
|
+
if ($tag eq $full) {
|
|
8944
|
+
$tag = $short;
|
|
8945
|
+
last;
|
|
8817
8946
|
}
|
|
8947
|
+
$tag = $full;
|
|
8818
8948
|
}
|
|
8819
8949
|
my ($newInfo, $msg);
|
|
8820
8950
|
if ($tagInfo) {
|
|
@@ -8855,6 +8985,7 @@ sub ProcessKeys($$$)
|
|
|
8855
8985
|
delete $$itemList{$id};
|
|
8856
8986
|
}
|
|
8857
8987
|
if ($newInfo) {
|
|
8988
|
+
$$newInfo{KeysID} = $tag; # save original ID for use in family 7 group name
|
|
8858
8989
|
AddTagToTable($itemList, $id, $newInfo);
|
|
8859
8990
|
$msg or $msg = '';
|
|
8860
8991
|
$out and print $out "$$et{INDENT}Added ItemList Tag $id = ($ns) $tag$msg\n";
|
|
@@ -8933,6 +9064,7 @@ sub ProcessMOV($$;$)
|
|
|
8933
9064
|
if ($raf->Read($buff, $size-8) == $size-8) {
|
|
8934
9065
|
$raf->Seek(-($size-8), 1);
|
|
8935
9066
|
my $type = substr($buff, 0, 4);
|
|
9067
|
+
$$et{save_ftyp} = $type;
|
|
8936
9068
|
# see if we know the extension for this file type
|
|
8937
9069
|
if ($ftypLookup{$type} and $ftypLookup{$type} =~ /\(\.(\w+)/) {
|
|
8938
9070
|
$fileType = $1;
|
|
@@ -8981,6 +9113,12 @@ sub ProcessMOV($$;$)
|
|
|
8981
9113
|
} else {
|
|
8982
9114
|
my $t = PrintableTagID($tag,2);
|
|
8983
9115
|
$et->VPrint(0,"$$et{INDENT}Tag '${t}' extends to end of file");
|
|
9116
|
+
if ($$tagTablePtr{"$tag-size"}) {
|
|
9117
|
+
my $pos = $raf->Tell();
|
|
9118
|
+
$raf->Seek(0, 2);
|
|
9119
|
+
$et->HandleTag($tagTablePtr, "$tag-size", $raf->Tell() - $pos);
|
|
9120
|
+
$et->HandleTag($tagTablePtr, "$tag-offset", $pos) if $$tagTablePtr{"$tag-offset"};
|
|
9121
|
+
}
|
|
8984
9122
|
}
|
|
8985
9123
|
last;
|
|
8986
9124
|
}
|
|
@@ -9207,6 +9345,7 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9207
9345
|
Name => $name,
|
|
9208
9346
|
Description => $desc,
|
|
9209
9347
|
};
|
|
9348
|
+
$et->VPrint(0, $$et{INDENT}, "[adding QuickTime:$name]\n");
|
|
9210
9349
|
AddTagToTable($tagTablePtr, $tag, $tagInfo);
|
|
9211
9350
|
}
|
|
9212
9351
|
# ignore 8-byte header
|
|
@@ -9218,9 +9357,9 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9218
9357
|
$val = \$buff;
|
|
9219
9358
|
}
|
|
9220
9359
|
}
|
|
9221
|
-
|
|
9360
|
+
$$tagInfo{List} = 1; # (allow any of these tags to have multiple data elements)
|
|
9361
|
+
$et->VerboseInfo($tag, $tagInfo, Value => $val) if $verbose;
|
|
9222
9362
|
} else {
|
|
9223
|
-
undef %triplet if $tag eq 'mean';
|
|
9224
9363
|
$triplet{$tag} = substr($val,4) if length($val) > 4;
|
|
9225
9364
|
undef $tagInfo; # don't store this tag
|
|
9226
9365
|
}
|
|
@@ -9304,7 +9443,13 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9304
9443
|
# (shouldn't be null terminated, but some software writes it anyway)
|
|
9305
9444
|
$value =~ s/\0$// unless $$tagInfo{Binary};
|
|
9306
9445
|
} else {
|
|
9307
|
-
|
|
9446
|
+
if (not $format) {
|
|
9447
|
+
$format = QuickTimeFormat($flags, $len);
|
|
9448
|
+
} elsif ($format =~ /^int\d+([us])$/) {
|
|
9449
|
+
# adjust integer to available length (but not int64)
|
|
9450
|
+
my $fmt = { 1=>'int8', 2=>'int16', 4=>'int32' }->{$len};
|
|
9451
|
+
$format = $fmt . $1 if defined $fmt;
|
|
9452
|
+
}
|
|
9308
9453
|
if ($format) {
|
|
9309
9454
|
$value = ReadValue(\$value, 0, $format, $$tagInfo{Count}, $len);
|
|
9310
9455
|
} elsif (not $$tagInfo{ValueConv}) {
|
|
@@ -9356,9 +9501,9 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9356
9501
|
}
|
|
9357
9502
|
for (;;) {
|
|
9358
9503
|
my ($len, $lang);
|
|
9359
|
-
if ($$tagInfo{IText} and $$tagInfo{IText}
|
|
9360
|
-
last if $pos +
|
|
9361
|
-
$pos +=
|
|
9504
|
+
if ($$tagInfo{IText} and $$tagInfo{IText} >= 6) {
|
|
9505
|
+
last if $pos + $$tagInfo{IText} > $size;
|
|
9506
|
+
$pos += $$tagInfo{IText} - 2;
|
|
9362
9507
|
$lang = unpack("x${pos}n", $val);
|
|
9363
9508
|
$pos += 2;
|
|
9364
9509
|
$len = $size - $pos;
|
|
@@ -9378,7 +9523,7 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9378
9523
|
# ignore any empty entries (or null padding) after the first
|
|
9379
9524
|
next if not $len and $pos;
|
|
9380
9525
|
my $str = substr($val, $pos, $len);
|
|
9381
|
-
my $langInfo;
|
|
9526
|
+
my ($langInfo, $enc);
|
|
9382
9527
|
if (($lang < 0x400 or $lang == 0x7fff) and $str !~ /^\xfe\xff/) {
|
|
9383
9528
|
# this is a Macintosh language code
|
|
9384
9529
|
# a language code of 0 is Macintosh english, so treat as default
|
|
@@ -9395,15 +9540,22 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9395
9540
|
}
|
|
9396
9541
|
# the spec says only "Macintosh text encoding", but
|
|
9397
9542
|
# allow this to be configured by the user
|
|
9398
|
-
$
|
|
9543
|
+
$enc = $charsetQuickTime;
|
|
9399
9544
|
} else {
|
|
9400
9545
|
# convert language code to ASCII (ignore read-only bit)
|
|
9401
9546
|
$lang = UnpackLang($lang);
|
|
9402
9547
|
# may be either UTF-8 or UTF-16BE
|
|
9403
|
-
|
|
9548
|
+
$enc = $str=~s/^\xfe\xff// ? 'UTF16' : 'UTF8';
|
|
9549
|
+
}
|
|
9550
|
+
unless ($$tagInfo{NoDecode}) {
|
|
9404
9551
|
$str = $et->Decode($str, $enc);
|
|
9552
|
+
$str =~ s/\0+$//; # remove any trailing nulls (eg. 3gp tags)
|
|
9553
|
+
}
|
|
9554
|
+
if ($$tagInfo{IText} and $$tagInfo{IText} > 6) {
|
|
9555
|
+
my $n = $$tagInfo{IText} - 6;
|
|
9556
|
+
# add back extra bytes (eg. 'rtng' box)
|
|
9557
|
+
$str = substr($val, $pos-$n-2, $n) . $str;
|
|
9405
9558
|
}
|
|
9406
|
-
$str =~ s/\0+$//; # remove any trailing nulls (eg. 3gp tags)
|
|
9407
9559
|
$langInfo = GetLangInfoQT($et, $tagInfo, $lang) if $lang;
|
|
9408
9560
|
$et->FoundTag($langInfo || $tagInfo, $str);
|
|
9409
9561
|
$pos += $len;
|
|
@@ -9453,6 +9605,13 @@ ItemID: foreach $id (keys %$items) {
|
|
|
9453
9605
|
($size, $tag) = unpack('Na4', $buff);
|
|
9454
9606
|
++$index if defined $index;
|
|
9455
9607
|
}
|
|
9608
|
+
# tweak file type based on track content ("iso*" and "dash" ftyp only)
|
|
9609
|
+
if ($topLevel and $$et{VALUE}{FileType} and $$et{VALUE}{FileType} eq 'MP4' and
|
|
9610
|
+
$$et{save_ftyp} and $$et{HasHandler} and $$et{save_ftyp} =~ /^(iso|dash)/ and
|
|
9611
|
+
$$et{HasHandler}{soun} and not $$et{HasHandler}{vide})
|
|
9612
|
+
{
|
|
9613
|
+
$et->OverrideFileType('M4A', 'audio/mp4');
|
|
9614
|
+
}
|
|
9456
9615
|
# fill in missing defaults for alternate language tags
|
|
9457
9616
|
# (the first language is taken as the default)
|
|
9458
9617
|
if ($doDefaultLang and $$et{QTLang}) {
|