exiftool_vendored 13.04.0 → 13.08.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/Changes +48 -0
- data/bin/MANIFEST +1 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/exiftool +30 -23
- data/bin/lib/Image/ExifTool/AIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/APE.pm +1 -1
- data/bin/lib/Image/ExifTool/ASF.pm +1 -1
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +4 -3
- data/bin/lib/Image/ExifTool/Canon.pm +19 -1
- data/bin/lib/Image/ExifTool/DJI.pm +91 -29
- data/bin/lib/Image/ExifTool/Exif.pm +2 -2
- data/bin/lib/Image/ExifTool/FITS.pm +2 -2
- data/bin/lib/Image/ExifTool/FLIF.pm +2 -2
- data/bin/lib/Image/ExifTool/FlashPix.pm +11 -11
- data/bin/lib/Image/ExifTool/Font.pm +1 -1
- data/bin/lib/Image/ExifTool/Geolocation.pm +2 -1
- data/bin/lib/Image/ExifTool/GoPro.pm +3 -3
- data/bin/lib/Image/ExifTool/HP.pm +1 -1
- data/bin/lib/Image/ExifTool/ID3.pm +3 -3
- data/bin/lib/Image/ExifTool/IPTC.pm +2 -2
- data/bin/lib/Image/ExifTool/InDesign.pm +1 -1
- data/bin/lib/Image/ExifTool/JPEG.pm +19 -4
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +6 -6
- data/bin/lib/Image/ExifTool/M2TS.pm +39 -9
- data/bin/lib/Image/ExifTool/MXF.pm +2 -2
- data/bin/lib/Image/ExifTool/Matroska.pm +1 -1
- data/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
- data/bin/lib/Image/ExifTool/PDF.pm +15 -15
- data/bin/lib/Image/ExifTool/PLIST.pm +1 -1
- data/bin/lib/Image/ExifTool/PNG.pm +4 -4
- data/bin/lib/Image/ExifTool/Panasonic.pm +1 -1
- data/bin/lib/Image/ExifTool/PhaseOne.pm +3 -3
- data/bin/lib/Image/ExifTool/Photoshop.pm +63 -3
- data/bin/lib/Image/ExifTool/Protobuf.pm +242 -0
- data/bin/lib/Image/ExifTool/QuickTime.pm +23 -14
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +395 -109
- data/bin/lib/Image/ExifTool/README +4 -1
- data/bin/lib/Image/ExifTool/RIFF.pm +3 -3
- data/bin/lib/Image/ExifTool/RTF.pm +1 -1
- data/bin/lib/Image/ExifTool/Ricoh.pm +3 -3
- data/bin/lib/Image/ExifTool/Sony.pm +4 -3
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +4 -3
- data/bin/lib/Image/ExifTool/TagLookup.pm +6988 -6967
- data/bin/lib/Image/ExifTool/TagNames.pod +85 -5
- data/bin/lib/Image/ExifTool/VCard.pm +2 -2
- data/bin/lib/Image/ExifTool/Validate.pm +3 -3
- data/bin/lib/Image/ExifTool/WriteExif.pl +2 -2
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +4 -4
- data/bin/lib/Image/ExifTool/WriteXMP.pl +2 -2
- data/bin/lib/Image/ExifTool/Writer.pl +17 -17
- data/bin/lib/Image/ExifTool/XMP.pm +20 -10
- data/bin/lib/Image/ExifTool/XMP2.pl +38 -0
- data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
- data/bin/lib/Image/ExifTool.pm +109 -82
- data/bin/lib/Image/ExifTool.pod +8 -7
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53adc02bd5bb808506a883f10c449fd0172d7d82c099a4c5d5a4dbbcb9971d68
|
4
|
+
data.tar.gz: 76a6795061f0128324568a9907804699dd0635e94bc7042bf5ba1cb3c40c92e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd68829340a5e18d410b4485e0789bef799d78d2fb7d6ff49612fa4a596b918c86b3515c2cd0ef0d90a0a04c72403a7a2113b86d882c93d5a4e0495d01573bbd
|
7
|
+
data.tar.gz: d44cfcbc7dd21d7e74bc26ea46fcdf19f724ccffcb08e7375f21ae58f1544fcc753804348bb61f3dc706b984e5b8bdc43437f296e85a7e8767c1a168be879df9
|
data/bin/Changes
CHANGED
@@ -7,6 +7,52 @@ RSS feed: https://exiftool.org/rss.xml
|
|
7
7
|
Note: The most recent production release is Version 13.00. (Other versions are
|
8
8
|
considered development releases, and are not uploaded to MetaCPAN.)
|
9
9
|
|
10
|
+
Dec. 14, 2024 - Version 13.08
|
11
|
+
|
12
|
+
- Decode ShutterCount for Canon EOS R6 Mark II (thanks Agoston Kapitany)
|
13
|
+
- Decode a few new Photoshop tags
|
14
|
+
- Suppress all duplicate Warning tags and add count to end of message
|
15
|
+
- Changed format of bitmask keys in -list x output
|
16
|
+
- Internal streamlining of LIGOGPSINFO decoding
|
17
|
+
- Fixed issue where some tags were incorrectly shown as writable in -listx
|
18
|
+
output
|
19
|
+
- Fixed incorrect scaling for GPSSpeed in one LIGOGPSINFO variant
|
20
|
+
- Fixed an issue with filename encoding when the -L option is used and the API
|
21
|
+
WindowsLongPath option is active
|
22
|
+
|
23
|
+
Dec. 11, 2024 - Version 13.07
|
24
|
+
|
25
|
+
- Decode a number of LIGOGPSINFO encrypted and enciphered timed GPS types
|
26
|
+
(long overdue, but it took me a couple of years to acquire enough sample
|
27
|
+
videos to have a good cross-section of the different formats)
|
28
|
+
- Fixed another place where FileSequence could be incremented twice when a -if
|
29
|
+
condition was used
|
30
|
+
- Fixed a few places where character 0x7f may not have been escaped in string
|
31
|
+
values
|
32
|
+
- API Changes:
|
33
|
+
- Changed default WindowsLongPath option back to 1 after adding a patch to
|
34
|
+
fix issue with piping from stdin
|
35
|
+
|
36
|
+
Dec. 5, 2024 - Version 13.06
|
37
|
+
|
38
|
+
- Decode timed metadata from MP4 videos of yet another dashcam model
|
39
|
+
- Patched issue where FileSequence could increment twice for each file when a
|
40
|
+
-if condition was used
|
41
|
+
- API Changes:
|
42
|
+
- Revert default WindowsLongPath option to the pre-13.05 setting
|
43
|
+
until we can solve the pipe problem
|
44
|
+
|
45
|
+
Dec. 4, 2024 - Version 13.05
|
46
|
+
|
47
|
+
- Added a new SonyModelID
|
48
|
+
- Added support for XMP HDRGainMap and apdi namespaces
|
49
|
+
- Decode DJI timed djmd and dbgi protobuf-format metadata
|
50
|
+
- Decode APP10 AROT HDRGainCurve and APP2 URN UniformResourceName
|
51
|
+
- Decode a couple of new GoPro tags
|
52
|
+
- API Changes:
|
53
|
+
- Changed default WindowsLongPath option to 1 (please report if this
|
54
|
+
causes any problems)
|
55
|
+
|
10
56
|
Nov. 26, 2024 - Version 13.04
|
11
57
|
|
12
58
|
- Added the ability to write GPSDOP and GPSMeasureMode from the -geotag option
|
@@ -21,6 +67,8 @@ Nov. 26, 2024 - Version 13.04
|
|
21
67
|
- Renamed an Unknown Photoshop tag
|
22
68
|
- Convert GoPro GPSSpeed and GPSSpeed3D from m/s to km/h
|
23
69
|
- Patched to tolerate XML header in DOCX xml files
|
70
|
+
- Fixed incorrect file offsets for tags in some embedded files of -htmldump
|
71
|
+
output
|
24
72
|
- Fixed -htmldump output to show the same names for unknown EXIF tags as with
|
25
73
|
the -u option
|
26
74
|
|
data/bin/MANIFEST
CHANGED
@@ -397,6 +397,7 @@ lib/Image/ExifTool/PhotoMechanic.pm
|
|
397
397
|
lib/Image/ExifTool/Photoshop.pm
|
398
398
|
lib/Image/ExifTool/PostScript.pm
|
399
399
|
lib/Image/ExifTool/PrintIM.pm
|
400
|
+
lib/Image/ExifTool/Protobuf.pm
|
400
401
|
lib/Image/ExifTool/Qualcomm.pm
|
401
402
|
lib/Image/ExifTool/QuickTime.pm
|
402
403
|
lib/Image/ExifTool/QuickTimeStream.pl
|
data/bin/META.json
CHANGED
data/bin/META.yml
CHANGED
data/bin/README
CHANGED
@@ -109,8 +109,8 @@ your home directory, then you would type the following commands in a
|
|
109
109
|
terminal window to extract and run ExifTool:
|
110
110
|
|
111
111
|
cd ~/Desktop
|
112
|
-
gzip -dc Image-ExifTool-13.
|
113
|
-
cd Image-ExifTool-13.
|
112
|
+
gzip -dc Image-ExifTool-13.08.tar.gz | tar -xf -
|
113
|
+
cd Image-ExifTool-13.08
|
114
114
|
./exiftool t/images/ExifTool.jpg
|
115
115
|
|
116
116
|
Note: These commands extract meta information from one of the test images.
|
data/bin/exiftool
CHANGED
@@ -11,7 +11,7 @@ use strict;
|
|
11
11
|
use warnings;
|
12
12
|
require 5.004;
|
13
13
|
|
14
|
-
my $version = '13.
|
14
|
+
my $version = '13.08';
|
15
15
|
|
16
16
|
# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
|
17
17
|
my $exePath;
|
@@ -1918,7 +1918,7 @@ if (@dbKeys) {
|
|
1918
1918
|
print $vout "Imported entry for '${_}' (full path: '${absPath}')\n";
|
1919
1919
|
}
|
1920
1920
|
} elsif ($verbose and $verbose > 1) {
|
1921
|
-
print $vout "Imported entry for '${_}' (
|
1921
|
+
print $vout "Imported entry for '${_}' (no full path)\n";
|
1922
1922
|
}
|
1923
1923
|
}
|
1924
1924
|
}
|
@@ -2172,7 +2172,11 @@ sub GetImageInfo($$)
|
|
2172
2172
|
}
|
2173
2173
|
# can't make use of $info if verbose because we must reprocess
|
2174
2174
|
# the file anyway to generate the verbose output
|
2175
|
-
|
2175
|
+
# (also if writing just to avoid double-incrementing FileSequence)
|
2176
|
+
if ($isWriting or $verbose or defined $fastCondition or defined $diff) {
|
2177
|
+
undef $info;
|
2178
|
+
--$$et{FILE_SEQUENCE};
|
2179
|
+
}
|
2176
2180
|
} elsif ($file =~ s/^(\@JSON:)(.*)/$1/) {
|
2177
2181
|
# read JSON file from command line
|
2178
2182
|
my $dat = $2;
|
@@ -3636,7 +3640,7 @@ sub EscapeJSON($;$)
|
|
3636
3640
|
if ($json < 2) { # JSON
|
3637
3641
|
$str =~ tr/\0//d; # remove all nulls
|
3638
3642
|
# escape other control characters with \u
|
3639
|
-
$str =~ s/([\0-\x1f])/sprintf("\\u%.4X",ord $1)/sge;
|
3643
|
+
$str =~ s/([\0-\x1f\x7f])/sprintf("\\u%.4X",ord $1)/sge;
|
3640
3644
|
# JSON strings must be valid UTF8
|
3641
3645
|
Image::ExifTool::XMP::FixUTF8(\$str) unless $altEnc;
|
3642
3646
|
} else { # PHP
|
@@ -3644,7 +3648,7 @@ sub EscapeJSON($;$)
|
|
3644
3648
|
# must escape "$" too for PHP
|
3645
3649
|
$str =~ s/\$/\\\$/sg;
|
3646
3650
|
# escape other control characters with \x
|
3647
|
-
$str =~ s/([\0-\x1f])/sprintf("\\x%.2X",ord $1)/sge;
|
3651
|
+
$str =~ s/([\0-\x1f\x7f])/sprintf("\\x%.2X",ord $1)/sge;
|
3648
3652
|
}
|
3649
3653
|
return '"' . $str . '"'; # return the quoted string
|
3650
3654
|
}
|
@@ -4163,11 +4167,12 @@ sub ScanDir($$;$)
|
|
4163
4167
|
}
|
4164
4168
|
$dir =~ /\/$/ or $dir .= '/'; # make sure directory name ends with '/'
|
4165
4169
|
foreach $file (@fileList) {
|
4170
|
+
next if $file eq '.' or $file eq '..';
|
4166
4171
|
my $path = "$dir$file";
|
4167
4172
|
if ($et->IsDirectory($path)) {
|
4168
4173
|
next unless $recurse;
|
4169
4174
|
# ignore directories starting with "." by default
|
4170
|
-
next if $file =~ /^\./ and
|
4175
|
+
next if $file =~ /^\./ and $recurse == 1;
|
4171
4176
|
next if $ignore{$file} or ($ignore{SYMLINKS} and -l $path);
|
4172
4177
|
ScanDir($et, $path, $list);
|
4173
4178
|
last if $end;
|
@@ -4315,14 +4320,15 @@ sub AbsPath($)
|
|
4315
4320
|
{
|
4316
4321
|
my $file = shift;
|
4317
4322
|
my $path;
|
4318
|
-
if (defined $file
|
4319
|
-
|
4320
|
-
|
4321
|
-
|
4322
|
-
|
4323
|
-
$
|
4324
|
-
$path =
|
4323
|
+
if (defined $file) {
|
4324
|
+
return undef if $file eq '*'; # (CSV SourceFile may be '*' -- no absolute path for that)
|
4325
|
+
if ($^O eq 'MSWin32' and $mt->Options('WindowsLongPath')) {
|
4326
|
+
$path = $mt->WindowsLongPath($file);
|
4327
|
+
} elsif (eval { require Cwd }) {
|
4328
|
+
local $SIG{'__WARN__'} = sub { };
|
4329
|
+
$path = eval { Cwd::abs_path($file) };
|
4325
4330
|
}
|
4331
|
+
$path =~ tr/\\/\// if $^O eq 'MSWin32' and defined $path; # use forward slashes
|
4326
4332
|
}
|
4327
4333
|
return $path;
|
4328
4334
|
}
|
@@ -5907,7 +5913,7 @@ with this command:
|
|
5907
5913
|
|
5908
5914
|
produces output like this:
|
5909
5915
|
|
5910
|
-
-- Generated by ExifTool 13.
|
5916
|
+
-- Generated by ExifTool 13.08 --
|
5911
5917
|
File: a.jpg - 2003:10:31 15:44:19
|
5912
5918
|
(f/5.6, 1/60s, ISO 100)
|
5913
5919
|
File: b.jpg - 2006:05:23 11:57:38
|
@@ -6022,7 +6028,8 @@ import). May be combined with B<-s> to print tag names instead of
|
|
6022
6028
|
descriptions, or B<-S> to print tag values only, tab-delimited on a single
|
6023
6029
|
line. The B<-t> option may be combined with B<-j>, B<-php> or B<-X> to add
|
6024
6030
|
tag table information (C<table>, tag C<id>, and C<index> for cases where
|
6025
|
-
multiple conditional tags exist with the same ID)
|
6031
|
+
multiple conditional tags exist with the same ID), which allows the
|
6032
|
+
corresponding tag to be located in the B<-listx> output.
|
6026
6033
|
|
6027
6034
|
=item B<-T> (B<-table>)
|
6028
6035
|
|
@@ -6781,14 +6788,14 @@ written (provided they can be calculated from the track log, and they are
|
|
6781
6788
|
supported by the destination metadata format): GPSLatitude, GPSLatitudeRef,
|
6782
6789
|
GPSLongitude, GPSLongitudeRef, GPSAltitude, GPSAltitudeRef, GPSDateStamp,
|
6783
6790
|
GPSTimeStamp, GPSDateTime, GPSTrack, GPSTrackRef, GPSSpeed, GPSSpeedRef,
|
6784
|
-
GPSImgDirection, GPSImgDirectionRef,
|
6785
|
-
AmbientTemperature and CameraElevationAngle. By
|
6786
|
-
tags are created in EXIF, and updated in XMP only if
|
6787
|
-
QuickTime-format files GPSCoordinates is created in
|
6788
|
-
(ItemList by default) as well as in XMP. However,
|
6789
|
-
C<XMP:Geotime> or C<QuickTime:Geotime> may be specified to
|
6790
|
-
only to one group. Also, C<ItemList:Geotime>, C<Keys:Geotime>
|
6791
|
-
C<UserData:Geotime> may be used to write to a specific location in
|
6791
|
+
GPSImgDirection, GPSImgDirectionRef, GPSMeasureMode, GPSDOP, GPSPitch,
|
6792
|
+
GPSRoll, GPSCoordinates, AmbientTemperature and CameraElevationAngle. By
|
6793
|
+
default, in image files tags are created in EXIF, and updated in XMP only if
|
6794
|
+
they already exist. In QuickTime-format files GPSCoordinates is created in
|
6795
|
+
the preferred location (ItemList by default) as well as in XMP. However,
|
6796
|
+
C<EXIF:Geotime>, C<XMP:Geotime> or C<QuickTime:Geotime> may be specified to
|
6797
|
+
write to write only to one group. Also, C<ItemList:Geotime>, C<Keys:Geotime>
|
6798
|
+
or C<UserData:Geotime> may be used to write to a specific location in
|
6792
6799
|
QuickTime-format files. Note that GPSPitch and GPSRoll are non-standard,
|
6793
6800
|
and require user-defined tags in order to be written.
|
6794
6801
|
|
@@ -231,7 +231,7 @@ sub ProcessAIFF($$)
|
|
231
231
|
$et->Warn('End of processing at large chunk (LargeFileSupport not enabled)');
|
232
232
|
last;
|
233
233
|
} elsif ($et->Options('LargeFileSupport') eq '2') {
|
234
|
-
$et->
|
234
|
+
$et->Warn('Skipping large chunk (LargeFileSupport is 2)');
|
235
235
|
}
|
236
236
|
}
|
237
237
|
if ($tagInfo) {
|
@@ -217,7 +217,7 @@ sub ProcessAPE($$)
|
|
217
217
|
$val = \$buf2;
|
218
218
|
# extract cover art description separately (hackitty hack)
|
219
219
|
if ($tag =~ /^Cover Art/) {
|
220
|
-
$buf2 =~ s/^([\x20-\
|
220
|
+
$buf2 =~ s/^([\x20-\x7e]*)\0//;
|
221
221
|
if ($1) {
|
222
222
|
my $t = "$tag Desc";
|
223
223
|
my $v = $1;
|
@@ -781,7 +781,7 @@ sub ProcessASF($$;$)
|
|
781
781
|
$err = 'Invalid ASF object size';
|
782
782
|
} elsif ($et->Options('LargeFileSupport')) {
|
783
783
|
if ($et->Options('LargeFileSupport') eq '2') {
|
784
|
-
$et->
|
784
|
+
$et->Warn('Skipping large ASF object (LargeFileSupport is 2)');
|
785
785
|
}
|
786
786
|
if ($raf->Seek($size, 1)) {
|
787
787
|
$et->VPrint(0, " Skipped large ASF object ($size bytes)\n");
|
@@ -35,7 +35,7 @@ use Image::ExifTool::Sony;
|
|
35
35
|
use Image::ExifTool::Validate;
|
36
36
|
use Image::ExifTool::MacOS;
|
37
37
|
|
38
|
-
$VERSION = '3.
|
38
|
+
$VERSION = '3.59';
|
39
39
|
@ISA = qw(Exporter);
|
40
40
|
|
41
41
|
sub NumbersFirst($$);
|
@@ -869,7 +869,8 @@ sub new
|
|
869
869
|
my $processBinaryData = ($$table{PROCESS_PROC} and (
|
870
870
|
$$table{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData or
|
871
871
|
$$table{PROCESS_PROC} eq \&Image::ExifTool::Nikon::ProcessNikonEncrypted or
|
872
|
-
$$table{PROCESS_PROC} eq \&Image::ExifTool::Sony::ProcessEnciphered)
|
872
|
+
$$table{PROCESS_PROC} eq \&Image::ExifTool::Sony::ProcessEnciphered) or
|
873
|
+
$$table{VARS} and $$table{VARS}{IS_BINARY});
|
873
874
|
if ($$vars{ID_LABEL} or $processBinaryData) {
|
874
875
|
my $s = $$table{FORMAT} ? Image::ExifTool::FormatSize($$table{FORMAT}) || 1 : 1;
|
875
876
|
$binaryTable = 1;
|
@@ -1248,7 +1249,7 @@ TagID: foreach $tagID (@keys) {
|
|
1248
1249
|
}
|
1249
1250
|
} elsif ($$tagInfo{PrintString} or not /^[+-]?(?=\d|\.\d)\d*(\.\d*)?$/) {
|
1250
1251
|
# translate unprintable values
|
1251
|
-
if ($index =~ s/([\x00-\x1f\
|
1252
|
+
if ($index =~ s/([\x00-\x1f\x7f-\xff])/sprintf("\\x%.2x",ord $1)/eg) {
|
1252
1253
|
$index = qq{"$index"};
|
1253
1254
|
} else {
|
1254
1255
|
$index = qq{'${index}'};
|
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
|
|
88
88
|
sub ProcessExifInfo($$$);
|
89
89
|
sub SwapWords($);
|
90
90
|
|
91
|
-
$VERSION = '4.
|
91
|
+
$VERSION = '4.86';
|
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)
|
@@ -1404,6 +1404,11 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
|
|
1404
1404
|
Condition => '$$self{Model} =~ /\bEOS R[56]$/',
|
1405
1405
|
SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoR6' },
|
1406
1406
|
},
|
1407
|
+
{
|
1408
|
+
Name => 'CanonCameraInfoR6m2',
|
1409
|
+
Condition => '$$self{Model} =~ /\bEOS R6m2$/',
|
1410
|
+
SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoR6m2' },
|
1411
|
+
},
|
1407
1412
|
{
|
1408
1413
|
Name => 'CanonCameraInfoG5XII',
|
1409
1414
|
Condition => '$$self{Model} =~ /\bG5 X Mark II$/',
|
@@ -4752,6 +4757,19 @@ my %ciMaxFocal = (
|
|
4752
4757
|
# 0x0bb7 - counts down during focus stack (ref forum16111)
|
4753
4758
|
);
|
4754
4759
|
|
4760
|
+
%Image::ExifTool::Canon::CameraInfoR6m2 = (
|
4761
|
+
%binaryDataAttrs,
|
4762
|
+
FIRST_ENTRY => 0,
|
4763
|
+
PRIORITY => 0,
|
4764
|
+
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
|
4765
|
+
NOTES => 'CameraInfo tags for the EOS R6 Mark II.',
|
4766
|
+
0x0d29 => { #AgostonKapitany
|
4767
|
+
Name => 'ShutterCount',
|
4768
|
+
Format => 'int32u',
|
4769
|
+
Notes => 'includes electronic + mechanical shutter',
|
4770
|
+
},
|
4771
|
+
);
|
4772
|
+
|
4755
4773
|
# ref https://exiftool.org/forum/index.php?topic=15356.0
|
4756
4774
|
%Image::ExifTool::Canon::CameraInfoG5XII = (
|
4757
4775
|
%binaryDataAttrs,
|
@@ -15,11 +15,11 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
15
15
|
use Image::ExifTool::Exif;
|
16
16
|
use Image::ExifTool::XMP;
|
17
17
|
use Image::ExifTool::GPS;
|
18
|
+
use Image::ExifTool::Protobuf;
|
18
19
|
|
19
|
-
$VERSION = '1.
|
20
|
+
$VERSION = '1.10';
|
20
21
|
|
21
22
|
sub ProcessDJIInfo($$$);
|
22
|
-
sub Process_djmd($$$);
|
23
23
|
|
24
24
|
my %convFloat2 = (
|
25
25
|
PrintConv => 'sprintf("%+.2f", $val)',
|
@@ -187,34 +187,96 @@ my %convFloat2 = (
|
|
187
187
|
},
|
188
188
|
);
|
189
189
|
|
190
|
-
#
|
191
|
-
%Image::ExifTool::DJI::
|
192
|
-
|
190
|
+
# metadata in protobuf format (djmd and dbgi meta types, ref PH)
|
191
|
+
%Image::ExifTool::DJI::Protobuf = (
|
192
|
+
GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Location' },
|
193
|
+
TAG_PREFIX => '',
|
194
|
+
PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
|
195
|
+
NOTES => q{
|
196
|
+
Tags found in protobuf-format DJI meta djmd and dbgi timed metadata. Only a
|
197
|
+
few tags are currently known, but unknown djmd tags may be extracted by
|
198
|
+
setting the Unknown option to 1 (or 2 to also extract unknown dbgi debug
|
199
|
+
tags). Tag ID's are composed of the corresponding .proto file name combined
|
200
|
+
with the hierarchical protobuf field numbers. The "dvtm_AVATA2.proto" file
|
201
|
+
is used by the DJI Avanta 2, and "dvtm_ac203.proto" by the OsmoAction4.
|
202
|
+
},
|
203
|
+
Protocol => { },
|
204
|
+
# dvtm_ac203_1-1-6 - some version number
|
205
|
+
'dvtm_ac203_1-1-10' => 'Model',
|
206
|
+
'dvtm_ac203_2-3-1' => { Name => 'FrameWidth', Format => 'unsigned' },
|
207
|
+
'dvtm_ac203_2-3-2' => { Name => 'FrameHeight', Format => 'unsigned' },
|
208
|
+
'dvtm_ac203_2-3-3' => { Name => 'FrameRate', Format => 'float' },
|
209
|
+
# dvtm_ac203_3-4-1-4 - model code?
|
210
|
+
'dvtm_ac203_3-4-2-1-1' => {
|
211
|
+
Name => 'CoordinateUnits',
|
212
|
+
Format => 'unsigned',
|
213
|
+
# don't extract this -- just convert to degrees
|
214
|
+
RawConv => '$$self{CoordUnits} = $val; undef',
|
215
|
+
Hidden => 1,
|
216
|
+
# PrintConv => { 0 => 'Radians', 1 => 'Degrees' },
|
217
|
+
},
|
218
|
+
'dvtm_ac203_3-4-2-1-2' => {
|
219
|
+
Name => 'GPSLatitude',
|
220
|
+
Format => 'double',
|
221
|
+
# set ExifTool GPSLatitude/GPSLongitude members so GPSDateTime will be generated if necessary
|
222
|
+
RawConv => '$$self{GPSLatitude} = $$self{CoordUnits} ? $val : $val * 180 / 3.141592653589793', # (NC)
|
223
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
|
224
|
+
},
|
225
|
+
'dvtm_ac203_3-4-2-1-3' => {
|
226
|
+
Name => 'GPSLongitude',
|
227
|
+
Format => 'double',
|
228
|
+
RawConv => '$$self{GPSLongitude} = $$self{CoordUnits} ? $val : $val * 180 / 3.141592653589793', # (NC)
|
229
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
|
230
|
+
},
|
231
|
+
'dvtm_ac203_3-4-2-2' => {
|
232
|
+
Name => 'GPSAltitude',
|
233
|
+
Format => 'unsigned',
|
234
|
+
ValueConv => '$val / 1000',
|
235
|
+
},
|
236
|
+
'dvtm_ac203_3-4-2-6-1' => {
|
237
|
+
Name => 'GPSDateTime',
|
238
|
+
Format => 'string',
|
239
|
+
Groups => { 2 => 'Time' },
|
240
|
+
RawConv => '$$self{GPSDateTime} = $val',
|
241
|
+
ValueConv => '$val =~ tr/-/:/; $val',
|
242
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
243
|
+
},
|
244
|
+
# dvtm_AVATA2_1-1-2 - some version number
|
245
|
+
# dvtm_AVATA2_1-1-3 - some version number
|
246
|
+
'dvtm_AVATA2_1-1-10' => 'Model',
|
247
|
+
'dvtm_AVATA2_2-2-3-1' => 'SerialNumber', # (NC)
|
248
|
+
'dvtm_AVATA2_2-3-1' => { Name => 'FrameWidth', Format => 'unsigned' },
|
249
|
+
'dvtm_AVATA2_2-3-2' => { Name => 'FrameHeight', Format => 'unsigned' },
|
250
|
+
'dvtm_AVATA2_2-3-3' => { Name => 'FrameRate', Format => 'float' },
|
251
|
+
# dvtm_AVATA2_3-1-1 - frame number (starting at 1)
|
252
|
+
'dvtm_AVATA2_3-1-2' => { # (also 3-2-1-6 and 3-4-1-6)
|
253
|
+
Name => 'TimeStamp',
|
254
|
+
Format => 'unsigned',
|
255
|
+
# milliseconds, but I don't know what the zero is
|
256
|
+
ValueConv => '$val / 1e6',
|
257
|
+
},
|
258
|
+
# dvtm_AVATA2_3-2-1-4 - model code?
|
259
|
+
# dvtm_AVATA2_3-4-1-4 - model code?
|
260
|
+
'dvtm_AVATA2_3-4-4-1-1' => { # (NC) (default seems to be radians if missing)
|
261
|
+
Name => 'CoordinateDegrees',
|
262
|
+
Format => 'unsigned',
|
263
|
+
RawConv => '$$self{CoordDegrees} = $val; undef',
|
264
|
+
Hidden => 1,
|
265
|
+
},
|
266
|
+
'dvtm_AVATA2_3-4-4-1-2' => {
|
267
|
+
Name => 'GPSLatitude',
|
268
|
+
Format => 'double',
|
269
|
+
RawConv => '$$self{GPSLatitude} = $$self{CoordDegrees} ? $val : $val * 180 / 3.141592653589793', # (NC)
|
270
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
|
271
|
+
},
|
272
|
+
'dvtm_AVATA2_3-4-4-1-3' => {
|
273
|
+
Name => 'GPSLongitude',
|
274
|
+
Format => 'double',
|
275
|
+
RawConv => '$$self{GPSLongitude} = $$self{CoordDegrees} ? $val : $val * 180 / 3.141592653589793', # (NC)
|
276
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
|
277
|
+
},
|
193
278
|
);
|
194
279
|
|
195
|
-
#------------------------------------------------------------------------------
|
196
|
-
# Process DJI djmd timed data from Action4 videos (ref PH)
|
197
|
-
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
|
198
|
-
# Returns: 1 on success
|
199
|
-
# TODO: work in progress
|
200
|
-
sub Process_djmd($$$)
|
201
|
-
{
|
202
|
-
my ($et, $dirInfo, $tagTbl) = @_;
|
203
|
-
my $dataPt = $$dirInfo{DataPt};
|
204
|
-
my ($pos, $bit, $val) = (6, 0, 0);
|
205
|
-
for (;;) {
|
206
|
-
my $v = Get8u($dataPt, $pos);
|
207
|
-
$val += ($v & 0x7f) << $bit;
|
208
|
-
last unless $v & 0x80;
|
209
|
-
++$pos;
|
210
|
-
$bit += 7;
|
211
|
-
}
|
212
|
-
$pos += 49;
|
213
|
-
my @a = unpack("x${pos}fxfxfxfx3fxfxf", $$dataPt);
|
214
|
-
print "$val @a\n";
|
215
|
-
return 1;
|
216
|
-
}
|
217
|
-
|
218
280
|
#------------------------------------------------------------------------------
|
219
281
|
# Process DJI info (ref PH)
|
220
282
|
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
|
@@ -233,7 +295,7 @@ sub ProcessDJIInfo($$$)
|
|
233
295
|
while ($$dataPt =~ /\G\[(.*?)\](?=(\[|$))/sg) {
|
234
296
|
my ($tag, $val) = split /:/, $1, 2;
|
235
297
|
next unless defined $tag and defined $val;
|
236
|
-
if ($val =~ /^([\x20-\
|
298
|
+
if ($val =~ /^([\x20-\x7e]+)\0*$/) {
|
237
299
|
$val = $1;
|
238
300
|
} else {
|
239
301
|
my $buff = $val;
|
@@ -6186,7 +6186,7 @@ sub ProcessExif($$$)
|
|
6186
6186
|
if ($$dirInfo{DirName} eq 'MakerNotes' and $$et{FileType} eq 'CR3' and
|
6187
6187
|
$$dirInfo{Parent} and $$dirInfo{Parent} eq 'ExifIFD')
|
6188
6188
|
{
|
6189
|
-
$et->
|
6189
|
+
$et->Warn("MakerNotes shouldn't exist ExifIFD of CR3 image", 1);
|
6190
6190
|
}
|
6191
6191
|
# set flag to calculate image data hash if requested
|
6192
6192
|
$doHash = 1 if $$et{ImageDataHash} and (($$et{FILE_TYPE} eq 'TIFF' and not $base and not $inMakerNotes) or
|
@@ -6656,7 +6656,7 @@ sub ProcessExif($$$)
|
|
6656
6656
|
if ($count > 500 and $formatStr !~ /^(undef|string|binary)$/ and
|
6657
6657
|
(not $tagInfo or $$tagInfo{LongBinary} or $warned) and not $$et{OPTIONS}{IgnoreMinorErrors})
|
6658
6658
|
{
|
6659
|
-
$et->
|
6659
|
+
$et->Warn('Not decoding some large array(s). Ignore minor errors to decode', 2) unless $warned;
|
6660
6660
|
next if $$et{TAGS_FROM_FILE}; # don't generate bogus value when copying tags
|
6661
6661
|
$val = "(large array of $count $formatStr values)";
|
6662
6662
|
} else {
|
@@ -61,7 +61,7 @@ sub ProcessFITS($$)
|
|
61
61
|
my $key = substr($buff, 0, 8);
|
62
62
|
$key =~ s/ +$//; # remove trailing space from key
|
63
63
|
if ($key eq 'CONTINUE') {
|
64
|
-
defined $continue or $et->
|
64
|
+
defined $continue or $et->Warn('Unexpected FITS CONTINUE keyword'), next;
|
65
65
|
} else {
|
66
66
|
if (defined $continue) {
|
67
67
|
# the previous value wasn't continued, so store with the trailing '&'
|
@@ -104,7 +104,7 @@ sub ProcessFITS($$)
|
|
104
104
|
# check for possible continuation, removing trailing '&'
|
105
105
|
$val =~ s/\&$// and $continue = $val, next;
|
106
106
|
} elsif (defined $continue) {
|
107
|
-
$et->
|
107
|
+
$et->Warn('Invalid FITS CONTINUE value');
|
108
108
|
next;
|
109
109
|
} else {
|
110
110
|
$val =~ s/ *(\/.*)?$//; # remove trailing spaces and comment
|
@@ -244,7 +244,7 @@ sub WriteFLIF($$)
|
|
244
244
|
}
|
245
245
|
}
|
246
246
|
} else {
|
247
|
-
$et->
|
247
|
+
$et->Warn('Install IO::Compress::RawDeflate to write FLIF metadata');
|
248
248
|
}
|
249
249
|
Write($outfile, $tag, SetVarInt(length $buff), $buff) or return -1;
|
250
250
|
} elsif (not defined $soi) {
|
@@ -301,7 +301,7 @@ sub ProcessFLIF($$)
|
|
301
301
|
$et->Warn("Error inflating FLIF $tag chunk");
|
302
302
|
}
|
303
303
|
} else {
|
304
|
-
$et->
|
304
|
+
$et->Warn('Install IO::Uncompress::RawInflate to decode FLIF metadata');
|
305
305
|
}
|
306
306
|
} else {
|
307
307
|
$raf->Seek($size, 1) or $et->Warn('Seek error'), last;
|
@@ -1449,7 +1449,7 @@ sub ReadFPXValue($$$$$;$$)
|
|
1449
1449
|
$noPad = 1; # values sometimes aren't padded inside vectors!!
|
1450
1450
|
my $size = $oleFormatSize{VT_VECTOR};
|
1451
1451
|
if ($valPos + $size > $dirEnd) {
|
1452
|
-
$et->
|
1452
|
+
$et->Warn('Incorrect FPX VT_VECTOR size');
|
1453
1453
|
last;
|
1454
1454
|
}
|
1455
1455
|
$count = Get32u($dataPt, $valPos);
|
@@ -1457,14 +1457,14 @@ sub ReadFPXValue($$$$$;$$)
|
|
1457
1457
|
$valPos += 4;
|
1458
1458
|
} else {
|
1459
1459
|
# can't yet handle this property flag
|
1460
|
-
$et->
|
1460
|
+
$et->Warn('Unknown FPX property');
|
1461
1461
|
last;
|
1462
1462
|
}
|
1463
1463
|
}
|
1464
1464
|
unless ($format =~ /^VT_/) {
|
1465
1465
|
my $size = Image::ExifTool::FormatSize($format) * $count;
|
1466
1466
|
if ($valPos + $size > $dirEnd) {
|
1467
|
-
$et->
|
1467
|
+
$et->Warn("Incorrect FPX $format size");
|
1468
1468
|
last;
|
1469
1469
|
}
|
1470
1470
|
@vals = ReadValue($dataPt, $valPos, $format, $count, $size);
|
@@ -1476,7 +1476,7 @@ sub ReadFPXValue($$$$$;$$)
|
|
1476
1476
|
my ($item, $val, $len);
|
1477
1477
|
for ($item=0; $item<$count; ++$item) {
|
1478
1478
|
if ($valPos + $size > $dirEnd) {
|
1479
|
-
$et->
|
1479
|
+
$et->Warn("Truncated FPX $format value");
|
1480
1480
|
last;
|
1481
1481
|
}
|
1482
1482
|
# sometimes VT_VECTOR items are padded to even 4-byte boundaries, and sometimes they aren't
|
@@ -1528,7 +1528,7 @@ sub ReadFPXValue($$$$$;$$)
|
|
1528
1528
|
$len = Get32u($dataPt, $valPos);
|
1529
1529
|
$len *= 2 if $format eq 'VT_LPWSTR'; # convert to byte count
|
1530
1530
|
if ($valPos + $len + 4 > $dirEnd) {
|
1531
|
-
$et->
|
1531
|
+
$et->Warn("Truncated $format value");
|
1532
1532
|
last;
|
1533
1533
|
}
|
1534
1534
|
$val = substr($$dataPt, $valPos + 4, $len);
|
@@ -1551,7 +1551,7 @@ sub ReadFPXValue($$$$$;$$)
|
|
1551
1551
|
} elsif ($format eq 'VT_BLOB' or $format eq 'VT_CF') {
|
1552
1552
|
my $len = Get32u($dataPt, $valPos); # (use local $len because we always expect padding)
|
1553
1553
|
if ($valPos + $len + 4 > $dirEnd) {
|
1554
|
-
$et->
|
1554
|
+
$et->Warn("Truncated $format value");
|
1555
1555
|
last;
|
1556
1556
|
}
|
1557
1557
|
$val = substr($$dataPt, $valPos + 4, $len);
|
@@ -1627,7 +1627,7 @@ sub ProcessContents($$$)
|
|
1627
1627
|
while ($$dataPt =~ /\x0bTargetRole1(?:.\x80|\xff\xff.\0.\0Vn(\w+))\0\0\x01.{4}(.{24})/sg) {
|
1628
1628
|
my ($index, @coords) = unpack('Vx4V4', $2);
|
1629
1629
|
next if $index == 0xffffffff;
|
1630
|
-
$$et{IeImg_lkup}{$index} and $et->
|
1630
|
+
$$et{IeImg_lkup}{$index} and $et->Warn('Duplicate image index');
|
1631
1631
|
$$et{IeImg_lkup}{$index} = "@coords";
|
1632
1632
|
$$et{IeImg_class}{$index} = $1 if $1;
|
1633
1633
|
}
|
@@ -1661,7 +1661,7 @@ sub ProcessWordDocument($$$)
|
|
1661
1661
|
my $dirLen = length $$dataPt;
|
1662
1662
|
# validate the FIB signature
|
1663
1663
|
unless ($dirLen > 2 and Get16u($dataPt,0) == 0xa5ec) {
|
1664
|
-
$et->
|
1664
|
+
$et->Warn('Invalid FIB signature', 1);
|
1665
1665
|
return 0;
|
1666
1666
|
}
|
1667
1667
|
$et->ProcessBinaryData($dirInfo, $tagTablePtr); # process FIB
|
@@ -2098,7 +2098,7 @@ sub ProcessFPXR($$$)
|
|
2098
2098
|
my $overlap = length($$obj{Stream}) - $offset;
|
2099
2099
|
my $start = $dirStart + 13;
|
2100
2100
|
if ($overlap < 0 or $dirLen - $overlap < 13) {
|
2101
|
-
$et->
|
2101
|
+
$et->Warn("Bad FPXR stream $index offset",1);
|
2102
2102
|
} else {
|
2103
2103
|
# ignore any overlapping data in this segment
|
2104
2104
|
# (this seems to be the convention)
|
@@ -2338,7 +2338,7 @@ sub ProcessFPX($$)
|
|
2338
2338
|
$tag =~ s/\0.*//s; # truncate at null (in case length was wrong)
|
2339
2339
|
|
2340
2340
|
if ($tag eq '0' and not defined $ee) {
|
2341
|
-
$et->
|
2341
|
+
$et->Warn('Use the ExtractEmbedded option to extract embedded information', 3);
|
2342
2342
|
}
|
2343
2343
|
my $sect = Get32u(\$dir, $pos + 0x74); # start sector number
|
2344
2344
|
my $size = Get32u(\$dir, $pos + 0x78); # stream length
|
@@ -2441,7 +2441,7 @@ sub ProcessFPX($$)
|
|
2441
2441
|
my $subTablePtr = GetTagTable($$subdir{TagTable});
|
2442
2442
|
$et->ProcessDirectory(\%dirInfo, $subTablePtr, $$subdir{ProcessProc});
|
2443
2443
|
} elsif (defined $size and $size > length($buff)) {
|
2444
|
-
$et->
|
2444
|
+
$et->Warn('Truncated object');
|
2445
2445
|
} else {
|
2446
2446
|
$buff = substr($buff, 0, $size) if defined $size and $size < length($buff);
|
2447
2447
|
if ($tag =~ /^IeImg_0*(\d+)$/) {
|
@@ -405,7 +405,7 @@ sub ProcessOTF($$)
|
|
405
405
|
next;
|
406
406
|
}
|
407
407
|
if ($verbose) {
|
408
|
-
$tag =~ s/([\0-\x1f\
|
408
|
+
$tag =~ s/([\0-\x1f\x7f-\xff])/sprintf('\x%.2x',ord $1)/ge;
|
409
409
|
my $str = sprintf("%s%d) Tag '%s' (offset 0x%.4x, %d bytes)\n",
|
410
410
|
$$et{INDENT}, $pos/16, $tag, $offset, $size);
|
411
411
|
$et->VPrint(0, $str);
|