exiftool_vendored 12.59.0 → 12.60.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 +23 -6
- 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 +34 -22
- data/bin/lib/Image/ExifTool/CanonRaw.pm +5 -1
- data/bin/lib/Image/ExifTool/Exif.pm +53 -14
- data/bin/lib/Image/ExifTool/FujiFilm.pm +6 -3
- data/bin/lib/Image/ExifTool/Geotag.pm +30 -7
- data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -1
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -8
- data/bin/lib/Image/ExifTool/PNG.pm +1 -6
- data/bin/lib/Image/ExifTool/QuickTime.pm +10 -0
- data/bin/lib/Image/ExifTool/RIFF.pm +2 -9
- data/bin/lib/Image/ExifTool/Ricoh.pm +2 -1
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +9 -3
- data/bin/lib/Image/ExifTool/Sony.pm +2 -1
- data/bin/lib/Image/ExifTool/TagLookup.pm +3 -2
- data/bin/lib/Image/ExifTool/TagNames.pod +4 -1
- data/bin/lib/Image/ExifTool/WriteExif.pl +2 -9
- data/bin/lib/Image/ExifTool/Writer.pl +40 -6
- data/bin/lib/Image/ExifTool.pm +45 -22
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 348c2538720f815bacaf609de1dbb52e18f720663ea9e2194c92941b5f80d5ec
|
4
|
+
data.tar.gz: 124c2564aba8f2fa4af8b2bf16c654b46624031b38bb64e6ed4ed3d6cc2fb596
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b32a41d3586f914940ddfc5f3f947c323006f627ce6c3a050f34111817776e26a4a5e535f56194998ec38aa5ea7f27e350388fbbd517dd366d826324c9dcd9e4
|
7
|
+
data.tar.gz: 9b3d5cb69b62ca6bc41293ec56110e0c28e7510561303bc8c3f3eb0ee01500f5c92dd8ff60ace8f53c54c64a28c92cfa84b0fbebe7238cb190872433c62f4103
|
data/bin/Changes
CHANGED
@@ -4,9 +4,27 @@ ExifTool Version History
|
|
4
4
|
|
5
5
|
RSS feed: https://exiftool.org/rss.xml
|
6
6
|
|
7
|
-
Note: The most recent production release is Version 12.
|
7
|
+
Note: The most recent production release is Version 12.60. (Other versions are
|
8
8
|
considered development releases, and are not uploaded to MetaCPAN.)
|
9
9
|
|
10
|
+
Apr. 5, 2023 - Version 12.60 (production release)
|
11
|
+
|
12
|
+
- Added a new Sony FileFormat value
|
13
|
+
- Added Validate warning about duplicate EXIF
|
14
|
+
- Added ability to edit JPEG APP1 EXIF segment with incorrect header
|
15
|
+
- Decode a few new Sony ARW tags
|
16
|
+
- Improved -htmldump of non-EXIF-based maker notes
|
17
|
+
- Enhanced -geotag from CSV files support GPSSpeed (with variable units),
|
18
|
+
"bearing" for GPSTrack, and GPSDateTime in format "dd.mm.YYYY HH:MM:SS"
|
19
|
+
- Enhanced ImageDataMD5 to also support CRW, RAF, X3F and AVIF images
|
20
|
+
- Enhanced -efile option to also record updated and created file names
|
21
|
+
- Family 8 group names may now also be used in Composite Require/Desire tags
|
22
|
+
- Fixed handling of undefined tags in -if conditions to conform with
|
23
|
+
documentation and match -p and -tagsFromFile behaviour when -m or -f option
|
24
|
+
is used
|
25
|
+
- Fixed problem where setting the Geotime value didn't work when using an
|
26
|
+
advanced-formatting expression containing a greater-than symbol (>)
|
27
|
+
|
10
28
|
Mar. 28, 2023 - Version 12.59
|
11
29
|
|
12
30
|
- COMPATIBILITY WARNING: Changed the calculated ImageDataMD5 for JPEG images
|
@@ -20,14 +38,13 @@ Mar. 28, 2023 - Version 12.59
|
|
20
38
|
- Decode a new Olympus tag and improved decoding of another (thanks Herb)
|
21
39
|
- Decode a couple of new PanasonicRaw tags
|
22
40
|
- Decode image coordinates for a couple more VNT object types
|
23
|
-
- Enhanced ImageDataMD5 to also support MRW, CR3, PNG, MOV/MP4 and
|
24
|
-
files
|
41
|
+
- Enhanced ImageDataMD5 to also support MRW, CR3, IIQ, PNG, MOV/MP4 and some
|
42
|
+
RIFF-based files
|
25
43
|
- Improved verbose messages when deleting NikonApp trailer
|
26
44
|
- Patched to avoid structure warnings when copying tags from Nikon files
|
27
45
|
containing NKSC metadata
|
28
46
|
- Fixed %-C filename format code to work properly with the -fileOrder and
|
29
47
|
-progress options
|
30
|
-
- Fixed new ImageDataMD5 tag to work properly with PhaseOne IIQ files
|
31
48
|
- Fixed potential ValueConv warning when reading LIF files
|
32
49
|
- API Changes:
|
33
50
|
- Added SetAlternateFile method
|
@@ -196,6 +213,8 @@ Nov. 8, 2022 - Version 12.50 (production release)
|
|
196
213
|
- Fixed inconsistent year and time zone for Kenwood dashcam timed GPS in MP4
|
197
214
|
videos
|
198
215
|
|
216
|
+
History of older versions (back to Nov. 19, 2003 - Version 1.00) -->
|
217
|
+
|
199
218
|
Oct. 19, 2022 - Version 12.49
|
200
219
|
|
201
220
|
- Added read support for Windows ICO and CUR files
|
@@ -363,8 +382,6 @@ June 1, 2022 - Version 12.42 (production release)
|
|
363
382
|
- Patched to allow PDF Encrypt object to be "null"
|
364
383
|
- Fixed bug reading ICC_Profile 'meta' tags
|
365
384
|
|
366
|
-
History of older versions (back to Nov. 19, 2003 - Version 1.00) -->
|
367
|
-
|
368
385
|
Apr. 7, 2022 - Version 12.41
|
369
386
|
|
370
387
|
- Added support for "OM SYSTEM" maker notes
|
data/bin/MANIFEST
CHANGED
data/bin/META.json
CHANGED
data/bin/META.yml
CHANGED
data/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.60.tar.gz | tar -xf -
|
111
|
+
cd Image-ExifTool-12.60
|
112
112
|
./exiftool t/images/ExifTool.jpg
|
113
113
|
|
114
114
|
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 = '12.
|
14
|
+
my $version = '12.60';
|
15
15
|
|
16
16
|
# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
|
17
17
|
BEGIN {
|
@@ -922,12 +922,14 @@ for (;;) {
|
|
922
922
|
$mt->Options(Duplicates => 1);
|
923
923
|
next;
|
924
924
|
}
|
925
|
-
if (/^efile(\d)?(!)?$/i) {
|
925
|
+
if (/^efile(\d+)?(!)?$/i) {
|
926
926
|
my $arg = shift;
|
927
927
|
defined $arg or Error("Expecting file name for -$_ option\n"), $badCmd=1, next;
|
928
|
-
$efile[0] = $arg if not $1 or $1 & 0x01
|
929
|
-
$efile[1] = $arg if $1 and $1 & 0x02;
|
930
|
-
$efile[2] = $arg if $1 and $1 & 0x04;
|
928
|
+
$efile[0] = $arg if not $1 or $1 & 0x01;# error
|
929
|
+
$efile[1] = $arg if $1 and $1 & 0x02; # unchanged
|
930
|
+
$efile[2] = $arg if $1 and $1 & 0x04; # failed -if condition
|
931
|
+
$efile[3] = $arg if $1 and $1 & 0x08; # updated
|
932
|
+
$efile[4] = $arg if $1 and $1 & 0x016; # created
|
931
933
|
unlink $arg if $2;
|
932
934
|
next;
|
933
935
|
}
|
@@ -1337,7 +1339,7 @@ for (;;) {
|
|
1337
1339
|
AddSetTagsFile($setTagsFile = '@') if not $setTagsFile and /(<|>)/;
|
1338
1340
|
if ($setTagsFile) {
|
1339
1341
|
push @{$setTags{$setTagsFile}}, $_;
|
1340
|
-
if (
|
1342
|
+
if ($1 eq '>') {
|
1341
1343
|
$useMWG = 1 if /^(.*>\s*)?mwg:/si;
|
1342
1344
|
if (/\b(filename|directory|testname)#?$/i) {
|
1343
1345
|
$doSetFileName = 1;
|
@@ -2083,6 +2085,7 @@ sub GetImageInfo($$)
|
|
2083
2085
|
push @delFiles, $original;
|
2084
2086
|
} elsif ($et->Rename($original, $file)) {
|
2085
2087
|
$verbose and print $vout "Restored from $original\n";
|
2088
|
+
EFile($file, 3);
|
2086
2089
|
++$countGoodWr;
|
2087
2090
|
} else {
|
2088
2091
|
Warn "Error renaming $original\n";
|
@@ -3042,6 +3045,7 @@ sub SetImageInfo($$$)
|
|
3042
3045
|
$r3 = $et->SetSystemTags($file);
|
3043
3046
|
}
|
3044
3047
|
if ($r0 > 0 or $r1 > 0 or $r2 > 0 or $r3 > 0) {
|
3048
|
+
EFile($infile, 3);
|
3045
3049
|
++$countGoodWr;
|
3046
3050
|
} elsif ($r0 < 0 or $r1 < 0 or $r2 < 0 or $r3 < 0) {
|
3047
3051
|
EFile($infile);
|
@@ -3156,6 +3160,7 @@ sub SetImageInfo($$$)
|
|
3156
3160
|
$preserveTime{$file} = [ $aTime, $mTime, $cTime ];
|
3157
3161
|
}
|
3158
3162
|
}
|
3163
|
+
EFile($infile, 3);
|
3159
3164
|
++$countGoodWr;
|
3160
3165
|
} else {
|
3161
3166
|
close(NEW_FILE);
|
@@ -3171,6 +3176,7 @@ sub SetImageInfo($$$)
|
|
3171
3176
|
# simply rename temporary file to replace original
|
3172
3177
|
# (if we didn't already rename it to add "_original")
|
3173
3178
|
} elsif ($et->Rename($tmpFile, $dstFile)) {
|
3179
|
+
EFile($infile, 3);
|
3174
3180
|
++$countGoodWr;
|
3175
3181
|
} else {
|
3176
3182
|
my $newFile = $tmpFile;
|
@@ -3188,21 +3194,26 @@ sub SetImageInfo($$$)
|
|
3188
3194
|
# (don't delete tmp file now because it is all we have left)
|
3189
3195
|
++$countBadWr;
|
3190
3196
|
} else {
|
3197
|
+
EFile($infile, 3);
|
3191
3198
|
++$countGoodWr;
|
3192
3199
|
}
|
3193
3200
|
}
|
3194
3201
|
} elsif ($overwriteOrig) {
|
3195
3202
|
# erase original file
|
3203
|
+
EFile($infile, 3);
|
3196
3204
|
$et->Unlink($file) or Warn "Error erasing original $file\n";
|
3197
3205
|
++$countGoodWr;
|
3198
3206
|
} else {
|
3207
|
+
EFile($infile, 4);
|
3199
3208
|
++$countGoodCr;
|
3200
3209
|
}
|
3201
3210
|
} else {
|
3202
3211
|
# this file was created from scratch, not edited
|
3212
|
+
EFile($infile, 4);
|
3203
3213
|
++$countGoodCr;
|
3204
3214
|
}
|
3205
3215
|
} else {
|
3216
|
+
EFile($infile, 3);
|
3206
3217
|
++$countGoodWr;
|
3207
3218
|
}
|
3208
3219
|
} elsif ($success) {
|
@@ -4439,7 +4450,7 @@ sub ReadStayOpen($)
|
|
4439
4450
|
|
4440
4451
|
#------------------------------------------------------------------------------
|
4441
4452
|
# Add new entry to -efile output file
|
4442
|
-
# Inputs: 0) file name, 1) -efile option number (0=error, 1=same, 2=failed)
|
4453
|
+
# Inputs: 0) file name, 1) -efile option number (0=error, 1=same, 2=failed, 3=updated, 4=created)
|
4443
4454
|
sub EFile($$)
|
4444
4455
|
{
|
4445
4456
|
my $entry = shift;
|
@@ -5301,12 +5312,12 @@ escaped. The inverse conversion is applied when writing tags.
|
|
5301
5312
|
|
5302
5313
|
=item B<-f> (B<-forcePrint>)
|
5303
5314
|
|
5304
|
-
Force printing of tags even if
|
5305
|
-
|
5306
|
-
|
5307
|
-
|
5308
|
-
MissingTagValue option.
|
5309
|
-
B<-listx> output, or to allow tags to be deleted when writing with the
|
5315
|
+
Force printing of tags even if they don't exist. This option applies to
|
5316
|
+
tags specified on the command line, or with the B<-p>, B<-if> or
|
5317
|
+
B<-tagsFromFile> options. When B<-f> is used, the value of any missing tag
|
5318
|
+
is set to a dash (C<->) by default, but this may be configured via the API
|
5319
|
+
MissingTagValue option. B<-f> is also used to add a 'flags' attribute to
|
5320
|
+
the B<-listx> output, or to allow tags to be deleted when writing with the
|
5310
5321
|
B<-csv>=I<CSVFILE> feature.
|
5311
5322
|
|
5312
5323
|
=item B<-g>[I<NUM>][:I<NUM>...] (B<-groupHeadings>)
|
@@ -5530,7 +5541,7 @@ with this command:
|
|
5530
5541
|
|
5531
5542
|
produces output like this:
|
5532
5543
|
|
5533
|
-
-- Generated by ExifTool 12.
|
5544
|
+
-- Generated by ExifTool 12.60 --
|
5534
5545
|
File: a.jpg - 2003:10:31 15:44:19
|
5535
5546
|
(f/5.6, 1/60s, ISO 100)
|
5536
5547
|
File: b.jpg - 2006:05:23 11:57:38
|
@@ -6512,10 +6523,11 @@ exit status of the command (see L</EXIT STATUS>).
|
|
6512
6523
|
|
6513
6524
|
Save the names of files giving errors (I<NUM> missing or 1), files that were
|
6514
6525
|
unchanged (I<NUM> is 2), files that fail the B<-if> condition (I<NUM> is 4),
|
6515
|
-
|
6516
|
-
|
6517
|
-
|
6518
|
-
I<ERRFILE>
|
6526
|
+
files that were updated (I<NUM> is 8), files that were created (I<NUM> is
|
6527
|
+
16), or any combination thereof by summing I<NUM> (eg. B<-efile3> is the
|
6528
|
+
same has having both B<-efile> and B<-efile2> options with the same
|
6529
|
+
I<ERRFILE>). By default, file names are appended to any existing I<ERRFILE>,
|
6530
|
+
but I<ERRFILE> is overwritten if an exclamation point is added to the option
|
6519
6531
|
(eg. B<-efile!>). Saves the name of the file specified by the B<-srcfile>
|
6520
6532
|
option if applicable.
|
6521
6533
|
|
@@ -6533,10 +6545,10 @@ option no longer suppresses the output "{readyNUM}" message.
|
|
6533
6545
|
=item B<-file>I<NUM> I<ALTFILE>
|
6534
6546
|
|
6535
6547
|
Read tags from an alternate source file. These tags are accessed via the
|
6536
|
-
family 8 group name (eg. C<File1:TAG
|
6537
|
-
contain filename formatting codes %d,
|
6538
|
-
allows tags from different files to be
|
6539
|
-
B<-if> and B<-p> options.
|
6548
|
+
family 8 group name (eg. C<File1:TAG> for the B<-file1> option, C<File2:TAG>
|
6549
|
+
for B<-file2>, etc). I<ALTFILE> may contain filename formatting codes %d,
|
6550
|
+
%f and %e. Among other things, this allows tags from different files to be
|
6551
|
+
compared and combined using the B<-if> and B<-p> options.
|
6540
6552
|
|
6541
6553
|
=item B<-list_dir>
|
6542
6554
|
|
@@ -21,7 +21,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
21
21
|
use Image::ExifTool::Exif;
|
22
22
|
use Image::ExifTool::Canon;
|
23
23
|
|
24
|
-
$VERSION = '1.
|
24
|
+
$VERSION = '1.60';
|
25
25
|
|
26
26
|
sub WriteCRW($$);
|
27
27
|
sub ProcessCanonRaw($$$);
|
@@ -698,6 +698,10 @@ sub ProcessCanonRaw($$$)
|
|
698
698
|
$format ne 'string' and not $subdir;
|
699
699
|
} else {
|
700
700
|
$valueDataPos = $ptr;
|
701
|
+
# do MD5 of image data if requested
|
702
|
+
if ($$et{ImageDataMD5} and $tagID == 0x2005) {
|
703
|
+
$raf->Seek($ptr, 0) and $et->ImageDataMD5($raf, $size, 'raw');
|
704
|
+
}
|
701
705
|
if ($size <= 512 or ($verbose > 2 and $size <= 65536)
|
702
706
|
or ($tagInfo and ($$tagInfo{SubDirectory}
|
703
707
|
or grep(/^$$tagInfo{Name}$/i, $et->GetRequestedTags()) )))
|
@@ -56,7 +56,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
|
|
56
56
|
use Image::ExifTool qw(:DataAccess :Utils);
|
57
57
|
use Image::ExifTool::MakerNotes;
|
58
58
|
|
59
|
-
$VERSION = '4.
|
59
|
+
$VERSION = '4.44';
|
60
60
|
|
61
61
|
sub ProcessExif($$$);
|
62
62
|
sub WriteExif($$$);
|
@@ -1511,9 +1511,10 @@ my %opcodeInfo = (
|
|
1511
1511
|
0x7031 => {
|
1512
1512
|
Name => 'VignettingCorrection',
|
1513
1513
|
Notes => 'found in Sony ARW images',
|
1514
|
-
Protected => 1,
|
1515
1514
|
Writable => 'int16s',
|
1516
1515
|
WriteGroup => 'SubIFD',
|
1516
|
+
Permanent => 1,
|
1517
|
+
Protected => 1,
|
1517
1518
|
PrintConv => {
|
1518
1519
|
256 => 'Off',
|
1519
1520
|
257 => 'Auto',
|
@@ -1524,17 +1525,19 @@ my %opcodeInfo = (
|
|
1524
1525
|
0x7032 => {
|
1525
1526
|
Name => 'VignettingCorrParams', #forum7640
|
1526
1527
|
Notes => 'found in Sony ARW images',
|
1527
|
-
Protected => 1,
|
1528
1528
|
Writable => 'int16s',
|
1529
1529
|
WriteGroup => 'SubIFD',
|
1530
1530
|
Count => 17,
|
1531
|
+
Permanent => 1,
|
1532
|
+
Protected => 1,
|
1531
1533
|
},
|
1532
1534
|
0x7034 => {
|
1533
1535
|
Name => 'ChromaticAberrationCorrection',
|
1534
1536
|
Notes => 'found in Sony ARW images',
|
1535
|
-
Protected => 1,
|
1536
1537
|
Writable => 'int16s',
|
1537
1538
|
WriteGroup => 'SubIFD',
|
1539
|
+
Permanent => 1,
|
1540
|
+
Protected => 1,
|
1538
1541
|
PrintConv => {
|
1539
1542
|
0 => 'Off',
|
1540
1543
|
1 => 'Auto',
|
@@ -1544,17 +1547,19 @@ my %opcodeInfo = (
|
|
1544
1547
|
0x7035 => {
|
1545
1548
|
Name => 'ChromaticAberrationCorrParams', #forum6509
|
1546
1549
|
Notes => 'found in Sony ARW images',
|
1547
|
-
Protected => 1,
|
1548
1550
|
Writable => 'int16s',
|
1549
1551
|
WriteGroup => 'SubIFD',
|
1550
1552
|
Count => 33,
|
1553
|
+
Permanent => 1,
|
1554
|
+
Protected => 1,
|
1551
1555
|
},
|
1552
1556
|
0x7036 => {
|
1553
1557
|
Name => 'DistortionCorrection',
|
1554
1558
|
Notes => 'found in Sony ARW images',
|
1555
|
-
Protected => 1,
|
1556
1559
|
Writable => 'int16s',
|
1557
1560
|
WriteGroup => 'SubIFD',
|
1561
|
+
Permanent => 1,
|
1562
|
+
Protected => 1,
|
1558
1563
|
PrintConv => {
|
1559
1564
|
0 => 'Off',
|
1560
1565
|
1 => 'Auto',
|
@@ -1565,10 +1570,38 @@ my %opcodeInfo = (
|
|
1565
1570
|
0x7037 => {
|
1566
1571
|
Name => 'DistortionCorrParams', #forum6509
|
1567
1572
|
Notes => 'found in Sony ARW images',
|
1568
|
-
Protected => 1,
|
1569
1573
|
Writable => 'int16s',
|
1570
1574
|
WriteGroup => 'SubIFD',
|
1571
1575
|
Count => 17,
|
1576
|
+
Permanent => 1,
|
1577
|
+
Protected => 1,
|
1578
|
+
},
|
1579
|
+
0x7038 => { #github#195 (Sony ARW)
|
1580
|
+
Name => 'SonyRawImageSize',
|
1581
|
+
Notes => 'size of actual image in Sony ARW files',
|
1582
|
+
Writable => 'int32u',
|
1583
|
+
WriteGroup => 'SubIFD',
|
1584
|
+
Count => 2,
|
1585
|
+
Permanent => 1,
|
1586
|
+
Protected => 1,
|
1587
|
+
},
|
1588
|
+
0x7310 => { #github#195 (Sony ARW)
|
1589
|
+
Name => 'BlackLevel',
|
1590
|
+
Notes => 'found in Sony ARW images',
|
1591
|
+
Writable => 'int16u',
|
1592
|
+
WriteGroup => 'SubIFD',
|
1593
|
+
Count => 4,
|
1594
|
+
Permanent => 1,
|
1595
|
+
Protected => 1,
|
1596
|
+
},
|
1597
|
+
0x7313 => { #github#195 (Sony ARW)
|
1598
|
+
Name => 'WB_RGGBLevels',
|
1599
|
+
Notes => 'found in Sony ARW images',
|
1600
|
+
Writable => 'int16s',
|
1601
|
+
WriteGroup => 'SubIFD',
|
1602
|
+
Count => 4,
|
1603
|
+
Permanent => 1,
|
1604
|
+
Protected => 1,
|
1572
1605
|
},
|
1573
1606
|
0x74c7 => { #IB (in ARW images from some Sony cameras)
|
1574
1607
|
Name => 'SonyCropTopLeft',
|
@@ -5893,9 +5926,7 @@ sub ProcessExif($$$)
|
|
5893
5926
|
my $base = $$dirInfo{Base} || 0;
|
5894
5927
|
my $firstBase = $base;
|
5895
5928
|
my $raf = $$dirInfo{RAF};
|
5896
|
-
my $verbose =
|
5897
|
-
my $validate = $et->Options('Validate');
|
5898
|
-
my $saveFormat = $et->Options('SaveFormat');
|
5929
|
+
my ($verbose,$validate,$saveFormat) = @{$$et{OPTIONS}}{qw(Verbose Validate SaveFormat)};
|
5899
5930
|
my $htmlDump = $$et{HTML_DUMP};
|
5900
5931
|
my $success = 1;
|
5901
5932
|
my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffName, $doMD5);
|
@@ -5914,7 +5945,12 @@ sub ProcessExif($$$)
|
|
5914
5945
|
$isExif and $$et{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/)
|
5915
5946
|
{
|
5916
5947
|
my $path = $et->MetadataPath();
|
5917
|
-
|
5948
|
+
if ($path =~ /^(JPEG-APP1-IFD0|TIFF-IFD0|PSD-EXIFInfo-IFD0)$/) {
|
5949
|
+
unless ($$et{DOC_NUM}) {
|
5950
|
+
$et->Warn("Duplicate EXIF at $path") if $$et{HasExif};
|
5951
|
+
$$et{HasExif} = 1;
|
5952
|
+
}
|
5953
|
+
} else {
|
5918
5954
|
if ($Image::ExifTool::MWG::strict) {
|
5919
5955
|
$et->Warn("Ignored non-standard EXIF at $path");
|
5920
5956
|
return 0;
|
@@ -6378,10 +6414,10 @@ sub ProcessExif($$$)
|
|
6378
6414
|
$tval .= " ($rational)" if defined $rational;
|
6379
6415
|
if ($htmlDump) {
|
6380
6416
|
my ($tagName, $colName);
|
6381
|
-
if ($
|
6382
|
-
$tagName = 'MakerNotes';
|
6383
|
-
} elsif ($tagInfo) {
|
6417
|
+
if ($tagInfo) {
|
6384
6418
|
$tagName = $$tagInfo{Name};
|
6419
|
+
} elsif ($tagID == 0x927c and $dirName eq 'ExifIFD') {
|
6420
|
+
$tagName = 'MakerNotes';
|
6385
6421
|
} else {
|
6386
6422
|
$tagName = sprintf("Tag 0x%.4x",$tagID);
|
6387
6423
|
}
|
@@ -6456,6 +6492,9 @@ sub ProcessExif($$$)
|
|
6456
6492
|
}
|
6457
6493
|
# add value data block (underlining maker notes data)
|
6458
6494
|
$et->HDump($exifDumpPos,$size,"$tagName value",'SAME', $flag, $sid);
|
6495
|
+
if ($subdir and $$tagInfo{MakerNotes} and $$tagInfo{NotIFD}) {
|
6496
|
+
$et->HDump($exifDumpPos,$size,"$tagName value",undef,undef,$$dirInfo{OffsetName});
|
6497
|
+
}
|
6459
6498
|
}
|
6460
6499
|
} else {
|
6461
6500
|
if ($tagID <= $lastID and not $inMakerNotes) {
|
@@ -1671,11 +1671,11 @@ sub ProcessRAF($$)
|
|
1671
1671
|
my ($rafNum, $ifdNum) = ('','');
|
1672
1672
|
foreach $offset (0x5c, 0x64, 0x78, 0x80) {
|
1673
1673
|
last if $offset >= $jpos;
|
1674
|
-
unless ($raf->Seek($offset, 0) and $raf->Read($buff,
|
1674
|
+
unless ($raf->Seek($offset, 0) and $raf->Read($buff, 8)) {
|
1675
1675
|
$warn = 1;
|
1676
1676
|
last;
|
1677
1677
|
}
|
1678
|
-
my $start = unpack('
|
1678
|
+
my ($start, $len) = unpack('N2',$buff);
|
1679
1679
|
next unless $start;
|
1680
1680
|
if ($offset == 0x64 or $offset == 0x80) {
|
1681
1681
|
# parse FujiIFD directory
|
@@ -1686,7 +1686,10 @@ sub ProcessRAF($$)
|
|
1686
1686
|
$$et{SET_GROUP1} = "FujiIFD$ifdNum";
|
1687
1687
|
my $tagTablePtr = GetTagTable('Image::ExifTool::FujiFilm::IFD');
|
1688
1688
|
# this is TIFF-format data only for some models, so no warning if it fails
|
1689
|
-
$et->ProcessTIFF(\%dirInfo, $tagTablePtr, \&Image::ExifTool::ProcessTIFF)
|
1689
|
+
unless ($et->ProcessTIFF(\%dirInfo, $tagTablePtr, \&Image::ExifTool::ProcessTIFF)) {
|
1690
|
+
# do MD5 of image data if necessary
|
1691
|
+
$et->ImageDataMD5($raf, $len, 'raw') if $$et{ImageDataMD5} and $raf->Seek($start,0);
|
1692
|
+
}
|
1690
1693
|
delete $$et{SET_GROUP1};
|
1691
1694
|
$ifdNum = ($ifdNum || 1) + 1;
|
1692
1695
|
} else {
|
@@ -29,7 +29,7 @@ use vars qw($VERSION);
|
|
29
29
|
use Image::ExifTool qw(:Public);
|
30
30
|
use Image::ExifTool::GPS;
|
31
31
|
|
32
|
-
$VERSION = '1.
|
32
|
+
$VERSION = '1.71';
|
33
33
|
|
34
34
|
sub JITTER() { return 2 } # maximum time jitter
|
35
35
|
|
@@ -92,7 +92,7 @@ my %isOrient = ( dir => 1, pitch => 1, roll => 1 ); # test for orientation key
|
|
92
92
|
# tags which may exist separately in some formats (eg. CSV)
|
93
93
|
my %sepTags = ( dir => 1, pitch => 1, roll => 1, track => 1, speed => 1 );
|
94
94
|
|
95
|
-
# conversion factors for GPSSpeed
|
95
|
+
# conversion factors for GPSSpeed (standard EXIF units only)
|
96
96
|
my %speedConv = (
|
97
97
|
'K' => 1.852, # km/h per knot
|
98
98
|
'M' => 1.150779448, # mph per knot
|
@@ -102,7 +102,14 @@ my %speedConv = (
|
|
102
102
|
'mph' => 'M',
|
103
103
|
);
|
104
104
|
|
105
|
-
|
105
|
+
# all recognized speed conversion factors (non-EXIF included)
|
106
|
+
my %otherConv = (
|
107
|
+
'km/h' => 1.852,
|
108
|
+
'mph' => 1.150779448,
|
109
|
+
'm/s' => 0.514444,
|
110
|
+
);
|
111
|
+
|
112
|
+
my $secPerDay = 24 * 3600; # a useful constant
|
106
113
|
|
107
114
|
#------------------------------------------------------------------------------
|
108
115
|
# Load GPS track log file
|
@@ -140,6 +147,7 @@ sub LoadTrackLog($$;$)
|
|
140
147
|
my ($raf, $from, $time, $isDate, $noDate, $noDateChanged, $lastDate, $dateFlarm);
|
141
148
|
my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings, $sortFixes);
|
142
149
|
my ($canCut, $cutPDOP, $cutHDOP, $cutSats, $e0, $e1, @tmp, $trackFile, $trackTime);
|
150
|
+
my $scaleSpeed;
|
143
151
|
|
144
152
|
unless (eval { require Time::Local }) {
|
145
153
|
return 'Geotag feature requires Time::Local installed';
|
@@ -246,7 +254,9 @@ sub LoadTrackLog($$;$)
|
|
246
254
|
$format = 'CSV';
|
247
255
|
# convert recognized headings to our parameter names
|
248
256
|
foreach (@csvHeadings) {
|
257
|
+
my $head = $_;
|
249
258
|
my $param;
|
259
|
+
my $xtra = '';
|
250
260
|
s/^GPS ?//; # remove leading "GPS" to simplify regex patterns
|
251
261
|
if (/^Time ?\(seconds\)$/i) { # DJI
|
252
262
|
# DJI CSV log files have a column "Time(seconds)" which is seconds since
|
@@ -274,7 +284,16 @@ sub LoadTrackLog($$;$)
|
|
274
284
|
/ref$/i and $param .= 'ref';
|
275
285
|
} elsif (/^(Pos)?Alt/i) {
|
276
286
|
$param = 'alt';
|
277
|
-
} elsif (/^
|
287
|
+
} elsif (/^Speed/i) {
|
288
|
+
$param = 'speed';
|
289
|
+
# (recognize units in brackets)
|
290
|
+
if (m{\((mph|km/h|m/s)\)}) {
|
291
|
+
$scaleSpeed = $otherConv{$1};
|
292
|
+
$xtra = " in $1";
|
293
|
+
} else {
|
294
|
+
$xtra = ' in knots';
|
295
|
+
}
|
296
|
+
} elsif (/^(Angle)?(Heading|Track|Bearing)/i) {
|
278
297
|
$param = 'track';
|
279
298
|
} elsif (/^(Angle)?Pitch/i or /^Camera ?Elevation ?Angle/i) {
|
280
299
|
$param = 'pitch';
|
@@ -284,10 +303,10 @@ sub LoadTrackLog($$;$)
|
|
284
303
|
$param = 'dir';
|
285
304
|
}
|
286
305
|
if ($param) {
|
287
|
-
$et->VPrint(2, "CSV column '${
|
306
|
+
$et->VPrint(2, "CSV column '${head}' is $param$xtra\n");
|
288
307
|
$_ = $param;
|
289
308
|
} else {
|
290
|
-
$et->VPrint(2, "CSV column '${
|
309
|
+
$et->VPrint(2, "CSV column '${head}' ignored\n");
|
291
310
|
$_ = ''; # ignore this column
|
292
311
|
}
|
293
312
|
}
|
@@ -479,9 +498,11 @@ DoneFix: $isDate = 1;
|
|
479
498
|
my ($param, $date, $secs, %neg);
|
480
499
|
foreach $param (@csvHeadings) {
|
481
500
|
my $val = shift @vals;
|
482
|
-
last unless defined $val;
|
501
|
+
last unless defined $val and length($val);
|
483
502
|
next unless $param;
|
484
503
|
if ($param eq 'datetime') {
|
504
|
+
# (fix formats like "24.07.2016 13:47:30")
|
505
|
+
$val =~ s/^(\d{2})[^\d](\d{2})[^\d](\d{4}) /$3:$2:$1 /;
|
485
506
|
local $SIG{'__WARN__'} = sub { };
|
486
507
|
my $dateTime = $et->InverseDateTime($val);
|
487
508
|
if ($dateTime) {
|
@@ -510,6 +531,7 @@ DoneFix: $isDate = 1;
|
|
510
531
|
$date = $trackTime;
|
511
532
|
$secs = $val;
|
512
533
|
} else {
|
534
|
+
$val /= $scaleSpeed if $scaleSpeed and $param eq 'speed';
|
513
535
|
$$fix{$param} = $val;
|
514
536
|
$$has{$param} = 1 if $sepTags{$param};
|
515
537
|
}
|
@@ -1204,6 +1226,7 @@ Category: foreach $category (qw{pos track alt orient atemp}) {
|
|
1204
1226
|
@r = $et->SetNewValue(GPSTrackRef => (defined $$tFix{track} ? 'T' : undef), %opts);
|
1205
1227
|
my ($spd, $ref);
|
1206
1228
|
if (defined($spd = $$tFix{speed})) {
|
1229
|
+
# convert to specified units if necessary
|
1207
1230
|
$ref = $$et{OPTIONS}{GeoSpeedRef};
|
1208
1231
|
if ($ref and defined $speedConv{$ref}) {
|
1209
1232
|
$ref = $speedConv{$ref} if $speedConv{$speedConv{$ref}};
|
@@ -21,7 +21,7 @@ sub ProcessKodakPatch($$$);
|
|
21
21
|
sub WriteUnknownOrPreview($$$);
|
22
22
|
sub FixLeicaBase($$;$);
|
23
23
|
|
24
|
-
$VERSION = '2.
|
24
|
+
$VERSION = '2.14';
|
25
25
|
|
26
26
|
my $debug; # set to 1 to enable debugging code
|
27
27
|
|
@@ -92,6 +92,7 @@ my $debug; # set to 1 to enable debugging code
|
|
92
92
|
{
|
93
93
|
Name => 'MakerNoteDJIInfo',
|
94
94
|
Condition => '$$valPt =~ /^\[ae_dbg_info:/',
|
95
|
+
NotIFD => 1,
|
95
96
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::Info' },
|
96
97
|
},
|
97
98
|
{
|
@@ -489,14 +489,7 @@ sub ProcessMRW($$;$)
|
|
489
489
|
$err and $et->Error("MRW format error", $$et{TIFF_TYPE} eq 'ARW');
|
490
490
|
} else {
|
491
491
|
$err and $et->Warn("MRW format error");
|
492
|
-
|
493
|
-
my ($num, $md5) = (0, $$et{ImageDataMD5});
|
494
|
-
while ($raf->Read($data, 65536)) {
|
495
|
-
$md5->add($data);
|
496
|
-
$num += length $data;
|
497
|
-
}
|
498
|
-
$et->VPrint(0, "$$et{INDENT}(ImageDataMD5: $num bytes of raw data)\n");
|
499
|
-
}
|
492
|
+
$et->ImageDataMD5($raf, undef, 'raw');
|
500
493
|
}
|
501
494
|
return $rtnVal;
|
502
495
|
}
|
@@ -1542,12 +1542,7 @@ sub ProcessPNG($$)
|
|
1542
1542
|
# skip over data chunks if possible/necessary
|
1543
1543
|
} elsif (not $validate or $len > $chunkSizeLimit) {
|
1544
1544
|
if ($md5) {
|
1545
|
-
|
1546
|
-
my $n = $len > 65536 ? 65536 : $len;
|
1547
|
-
$raf->Read($dbuf,$n) == $n or last;
|
1548
|
-
$md5->add($dbuf);
|
1549
|
-
$len -= $n;
|
1550
|
-
}
|
1545
|
+
$et->ImageDataMD5($raf, $len);
|
1551
1546
|
$raf->Read($cbuf, 4) == 4 or $et->Warn('Truncated data'), last;
|
1552
1547
|
} else {
|
1553
1548
|
$raf->Seek($len + 4, 1) or $et->Warn('Seek error'), last;
|
@@ -8784,6 +8784,16 @@ sub HandleItemInfo($)
|
|
8784
8784
|
$et->VPrint(0, "$$et{INDENT} [snip $snip bytes]\n") if $snip;
|
8785
8785
|
}
|
8786
8786
|
}
|
8787
|
+
# do MD5 checksum of AVIF "av01" image data
|
8788
|
+
if ($type eq 'av01' and $$et{ImageDataMD5}) {
|
8789
|
+
my $md5 = $$et{ImageDataMD5};
|
8790
|
+
my $tot = 0;
|
8791
|
+
foreach $extent (@{$$item{Extents}}) {
|
8792
|
+
$raf->Seek($$extent[1] + $base, 0) or $et->Warn('Seek error in av01 image data'), last;
|
8793
|
+
$tot += $et->ImageDataMD5($raf, $$extent[2], 'av01 image', 1);
|
8794
|
+
}
|
8795
|
+
$et->VPrint(0, "$$et{INDENT}(ImageDataMD5: $tot bytes of av01 data)\n") if $tot;
|
8796
|
+
}
|
8787
8797
|
next unless $name;
|
8788
8798
|
# assemble the data for this item
|
8789
8799
|
undef $buff;
|
@@ -30,7 +30,7 @@ use strict;
|
|
30
30
|
use vars qw($VERSION $AUTOLOAD);
|
31
31
|
use Image::ExifTool qw(:DataAccess :Utils);
|
32
32
|
|
33
|
-
$VERSION = '1.
|
33
|
+
$VERSION = '1.64';
|
34
34
|
|
35
35
|
sub ConvertTimecode($);
|
36
36
|
sub ProcessSGLT($$$);
|
@@ -2102,14 +2102,7 @@ sub ProcessRIFF($$)
|
|
2102
2102
|
# do MD5 if required
|
2103
2103
|
if ($md5 and $isImageData{$tag}) {
|
2104
2104
|
$rewind = $raf->Tell();
|
2105
|
-
|
2106
|
-
while ($more) {
|
2107
|
-
my $n = $more > 65536 ? 65536 : $more;
|
2108
|
-
$raf->Read($buff, $n) == $n or $err = 1, last;
|
2109
|
-
$md5->add($buff);
|
2110
|
-
$more -= $n;
|
2111
|
-
}
|
2112
|
-
$et->VPrint(0, "$$et{INDENT}(ImageDataMD5: '${tag}' chunk, $len2 bytes)\n");
|
2105
|
+
$et->ImageDataMD5($raf, $len2, "'${tag}' chunk");
|
2113
2106
|
}
|
2114
2107
|
if ($tag eq 'LIST_movi' and $ee) {
|
2115
2108
|
$raf->Seek($rewind, 0) or $err = 1, last if $rewind;
|
@@ -19,7 +19,7 @@ use vars qw($VERSION);
|
|
19
19
|
use Image::ExifTool qw(:DataAccess :Utils);
|
20
20
|
use Image::ExifTool::Exif;
|
21
21
|
|
22
|
-
$VERSION = '1.
|
22
|
+
$VERSION = '1.36';
|
23
23
|
|
24
24
|
sub ProcessRicohText($$$);
|
25
25
|
sub ProcessRicohRMETA($$$);
|
@@ -949,6 +949,7 @@ sub ProcessRicohText($$$)
|
|
949
949
|
|
950
950
|
my $data = substr($$dataPt, $dirStart, $dirLen);
|
951
951
|
return 1 if $data =~ /^\0/; # blank Ricoh maker notes
|
952
|
+
$et->VerboseDir('RicohText', undef, $dirLen);
|
952
953
|
# validate text maker notes
|
953
954
|
unless ($data =~ /^(Rev|Rv)/) {
|
954
955
|
$et->Warn('Bad Ricoh maker notes');
|
@@ -16,7 +16,7 @@ use vars qw($VERSION);
|
|
16
16
|
use Image::ExifTool qw(:DataAccess :Utils);
|
17
17
|
use Image::ExifTool::Sigma;
|
18
18
|
|
19
|
-
$VERSION = '1.
|
19
|
+
$VERSION = '1.30';
|
20
20
|
|
21
21
|
sub ProcessX3FHeader($$$);
|
22
22
|
sub ProcessX3FDirectory($$$);
|
@@ -545,10 +545,16 @@ sub ProcessX3FDirectory($$$)
|
|
545
545
|
if ($$tagInfo{Name} eq 'PreviewImage') {
|
546
546
|
# check image header to see if this is a JPEG preview image
|
547
547
|
$raf->Read($buff, 28) == 28 or return 'Error reading PreviewImage header';
|
548
|
-
# ignore all image data but JPEG compressed (version 2.0, type 2, format 18)
|
549
|
-
next unless $buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/;
|
550
548
|
$offset += 28;
|
551
549
|
$len -= 28;
|
550
|
+
# ignore all image data but JPEG compressed (version 2.0, type 2, format 18)
|
551
|
+
unless ($buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/) {
|
552
|
+
# do MD5 on non-preview data if requested
|
553
|
+
if ($$et{ImageDataMD5} and substr($buff,8,1) ne "\x02") {
|
554
|
+
$et->ImageDataMD5($raf, $len, 'SigmaRaw IMAG');
|
555
|
+
}
|
556
|
+
next;
|
557
|
+
}
|
552
558
|
$raf->Read($buff, $len) == $len or return "Error reading PreviewImage data";
|
553
559
|
# check fore EXIF segment, and extract this image as the JpgFromRaw
|
554
560
|
if ($buff =~ /^\xff\xd8\xff\xe1/) {
|
@@ -34,7 +34,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
34
34
|
use Image::ExifTool::Exif;
|
35
35
|
use Image::ExifTool::Minolta;
|
36
36
|
|
37
|
-
$VERSION = '3.
|
37
|
+
$VERSION = '3.59';
|
38
38
|
|
39
39
|
sub ProcessSRF($$$);
|
40
40
|
sub ProcessSR2($$$);
|
@@ -1957,6 +1957,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1957
1957
|
'3 3 3 0' => 'ARW 2.3.3', #JR (ILCE-9)
|
1958
1958
|
'3 3 5 0' => 'ARW 2.3.5', #JR (DSC-HX99)
|
1959
1959
|
'4 0 0 0' => 'ARW 4.0', # (ILCE-7SM3)
|
1960
|
+
'4 0 1 0' => 'ARW 4.0.1', #github#195 (ZV-E1)
|
1960
1961
|
# what about cRAW images?
|
1961
1962
|
},
|
1962
1963
|
},
|
@@ -1149,7 +1149,7 @@ my %tagLookup = (
|
|
1149
1149
|
'bitspercomponent' => { 133 => 0x87 },
|
1150
1150
|
'bitspersample' => { 119 => 0x102, 340 => 0xa, 517 => 'BitsPerSample' },
|
1151
1151
|
'blackacquirerows' => { 138 => 0x18ba },
|
1152
|
-
'blacklevel' => { 119 => 0xc61a, 206 => 0x20, 233 => 0x3d, 317 => [0x401,0x1012], 379 => 0x21d, 442 => [0x7300,0x7310] },
|
1152
|
+
'blacklevel' => { 119 => [0x7310,0xc61a], 206 => 0x20, 233 => 0x3d, 317 => [0x401,0x1012], 379 => 0x21d, 442 => [0x7300,0x7310] },
|
1153
1153
|
'blacklevel2' => { 316 => 0x600, 320 => 0x600 },
|
1154
1154
|
'blacklevelblue' => { 340 => 0x1e },
|
1155
1155
|
'blacklevelbottom' => { 138 => 0x3f0 },
|
@@ -6271,6 +6271,7 @@ my %tagLookup = (
|
|
6271
6271
|
'sonyminaperture' => { 454 => 0x1, 455 => 0x1 },
|
6272
6272
|
'sonymodelid' => { 435 => 0xb001 },
|
6273
6273
|
'sonyquality' => { 184 => 0x3c },
|
6274
|
+
'sonyrawimagesize' => { 119 => 0x7038 },
|
6274
6275
|
'sonytimeminsec' => { 455 => 0x61 },
|
6275
6276
|
'sortalbum' => { 387 => 'soal' },
|
6276
6277
|
'sortalbumartist' => { 387 => 'soaa' },
|
@@ -7052,7 +7053,7 @@ my %tagLookup = (
|
|
7052
7053
|
'wb_rgbmulfluorescent' => { 138 => 0x854 },
|
7053
7054
|
'wb_rgbmultungsten' => { 138 => 0x853 },
|
7054
7055
|
'wb_rggbblacklevels' => { 35 => 0x25 },
|
7055
|
-
'wb_rggblevels' => { 190 => 0x4, 201 => 0x0, 205 => 0x13e8, 206 => 0x38, 442 => 0x7313 },
|
7056
|
+
'wb_rggblevels' => { 119 => 0x7313, 190 => 0x4, 201 => 0x0, 205 => 0x13e8, 206 => 0x38, 442 => 0x7313 },
|
7056
7057
|
'wb_rggblevelsasshot' => { 38 => 0x0, 39 => 0x0, 40 => 0x19, 41 => 0x55, 42 => 0x69, 43 => 0x22, 44 => 0x3f, 47 => 0x3f, 48 => 0x3f, 49 => 0x3f, 50 => 0x47 },
|
7057
7058
|
'wb_rggblevelsauto' => { 35 => 0x1, 38 => 0x5, 39 => 0x8, 40 => 0x1e, 41 => 0x5a, 42 => 0x6e, 43 => 0x18, 44 => 0x44, 47 => 0x44, 48 => 0x44, 49 => 0x44, 50 => 0x4c, 205 => 0x1478, 206 => 0x114, 409 => 0xa022, 442 => 0x7312 },
|
7058
7059
|
'wb_rggblevelsblack' => { 409 => 0xa028 },
|
@@ -12,7 +12,7 @@ meta information extracted from or written to a file.
|
|
12
12
|
=head1 TAG TABLES
|
13
13
|
|
14
14
|
The tables listed below give the names of all tags recognized by ExifTool.
|
15
|
-
They contain a total of
|
15
|
+
They contain a total of 26393 tags, with 16860 unique tag names.
|
16
16
|
|
17
17
|
B<Tag ID>, B<Index#> or B<Sequence> is given in the first column of each
|
18
18
|
table. A B<Tag ID> is the computer-readable equivalent of a tag name, and
|
@@ -498,6 +498,9 @@ for the official EXIF 2.32 specification.
|
|
498
498
|
0x7035 ChromaticAberrationCorrParams SubIFD int16s[33]!
|
499
499
|
0x7036 DistortionCorrection SubIFD int16s!
|
500
500
|
0x7037 DistortionCorrParams SubIFD int16s[17]!
|
501
|
+
0x7038 SonyRawImageSize SubIFD int32u[2]!
|
502
|
+
0x7310 BlackLevel SubIFD int16u[4]!
|
503
|
+
0x7313 WB_RGGBLevels SubIFD int16s[4]!
|
501
504
|
0x74c7 SonyCropTopLeft SubIFD int32u[2]!
|
502
505
|
0x74c8 SonyCropSize SubIFD int32u[2]!
|
503
506
|
0x800d ImageID - no
|
@@ -430,7 +430,6 @@ sub AddImageDataMD5($$$)
|
|
430
430
|
my $verbose = $et->Options('Verbose');
|
431
431
|
my $md5 = $$et{ImageDataMD5};
|
432
432
|
my $raf = $$dirInfo{RAF};
|
433
|
-
my $base = $$dirInfo{Base} || 0;
|
434
433
|
|
435
434
|
foreach $tagID (sort keys %$offsetInfo) {
|
436
435
|
next unless ref $$offsetInfo{$tagID} eq 'ARRAY'; # ignore scalar tag values used for Validate
|
@@ -451,14 +450,8 @@ sub AddImageDataMD5($$$)
|
|
451
450
|
foreach $offset (@offsets) {
|
452
451
|
my $size = shift @sizes;
|
453
452
|
next unless $offset =~ /^\d+$/ and $size and $size =~ /^\d+$/ and $size;
|
454
|
-
next unless $raf->Seek($offset
|
455
|
-
|
456
|
-
my $bytes = $size > 65536 ? 65536 : $size;
|
457
|
-
$raf->Read($buff, $bytes) or last;
|
458
|
-
$md5->add($buff);
|
459
|
-
$total += length($buff);
|
460
|
-
$size -= $bytes;
|
461
|
-
}
|
453
|
+
next unless $raf->Seek($offset, 0); # (offset is absolute)
|
454
|
+
$total += $et->ImageDataMD5($raf, $size);
|
462
455
|
}
|
463
456
|
if ($verbose) {
|
464
457
|
my $name = "$$dirInfo{DirName}:$$tagInfo{Name}";
|
@@ -3324,15 +3324,19 @@ sub InsertTagValues($$$;$$$)
|
|
3324
3324
|
undef $advFmtSelf;
|
3325
3325
|
$didExpr = 1; # set flag indicating an expression was evaluated
|
3326
3326
|
}
|
3327
|
-
unless (defined $val
|
3327
|
+
unless (defined $val) {
|
3328
3328
|
$val = $$self{OPTIONS}{MissingTagValue};
|
3329
3329
|
unless (defined $val) {
|
3330
3330
|
my $g3 = ($docGrp and $var !~ /\b(main|doc\d+):/i) ? $docGrp . ':' : '';
|
3331
3331
|
my $msg = $didExpr ? "Advanced formatting expression returned undef for '$g3${var}'" :
|
3332
3332
|
"Tag '$g3${var}' not defined";
|
3333
|
-
|
3334
|
-
|
3335
|
-
$
|
3333
|
+
if (ref $opt) {
|
3334
|
+
$self->Warn($msg,2) or $val = '';
|
3335
|
+
} elsif ($opt) {
|
3336
|
+
no strict 'refs';
|
3337
|
+
($opt eq 'Silent' or &$opt($self, $msg, 2)) and return $$self{FMT_EXPR} = undef;
|
3338
|
+
$val = '';
|
3339
|
+
}
|
3336
3340
|
}
|
3337
3341
|
}
|
3338
3342
|
if (ref $opt eq 'HASH') {
|
@@ -5566,7 +5570,7 @@ sub WriteJPEG($$)
|
|
5566
5570
|
$s =~ /^JFXX\0\x10/ and $dirName = 'JFXX';
|
5567
5571
|
$s =~ /^(II|MM).{4}HEAPJPGM/s and $dirName = 'CIFF';
|
5568
5572
|
} elsif ($marker == 0xe1) {
|
5569
|
-
if ($s =~ /^(.{0,4})
|
5573
|
+
if ($s =~ /^(.{0,4})Exif\0.(.{1,4})/is) {
|
5570
5574
|
$dirName = 'IFD0';
|
5571
5575
|
my ($junk, $bytes) = ($1, $2);
|
5572
5576
|
# support multi-segment EXIF
|
@@ -6132,7 +6136,7 @@ sub WriteJPEG($$)
|
|
6132
6136
|
}
|
6133
6137
|
} elsif ($marker == 0xe1) { # APP1 (EXIF, XMP)
|
6134
6138
|
# check for EXIF data
|
6135
|
-
if ($$segDataPt =~ /^(.{0,4})
|
6139
|
+
if ($$segDataPt =~ /^(.{0,4})Exif\0./is) {
|
6136
6140
|
my $hdrLen = length $exifAPP1hdr;
|
6137
6141
|
if (length $1) {
|
6138
6142
|
$hdrLen += length $1;
|
@@ -6867,6 +6871,36 @@ sub SetFileTime($$;$$$$)
|
|
6867
6871
|
return 1; # (nothing to do)
|
6868
6872
|
}
|
6869
6873
|
|
6874
|
+
#------------------------------------------------------------------------------
|
6875
|
+
# Add data to MD5 checksum
|
6876
|
+
# Inputs: 0) ExifTool ref, 1) RAF ref, 2) data size (or undef to read to end of file),
|
6877
|
+
# 3) data name (or undef for no warnings or messages), 4) flag for no verbose message
|
6878
|
+
# Returns: number of bytes read and MD5'd
|
6879
|
+
sub ImageDataMD5($$$;$$)
|
6880
|
+
{
|
6881
|
+
my ($self, $raf, $size, $type, $noMsg) = @_;
|
6882
|
+
my $md5 = $$self{ImageDataMD5} or return;
|
6883
|
+
my ($bytesRead, $n) = (0, 65536);
|
6884
|
+
my $buff;
|
6885
|
+
for (;;) {
|
6886
|
+
if (defined $size) {
|
6887
|
+
last unless $size;
|
6888
|
+
$n = $size > 65536 ? 65536 : $size;
|
6889
|
+
$size -= $n;
|
6890
|
+
}
|
6891
|
+
unless ($raf->Read($buff, $n)) {
|
6892
|
+
$self->Warn("Error reading $type data") if $type and defined $size;
|
6893
|
+
last;
|
6894
|
+
}
|
6895
|
+
$md5->add($buff);
|
6896
|
+
$bytesRead += length $buff;
|
6897
|
+
}
|
6898
|
+
if ($$self{OPTIONS}{Verbose} and $bytesRead and $type and not $noMsg) {
|
6899
|
+
$self->VPrint(0, "$$self{INDENT}(ImageDataMD5: $bytesRead bytes of $type data)\n");
|
6900
|
+
}
|
6901
|
+
return $bytesRead;
|
6902
|
+
}
|
6903
|
+
|
6870
6904
|
#------------------------------------------------------------------------------
|
6871
6905
|
# Copy data block from RAF to output file in max 64kB chunks
|
6872
6906
|
# Inputs: 0) RAF ref, 1) outfile ref, 2) block size
|
data/bin/lib/Image/ExifTool.pm
CHANGED
@@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
29
29
|
%jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
|
30
30
|
%static_vars);
|
31
31
|
|
32
|
-
$VERSION = '12.
|
32
|
+
$VERSION = '12.60';
|
33
33
|
$RELEASE = '';
|
34
34
|
@ISA = qw(Exporter);
|
35
35
|
%EXPORT_TAGS = (
|
@@ -114,6 +114,7 @@ sub WriteTIFF($$$);
|
|
114
114
|
sub PackUTF8(@);
|
115
115
|
sub UnpackUTF8($);
|
116
116
|
sub SetPreferredByteOrder($;$);
|
117
|
+
sub ImageDataMD5($$$;$$);
|
117
118
|
sub CopyBlock($$$);
|
118
119
|
sub CopyFileAttrs($$$);
|
119
120
|
sub TimeNow(;$$);
|
@@ -1825,11 +1826,12 @@ my %systemTagsNotes = (
|
|
1825
1826
|
ImageDataMD5 => {
|
1826
1827
|
Notes => q{
|
1827
1828
|
MD5 of image data. Generated only if specifically requested for JPEG and
|
1828
|
-
TIFF-based images, CR3, MRW and
|
1829
|
-
files.
|
1830
|
-
some formats, but does not include
|
1831
|
-
video and audio data for MOV/MP4.
|
1832
|
-
tag|XMP.html#ExifTool> provides a place to
|
1829
|
+
TIFF-based images, PNG, CRW, CR3, MRW, RAF, X3F and AVIF images, MOV/MP4
|
1830
|
+
videos, and some RIFF-based files. The MD5 includes the main image data,
|
1831
|
+
plus JpgFromRaw/OtherImage for some formats, but does not include
|
1832
|
+
ThumbnailImage or PreviewImage. Includes video and audio data for MOV/MP4.
|
1833
|
+
The L<XMP-et:OriginalImageMD5 tag|XMP.html#ExifTool> provides a place to
|
1834
|
+
store these values in the file.
|
1833
1835
|
},
|
1834
1836
|
},
|
1835
1837
|
);
|
@@ -3731,13 +3733,21 @@ COMPOSITE_TAG:
|
|
3731
3733
|
next COMPOSITE_TAG;
|
3732
3734
|
}
|
3733
3735
|
}
|
3736
|
+
my ($i, $key, @keys, $altFile);
|
3737
|
+
my $et = $self;
|
3738
|
+
# get tags from alternate file if a family 8 group was specified
|
3739
|
+
if ($reqTag =~ /\b(File\d+):/i and $$self{ALT_EXIFTOOL}{$1}) {
|
3740
|
+
$et = $$self{ALT_EXIFTOOL}{$1};
|
3741
|
+
$altFile = $1;
|
3742
|
+
}
|
3734
3743
|
# (CAREFUL! keys may not be sequential if one was deleted)
|
3735
|
-
|
3736
|
-
|
3737
|
-
push @keys, $key if defined $$rawValue{$key};
|
3744
|
+
for ($key=$name, $i=$$et{DUPL_TAG}{$name} || 0; ; --$i) {
|
3745
|
+
push @keys, $key if defined $$et{VALUE}{$key};
|
3738
3746
|
last if $i <= 0;
|
3739
3747
|
$key = "$name ($i)";
|
3740
3748
|
}
|
3749
|
+
# make sure the necessary information is available from the alternate file
|
3750
|
+
$self->CopyAltInfo($altFile, \@keys) if $altFile;
|
3741
3751
|
# find first matching tag
|
3742
3752
|
$key = $self->GroupMatches($reqGroup, \@keys);
|
3743
3753
|
$reqTag = $key || "$name (0)";
|
@@ -4598,6 +4608,29 @@ sub RemoveTagsFromList($$$$;$)
|
|
4598
4608
|
$_[0] = \@filteredTags; # update tag list
|
4599
4609
|
}
|
4600
4610
|
|
4611
|
+
#------------------------------------------------------------------------------
|
4612
|
+
# Copy tags from alternate input file
|
4613
|
+
# Inputs: 0) ExifTool ref, 1) family 8 group, 2) list ref for tag keys to copy
|
4614
|
+
# - updates tag key list to match keys newly added to $self
|
4615
|
+
sub CopyAltInfo($$$)
|
4616
|
+
{
|
4617
|
+
my ($self, $g8, $tags) = @_;
|
4618
|
+
my ($tag, $vtag);
|
4619
|
+
return unless $g8 =~ /(\d+)/;
|
4620
|
+
my $et = $$self{ALT_EXIFTOOL}{$g8} or return;
|
4621
|
+
my $altOrder = ($1 + 1) * 100000; # increment file order
|
4622
|
+
foreach $tag (@$tags) {
|
4623
|
+
($vtag = $tag) =~ s/( |$)/ #[$g8]/;
|
4624
|
+
unless (defined $$self{VALUE}{$vtag}) {
|
4625
|
+
$$self{VALUE}{$vtag} = $$et{VALUE}{$tag};
|
4626
|
+
$$self{TAG_INFO}{$vtag} = $$et{TAG_INFO}{$tag};
|
4627
|
+
$$self{TAG_EXTRA}{$vtag} = $$et{TAG_EXTRA}{$tag} || { };
|
4628
|
+
$$self{FILE_ORDER}{$vtag} = ($$et{FILE_ORDER}{$tag} || 0) + $altOrder;
|
4629
|
+
}
|
4630
|
+
$tag = $vtag;
|
4631
|
+
}
|
4632
|
+
}
|
4633
|
+
|
4601
4634
|
#------------------------------------------------------------------------------
|
4602
4635
|
# Set list of found tags from previously requested tags
|
4603
4636
|
# Inputs: 0) ExifTool object reference
|
@@ -4624,7 +4657,7 @@ sub SetFoundTags($)
|
|
4624
4657
|
my $tagHash = $$self{VALUE};
|
4625
4658
|
my $reqTag;
|
4626
4659
|
foreach $reqTag (@$reqTags) {
|
4627
|
-
my (@matches, $group, $allGrp, $allTag, $byValue, $g8
|
4660
|
+
my (@matches, $group, $allGrp, $allTag, $byValue, $g8);
|
4628
4661
|
my $et = $self;
|
4629
4662
|
if ($reqTag =~ /^(.*):(.+)/) {
|
4630
4663
|
($group, $tag) = ($1, $2);
|
@@ -4632,7 +4665,6 @@ sub SetFoundTags($)
|
|
4632
4665
|
$allGrp = 1;
|
4633
4666
|
} elsif ($reqTag =~ /\bfile(\d+):/i) {
|
4634
4667
|
$g8 = "File$1";
|
4635
|
-
$altOrder = ($1 + 1) * 100000;
|
4636
4668
|
$et = $$self{ALT_EXIFTOOL}{$g8} || $self;
|
4637
4669
|
$fileOrder = $$et{FILE_ORDER};
|
4638
4670
|
$tagHash = $$et{VALUE};
|
@@ -4704,16 +4736,7 @@ sub SetFoundTags($)
|
|
4704
4736
|
}
|
4705
4737
|
# copy over necessary information for tags from alternate files
|
4706
4738
|
if ($g8) {
|
4707
|
-
|
4708
|
-
foreach $tag (@matches) {
|
4709
|
-
my $vtag = $tag;
|
4710
|
-
$vtag =~ s/( |$)/ #[$g8]/;
|
4711
|
-
$$self{VALUE}{$vtag} = $$et{VALUE}{$tag};
|
4712
|
-
$$self{TAG_INFO}{$vtag} = $$et{TAG_INFO}{$tag};
|
4713
|
-
$$self{TAG_EXTRA}{$vtag} = $$et{TAG_EXTRA}{$tag} || { };
|
4714
|
-
$$self{FILE_ORDER}{$vtag} = ($$et{FILE_ORDER}{$tag} || 0) + $altOrder;
|
4715
|
-
$tag = $vtag;
|
4716
|
-
}
|
4739
|
+
$self->CopyAltInfo($g8, \@matches);
|
4717
4740
|
# restore variables to original values for main file
|
4718
4741
|
$fileOrder = $$self{FILE_ORDER};
|
4719
4742
|
$tagHash = $$self{VALUE};
|
@@ -6802,7 +6825,7 @@ sub ProcessJPEG($$)
|
|
6802
6825
|
} elsif ($marker == 0xe1) { # APP1 (EXIF, XMP, QVCI, PARROT)
|
6803
6826
|
# (some Kodak cameras don't put a second "\0", and I have seen an
|
6804
6827
|
# example where there was a second 4-byte APP1 segment header)
|
6805
|
-
if ($$segDataPt =~ /^(.{0,4})Exif\0
|
6828
|
+
if ($$segDataPt =~ /^(.{0,4})Exif\0./is) {
|
6806
6829
|
undef $dumpType; # (will be dumped here)
|
6807
6830
|
# this is EXIF data --
|
6808
6831
|
# get the data block (into a common variable)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exiftool_vendored
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 12.
|
4
|
+
version: 12.60.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew McEachen
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-04-
|
12
|
+
date: 2023-04-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: exiftool
|