exiftool-vendored.pl 12.84.0 → 12.89.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.
- package/bin/Changes +94 -3
- package/bin/MANIFEST +1 -0
- package/bin/META.json +1 -1
- package/bin/META.yml +16 -16
- package/bin/README +47 -46
- package/bin/build_geolocation +96 -20
- package/bin/config_files/example.config +5 -0
- package/bin/config_files/onone.config +28 -0
- package/bin/exiftool +67 -57
- package/bin/lib/Image/ExifTool/AIFF.pm +8 -4
- package/bin/lib/Image/ExifTool/ASF.pm +4 -1
- package/bin/lib/Image/ExifTool/Apple.pm +2 -1
- package/bin/lib/Image/ExifTool/BuildTagLookup.pm +14 -8
- package/bin/lib/Image/ExifTool/Canon.pm +100 -7
- package/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
- package/bin/lib/Image/ExifTool/CanonVRD.pm +5 -2
- package/bin/lib/Image/ExifTool/DPX.pm +3 -3
- package/bin/lib/Image/ExifTool/FujiFilm.pm +46 -4
- package/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- package/bin/lib/Image/ExifTool/Geolocation.pm +18 -8
- package/bin/lib/Image/ExifTool/ID3.pm +36 -8
- package/bin/lib/Image/ExifTool/InDesign.pm +8 -4
- package/bin/lib/Image/ExifTool/Jpeg2000.pm +0 -1
- package/bin/lib/Image/ExifTool/Lang/de.pm +2 -2
- package/bin/lib/Image/ExifTool/Matroska.pm +66 -10
- package/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -2
- package/bin/lib/Image/ExifTool/Nikon.pm +21 -2
- package/bin/lib/Image/ExifTool/Olympus.pm +27 -17
- package/bin/lib/Image/ExifTool/Panasonic.pm +1 -0
- package/bin/lib/Image/ExifTool/PanasonicRaw.pm +1 -0
- package/bin/lib/Image/ExifTool/Pentax.pm +139 -22
- package/bin/lib/Image/ExifTool/QuickTime.pm +70 -16
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +24 -2
- package/bin/lib/Image/ExifTool/RIFF.pm +20 -10
- package/bin/lib/Image/ExifTool/Samsung.pm +29 -1
- package/bin/lib/Image/ExifTool/Sony.pm +21 -11
- package/bin/lib/Image/ExifTool/TagLookup.pm +6806 -6782
- package/bin/lib/Image/ExifTool/TagNames.pod +124 -34
- package/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
- package/bin/lib/Image/ExifTool/WriteQuickTime.pl +86 -16
- package/bin/lib/Image/ExifTool/Writer.pl +8 -6
- package/bin/lib/Image/ExifTool/XMP.pm +10 -8
- package/bin/lib/Image/ExifTool/XMP2.pl +51 -30
- package/bin/lib/Image/ExifTool/ZIP.pm +8 -4
- package/bin/lib/Image/ExifTool.pm +78 -45
- package/bin/lib/Image/ExifTool.pod +66 -50
- package/bin/perl-Image-ExifTool.spec +45 -45
- package/bin/pp_build_exe.args +4 -4
- package/package.json +3 -3
|
@@ -31,7 +31,7 @@ use vars qw($VERSION);
|
|
|
31
31
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
32
32
|
use Image::ExifTool::Exif;
|
|
33
33
|
|
|
34
|
-
$VERSION = '1.
|
|
34
|
+
$VERSION = '1.95';
|
|
35
35
|
|
|
36
36
|
sub ProcessFujiDir($$$);
|
|
37
37
|
sub ProcessFaceRec($$$);
|
|
@@ -1169,6 +1169,46 @@ my %faceCategories = (
|
|
|
1169
1169
|
Face8Birthday => { },
|
|
1170
1170
|
);
|
|
1171
1171
|
|
|
1172
|
+
# tags extracted from RAF header
|
|
1173
|
+
%Image::ExifTool::FujiFilm::RAFHeader = (
|
|
1174
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
1175
|
+
GROUPS => { 0 => 'RAF', 1 => 'RAF', 2 => 'Image' },
|
|
1176
|
+
NOTES => 'Tags extracted from the header of RAF images.',
|
|
1177
|
+
# 0x00 - eg. "FUJIFILMCCD-RAW 0201FA392001FinePix S3Pro"
|
|
1178
|
+
0x3c => { #PH
|
|
1179
|
+
Name => 'RAFVersion',
|
|
1180
|
+
Format => 'undef[4]',
|
|
1181
|
+
},
|
|
1182
|
+
# (all int32u values)
|
|
1183
|
+
# 0x40 - 1 for M-RAW, 0 otherwise?
|
|
1184
|
+
# 0x44 - high word of M-RAW offset? (only seen zero)
|
|
1185
|
+
# 0x48 - M-RAW header offset
|
|
1186
|
+
# 0x4c - M-RAW header length
|
|
1187
|
+
# 0x50 - ? (only seen zero)
|
|
1188
|
+
# 0x54 - JPEG offset
|
|
1189
|
+
# 0x58 - JPEG length
|
|
1190
|
+
# 0x5c - RAF directory offset
|
|
1191
|
+
# 0x60 - RAF directory length
|
|
1192
|
+
# 0x64 - FujiIFD dir offset
|
|
1193
|
+
# 0x68 - FujiIFD dir length
|
|
1194
|
+
# 0x6c - RAFCompression or JPEG start
|
|
1195
|
+
0x6c => { #10
|
|
1196
|
+
Name => 'RAFCompression',
|
|
1197
|
+
Condition => '$$valPt =~ /^\0\0\0/', # (JPEG header is in this location for some RAF versions)
|
|
1198
|
+
Format => 'int32u',
|
|
1199
|
+
PrintConv => { 0 => 'Uncompressed', 2 => 'Lossless', 3 => 'Lossy' },
|
|
1200
|
+
},
|
|
1201
|
+
# 0x70 - ? same as 0x68?
|
|
1202
|
+
# 0x74 - ? usually 0, but have seen 0x1700
|
|
1203
|
+
# 0x78 - RAF1 dir offset
|
|
1204
|
+
# 0x7c - RAF1 dir length
|
|
1205
|
+
# 0x80 - FujiIFD1 dir offset
|
|
1206
|
+
# 0x84 - FujiIFD1 dir length
|
|
1207
|
+
# 0x88-0x8c - always zero?
|
|
1208
|
+
# 0x90 - ? same as 0x74?
|
|
1209
|
+
# 0x94 - JPEG or M-RAW start
|
|
1210
|
+
);
|
|
1211
|
+
|
|
1172
1212
|
# tags in RAF images (ref 5)
|
|
1173
1213
|
%Image::ExifTool::FujiFilm::RAF = (
|
|
1174
1214
|
PROCESS_PROC => \&ProcessFujiDir,
|
|
@@ -1797,7 +1837,7 @@ sub ProcessRAF($$)
|
|
|
1797
1837
|
my ($buff, $jpeg, $warn, $offset);
|
|
1798
1838
|
|
|
1799
1839
|
my $raf = $$dirInfo{RAF};
|
|
1800
|
-
$raf->Read($buff,
|
|
1840
|
+
$raf->Read($buff,0x70) == 0x70 or return 0;
|
|
1801
1841
|
$buff =~ /^FUJIFILM/ or return 0;
|
|
1802
1842
|
# get position and size of M-RAW header and jpeg preview
|
|
1803
1843
|
my ($mpos, $mlen) = unpack('x72NN', $buff);
|
|
@@ -1807,9 +1847,11 @@ sub ProcessRAF($$)
|
|
|
1807
1847
|
$raf->Seek($jpos, 0) or return 0;
|
|
1808
1848
|
$raf->Read($jpeg, $jlen) == $jlen or return 0;
|
|
1809
1849
|
}
|
|
1850
|
+
SetByteOrder('MM');
|
|
1810
1851
|
$et->SetFileType();
|
|
1811
|
-
$
|
|
1812
|
-
|
|
1852
|
+
my $tbl = GetTagTable('Image::ExifTool::FujiFilm::RAFHeader');
|
|
1853
|
+
$et->ProcessDirectory({ DataPt => \$buff, DirName => 'RAFHeader' }, $tbl);
|
|
1854
|
+
|
|
1813
1855
|
# extract information from embedded JPEG
|
|
1814
1856
|
my %dirInfo = (
|
|
1815
1857
|
Parent => 'RAF',
|
|
Binary file
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
# 1. Time zone name, terminated by newline
|
|
56
56
|
# "\0\0\0\0\x05" (feature codes added in v1.03)
|
|
57
57
|
# Feature codes:
|
|
58
|
-
# 1. Feature code,
|
|
58
|
+
# 1. Feature code, optional space-followed-by-feature-name, then newline
|
|
59
59
|
# "\0\0\0\0\0"
|
|
60
60
|
#
|
|
61
61
|
# Feature Codes v1.02: (see http://www.geonames.org/export/codes.html#P for descriptions)
|
|
@@ -70,7 +70,7 @@ package Image::ExifTool::Geolocation;
|
|
|
70
70
|
use strict;
|
|
71
71
|
use vars qw($VERSION $geoDir $altDir $dbInfo);
|
|
72
72
|
|
|
73
|
-
$VERSION = '1.
|
|
73
|
+
$VERSION = '1.08'; # (this is the module version number, not the database version)
|
|
74
74
|
|
|
75
75
|
my $debug; # set to output processing time for testing
|
|
76
76
|
|
|
@@ -82,7 +82,7 @@ sub Geolocate($;$);
|
|
|
82
82
|
|
|
83
83
|
my (@cityList, @countryList, @regionList, @subregionList, @timezoneList);
|
|
84
84
|
my (%countryNum, %regionNum, %subregionNum, %timezoneNum); # reverse lookups
|
|
85
|
-
my (@sortOrder, @altNames, %langLookup, $nCity, %featureCodes);
|
|
85
|
+
my (@sortOrder, @altNames, %langLookup, $nCity, %featureCodes, %featureTypes);
|
|
86
86
|
my ($lastArgs, %lastFound, @lastByPop, @lastByLat); # cached city matches
|
|
87
87
|
my $dbVer = '1.03';
|
|
88
88
|
my $sortedBy = 'Latitude';
|
|
@@ -200,7 +200,7 @@ sub ReadDatabase($)
|
|
|
200
200
|
$line = <DATFILE>;
|
|
201
201
|
last if length($line) == 6 and $line =~ /\0\0\0\0/;
|
|
202
202
|
chomp $line;
|
|
203
|
-
$line =~ s/
|
|
203
|
+
$featureTypes{$line} = $1 if $line =~ s/ (.*)//;
|
|
204
204
|
push @featureCodes, $line;
|
|
205
205
|
}
|
|
206
206
|
}
|
|
@@ -288,7 +288,7 @@ sub AddEntry(@)
|
|
|
288
288
|
my ($city, $region, $subregion, $cc, $country, $timezone, $fc, $pop, $lat, $lon, $altNames) = @_;
|
|
289
289
|
@_ < 10 and warn("Too few arguments in $city definition (check for updated format)\n"), return 0;
|
|
290
290
|
length($cc) != 2 and warn("Country code '${cc}' is not 2 characters\n"), return 0;
|
|
291
|
-
$fc =~ s/
|
|
291
|
+
$featureTypes{$fc} = $1 if $fc =~ s/ (.*)//;
|
|
292
292
|
my $fn = $featureCodes{lc $fc};
|
|
293
293
|
unless (defined $fn) {
|
|
294
294
|
if ($dbVer eq '1.02' or @featureCodes > 0x3f or not length $fc) {
|
|
@@ -372,7 +372,7 @@ sub AddEntry(@)
|
|
|
372
372
|
# Inputs: 0) entry number or index into sorted database,
|
|
373
373
|
# 1) optional language code, 2) flag to use index into sorted database
|
|
374
374
|
# Returns: 0-10) city,region,subregion,country_code,country,timezone,
|
|
375
|
-
# feature_code,pop,lat,lon,
|
|
375
|
+
# feature_code,pop,lat,lon,feature_type
|
|
376
376
|
sub GetEntry($;$$)
|
|
377
377
|
{
|
|
378
378
|
my ($entryNum, $lang, $sort) = @_;
|
|
@@ -395,7 +395,8 @@ sub GetEntry($;$$)
|
|
|
395
395
|
my $fc = $featureCodes[$fn & 0x3f] || 'Other';
|
|
396
396
|
my $cc = substr($ctry, 0, 2);
|
|
397
397
|
my $country = substr($ctry, 2);
|
|
398
|
-
|
|
398
|
+
my $ft = $featureTypes{$fc};
|
|
399
|
+
if ($lang and $lang ne 'en') {
|
|
399
400
|
my $xlat = $langLookup{$lang};
|
|
400
401
|
# load language lookups if not done already
|
|
401
402
|
if (not defined $xlat) {
|
|
@@ -429,9 +430,10 @@ sub GetEntry($;$$)
|
|
|
429
430
|
$sub = $$xlat{"$cc$rgn,$sub,"} || $$xlat{$sub} || $sub;
|
|
430
431
|
$rgn = $$xlat{"$cc$rgn,"} || $$xlat{$rgn} || $rgn;
|
|
431
432
|
$country = $$xlat{"$cc,"} || $$xlat{$country} || $country;
|
|
433
|
+
$ft = $$xlat{$fc} if $$xlat{$fc};
|
|
432
434
|
}
|
|
433
435
|
}
|
|
434
|
-
return($city,$rgn,$sub,$cc,$country,$timezoneList[$tn],$fc,$pop,$lt,$ln);
|
|
436
|
+
return($city,$rgn,$sub,$cc,$country,$timezoneList[$tn],$fc,$pop,$lt,$ln,$ft);
|
|
435
437
|
}
|
|
436
438
|
|
|
437
439
|
#------------------------------------------------------------------------------
|
|
@@ -507,6 +509,12 @@ sub Geolocate($;$)
|
|
|
507
509
|
$city = '' unless defined $city;
|
|
508
510
|
} elsif (/^[-+]?\d+(\.\d+)?$/) { # coordinate format
|
|
509
511
|
push @coords, $_ if @coords < 2;
|
|
512
|
+
} elsif (/^([-+]?\d+(?:\.\d+)?) *(([NS])[A-Z]*)? +([-+]?\d+(?:\.\d+)?) *(([EW])[A-Z]*)?/i) { # "lat lon" format
|
|
513
|
+
next if @coords;
|
|
514
|
+
my ($lat, $lon) = ($1, $4);
|
|
515
|
+
$lat = -abs($lat) if $3 and uc($3) eq 'S';
|
|
516
|
+
$lon = -abs($lon) if $6 and uc($6) eq 'W';
|
|
517
|
+
push @coords, $lat, $lon;
|
|
510
518
|
} elsif (lc $_ eq 'both') {
|
|
511
519
|
$both = 1;
|
|
512
520
|
} elsif ($_ =~ /^num=(\d+)$/i) {
|
|
@@ -863,6 +871,8 @@ item Return Values:
|
|
|
863
871
|
|
|
864
872
|
9) GPS longitude
|
|
865
873
|
|
|
874
|
+
10) Feature type, or undef
|
|
875
|
+
|
|
866
876
|
=back
|
|
867
877
|
|
|
868
878
|
=head2 GetAltNames
|
|
@@ -18,7 +18,7 @@ use strict;
|
|
|
18
18
|
use vars qw($VERSION);
|
|
19
19
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
20
20
|
|
|
21
|
-
$VERSION = '1.
|
|
21
|
+
$VERSION = '1.62';
|
|
22
22
|
|
|
23
23
|
sub ProcessID3v2($$$);
|
|
24
24
|
sub ProcessPrivate($$$);
|
|
@@ -68,6 +68,12 @@ my %dateTimeConv = (
|
|
|
68
68
|
PrintConv => '$self->ConvertDateTime($val)',
|
|
69
69
|
);
|
|
70
70
|
|
|
71
|
+
# patch for names of user-defined tags which don't automatically generate very well
|
|
72
|
+
my %userTagName = (
|
|
73
|
+
ALBUMARTISTSORT => 'AlbumArtistSort',
|
|
74
|
+
ASIN => 'ASIN',
|
|
75
|
+
);
|
|
76
|
+
|
|
71
77
|
# This table is just for documentation purposes
|
|
72
78
|
%Image::ExifTool::ID3::Main = (
|
|
73
79
|
VARS => { NO_ID => 1 },
|
|
@@ -871,6 +877,19 @@ Image::ExifTool::AddCompositeTags('Image::ExifTool::ID3');
|
|
|
871
877
|
}
|
|
872
878
|
}
|
|
873
879
|
|
|
880
|
+
#------------------------------------------------------------------------------
|
|
881
|
+
# Make tag name for user-defined tag
|
|
882
|
+
# Inputs: 0) User defined tag description
|
|
883
|
+
# Returns: Tag name
|
|
884
|
+
sub MakeTagName($)
|
|
885
|
+
{
|
|
886
|
+
my $name = shift;
|
|
887
|
+
return $userTagName{$name} if $userTagName{$name};
|
|
888
|
+
$name = ucfirst(lc $name) unless $name =~ /[a-z]/; # convert all uppercase to mixed case
|
|
889
|
+
$name =~ s/([a-z])[_ ]([a-z])/$1\U$2/g;
|
|
890
|
+
return Image::ExifTool::MakeTagName($name);
|
|
891
|
+
}
|
|
892
|
+
|
|
874
893
|
#------------------------------------------------------------------------------
|
|
875
894
|
# Convert ID3v1 text to exiftool character set
|
|
876
895
|
# Inputs: 0) ExifTool object ref, 1) text string
|
|
@@ -1247,25 +1266,34 @@ sub ProcessID3v2($$$)
|
|
|
1247
1266
|
# two encoded strings separated by a null
|
|
1248
1267
|
my @vals = DecodeString($et, $val);
|
|
1249
1268
|
foreach (0..1) { $vals[$_] = '' unless defined $vals[$_]; }
|
|
1250
|
-
(
|
|
1269
|
+
if (length $vals[0]) {
|
|
1270
|
+
$id .= "_$vals[0]";
|
|
1271
|
+
$tagInfo = $$tagTablePtr{$id} || AddTagToTable($tagTablePtr, $id, MakeTagName($vals[0]));
|
|
1272
|
+
}
|
|
1273
|
+
$val = $vals[1];
|
|
1251
1274
|
} elsif ($id =~ /^T/ or $id =~ /^(IPL|IPLS|GP1|MVI|MVN)$/) {
|
|
1252
1275
|
$val = DecodeString($et, $val);
|
|
1253
1276
|
} elsif ($id =~ /^(WXX|WXXX)$/) {
|
|
1254
1277
|
# one encoded string and one Latin string separated by a null
|
|
1255
1278
|
my $enc = unpack('C', $val);
|
|
1256
|
-
my $url;
|
|
1279
|
+
my ($tag, $url);
|
|
1257
1280
|
if ($enc == 1 or $enc == 2) {
|
|
1258
|
-
($
|
|
1281
|
+
($tag, $url) = ($tag =~ /^(.(?:..)*?)\0\0(.*)/s);
|
|
1259
1282
|
} else {
|
|
1260
|
-
($
|
|
1283
|
+
($tag, $url) = ($tag =~ /^(..*?)\0(.*)/s);
|
|
1261
1284
|
}
|
|
1262
|
-
unless (defined $
|
|
1285
|
+
unless (defined $tag and defined $url) {
|
|
1263
1286
|
$et->Warn("Invalid $id frame value");
|
|
1264
1287
|
next;
|
|
1265
1288
|
}
|
|
1266
|
-
$
|
|
1289
|
+
$tag = DecodeString($et, $tag);
|
|
1290
|
+
if (length $tag) {
|
|
1291
|
+
$id .= "_$tag";
|
|
1292
|
+
$tag .= '_URL' unless $tag =~ /url/i;
|
|
1293
|
+
$tagInfo = $$tagTablePtr{$id} || AddTagToTable($tagTablePtr, $id, MakeTagName($tag));
|
|
1294
|
+
}
|
|
1267
1295
|
$url =~ s/\0.*//s;
|
|
1268
|
-
$val =
|
|
1296
|
+
$val = $url;
|
|
1269
1297
|
} elsif ($id =~ /^W/) {
|
|
1270
1298
|
$val =~ s/\0.*//s; # truncate at null
|
|
1271
1299
|
} elsif ($id =~ /^(COM|COMM|ULT|USLT)$/) {
|
|
@@ -14,7 +14,7 @@ use strict;
|
|
|
14
14
|
use vars qw($VERSION);
|
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
16
16
|
|
|
17
|
-
$VERSION = '1.
|
|
17
|
+
$VERSION = '1.07';
|
|
18
18
|
|
|
19
19
|
# map for writing metadata to InDesign files (currently only write XMP)
|
|
20
20
|
my %indMap = (
|
|
@@ -73,9 +73,13 @@ sub ProcessIND($$)
|
|
|
73
73
|
my $pages = Get32u($curPage, 280);
|
|
74
74
|
$pages < 2 and $err = 'Invalid page count', goto DONE;
|
|
75
75
|
my $pos = $pages * 4096;
|
|
76
|
-
if ($pos > 0x7fffffff
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
if ($pos > 0x7fffffff) {
|
|
77
|
+
if (not $et->Options('LargeFileSupport')) {
|
|
78
|
+
$err = 'InDesign files larger than 2 GB not supported (LargeFileSupport not set)';
|
|
79
|
+
goto DONE;
|
|
80
|
+
} elsif ($et->Options('LargeFileSupport') eq '2') {
|
|
81
|
+
$et->WarnOnce('Processing large file (LargeFileSupport is 2)');
|
|
82
|
+
}
|
|
79
83
|
}
|
|
80
84
|
if ($outfile) {
|
|
81
85
|
# make XMP the preferred group for writing
|
|
@@ -11,7 +11,7 @@ package Image::ExifTool::Lang::de;
|
|
|
11
11
|
use strict;
|
|
12
12
|
use vars qw($VERSION);
|
|
13
13
|
|
|
14
|
-
$VERSION = '1.
|
|
14
|
+
$VERSION = '1.37';
|
|
15
15
|
|
|
16
16
|
%Image::ExifTool::Lang::de::Translate = (
|
|
17
17
|
'AEAperture' => 'AE-Blende',
|
|
@@ -5118,7 +5118,7 @@ $VERSION = '1.36';
|
|
|
5118
5118
|
'LensMake' => 'Objektivhersteller',
|
|
5119
5119
|
'LensManufacturer' => 'Objektivhersteller',
|
|
5120
5120
|
'LensMaxApertureRange' => 'Objektiv Blendenbereich',
|
|
5121
|
-
'LensModel' => '
|
|
5121
|
+
'LensModel' => 'Objektivmodell',
|
|
5122
5122
|
'LensProfileDigest' => 'Kennwert des Objektivprofils',
|
|
5123
5123
|
'LensProperties' => 'Objektivfunktionen?',
|
|
5124
5124
|
'LensSerialNumber' => 'Objektiv-Seriennummer',
|
|
@@ -15,7 +15,7 @@ use strict;
|
|
|
15
15
|
use vars qw($VERSION);
|
|
16
16
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
17
17
|
|
|
18
|
-
$VERSION = '1.
|
|
18
|
+
$VERSION = '1.16';
|
|
19
19
|
|
|
20
20
|
sub HandleStruct($$;$$$$);
|
|
21
21
|
|
|
@@ -44,7 +44,8 @@ my %uidInfo = (
|
|
|
44
44
|
NOTES => q{
|
|
45
45
|
The following tags are extracted from Matroska multimedia container files.
|
|
46
46
|
This container format is used by file types such as MKA, MKV, MKS and WEBM.
|
|
47
|
-
For speed, by default ExifTool extracts tags only up to the first Cluster
|
|
47
|
+
For speed, by default ExifTool extracts tags only up to the first Cluster
|
|
48
|
+
unless a Seek element specifies the position of a Tags element after this.
|
|
48
49
|
However, the L<Verbose|../ExifTool.html#Verbose> (-v) and L<Unknown|../ExifTool.html#Unknown> = 2 (-U) options force processing of
|
|
49
50
|
Cluster data, and the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> (-ee) option skips over Clusters to
|
|
50
51
|
read subsequent tags. See
|
|
@@ -112,8 +113,25 @@ my %uidInfo = (
|
|
|
112
113
|
Name => 'Seek',
|
|
113
114
|
SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
|
|
114
115
|
},
|
|
115
|
-
0x13ab => {
|
|
116
|
-
|
|
116
|
+
0x13ab => {
|
|
117
|
+
Name => 'SeekID',
|
|
118
|
+
Unknown => 1,
|
|
119
|
+
SeekInfo => 'ID', # save seek ID's
|
|
120
|
+
# (note: converted from VInt internally)
|
|
121
|
+
PrintConv => q{
|
|
122
|
+
my $tagInfo = $Image::ExifTool::Matroska::Main{$val};
|
|
123
|
+
$val = sprintf('0x%x', $val);
|
|
124
|
+
$val .= " ($$tagInfo{Name})" if ref $tagInfo eq 'HASH' and $$tagInfo{Name};
|
|
125
|
+
return $val;
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
0x13ac => {
|
|
129
|
+
Name => 'SeekPosition',
|
|
130
|
+
Format => 'unsigned',
|
|
131
|
+
Unknown => 1,
|
|
132
|
+
SeekInfo => 'Position', # save seek positions
|
|
133
|
+
RawConv => '$val + $$self{SeekHeadOffset}',
|
|
134
|
+
},
|
|
117
135
|
#
|
|
118
136
|
# Segment Info
|
|
119
137
|
#
|
|
@@ -350,8 +368,9 @@ my %uidInfo = (
|
|
|
350
368
|
Name => 'VideoScanType',
|
|
351
369
|
Format => 'unsigned',
|
|
352
370
|
PrintConv => {
|
|
353
|
-
0 => '
|
|
371
|
+
0 => 'Undetermined',
|
|
354
372
|
1 => 'Interlaced',
|
|
373
|
+
2 => 'Progressive',
|
|
355
374
|
},
|
|
356
375
|
},
|
|
357
376
|
0x13b8 => {
|
|
@@ -893,6 +912,7 @@ sub HandleStruct($$;$$$$)
|
|
|
893
912
|
# Inputs: 0) data buffer, 1) position in data
|
|
894
913
|
# Returns: integer value and updates position, -1 for unknown/reserved value,
|
|
895
914
|
# or undef if no data left
|
|
915
|
+
# Notes: Increments position pointer
|
|
896
916
|
sub GetVInt($$)
|
|
897
917
|
{
|
|
898
918
|
return undef if $_[1] >= length $_[0];
|
|
@@ -929,7 +949,7 @@ sub ProcessMKV($$)
|
|
|
929
949
|
{
|
|
930
950
|
my ($et, $dirInfo) = @_;
|
|
931
951
|
my $raf = $$dirInfo{RAF};
|
|
932
|
-
my ($buff, $buf2, @dirEnd, $trackIndent, %trackTypes, $struct);
|
|
952
|
+
my ($buff, $buf2, @dirEnd, $trackIndent, %trackTypes, $struct, %seekInfo, %seek);
|
|
933
953
|
|
|
934
954
|
$raf->Read($buff, 4) == 4 or return 0;
|
|
935
955
|
return 0 unless $buff =~ /^\x1a\x45\xdf\xa3/;
|
|
@@ -952,6 +972,7 @@ sub ProcessMKV($$)
|
|
|
952
972
|
my $processAll = ($verbose or $et->Options('Unknown') > 1) ? 2 : 0;
|
|
953
973
|
++$processAll if $et->Options('ExtractEmbedded');
|
|
954
974
|
$$et{TrackTypes} = \%trackTypes; # store Track types reference
|
|
975
|
+
$$et{SeekHeadOffset} = 0;
|
|
955
976
|
my $oldIndent = $$et{INDENT};
|
|
956
977
|
my $chapterNum = 0;
|
|
957
978
|
my $dirName = 'MKV';
|
|
@@ -960,6 +981,16 @@ sub ProcessMKV($$)
|
|
|
960
981
|
for (;;) {
|
|
961
982
|
while (@dirEnd) {
|
|
962
983
|
if ($pos + $dataPos >= $dirEnd[-1][0]) {
|
|
984
|
+
if ($dirEnd[-1][1] eq 'Seek') {
|
|
985
|
+
# save seek info
|
|
986
|
+
if (defined $seekInfo{ID} and defined $seekInfo{Position}) {
|
|
987
|
+
my $seekTag = $$tagTablePtr{$seekInfo{ID}};
|
|
988
|
+
if (ref $seekTag eq 'HASH' and $$seekTag{Name}) {
|
|
989
|
+
$seek{$$seekTag{Name}} = $seekInfo{Position} + $$et{SeekHeadOffset};
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
undef %seekInfo;
|
|
993
|
+
}
|
|
963
994
|
pop @dirEnd;
|
|
964
995
|
if ($struct) {
|
|
965
996
|
if (@dirEnd and $dirEnd[-1][2]) {
|
|
@@ -993,9 +1024,10 @@ sub ProcessMKV($$)
|
|
|
993
1024
|
}
|
|
994
1025
|
my $tag = GetVInt($buff, $pos);
|
|
995
1026
|
last unless defined $tag and $tag >= 0;
|
|
1027
|
+
$$et{SeekHeadOffset} = $pos if $tag == 0x14d9b74; # save offset of seek head
|
|
996
1028
|
my $size = GetVInt($buff, $pos);
|
|
997
1029
|
last unless defined $size;
|
|
998
|
-
my $unknownSize;
|
|
1030
|
+
my ($unknownSize, $seekInfoOnly);
|
|
999
1031
|
$size < 0 and $unknownSize = 1, $size = 1e20;
|
|
1000
1032
|
if (@dirEnd and $pos + $dataPos + $size > $dirEnd[-1][0]) {
|
|
1001
1033
|
$et->Warn("Invalid or corrupted $dirEnd[-1][1] master element");
|
|
@@ -1010,14 +1042,28 @@ sub ProcessMKV($$)
|
|
|
1010
1042
|
next;
|
|
1011
1043
|
}
|
|
1012
1044
|
my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
|
|
1013
|
-
|
|
1045
|
+
if (not $tagInfo and ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{SeekInfo}) {
|
|
1046
|
+
$tagInfo = $$tagTablePtr{$tag};
|
|
1047
|
+
$seekInfoOnly = 1;
|
|
1048
|
+
}
|
|
1014
1049
|
if ($tagInfo) {
|
|
1015
1050
|
if ($$tagInfo{SubDirectory}) {
|
|
1016
1051
|
# stop processing at first cluster unless we are using -v -U or -ee
|
|
1052
|
+
# or there are Tags after this
|
|
1017
1053
|
if ($$tagInfo{Name} eq 'Cluster' and $processAll < 2) {
|
|
1018
|
-
|
|
1054
|
+
# jump to Tags if possible
|
|
1055
|
+
unless ($processAll) {
|
|
1056
|
+
if ($seek{Tags} and $seek{Tags} > $pos + $dataPos and $raf->Seek($seek{Tags},0)) {
|
|
1057
|
+
$buff = '';
|
|
1058
|
+
$dataPos = $seek{Tags};
|
|
1059
|
+
$pos = $dataLen = 0;
|
|
1060
|
+
next;
|
|
1061
|
+
}
|
|
1062
|
+
last;
|
|
1063
|
+
}
|
|
1019
1064
|
undef $tagInfo; # just skip the Cluster when -ee is used
|
|
1020
1065
|
} else {
|
|
1066
|
+
# just fall through into the contained EBML elements
|
|
1021
1067
|
$$et{INDENT} .= '| ';
|
|
1022
1068
|
$et->VerboseDir($$tagTablePtr{$tag}{Name}, undef, $size);
|
|
1023
1069
|
$dirName = $$tagInfo{Name};
|
|
@@ -1040,7 +1086,12 @@ sub ProcessMKV($$)
|
|
|
1040
1086
|
# just skip unknown and large data blocks
|
|
1041
1087
|
if (not $tagInfo or $more > 10000000) {
|
|
1042
1088
|
# don't try to skip very large blocks unless LargeFileSupport is enabled
|
|
1043
|
-
|
|
1089
|
+
if ($more >= 0x80000000) {
|
|
1090
|
+
last unless $et->Options('LargeFileSupport');
|
|
1091
|
+
if ($et->Options('LargeFileSupport') eq '2') {
|
|
1092
|
+
$et->WarnOnce('Processing large block (LargeFileSupport is 2)');
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1044
1095
|
$raf->Seek($more, 1) or last;
|
|
1045
1096
|
$buff = '';
|
|
1046
1097
|
$dataPos += $dataLen + $more;
|
|
@@ -1118,6 +1169,11 @@ sub ProcessMKV($$)
|
|
|
1118
1169
|
if ($$tagInfo{NoSave} or $struct) {
|
|
1119
1170
|
$et->VerboseInfo($tag, $tagInfo, Value => $val, %parms) if $verbose;
|
|
1120
1171
|
$$struct{$$tagInfo{Name}} = $val if $struct;
|
|
1172
|
+
} elsif ($$tagInfo{SeekInfo}) {
|
|
1173
|
+
my $p = $pos;
|
|
1174
|
+
$val = GetVInt($buff, $p) unless defined $val;
|
|
1175
|
+
$seekInfo{$$tagInfo{SeekInfo}} = $val;
|
|
1176
|
+
$et->HandleTag($tagTablePtr, $tag, $val, %parms) unless $seekInfoOnly;
|
|
1121
1177
|
} else {
|
|
1122
1178
|
$et->HandleTag($tagTablePtr, $tag, $val, %parms);
|
|
1123
1179
|
}
|
|
@@ -203,13 +203,13 @@ sub WriteMRW($$;$);
|
|
|
203
203
|
Name => 'ColorMode',
|
|
204
204
|
Condition => '$$self{Make} !~ /^SONY/',
|
|
205
205
|
Priority => 0,
|
|
206
|
-
Writable =>
|
|
206
|
+
Writable => 1,
|
|
207
207
|
PrintConv => \%Image::ExifTool::Minolta::minoltaColorMode,
|
|
208
208
|
},
|
|
209
209
|
{ #3
|
|
210
210
|
Name => 'ColorMode',
|
|
211
211
|
Condition => '$$self{Model} eq "DSLR-A100"',
|
|
212
|
-
Writable =>
|
|
212
|
+
Writable => 1,
|
|
213
213
|
Notes => 'Sony A100',
|
|
214
214
|
Priority => 0,
|
|
215
215
|
PrintHex => 1,
|
|
@@ -65,7 +65,7 @@ use Image::ExifTool::Exif;
|
|
|
65
65
|
use Image::ExifTool::GPS;
|
|
66
66
|
use Image::ExifTool::XMP;
|
|
67
67
|
|
|
68
|
-
$VERSION = '4.
|
|
68
|
+
$VERSION = '4.35';
|
|
69
69
|
|
|
70
70
|
sub LensIDConv($$$);
|
|
71
71
|
sub ProcessNikonAVI($$$);
|
|
@@ -720,6 +720,7 @@ sub GetAFPointGrid($$;$);
|
|
|
720
720
|
'9A 4C 50 50 14 14 9C 06' => 'Yongnuo YN50mm F1.8N',
|
|
721
721
|
'9F 48 48 48 24 24 A1 06' => 'Yongnuo YN40mm F2.8N', #30
|
|
722
722
|
'9F 54 68 68 18 18 A2 06' => 'Yongnuo YN100mm F2N', #30
|
|
723
|
+
'9F 4C 44 44 18 18 A1 06' => 'Yongnuo YN35mm F2', #30
|
|
723
724
|
#
|
|
724
725
|
'02 40 44 5C 2C 34 02 00' => 'Exakta AF 35-70mm 1:3.5-4.5 MC',
|
|
725
726
|
#
|
|
@@ -11710,7 +11711,7 @@ my %nikonFocalConversions = (
|
|
|
11710
11711
|
},
|
|
11711
11712
|
10 => {
|
|
11712
11713
|
Name => 'NEFCompression',
|
|
11713
|
-
|
|
11714
|
+
Format => 'int16u',
|
|
11714
11715
|
SeparateTable => 'NEFCompression',
|
|
11715
11716
|
PrintConv => \%nefCompression,
|
|
11716
11717
|
},
|
|
@@ -13688,6 +13689,24 @@ sub ProcessNikonCaptureOffsets($$$)
|
|
|
13688
13689
|
return $success;
|
|
13689
13690
|
}
|
|
13690
13691
|
|
|
13692
|
+
#------------------------------------------------------------------------------
|
|
13693
|
+
# Read Nikon NKA file
|
|
13694
|
+
# Inputs: 0) ExifTool ref, 1) dirInfo ref
|
|
13695
|
+
# Returns: 1 on success
|
|
13696
|
+
sub ProcessNKA($$)
|
|
13697
|
+
{
|
|
13698
|
+
my ($et, $dirInfo) = @_;
|
|
13699
|
+
my $raf = $$et{RAF};
|
|
13700
|
+
my $buff;
|
|
13701
|
+
$raf->Read($buff, 0x35) == 0x35 or return 0;
|
|
13702
|
+
my $len = unpack('x49V', $buff);
|
|
13703
|
+
$raf->Read($buff, $len) == $len or return 0;
|
|
13704
|
+
$et->SetFileType('NKA', 'application/x-nikon-nxstudio');
|
|
13705
|
+
my %dirInfo = ( DataPt => \$buff, DataPos => 0x35 );
|
|
13706
|
+
my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::XML');
|
|
13707
|
+
return $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
|
13708
|
+
}
|
|
13709
|
+
|
|
13691
13710
|
#------------------------------------------------------------------------------
|
|
13692
13711
|
# Read/write Nikon MakerNotes directory
|
|
13693
13712
|
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|
|
@@ -1935,6 +1935,7 @@ my %indexInfo = (
|
|
|
1935
1935
|
3 => 'Trains',
|
|
1936
1936
|
4 => 'Birds',
|
|
1937
1937
|
5 => 'Dogs & Cats',
|
|
1938
|
+
6 => 'Human', #forum16072
|
|
1938
1939
|
},{
|
|
1939
1940
|
0 => 'Object Not Found',
|
|
1940
1941
|
1 => 'Object Found',
|
|
@@ -2842,24 +2843,32 @@ my %indexInfo = (
|
|
|
2842
2843
|
RawConv => '$val=~s/\0+$//; $val', # (may be null terminated)
|
|
2843
2844
|
Count => 4,
|
|
2844
2845
|
},
|
|
2845
|
-
0x100 => {
|
|
2846
|
+
0x100 => { #6
|
|
2847
|
+
Name => 'WB_RBLevels',
|
|
2848
|
+
Writable => 'int16u',
|
|
2849
|
+
Notes => q{
|
|
2850
|
+
These tags store 2 values, red and blue levels, for some models, but 4
|
|
2851
|
+
values, presumably RBGG levels, for other models
|
|
2852
|
+
},
|
|
2853
|
+
Count => -1,
|
|
2854
|
+
}, #6
|
|
2846
2855
|
# 0x101 - in-camera AutoWB unless it is all 0's or all 256's (ref IB)
|
|
2847
|
-
0x102 => { Name => 'WB_RBLevels3000K', Writable => 'int16u', Count =>
|
|
2848
|
-
0x103 => { Name => 'WB_RBLevels3300K', Writable => 'int16u', Count =>
|
|
2849
|
-
0x104 => { Name => 'WB_RBLevels3600K', Writable => 'int16u', Count =>
|
|
2850
|
-
0x105 => { Name => 'WB_RBLevels3900K', Writable => 'int16u', Count =>
|
|
2851
|
-
0x106 => { Name => 'WB_RBLevels4000K', Writable => 'int16u', Count =>
|
|
2852
|
-
0x107 => { Name => 'WB_RBLevels4300K', Writable => 'int16u', Count =>
|
|
2853
|
-
0x108 => { Name => 'WB_RBLevels4500K', Writable => 'int16u', Count =>
|
|
2854
|
-
0x109 => { Name => 'WB_RBLevels4800K', Writable => 'int16u', Count =>
|
|
2855
|
-
0x10a => { Name => 'WB_RBLevels5300K', Writable => 'int16u', Count =>
|
|
2856
|
-
0x10b => { Name => 'WB_RBLevels6000K', Writable => 'int16u', Count =>
|
|
2857
|
-
0x10c => { Name => 'WB_RBLevels6600K', Writable => 'int16u', Count =>
|
|
2858
|
-
0x10d => { Name => 'WB_RBLevels7500K', Writable => 'int16u', Count =>
|
|
2859
|
-
0x10e => { Name => 'WB_RBLevelsCWB1', Writable => 'int16u', Count =>
|
|
2860
|
-
0x10f => { Name => 'WB_RBLevelsCWB2', Writable => 'int16u', Count =>
|
|
2861
|
-
0x110 => { Name => 'WB_RBLevelsCWB3', Writable => 'int16u', Count =>
|
|
2862
|
-
0x111 => { Name => 'WB_RBLevelsCWB4', Writable => 'int16u', Count =>
|
|
2856
|
+
0x102 => { Name => 'WB_RBLevels3000K', Writable => 'int16u', Count => -1 }, #11
|
|
2857
|
+
0x103 => { Name => 'WB_RBLevels3300K', Writable => 'int16u', Count => -1 }, #11
|
|
2858
|
+
0x104 => { Name => 'WB_RBLevels3600K', Writable => 'int16u', Count => -1 }, #11
|
|
2859
|
+
0x105 => { Name => 'WB_RBLevels3900K', Writable => 'int16u', Count => -1 }, #11
|
|
2860
|
+
0x106 => { Name => 'WB_RBLevels4000K', Writable => 'int16u', Count => -1 }, #11
|
|
2861
|
+
0x107 => { Name => 'WB_RBLevels4300K', Writable => 'int16u', Count => -1 }, #11
|
|
2862
|
+
0x108 => { Name => 'WB_RBLevels4500K', Writable => 'int16u', Count => -1 }, #11
|
|
2863
|
+
0x109 => { Name => 'WB_RBLevels4800K', Writable => 'int16u', Count => -1 }, #11
|
|
2864
|
+
0x10a => { Name => 'WB_RBLevels5300K', Writable => 'int16u', Count => -1 }, #11
|
|
2865
|
+
0x10b => { Name => 'WB_RBLevels6000K', Writable => 'int16u', Count => -1 }, #11
|
|
2866
|
+
0x10c => { Name => 'WB_RBLevels6600K', Writable => 'int16u', Count => -1 }, #11
|
|
2867
|
+
0x10d => { Name => 'WB_RBLevels7500K', Writable => 'int16u', Count => -1 }, #11
|
|
2868
|
+
0x10e => { Name => 'WB_RBLevelsCWB1', Writable => 'int16u', Count => -1 }, #11
|
|
2869
|
+
0x10f => { Name => 'WB_RBLevelsCWB2', Writable => 'int16u', Count => -1 }, #11
|
|
2870
|
+
0x110 => { Name => 'WB_RBLevelsCWB3', Writable => 'int16u', Count => -1 }, #11
|
|
2871
|
+
0x111 => { Name => 'WB_RBLevelsCWB4', Writable => 'int16u', Count => -1 }, #11
|
|
2863
2872
|
0x113 => { Name => 'WB_GLevel3000K', Writable => 'int16u' }, #11
|
|
2864
2873
|
0x114 => { Name => 'WB_GLevel3300K', Writable => 'int16u' }, #11
|
|
2865
2874
|
0x115 => { Name => 'WB_GLevel3600K', Writable => 'int16u' }, #11
|
|
@@ -3246,6 +3255,7 @@ my %indexInfo = (
|
|
|
3246
3255
|
3 => 'Trains',
|
|
3247
3256
|
4 => 'Birds',
|
|
3248
3257
|
5 => 'Dogs & Cats',
|
|
3258
|
+
6 => 'Human', #forum16072
|
|
3249
3259
|
},{
|
|
3250
3260
|
0 => 'Face Priority',
|
|
3251
3261
|
1 => 'Target Priority',
|
|
@@ -366,6 +366,7 @@ my %shootingMode = (
|
|
|
366
366
|
'32 1' => '3-area (left)?', # (DMC-L1 guess)
|
|
367
367
|
'32 2' => '3-area (center)?', # (DMC-L1 guess)
|
|
368
368
|
'32 3' => '3-area (right)?', # (DMC-L1 guess)
|
|
369
|
+
# '32 16' ? (DC-GH6)
|
|
369
370
|
'64 0' => 'Face Detect',
|
|
370
371
|
'64 1' => 'Face Detect (animal detect on)', #forum11194
|
|
371
372
|
'64 2' => 'Face Detect (animal detect off)', #forum11194
|
|
@@ -218,6 +218,7 @@ my %panasonicWhiteBalance = ( #forum9396
|
|
|
218
218
|
0x30 => { Name => 'CropLeft', Writable => 'int16u' },
|
|
219
219
|
0x31 => { Name => 'CropBottom', Writable => 'int16u' },
|
|
220
220
|
0x32 => { Name => 'CropRight', Writable => 'int16u' },
|
|
221
|
+
0x37 => { Name => 'ISO', Writable => 'int32u' },
|
|
221
222
|
# 0x44 - may contain another pointer to the raw data starting at byte 2 in this data (DC-GH6)
|
|
222
223
|
0x10f => {
|
|
223
224
|
Name => 'Make',
|