exiftool-vendored.pl 12.42.0 → 12.43.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 +22 -0
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +2 -2
- package/bin/exiftool +2 -2
- package/bin/lib/Image/ExifTool/Apple.pm +11 -2
- package/bin/lib/Image/ExifTool/Canon.pm +33 -27
- package/bin/lib/Image/ExifTool/DJI.pm +2 -1
- package/bin/lib/Image/ExifTool/DarwinCore.pm +12 -1
- package/bin/lib/Image/ExifTool/FlashPix.pm +14 -1
- package/bin/lib/Image/ExifTool/FujiFilm.pm +21 -2
- package/bin/lib/Image/ExifTool/Geotag.pm +24 -4
- package/bin/lib/Image/ExifTool/LNK.pm +5 -2
- package/bin/lib/Image/ExifTool/Nikon.pm +15 -6
- package/bin/lib/Image/ExifTool/Olympus.pm +1 -1
- package/bin/lib/Image/ExifTool/Parrot.pm +1 -0
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +38 -6
- package/bin/lib/Image/ExifTool/README +5 -1
- package/bin/lib/Image/ExifTool/Sony.pm +29 -27
- package/bin/lib/Image/ExifTool/TagLookup.pm +2493 -2479
- package/bin/lib/Image/ExifTool/TagNames.pod +77 -59
- package/bin/lib/Image/ExifTool/WritePhotoshop.pl +5 -5
- package/bin/lib/Image/ExifTool/Writer.pl +1 -0
- package/bin/lib/Image/ExifTool.pm +31 -7
- package/bin/lib/Image/ExifTool.pod +13 -4
- package/bin/perl-Image-ExifTool.spec +1 -1
- package/bin/pp_build_exe.args +4 -4
- package/package.json +1 -1
package/bin/Changes
CHANGED
|
@@ -7,6 +7,28 @@ RSS feed: https://exiftool.org/rss.xml
|
|
|
7
7
|
Note: The most recent production release is Version 12.42. (Other versions are
|
|
8
8
|
considered development releases, and are not uploaded to MetaCPAN.)
|
|
9
9
|
|
|
10
|
+
July 6, 2022 - Version 12.43
|
|
11
|
+
|
|
12
|
+
- Added the ability to geotag from Google Takeout JSON files
|
|
13
|
+
- Added a few new Canon RF LensType values and a couple of new CanonModelID's
|
|
14
|
+
(thanks Norbert Wasser)
|
|
15
|
+
- Added new values to a couple of FujiFilm tags (thanks Greybeard)
|
|
16
|
+
- Added a new Nikon LensID (thanks BertJan Bakker)
|
|
17
|
+
- Recognize Autodesk Revit files (but don't yet support reading metadata)
|
|
18
|
+
- Decode DriveSerialNumber from LNK files (github #145)
|
|
19
|
+
- Decode Apple FocusDistanceRange (thanks Neal Krawetz)
|
|
20
|
+
- Made a number of Sony SR2SubIFD tags writable
|
|
21
|
+
- Tolerate dashes instead of colons as date separators in -geotag CSV files
|
|
22
|
+
- Patched to read new format accelerometer data from Insta360 files
|
|
23
|
+
- Patched to avoid outputting some Unknown tags when the -validate option is
|
|
24
|
+
used after a previously -execute'd command used the -u option
|
|
25
|
+
- Fixed names of Canon G9 WB levels tags (changed from GRGB to GRBG) (thanks
|
|
26
|
+
Christoph)
|
|
27
|
+
- Fixed typo in new Olympus AISubjectTrackingMode value
|
|
28
|
+
- Fixed "use of undefined value" warning when reading DJI metadata
|
|
29
|
+
- API Changes:
|
|
30
|
+
- Added IgnoreTags option
|
|
31
|
+
|
|
10
32
|
June 1, 2022 - Version 12.42 (production release)
|
|
11
33
|
|
|
12
34
|
- Added support for reading maker notes from Panasonic DC-GH6 videos
|
package/bin/META.json
CHANGED
package/bin/META.yml
CHANGED
package/bin/README
CHANGED
|
@@ -107,8 +107,8 @@ your home directory, then you would type the following commands in a
|
|
|
107
107
|
terminal window to extract and run ExifTool:
|
|
108
108
|
|
|
109
109
|
cd ~/Desktop
|
|
110
|
-
gzip -dc Image-ExifTool-12.
|
|
111
|
-
cd Image-ExifTool-12.
|
|
110
|
+
gzip -dc Image-ExifTool-12.43.tar.gz | tar -xf -
|
|
111
|
+
cd Image-ExifTool-12.43
|
|
112
112
|
./exiftool t/images/ExifTool.jpg
|
|
113
113
|
|
|
114
114
|
Note: These commands extract meta information from one of the test images.
|
package/bin/exiftool
CHANGED
|
@@ -11,7 +11,7 @@ use strict;
|
|
|
11
11
|
use warnings;
|
|
12
12
|
require 5.004;
|
|
13
13
|
|
|
14
|
-
my $version = '12.
|
|
14
|
+
my $version = '12.43';
|
|
15
15
|
|
|
16
16
|
# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
|
|
17
17
|
BEGIN {
|
|
@@ -5467,7 +5467,7 @@ with this command:
|
|
|
5467
5467
|
|
|
5468
5468
|
produces output like this:
|
|
5469
5469
|
|
|
5470
|
-
-- Generated by ExifTool 12.
|
|
5470
|
+
-- Generated by ExifTool 12.43 --
|
|
5471
5471
|
File: a.jpg - 2003:10:31 15:44:19
|
|
5472
5472
|
(f/5.6, 1/60s, ISO 100)
|
|
5473
5473
|
File: b.jpg - 2006:05:23 11:57:38
|
|
@@ -15,7 +15,7 @@ use vars qw($VERSION);
|
|
|
15
15
|
use Image::ExifTool::Exif;
|
|
16
16
|
use Image::ExifTool::PLIST;
|
|
17
17
|
|
|
18
|
-
$VERSION = '1.
|
|
18
|
+
$VERSION = '1.06';
|
|
19
19
|
|
|
20
20
|
# Apple iPhone metadata (ref PH)
|
|
21
21
|
%Image::ExifTool::Apple::Main = (
|
|
@@ -66,7 +66,16 @@ $VERSION = '1.05';
|
|
|
66
66
|
Writable => 'string',
|
|
67
67
|
Notes => 'unique ID for all images in a burst',
|
|
68
68
|
},
|
|
69
|
-
#
|
|
69
|
+
0x000c => { # ref forum13710 (Neal Krawetz)
|
|
70
|
+
Name => 'FocusDistanceRange',
|
|
71
|
+
Writable => 'rational64s',
|
|
72
|
+
Count => 2,
|
|
73
|
+
PrintConv => q{
|
|
74
|
+
my @a = split ' ', $val;
|
|
75
|
+
sprintf('%.2f - %.2f m', $a[0] <= $a[1] ? @a : reverse @a);
|
|
76
|
+
},
|
|
77
|
+
PrintConvInv => '$val =~ s/ - //; $val =~ s/ ?m$//; $val',
|
|
78
|
+
},
|
|
70
79
|
# 0x000d - int32s: 0,1,6,20,24,32,40
|
|
71
80
|
# 0x000e - int32s: 0,1,4,12 (Orientation? 0=landscape? 4=portrait? ref 1)
|
|
72
81
|
# 0x000f - int32s: 2,3
|
|
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
|
|
|
88
88
|
sub ProcessExifInfo($$$);
|
|
89
89
|
sub SwapWords($);
|
|
90
90
|
|
|
91
|
-
$VERSION = '4.
|
|
91
|
+
$VERSION = '4.59';
|
|
92
92
|
|
|
93
93
|
# Note: Removed 'USM' from 'L' lenses since it is redundant - PH
|
|
94
94
|
# (or is it? Ref 32 shows 5 non-USM L-type lenses)
|
|
@@ -597,21 +597,23 @@ $VERSION = '4.58';
|
|
|
597
597
|
'61182.19' => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF1.4x',
|
|
598
598
|
'61182.20' => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF2x',
|
|
599
599
|
'61182.21' => 'Canon RF 70-200mm F4L IS USM', #42
|
|
600
|
-
'61182.22' => 'Canon RF
|
|
601
|
-
'61182.23' => 'Canon RF
|
|
602
|
-
'61182.24' => 'Canon RF
|
|
603
|
-
'61182.25' => 'Canon RF
|
|
604
|
-
'61182.26' => 'Canon RF 100-400mm F5.6-8 IS USM
|
|
605
|
-
'61182.27' => 'Canon RF
|
|
606
|
-
'61182.28' => 'Canon RF 400mm
|
|
607
|
-
'61182.29' => 'Canon RF
|
|
608
|
-
'61182.30' => 'Canon RF
|
|
609
|
-
'61182.31' => 'Canon RF
|
|
600
|
+
'61182.22' => 'Canon RF 100mm F2.8L MACRO IS USM', #42
|
|
601
|
+
'61182.23' => 'Canon RF 50mm F1.8 STM', #42
|
|
602
|
+
'61182.24' => 'Canon RF 14-35mm F4L IS USM', #IB
|
|
603
|
+
'61182.25' => 'Canon RF-S 18-45mm F4.5-6.3 IS STM', #42
|
|
604
|
+
'61182.26' => 'Canon RF 100-400mm F5.6-8 IS USM', #42
|
|
605
|
+
'61182.27' => 'Canon RF 100-400mm F5.6-8 IS USM + RF1.4x', #42 (NC)
|
|
606
|
+
'61182.28' => 'Canon RF 100-400mm F5.6-8 IS USM + RF2x', #42 (NC)
|
|
607
|
+
'61182.29' => 'Canon RF-S 18-150mm F3.5-6.3 IS STM', #42
|
|
608
|
+
'61182.30' => 'Canon RF 16mm F2.8 STM', #42
|
|
609
|
+
'61182.31' => 'Canon RF 400mm F2.8L IS USM', #IB
|
|
610
|
+
'61182.32' => 'Canon RF 400mm F2.8L IS USM + RF1.4x', #IB
|
|
611
|
+
'61182.33' => 'Canon RF 400mm F2.8L IS USM + RF2x', #IB
|
|
612
|
+
'61182.34' => 'Canon RF 600mm F4L IS USM', #GiaZopatti
|
|
610
613
|
# we need the RFLensType values for the following...
|
|
611
|
-
'61182.
|
|
612
|
-
'61182.
|
|
613
|
-
'61182.
|
|
614
|
-
'61182.35' => 'Canon RF 100mm F2.8L MACRO IS USM', #(NC)
|
|
614
|
+
'61182.35' => 'Canon RF 800mm F5.6L IS USM', #PH (NC)
|
|
615
|
+
'61182.36' => 'Canon RF 1200mm F8L IS USM', #PH (NC)
|
|
616
|
+
'61182.37' => 'Canon RF 5.2mm F2.8L Dual Fisheye 3D VR', #PH (NC)
|
|
615
617
|
65535 => 'n/a',
|
|
616
618
|
);
|
|
617
619
|
|
|
@@ -968,6 +970,8 @@ $VERSION = '4.58';
|
|
|
968
970
|
0x80000437 => 'EOS 90D', #IB
|
|
969
971
|
0x80000450 => 'EOS R3', #42
|
|
970
972
|
0x80000453 => 'EOS R6', #PH
|
|
973
|
+
0x80000464 => 'EOS R7', #42
|
|
974
|
+
0x80000465 => 'EOS R10', #42
|
|
971
975
|
0x80000467 => 'PowerShot ZOOM',
|
|
972
976
|
0x80000468 => 'EOS M50 Mark II / Kiss M2', #IB
|
|
973
977
|
0x80000520 => 'EOS D2000C', #IB
|
|
@@ -6530,23 +6534,23 @@ my %ciMaxFocal = (
|
|
|
6530
6534
|
0x02 => 'FacesDetected',
|
|
6531
6535
|
);
|
|
6532
6536
|
|
|
6533
|
-
# G9 white balance information (MakerNotes tag 0x29) (ref IB)
|
|
6537
|
+
# G9 white balance information (MakerNotes tag 0x29) (ref IB, changed ref forum13640)
|
|
6534
6538
|
%Image::ExifTool::Canon::WBInfo = (
|
|
6535
6539
|
%binaryDataAttrs,
|
|
6536
6540
|
NOTES => 'WB tags for the Canon G9.',
|
|
6537
6541
|
FORMAT => 'int32u',
|
|
6538
6542
|
FIRST_ENTRY => 1,
|
|
6539
6543
|
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
|
|
6540
|
-
0x02 => { Name => '
|
|
6541
|
-
0x0a => { Name => '
|
|
6542
|
-
0x12 => { Name => '
|
|
6543
|
-
0x1a => { Name => '
|
|
6544
|
-
0x22 => { Name => '
|
|
6545
|
-
0x2a => { Name => '
|
|
6546
|
-
0x32 => { Name => '
|
|
6547
|
-
0x3a => { Name => '
|
|
6548
|
-
0x42 => { Name => '
|
|
6549
|
-
0x4a => { Name => '
|
|
6544
|
+
0x02 => { Name => 'WB_GRBGLevelsAuto', Format => 'int32s[4]' },
|
|
6545
|
+
0x0a => { Name => 'WB_GRBGLevelsDaylight', Format => 'int32s[4]' },
|
|
6546
|
+
0x12 => { Name => 'WB_GRBGLevelsCloudy', Format => 'int32s[4]' },
|
|
6547
|
+
0x1a => { Name => 'WB_GRBGLevelsTungsten', Format => 'int32s[4]' },
|
|
6548
|
+
0x22 => { Name => 'WB_GRBGLevelsFluorescent', Format => 'int32s[4]' },
|
|
6549
|
+
0x2a => { Name => 'WB_GRBGLevelsFluorHigh', Format => 'int32s[4]' },
|
|
6550
|
+
0x32 => { Name => 'WB_GRBGLevelsFlash', Format => 'int32s[4]' },
|
|
6551
|
+
0x3a => { Name => 'WB_GRBGLevelsUnderwater', Format => 'int32s[4]' },
|
|
6552
|
+
0x42 => { Name => 'WB_GRBGLevelsCustom1', Format => 'int32s[4]' },
|
|
6553
|
+
0x4a => { Name => 'WB_GRBGLevelsCustom2', Format => 'int32s[4]' },
|
|
6550
6554
|
);
|
|
6551
6555
|
|
|
6552
6556
|
# yet more face detect information (MakerNotes tag 0x2f) - PH (G12)
|
|
@@ -6803,17 +6807,19 @@ my %ciMaxFocal = (
|
|
|
6803
6807
|
276 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF1.4x',
|
|
6804
6808
|
277 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF2x',
|
|
6805
6809
|
278 => 'Canon RF 70-200mm F4L IS USM', #42
|
|
6810
|
+
279 => 'Canon RF 100mm F2.8L MACRO IS USM', #42
|
|
6806
6811
|
280 => 'Canon RF 50mm F1.8 STM', #42
|
|
6807
6812
|
281 => 'Canon RF 14-35mm F4L IS USM', #42/IB
|
|
6813
|
+
282 => 'Canon RF-S 18-45mm F4.5-6.3 IS STM', #42
|
|
6808
6814
|
283 => 'Canon RF 100-400mm F5.6-8 IS USM', #42
|
|
6809
6815
|
284 => 'Canon RF 100-400mm F5.6-8 IS USM + RF1.4x', #42 (NC)
|
|
6810
6816
|
285 => 'Canon RF 100-400mm F5.6-8 IS USM + RF2x', #42 (NC)
|
|
6817
|
+
286 => 'Canon RF-S 18-150mm F3.5-6.3 IS STM', #42
|
|
6811
6818
|
288 => 'Canon RF 16mm F2.8 STM', #42
|
|
6812
6819
|
289 => 'Canon RF 400mm F2.8L IS USM', #IB
|
|
6813
6820
|
290 => 'Canon RF 400mm F2.8L IS USM + RF1.4x', #IB
|
|
6814
6821
|
291 => 'Canon RF 400mm F2.8L IS USM + RF2x', #IB
|
|
6815
6822
|
292 => 'Canon RF 600mm F4L IS USM', #GiaZopatti
|
|
6816
|
-
#xxx => 'Canon RF 100mm F2.8L MACRO IS USM',
|
|
6817
6823
|
# Note: add new RF lenses to %canonLensTypes with ID 61182
|
|
6818
6824
|
},
|
|
6819
6825
|
},
|
|
@@ -16,7 +16,7 @@ use Image::ExifTool::Exif;
|
|
|
16
16
|
use Image::ExifTool::XMP;
|
|
17
17
|
use Image::ExifTool::GPS;
|
|
18
18
|
|
|
19
|
-
$VERSION = '1.
|
|
19
|
+
$VERSION = '1.06';
|
|
20
20
|
|
|
21
21
|
sub ProcessDJIInfo($$$);
|
|
22
22
|
|
|
@@ -176,6 +176,7 @@ sub ProcessDJIInfo($$$)
|
|
|
176
176
|
}
|
|
177
177
|
while ($$dataPt =~ /\G\[(.*?)\](?=(\[|$))/sg) {
|
|
178
178
|
my ($tag, $val) = split /:/, $1, 2;
|
|
179
|
+
next unless defined $tag and defined $val;
|
|
179
180
|
if ($val =~ /^([\x20-\x7f]+)\0*$/) {
|
|
180
181
|
$val = $1;
|
|
181
182
|
} else {
|
|
@@ -15,7 +15,7 @@ use strict;
|
|
|
15
15
|
use vars qw($VERSION);
|
|
16
16
|
use Image::ExifTool::XMP;
|
|
17
17
|
|
|
18
|
-
$VERSION = '1.
|
|
18
|
+
$VERSION = '1.07';
|
|
19
19
|
|
|
20
20
|
my %dateTimeInfo = (
|
|
21
21
|
# NOTE: Do NOT put "Groups" here because Groups hash must not be common!
|
|
@@ -138,6 +138,9 @@ my %event = (
|
|
|
138
138
|
identificationVerificationStatus => { },
|
|
139
139
|
identifiedBy => { },
|
|
140
140
|
typeStatus => { },
|
|
141
|
+
# new, ref forum13707
|
|
142
|
+
identifiedByID => { },
|
|
143
|
+
verbatimIdentification => { },
|
|
141
144
|
},
|
|
142
145
|
},
|
|
143
146
|
LivingSpecimen => { Struct => \%materialSample },
|
|
@@ -189,6 +192,10 @@ my %event = (
|
|
|
189
192
|
recordNumber => { },
|
|
190
193
|
reproductiveCondition => { },
|
|
191
194
|
sex => { },
|
|
195
|
+
# new, ref forum13707
|
|
196
|
+
degreeOfEstablishment => { },
|
|
197
|
+
georeferenceVerificationStatus => { },
|
|
198
|
+
recordedByID => { },
|
|
192
199
|
},
|
|
193
200
|
},
|
|
194
201
|
OccurrenceOccurrenceDetails => { Name => 'OccurrenceDetails', Flat => 1 },
|
|
@@ -242,6 +249,7 @@ my %event = (
|
|
|
242
249
|
relationshipRemarks => { },
|
|
243
250
|
resourceID => { },
|
|
244
251
|
resourceRelationshipID => { },
|
|
252
|
+
relationshipOfResourceID => { }, # new, ref forum13707
|
|
245
253
|
},
|
|
246
254
|
},
|
|
247
255
|
Taxon => {
|
|
@@ -255,6 +263,7 @@ my %event = (
|
|
|
255
263
|
genus => { },
|
|
256
264
|
higherClassification => { },
|
|
257
265
|
infraspecificEpithet => { },
|
|
266
|
+
cultivarEpithet => { }, # new, ref forum13707
|
|
258
267
|
kingdom => { },
|
|
259
268
|
nameAccordingTo => { },
|
|
260
269
|
nameAccordingToID => { },
|
|
@@ -338,6 +347,8 @@ my %event = (
|
|
|
338
347
|
verbatimLongitude => { },
|
|
339
348
|
verbatimSRS => { },
|
|
340
349
|
waterBody => { },
|
|
350
|
+
# new, ref forum13707
|
|
351
|
+
verticalDatum => { },
|
|
341
352
|
},
|
|
342
353
|
},
|
|
343
354
|
);
|
|
@@ -21,7 +21,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
21
21
|
use Image::ExifTool::Exif;
|
|
22
22
|
use Image::ExifTool::ASF; # for GetGUID()
|
|
23
23
|
|
|
24
|
-
$VERSION = '1.
|
|
24
|
+
$VERSION = '1.40';
|
|
25
25
|
|
|
26
26
|
sub ProcessFPX($$);
|
|
27
27
|
sub ProcessFPXR($$$);
|
|
@@ -467,6 +467,19 @@ my %fpxFileType = (
|
|
|
467
467
|
ByteOrder => 'BigEndian',
|
|
468
468
|
},
|
|
469
469
|
},
|
|
470
|
+
# recognize Autodesk Revit files by looking at BasicFileInfo
|
|
471
|
+
# (but don't yet support reading their metatdata)
|
|
472
|
+
BasicFileInfo => {
|
|
473
|
+
Name => 'BasicFileInfo',
|
|
474
|
+
Binary => 1,
|
|
475
|
+
RawConv => q{
|
|
476
|
+
$val =~ tr/\0//d; # brute force conversion to ASCII
|
|
477
|
+
if ($val =~ /\.(rfa|rft|rte|rvt)/) {
|
|
478
|
+
$self->OverrideFileType(uc($1), "application/$1", $1);
|
|
479
|
+
}
|
|
480
|
+
return $val;
|
|
481
|
+
},
|
|
482
|
+
},
|
|
470
483
|
);
|
|
471
484
|
|
|
472
485
|
# Summary Information properties
|
|
@@ -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.81';
|
|
35
35
|
|
|
36
36
|
sub ProcessFujiDir($$$);
|
|
37
37
|
sub ProcessFaceRec($$$);
|
|
@@ -689,8 +689,9 @@ my %faceCategories = (
|
|
|
689
689
|
PrintConv => [{
|
|
690
690
|
0 => 'None',
|
|
691
691
|
1 => 'Optical', #PH
|
|
692
|
-
2 => 'Sensor-shift', #PH
|
|
692
|
+
2 => 'Sensor-shift', #PH (now IBIS/OIS, ref forum13708)
|
|
693
693
|
3 => 'OIS Lens', #forum9815 (optical+sensor?)
|
|
694
|
+
258 => 'IBIS/OIS + DIS', #forum13708 (digital on top of IBIS/OIS)
|
|
694
695
|
512 => 'Digital', #PH
|
|
695
696
|
},{
|
|
696
697
|
0 => 'Off',
|
|
@@ -841,6 +842,24 @@ my %faceCategories = (
|
|
|
841
842
|
1 => 'Face',
|
|
842
843
|
2 => 'Left Eye',
|
|
843
844
|
3 => 'Right Eye',
|
|
845
|
+
7 => 'Body',
|
|
846
|
+
8 => 'Head',
|
|
847
|
+
11 => 'Bike',
|
|
848
|
+
12 => 'Body of Car',
|
|
849
|
+
13 => 'Front of Car',
|
|
850
|
+
14 => 'Animal Body',
|
|
851
|
+
15 => 'Animal Head',
|
|
852
|
+
16 => 'Animal Face',
|
|
853
|
+
17 => 'Animal Left Eye',
|
|
854
|
+
18 => 'Animal Right Eye',
|
|
855
|
+
19 => 'Bird Body',
|
|
856
|
+
20 => 'Bird Head',
|
|
857
|
+
21 => 'Bird Left Eye',
|
|
858
|
+
22 => 'Bird Right Eye',
|
|
859
|
+
23 => 'Aircraft Body',
|
|
860
|
+
25 => 'Aircraft Cockpit',
|
|
861
|
+
26 => 'Train Front',
|
|
862
|
+
27 => 'Train Cockpit',
|
|
844
863
|
},'REPEAT'],
|
|
845
864
|
},
|
|
846
865
|
# 0x4202 int8u[-1] - number of cooredinates in each rectangle? (ref 11)
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
# 2019/07/02 - PH Added ability to read IMU CSV files
|
|
15
15
|
# 2019/11/10 - PH Also write pitch to CameraElevationAngle
|
|
16
16
|
# 2020/12/01 - PH Added ability to read DJI CSV log files
|
|
17
|
+
# 2022/06/21 - PH Added ability to read Google Takeout JSON files
|
|
17
18
|
#
|
|
18
19
|
# References: 1) http://www.topografix.com/GPX/1/1/
|
|
19
20
|
# 2) http://www.gpsinformation.org/dale/nmea.htm#GSA
|
|
@@ -28,7 +29,7 @@ use vars qw($VERSION);
|
|
|
28
29
|
use Image::ExifTool qw(:Public);
|
|
29
30
|
use Image::ExifTool::GPS;
|
|
30
31
|
|
|
31
|
-
$VERSION = '1.
|
|
32
|
+
$VERSION = '1.68';
|
|
32
33
|
|
|
33
34
|
sub JITTER() { return 2 } # maximum time jitter
|
|
34
35
|
|
|
@@ -133,7 +134,7 @@ sub LoadTrackLog($$;$)
|
|
|
133
134
|
local ($_, $/, *EXIFTOOL_TRKFILE);
|
|
134
135
|
my ($et, $val) = @_;
|
|
135
136
|
my ($raf, $from, $time, $isDate, $noDate, $noDateChanged, $lastDate, $dateFlarm);
|
|
136
|
-
my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings);
|
|
137
|
+
my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings, $sortFixes);
|
|
137
138
|
my ($canCut, $cutPDOP, $cutHDOP, $cutSats, $e0, $e1, @tmp, $trackFile, $trackTime);
|
|
138
139
|
|
|
139
140
|
unless (eval { require Time::Local }) {
|
|
@@ -285,6 +286,10 @@ sub LoadTrackLog($$;$)
|
|
|
285
286
|
}
|
|
286
287
|
}
|
|
287
288
|
next;
|
|
289
|
+
} elsif (/"(timelineObjects|placeVisit|activitySegment|latitudeE7)":/) {
|
|
290
|
+
# Google Takeout JSON format
|
|
291
|
+
$format = 'JSON';
|
|
292
|
+
$sortFixes = 1; # (fixes are not all in order for this format)
|
|
288
293
|
} else {
|
|
289
294
|
# search only first 50 lines of file for a valid fix
|
|
290
295
|
last if ++$skipped > 50;
|
|
@@ -506,6 +511,19 @@ DoneFix: $isDate = 1;
|
|
|
506
511
|
goto DoneFix;
|
|
507
512
|
}
|
|
508
513
|
next;
|
|
514
|
+
} elsif ($format eq 'JSON') {
|
|
515
|
+
# Google Takeout JSON format
|
|
516
|
+
if (/"(latitudeE7|longitudeE7|latE7|lngE7|timestamp)":\s*"?(.*?)"?,?\s*[\x0d\x0a]/) {
|
|
517
|
+
if ($1 eq 'timestamp') {
|
|
518
|
+
$time = GetTime($2);
|
|
519
|
+
goto DoneFix if $time and $$fix{lat} and $$fix{lon};
|
|
520
|
+
} elsif ($1 eq 'latitudeE7' or $1 eq 'latE7') {
|
|
521
|
+
$$fix{lat} = $2 * 1e-7;
|
|
522
|
+
} else {
|
|
523
|
+
$$fix{lon} = $2 * 1e-7;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
next;
|
|
509
527
|
}
|
|
510
528
|
my (%fix, $secs, $date, $nmea);
|
|
511
529
|
if ($format eq 'NMEA') {
|
|
@@ -751,6 +769,8 @@ DoneFix: $isDate = 1;
|
|
|
751
769
|
$numPoints -= $cutHDOP;
|
|
752
770
|
$numPoints -= $cutSats;
|
|
753
771
|
}
|
|
772
|
+
# sort fixes if necessary
|
|
773
|
+
@fixTimes = sort { $a <=> $b } @fixTimes if $sortFixes;
|
|
754
774
|
# mark first fix of the track
|
|
755
775
|
while (@fixTimes) {
|
|
756
776
|
$fix = $$points{$fixTimes[0]} or shift(@fixTimes), next;
|
|
@@ -1409,8 +1429,8 @@ This module is used by Image::ExifTool
|
|
|
1409
1429
|
This module loads GPS track logs, interpolates to determine position based
|
|
1410
1430
|
on time, and sets new GPS values for geotagging images. Currently supported
|
|
1411
1431
|
formats are GPX, NMEA RMC/GGA/GLL, KML, IGC, Garmin XML and TCX, Magellan
|
|
1412
|
-
PMGNTRK, Honeywell PTNTHPR, Winplus Beacon text,
|
|
1413
|
-
|
|
1432
|
+
PMGNTRK, Honeywell PTNTHPR, Bramor gEO, Winplus Beacon text, Google Takeout
|
|
1433
|
+
JSON, GPS/IMU CSV, DJI CSV, ExifTool CSV log files.
|
|
1414
1434
|
|
|
1415
1435
|
Methods in this module should not be called directly. Instead, the Geotag
|
|
1416
1436
|
feature is accessed by writing the values of the ExifTool Geotag, Geosync
|
|
@@ -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.08';
|
|
19
19
|
|
|
20
20
|
sub ProcessItemID($$$);
|
|
21
21
|
sub ProcessLinkInfo($$$);
|
|
@@ -273,7 +273,9 @@ sub ProcessLinkInfo($$$);
|
|
|
273
273
|
6 => 'Ram Disk',
|
|
274
274
|
},
|
|
275
275
|
},
|
|
276
|
-
DriveSerialNumber => {
|
|
276
|
+
DriveSerialNumber => {
|
|
277
|
+
PrintConv => 'join("-", unpack("A4 A4", sprintf("%08X", $val)))',
|
|
278
|
+
},
|
|
277
279
|
VolumeLabel => { },
|
|
278
280
|
LocalBasePath => { },
|
|
279
281
|
CommonNetworkRelLink => { },
|
|
@@ -508,6 +510,7 @@ sub ProcessLinkInfo($$$)
|
|
|
508
510
|
if ($off + 0x20 <= $dataLen) {
|
|
509
511
|
# my $len = Get32u($dataPt, $off);
|
|
510
512
|
$et->HandleTag($tagTablePtr, 'DriveType', undef, %opts, Start=>$off+4);
|
|
513
|
+
$et->HandleTag($tagTablePtr, 'DriveSerialNumber', undef, %opts, Start=>$off+8);
|
|
511
514
|
$pos = Get32u($dataPt, $off + 0x0c);
|
|
512
515
|
if ($pos == 0x14) {
|
|
513
516
|
# use VolumeLabelOffsetUnicode instead
|
|
@@ -63,7 +63,7 @@ use Image::ExifTool::Exif;
|
|
|
63
63
|
use Image::ExifTool::GPS;
|
|
64
64
|
use Image::ExifTool::XMP;
|
|
65
65
|
|
|
66
|
-
$VERSION = '4.
|
|
66
|
+
$VERSION = '4.07';
|
|
67
67
|
|
|
68
68
|
sub LensIDConv($$$);
|
|
69
69
|
sub ProcessNikonAVI($$$);
|
|
@@ -606,6 +606,7 @@ sub GetAFPointGrid($$;$);
|
|
|
606
606
|
'CC 44 68 98 34 41 DF 0E' => 'Tamron 100-400mm f/4.5-6.3 Di VC USD', #30
|
|
607
607
|
'EB 40 76 A6 38 40 DF 0E' => 'Tamron SP AF 150-600mm f/5-6.3 VC USD (A011)',
|
|
608
608
|
'E3 40 76 A6 38 40 DF 4E' => 'Tamron SP 150-600mm f/5-6.3 Di VC USD G2', #30
|
|
609
|
+
'E3 40 76 A6 38 40 DF 0E' => 'Tamron SP 150-600mm f/5-6.3 Di VC USD G2 (A022)', #forum3833
|
|
609
610
|
'20 3C 80 98 3D 3D 1E 02' => 'Tamron AF 200-400mm f/5.6 LD IF (75D)',
|
|
610
611
|
'00 3E 80 A0 38 3F 00 02' => 'Tamron SP AF 200-500mm f/5-6.3 Di LD (IF) (A08)',
|
|
611
612
|
'00 3F 80 A0 38 3F 00 02' => 'Tamron SP AF 200-500mm f/5-6.3 Di (A08)',
|
|
@@ -4026,7 +4027,7 @@ my %base64coord = (
|
|
|
4026
4027
|
},
|
|
4027
4028
|
Format => 'int16u',
|
|
4028
4029
|
},
|
|
4029
|
-
0x2f => { #28 (Z7)
|
|
4030
|
+
0x2f => { #28 (Z7) Still photography range 1-17 for the 493 point Z7 (arranged in a 29x17 grid. Center at x=16, y=10).
|
|
4030
4031
|
Name => 'AFFocusPointXPosition',
|
|
4031
4032
|
Condition => q{
|
|
4032
4033
|
$$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/ or
|
|
@@ -4194,11 +4195,19 @@ my %base64coord = (
|
|
|
4194
4195
|
},
|
|
4195
4196
|
0x43 => {
|
|
4196
4197
|
Name => 'FocusPositionHorizontal',
|
|
4197
|
-
|
|
4198
|
+
Notes => q{
|
|
4199
|
+
the focus points form a 29x17 grid, but the X,Y coordinate values run from 1,1
|
|
4200
|
+
to 30,19. The horizontal coordinate 11R (5) and the vertical coordinates 6U
|
|
4201
|
+
(4) and 2D (12) are not used for some reason
|
|
4202
|
+
},
|
|
4203
|
+
# 493 focus points for Z9 fall in a 30x19 grid
|
|
4204
|
+
# (the 11R (5) position is not used, for a total of 29 columns, ref AlbertShan email)
|
|
4205
|
+
PrintConv => sub { my ($val) = @_; PrintAFPointsLeftRight($val, 29); },
|
|
4198
4206
|
},
|
|
4199
4207
|
0x45 => {
|
|
4200
4208
|
Name => 'FocusPositionVertical',
|
|
4201
|
-
|
|
4209
|
+
# (the 6U (4) and 2D (12) are not used, for a total of 17 rows, ref AlbertShan email)
|
|
4210
|
+
PrintConv => sub { my ($val) = @_; PrintAFPointsUpDown($val, 17); },
|
|
4202
4211
|
},
|
|
4203
4212
|
0x46 => {
|
|
4204
4213
|
Name => 'AFAreaWidth',
|
|
@@ -11316,7 +11325,7 @@ sub PrintAFPointsGridInv($$$)
|
|
|
11316
11325
|
#------------------------------------------------------------------------------
|
|
11317
11326
|
# Print conversion for relative Left/Right AF points (ref 28)
|
|
11318
11327
|
# Inputs: 0) column, 1) number of columns
|
|
11319
|
-
# Returns: AF point data as a string (e.g. '2L' or 'C' or '3R')
|
|
11328
|
+
# Returns: AF point data as a string (e.g. '2L of Center' or 'C' or '3R of Center')
|
|
11320
11329
|
sub PrintAFPointsLeftRight($$)
|
|
11321
11330
|
{
|
|
11322
11331
|
my ($col, $ncol) = @_;
|
|
@@ -11329,7 +11338,7 @@ sub PrintAFPointsLeftRight($$)
|
|
|
11329
11338
|
#------------------------------------------------------------------------------
|
|
11330
11339
|
# Print conversion for relative Up/Down AF points (ref 28)
|
|
11331
11340
|
# Inputs: 0) row, 1) number of rows
|
|
11332
|
-
# Returns: AF point data as a string (e.g. '2U' or 'C' or '3D')
|
|
11341
|
+
# Returns: AF point data as a string (e.g. '2U from Center' or 'C' or '3D from Center')
|
|
11333
11342
|
sub PrintAFPointsUpDown($$)
|
|
11334
11343
|
{
|
|
11335
11344
|
my ($row, $nrow) = @_;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
# Revisions: 2019-10-23 - P. Harvey Created
|
|
7
7
|
#
|
|
8
8
|
# References: 1) https://developer.parrot.com/docs/pdraw/metadata.html
|
|
9
|
+
# --> changed to https://developer.parrot.com/docs/pdraw/video-metadata.html
|
|
9
10
|
#------------------------------------------------------------------------------
|
|
10
11
|
|
|
11
12
|
package Image::ExifTool::Parrot;
|
|
@@ -80,7 +80,7 @@ my %processByMetaFormat = (
|
|
|
80
80
|
|
|
81
81
|
# data lengths for each INSV record type
|
|
82
82
|
my %insvDataLen = (
|
|
83
|
-
0x300 =>
|
|
83
|
+
0x300 => 0, # accelerometer (could be either 20 or 56 bytes)
|
|
84
84
|
0x400 => 16, # exposure (ref 6)
|
|
85
85
|
0x600 => 8, # timestamps (ref 6)
|
|
86
86
|
0x700 => 53, # GPS
|
|
@@ -2621,8 +2621,33 @@ sub ProcessInsta360($;$)
|
|
|
2621
2621
|
if ($verbose) {
|
|
2622
2622
|
$et->VPrint(0, sprintf("Insta360 Record 0x%x (offset 0x%x, %d bytes):\n", $id, $fileEnd + $epos, $len));
|
|
2623
2623
|
}
|
|
2624
|
+
# there are 2 types of record 0x300:
|
|
2625
|
+
# 1. 56 byte records
|
|
2626
|
+
# 0000: 4a f7 02 00 00 00 00 00 00 00 00 00 00 1e e7 3f [J..............?]
|
|
2627
|
+
# 0010: 00 00 00 00 00 b2 ef bf 00 00 00 00 00 70 c1 bf [.............p..]
|
|
2628
|
+
# 0020: 00 00 00 e0 91 5c 8c bf 00 00 00 20 8f ff 87 bf [.....\..... ....]
|
|
2629
|
+
# 0030: 00 00 00 00 88 7f c9 bf
|
|
2630
|
+
# 2. 20 byte records
|
|
2631
|
+
# 0000: c1 d8 d9 0b 00 00 00 00 f5 83 14 80 df 7f fe 7f [................]
|
|
2632
|
+
# 0010: fe 7f 01 80
|
|
2633
|
+
if ($id == 0x300) {
|
|
2634
|
+
if ($len % 20 and not $len % 56) {
|
|
2635
|
+
$dlen = 56;
|
|
2636
|
+
} elsif ($len % 56 and not $len % 20) {
|
|
2637
|
+
$dlen = 20;
|
|
2638
|
+
} else {
|
|
2639
|
+
if ($raf->Read($buff, 20) == 20) {
|
|
2640
|
+
if (substr($buff, 16, 3) eq "\0\0\0") {
|
|
2641
|
+
$dlen = 56;
|
|
2642
|
+
} else {
|
|
2643
|
+
$dlen = 20;
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
$raf->Seek($epos, 2) or last;
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2624
2649
|
# limit the number of records we read if necessary
|
|
2625
|
-
if ($insvLimit{$id} and $len > $insvLimit{$id}[1] * $dlen and
|
|
2650
|
+
if ($dlen and $insvLimit{$id} and $len > $insvLimit{$id}[1] * $dlen and
|
|
2626
2651
|
$et->Warn("Insta360 $insvLimit{$id}[0] data is huge. Processing only the first $insvLimit{$id}[1] records",2))
|
|
2627
2652
|
{
|
|
2628
2653
|
$len = $insvLimit{$id}[1] * $dlen;
|
|
@@ -2630,11 +2655,18 @@ sub ProcessInsta360($;$)
|
|
|
2630
2655
|
$raf->Read($buff, $len) == $len or last;
|
|
2631
2656
|
$et->VerboseDump(\$buff) if $verbose > 2;
|
|
2632
2657
|
if ($dlen) {
|
|
2633
|
-
$len % $dlen
|
|
2634
|
-
|
|
2658
|
+
if ($len % $dlen) {
|
|
2659
|
+
$et->Warn(sprintf('Unexpected Insta360 record 0x%x length',$id));
|
|
2660
|
+
} elsif ($id == 0x300) {
|
|
2635
2661
|
for ($p=0; $p<$len; $p+=$dlen) {
|
|
2636
2662
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
|
2637
|
-
my @a
|
|
2663
|
+
my @a;
|
|
2664
|
+
if ($dlen == 56) {
|
|
2665
|
+
@a = map { GetDouble(\$buff, $p + 8 * $_) } 1..6;
|
|
2666
|
+
} else {
|
|
2667
|
+
@a = unpack("x${p}x8v6", $buff);
|
|
2668
|
+
map { $_ = ($_ - 0x8000) / 1000 } @a;
|
|
2669
|
+
}
|
|
2638
2670
|
$et->HandleTag($tagTbl, TimeCode => sprintf('%.3f', Get64u(\$buff, $p) / 1000));
|
|
2639
2671
|
$et->HandleTag($tagTbl, Accelerometer => "@a[0..2]"); # (NC)
|
|
2640
2672
|
$et->HandleTag($tagTbl, AngularVelocity => "@a[3..5]"); # (NC)
|
|
@@ -2668,7 +2700,7 @@ sub ProcessInsta360($;$)
|
|
|
2668
2700
|
$a[$_] = GetDouble(\$a[$_], 0) foreach 4,6,8,9,10;
|
|
2669
2701
|
$a[4] = -abs($a[4]) if $a[5] eq 'S'; # (abs just in case it was already signed)
|
|
2670
2702
|
$a[6] = -abs($a[6]) if $a[7] ne 'E';
|
|
2671
|
-
$et->HandleTag($tagTbl,
|
|
2703
|
+
$et->HandleTag($tagTbl, GPSDateTifme => Image::ExifTool::ConvertUnixTime($a[0]) . 'Z');
|
|
2672
2704
|
$et->HandleTag($tagTbl, GPSLatitude => $a[4]);
|
|
2673
2705
|
$et->HandleTag($tagTbl, GPSLongitude => $a[6]);
|
|
2674
2706
|
$et->HandleTag($tagTbl, GPSSpeed => $a[8] * $mpsToKph);
|
|
@@ -531,7 +531,8 @@ numerical, and generated automatically otherwise.
|
|
|
531
531
|
SubIFD's where the PutFirst flag is valid.
|
|
532
532
|
|
|
533
533
|
'Unknown' - this is an unknown tag (only extracted when the
|
|
534
|
-
Unknown option is set).
|
|
534
|
+
Unknown option is set). This is set to 2 for Unknown tags in
|
|
535
|
+
binary tables (extracted when Unknown is 2).
|
|
535
536
|
|
|
536
537
|
'WriteNothing' - flag indicating that nothing is actually
|
|
537
538
|
written when this tag is set. It is a fake writable tag that
|
|
@@ -975,6 +976,9 @@ numerical, and generated automatically otherwise.
|
|
|
975
976
|
alternate language tags (eg. 'fr'). Only used with formats
|
|
976
977
|
which support alternate languages (eg. XMP, MIE, etc).
|
|
977
978
|
|
|
979
|
+
AddedUnknown : [reserved] Used internally to mark Unknown tags that were
|
|
980
|
+
added to the table at run time.
|
|
981
|
+
|
|
978
982
|
SubDirectory { If it exists, this specifies the start of a new subdirectory.
|
|
979
983
|
It contains a collection of variables which specify the type
|
|
980
984
|
and location of the subdirectory. Note that ValueConv and
|