exiftool_vendored 12.18.0 → 12.33.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 +236 -4
- data/bin/MANIFEST +23 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +45 -43
- data/bin/arg_files/xmp2exif.args +2 -1
- data/bin/config_files/acdsee.config +193 -6
- data/bin/config_files/convert_regions.config +25 -14
- data/bin/config_files/cuepointlist.config +70 -0
- data/bin/config_files/example.config +2 -9
- data/bin/exiftool +152 -97
- data/bin/fmt_files/gpx.fmt +2 -2
- data/bin/fmt_files/gpx_wpt.fmt +2 -2
- data/bin/fmt_files/kml.fmt +1 -1
- data/bin/fmt_files/kml_track.fmt +1 -1
- data/bin/lib/Image/ExifTool/Apple.pm +3 -2
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +31 -13
- data/bin/lib/Image/ExifTool/CBOR.pm +331 -0
- data/bin/lib/Image/ExifTool/Canon.pm +44 -19
- data/bin/lib/Image/ExifTool/DJI.pm +6 -6
- data/bin/lib/Image/ExifTool/DPX.pm +13 -2
- data/bin/lib/Image/ExifTool/DjVu.pm +6 -5
- data/bin/lib/Image/ExifTool/Exif.pm +124 -13
- data/bin/lib/Image/ExifTool/FITS.pm +13 -2
- data/bin/lib/Image/ExifTool/FlashPix.pm +35 -10
- data/bin/lib/Image/ExifTool/FujiFilm.pm +19 -8
- data/bin/lib/Image/ExifTool/GPS.pm +22 -11
- data/bin/lib/Image/ExifTool/Geotag.pm +13 -2
- data/bin/lib/Image/ExifTool/GoPro.pm +16 -1
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +2 -2
- data/bin/lib/Image/ExifTool/ID3.pm +15 -3
- data/bin/lib/Image/ExifTool/JPEG.pm +74 -4
- data/bin/lib/Image/ExifTool/JSON.pm +30 -5
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +395 -16
- data/bin/lib/Image/ExifTool/LIF.pm +153 -0
- data/bin/lib/Image/ExifTool/Lang/nl.pm +60 -59
- data/bin/lib/Image/ExifTool/M2TS.pm +137 -5
- data/bin/lib/Image/ExifTool/MIE.pm +4 -3
- data/bin/lib/Image/ExifTool/MRC.pm +341 -0
- data/bin/lib/Image/ExifTool/MWG.pm +3 -3
- data/bin/lib/Image/ExifTool/MXF.pm +1 -1
- data/bin/lib/Image/ExifTool/MacOS.pm +3 -3
- data/bin/lib/Image/ExifTool/Microsoft.pm +298 -82
- data/bin/lib/Image/ExifTool/Nikon.pm +18 -5
- data/bin/lib/Image/ExifTool/NikonSettings.pm +19 -2
- data/bin/lib/Image/ExifTool/Olympus.pm +10 -3
- data/bin/lib/Image/ExifTool/Other.pm +93 -0
- data/bin/lib/Image/ExifTool/PDF.pm +9 -12
- data/bin/lib/Image/ExifTool/PNG.pm +8 -7
- data/bin/lib/Image/ExifTool/Panasonic.pm +28 -3
- data/bin/lib/Image/ExifTool/Pentax.pm +28 -5
- data/bin/lib/Image/ExifTool/PhaseOne.pm +4 -3
- data/bin/lib/Image/ExifTool/Photoshop.pm +6 -0
- data/bin/lib/Image/ExifTool/QuickTime.pm +234 -75
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +283 -141
- data/bin/lib/Image/ExifTool/README +5 -2
- data/bin/lib/Image/ExifTool/RIFF.pm +89 -12
- data/bin/lib/Image/ExifTool/Samsung.pm +48 -10
- data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -0
- data/bin/lib/Image/ExifTool/Sony.pm +230 -69
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +1 -0
- data/bin/lib/Image/ExifTool/TagLookup.pm +4145 -4029
- data/bin/lib/Image/ExifTool/TagNames.pod +671 -287
- data/bin/lib/Image/ExifTool/Torrent.pm +18 -11
- data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePDF.pl +1 -0
- data/bin/lib/Image/ExifTool/WritePNG.pl +2 -0
- data/bin/lib/Image/ExifTool/WritePostScript.pl +1 -0
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +55 -21
- data/bin/lib/Image/ExifTool/WriteXMP.pl +7 -3
- data/bin/lib/Image/ExifTool/Writer.pl +47 -10
- data/bin/lib/Image/ExifTool/XMP.pm +45 -15
- data/bin/lib/Image/ExifTool/XMP2.pl +3 -1
- data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
- data/bin/lib/Image/ExifTool/ZISRAW.pm +121 -2
- data/bin/lib/Image/ExifTool.pm +233 -81
- data/bin/lib/Image/ExifTool.pod +114 -93
- data/bin/perl-Image-ExifTool.spec +43 -42
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +28 -13
@@ -18,7 +18,7 @@ use strict;
|
|
18
18
|
use vars qw($VERSION);
|
19
19
|
use Image::ExifTool qw(:DataAccess :Utils);
|
20
20
|
|
21
|
-
$VERSION = '1.
|
21
|
+
$VERSION = '1.07';
|
22
22
|
|
23
23
|
sub ParseAnt($);
|
24
24
|
sub ProcessAnt($$$);
|
@@ -227,10 +227,11 @@ Tok: for (;;) {
|
|
227
227
|
last unless $tok =~ /(\\+)$/ and length($1) & 0x01;
|
228
228
|
$tok .= '"'; # quote is part of the string
|
229
229
|
}
|
230
|
-
#
|
231
|
-
|
232
|
-
|
233
|
-
|
230
|
+
# convert C escape sequences, allowed in quoted text
|
231
|
+
# (note: this only converts a few of them!)
|
232
|
+
my %esc = ( a => "\a", b => "\b", f => "\f", n => "\n",
|
233
|
+
r => "\r", t => "\t", '"' => '"', '\\' => '\\' );
|
234
|
+
$tok =~ s/\\(.)/$esc{$1}||'\\'.$1/egs;
|
234
235
|
} else { # key name
|
235
236
|
pos($$dataPt) = pos($$dataPt) - 1;
|
236
237
|
# allow anything in key but whitespace, braces and double quotes
|
@@ -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.37';
|
60
60
|
|
61
61
|
sub ProcessExif($$$);
|
62
62
|
sub WriteExif($$$);
|
@@ -265,6 +265,7 @@ sub BINARY_DATA_LIMIT { return 10 * 1024 * 1024; }
|
|
265
265
|
32892 => 'Sequential Color Filter', #JR (Sony ARQ)
|
266
266
|
34892 => 'Linear Raw', #2
|
267
267
|
51177 => 'Depth Map', # (DNG 1.5)
|
268
|
+
52527 => 'Semantic Mask', # (DNG 1.6)
|
268
269
|
);
|
269
270
|
|
270
271
|
%orientation = (
|
@@ -291,6 +292,7 @@ sub BINARY_DATA_LIMIT { return 10 * 1024 * 1024; }
|
|
291
292
|
9 => 'Depth map of reduced-resolution image', # (DNG 1.5)
|
292
293
|
16 => 'Enhanced image data', # (DNG 1.5)
|
293
294
|
0x10001 => 'Alternate reduced-resolution image', # (DNG 1.2)
|
295
|
+
0x10004 => 'Semantic Mask', # (DNG 1.6)
|
294
296
|
0xffffffff => 'invalid', #(found in E5700 NEF's)
|
295
297
|
BITMASK => {
|
296
298
|
0 => 'Reduced resolution',
|
@@ -321,6 +323,7 @@ my %utf8StringConv = (
|
|
321
323
|
my %longBin = (
|
322
324
|
ValueConv => 'length($val) > 64 ? \$val : $val',
|
323
325
|
ValueConvInv => '$val',
|
326
|
+
LongBinary => 1, # flag to avoid decoding values of a large array
|
324
327
|
);
|
325
328
|
|
326
329
|
# PrintConv for SampleFormat (0x153)
|
@@ -365,6 +368,7 @@ my %opcodeInfo = (
|
|
365
368
|
11 => 'DeltaPerColumn',
|
366
369
|
12 => 'ScalePerRow',
|
367
370
|
13 => 'ScalePerColumn',
|
371
|
+
14 => 'WarpRectilinear2', # (DNG 1.6)
|
368
372
|
},
|
369
373
|
PrintConvInv => undef, # (so the inverse conversion is not performed)
|
370
374
|
);
|
@@ -1452,6 +1456,7 @@ my %opcodeInfo = (
|
|
1452
1456
|
1 => 'Sony Uncompressed 12-bit RAW', #IB
|
1453
1457
|
2 => 'Sony Compressed RAW', # (lossy, ref IB)
|
1454
1458
|
3 => 'Sony Lossless Compressed RAW', #IB
|
1459
|
+
4 => 'Sony Lossless Compressed RAW 2', #JR (ILCE-1)
|
1455
1460
|
},
|
1456
1461
|
},
|
1457
1462
|
# 0x7001 - int16u[1] (in SubIFD of Sony ARW images) - values: 0,1
|
@@ -1472,6 +1477,7 @@ my %opcodeInfo = (
|
|
1472
1477
|
PrintConv => {
|
1473
1478
|
256 => 'Off',
|
1474
1479
|
257 => 'Auto',
|
1480
|
+
272 => 'Auto (ILCE-1)', #JR
|
1475
1481
|
511 => 'No correction params available',
|
1476
1482
|
},
|
1477
1483
|
},
|
@@ -2578,7 +2584,7 @@ my %opcodeInfo = (
|
|
2578
2584
|
0xa301 => {
|
2579
2585
|
Name => 'SceneType',
|
2580
2586
|
Writable => 'undef',
|
2581
|
-
ValueConvInv => 'chr($val)',
|
2587
|
+
ValueConvInv => 'chr($val & 0xff)',
|
2582
2588
|
PrintConv => {
|
2583
2589
|
1 => 'Directly photographed',
|
2584
2590
|
},
|
@@ -3035,12 +3041,12 @@ my %opcodeInfo = (
|
|
3035
3041
|
},
|
3036
3042
|
},
|
3037
3043
|
#
|
3038
|
-
# DNG tags 0xc6XX and
|
3044
|
+
# DNG tags 0xc6XX, 0xc7XX and 0xcdXX (ref 2 unless otherwise stated)
|
3039
3045
|
#
|
3040
3046
|
0xc612 => {
|
3041
3047
|
Name => 'DNGVersion',
|
3042
3048
|
Notes => q{
|
3043
|
-
tags 0xc612-
|
3049
|
+
tags 0xc612-0xcd3b are defined by the DNG specification unless otherwise
|
3044
3050
|
noted. See L<https://helpx.adobe.com/photoshop/digital-negative.html> for
|
3045
3051
|
the specification
|
3046
3052
|
},
|
@@ -3616,11 +3622,11 @@ my %opcodeInfo = (
|
|
3616
3622
|
},
|
3617
3623
|
0xc6fc => {
|
3618
3624
|
Name => 'ProfileToneCurve',
|
3625
|
+
%longBin,
|
3619
3626
|
Writable => 'float',
|
3620
3627
|
WriteGroup => 'IFD0',
|
3621
3628
|
Count => -1,
|
3622
3629
|
Protected => 1,
|
3623
|
-
Binary => 1,
|
3624
3630
|
},
|
3625
3631
|
0xc6fd => {
|
3626
3632
|
Name => 'ProfileEmbedPolicy',
|
@@ -3745,11 +3751,11 @@ my %opcodeInfo = (
|
|
3745
3751
|
},
|
3746
3752
|
0xc726 => {
|
3747
3753
|
Name => 'ProfileLookTableData',
|
3754
|
+
%longBin,
|
3748
3755
|
Writable => 'float',
|
3749
3756
|
WriteGroup => 'IFD0',
|
3750
3757
|
Count => -1,
|
3751
3758
|
Protected => 1,
|
3752
|
-
Binary => 1,
|
3753
3759
|
},
|
3754
3760
|
0xc740 => { Name => 'OpcodeList1', %opcodeInfo }, # DNG 1.3
|
3755
3761
|
0xc741 => { Name => 'OpcodeList2', %opcodeInfo }, # DNG 1.3
|
@@ -4038,6 +4044,97 @@ my %opcodeInfo = (
|
|
4038
4044
|
Protected => 1,
|
4039
4045
|
WriteGroup => 'IFD0',
|
4040
4046
|
},
|
4047
|
+
0xcd2d => { # DNG 1.6
|
4048
|
+
Name => 'ProfileGainTableMap',
|
4049
|
+
Writable => 'undef',
|
4050
|
+
WriteGroup => 'SubIFD',
|
4051
|
+
Protected => 1,
|
4052
|
+
Binary => 1,
|
4053
|
+
},
|
4054
|
+
0xcd2e => { # DNG 1.6
|
4055
|
+
Name => 'SemanticName',
|
4056
|
+
# Writable => 'string',
|
4057
|
+
WriteGroup => 'SubIFD' #? (NC) Semantic Mask IFD (only for Validate)
|
4058
|
+
},
|
4059
|
+
0xcd30 => { # DNG 1.6
|
4060
|
+
Name => 'SemanticInstanceIFD',
|
4061
|
+
# Writable => 'string',
|
4062
|
+
WriteGroup => 'SubIFD' #? (NC) Semantic Mask IFD (only for Validate)
|
4063
|
+
},
|
4064
|
+
0xcd31 => { # DNG 1.6
|
4065
|
+
Name => 'CalibrationIlluminant3',
|
4066
|
+
Writable => 'int16u',
|
4067
|
+
WriteGroup => 'IFD0',
|
4068
|
+
Protected => 1,
|
4069
|
+
SeparateTable => 'LightSource',
|
4070
|
+
PrintConv => \%lightSource,
|
4071
|
+
},
|
4072
|
+
0xcd32 => { # DNG 1.6
|
4073
|
+
Name => 'CameraCalibration3',
|
4074
|
+
Writable => 'rational64s',
|
4075
|
+
WriteGroup => 'IFD0',
|
4076
|
+
Count => -1,
|
4077
|
+
Protected => 1,
|
4078
|
+
},
|
4079
|
+
0xcd33 => { # DNG 1.6
|
4080
|
+
Name => 'ColorMatrix3',
|
4081
|
+
Writable => 'rational64s',
|
4082
|
+
WriteGroup => 'IFD0',
|
4083
|
+
Count => -1,
|
4084
|
+
Protected => 1,
|
4085
|
+
},
|
4086
|
+
0xcd34 => { # DNG 1.6
|
4087
|
+
Name => 'ForwardMatrix3',
|
4088
|
+
Writable => 'rational64s',
|
4089
|
+
WriteGroup => 'IFD0',
|
4090
|
+
Count => -1,
|
4091
|
+
Protected => 1,
|
4092
|
+
},
|
4093
|
+
0xcd35 => { # DNG 1.6
|
4094
|
+
Name => 'IlluminantData1',
|
4095
|
+
Writable => 'undef',
|
4096
|
+
WriteGroup => 'IFD0',
|
4097
|
+
Protected => 1,
|
4098
|
+
},
|
4099
|
+
0xcd36 => { # DNG 1.6
|
4100
|
+
Name => 'IlluminantData2',
|
4101
|
+
Writable => 'undef',
|
4102
|
+
WriteGroup => 'IFD0',
|
4103
|
+
Protected => 1,
|
4104
|
+
},
|
4105
|
+
0xcd37 => { # DNG 1.6
|
4106
|
+
Name => 'IlluminantData3',
|
4107
|
+
Writable => 'undef',
|
4108
|
+
WriteGroup => 'IFD0',
|
4109
|
+
Protected => 1,
|
4110
|
+
},
|
4111
|
+
0xcd38 => { # DNG 1.6
|
4112
|
+
Name => 'MaskSubArea',
|
4113
|
+
# Writable => 'int32u',
|
4114
|
+
WriteGroup => 'SubIFD', #? (NC) Semantic Mask IFD (only for Validate)
|
4115
|
+
Count => 4,
|
4116
|
+
},
|
4117
|
+
0xcd39 => { # DNG 1.6
|
4118
|
+
Name => 'ProfileHueSatMapData3',
|
4119
|
+
%longBin,
|
4120
|
+
Writable => 'float',
|
4121
|
+
WriteGroup => 'IFD0',
|
4122
|
+
Count => -1,
|
4123
|
+
Protected => 1,
|
4124
|
+
},
|
4125
|
+
0xcd3a => { # DNG 1.6
|
4126
|
+
Name => 'ReductionMatrix3',
|
4127
|
+
Writable => 'rational64s',
|
4128
|
+
WriteGroup => 'IFD0',
|
4129
|
+
Count => -1,
|
4130
|
+
Protected => 1,
|
4131
|
+
},
|
4132
|
+
0xcd3b => { # DNG 1.6
|
4133
|
+
Name => 'RGBTables',
|
4134
|
+
Writable => 'undef',
|
4135
|
+
WriteGroup => 'IFD0',
|
4136
|
+
Protected => 1,
|
4137
|
+
},
|
4041
4138
|
0xea1c => { #13
|
4042
4139
|
Name => 'Padding',
|
4043
4140
|
Binary => 1,
|
@@ -5796,7 +5893,8 @@ sub ProcessExif($$$)
|
|
5796
5893
|
$numEntries = Get16u($dataPt, $dirStart);
|
5797
5894
|
} else {
|
5798
5895
|
$et->Warn("Bad $dir directory", $inMakerNotes);
|
5799
|
-
return 0 unless $inMakerNotes and $dirLen >= 14
|
5896
|
+
return 0 unless $inMakerNotes and $dirLen >= 14 and $dirStart >= 0 and
|
5897
|
+
$dirStart + $dirLen <= length($$dataPt);
|
5800
5898
|
$dirSize = $dirLen;
|
5801
5899
|
$numEntries = int(($dirSize - 2) / 12); # read what we can
|
5802
5900
|
Set16u($numEntries, $dataPt, $dirStart);
|
@@ -5914,7 +6012,7 @@ sub ProcessExif($$$)
|
|
5914
6012
|
my $size = $count * $formatSize[$format];
|
5915
6013
|
my $readSize = $size;
|
5916
6014
|
if ($size > 4) {
|
5917
|
-
if ($size > 0x7fffffff) {
|
6015
|
+
if ($size > 0x7fffffff and (not $tagInfo or not $$tagInfo{ReadFromRAF})) {
|
5918
6016
|
$et->Warn(sprintf("Invalid size (%u) for %s %s",$size,$dir,TagName($tagID,$tagInfo)), $inMakerNotes);
|
5919
6017
|
++$warnCount;
|
5920
6018
|
next;
|
@@ -6167,17 +6265,30 @@ sub ProcessExif($$$)
|
|
6167
6265
|
unless ($bad) {
|
6168
6266
|
# limit maximum length of data to reformat
|
6169
6267
|
# (avoids long delays when processing some corrupted files)
|
6268
|
+
my $warned;
|
6170
6269
|
if ($count > 100000 and $formatStr !~ /^(undef|string|binary)$/) {
|
6171
6270
|
my $tagName = $tagInfo ? $$tagInfo{Name} : sprintf('tag 0x%.4x', $tagID);
|
6271
|
+
# (count of 196608 is typical for ColorMap)
|
6172
6272
|
if ($tagName ne 'TransferFunction' or $count != 196608) {
|
6173
6273
|
my $minor = $count > 2000000 ? 0 : 2;
|
6174
|
-
|
6274
|
+
if ($et->Warn("Ignoring $dirName $tagName with excessive count", $minor)) {
|
6275
|
+
next unless $$et{OPTIONS}{HtmlDump};
|
6276
|
+
$warned = 1;
|
6277
|
+
}
|
6175
6278
|
}
|
6176
6279
|
}
|
6177
|
-
|
6178
|
-
|
6179
|
-
|
6180
|
-
|
6280
|
+
if ($count > 500 and $formatStr !~ /^(undef|string|binary)$/ and
|
6281
|
+
(not $tagInfo or $$tagInfo{LongBinary} or $warned) and not $$et{OPTIONS}{IgnoreMinorErrors})
|
6282
|
+
{
|
6283
|
+
$et->WarnOnce('Not decoding some large array(s). Ignore minor errors to decode', 2) unless $warned;
|
6284
|
+
next if $$et{TAGS_FROM_FILE}; # don't generate bogus value when copying tags
|
6285
|
+
$val = "(large array of $count $formatStr values)";
|
6286
|
+
} else {
|
6287
|
+
# convert according to specified format
|
6288
|
+
$val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$readSize,\$rational);
|
6289
|
+
# re-code if necessary
|
6290
|
+
$val = $et->Decode($val, $strEnc) if $strEnc and $formatStr eq 'string' and defined $val;
|
6291
|
+
}
|
6181
6292
|
}
|
6182
6293
|
|
6183
6294
|
if ($verbose) {
|
@@ -14,7 +14,7 @@ use strict;
|
|
14
14
|
use vars qw($VERSION);
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
16
16
|
|
17
|
-
$VERSION = '1.
|
17
|
+
$VERSION = '1.02';
|
18
18
|
|
19
19
|
# FITS tags (ref 1)
|
20
20
|
%Image::ExifTool::FITS::Main = (
|
@@ -36,6 +36,10 @@ $VERSION = '1.00';
|
|
36
36
|
'TIME-OBS'=> { Name => 'ObservationTime', Groups => { 2 => 'Time' } },
|
37
37
|
'DATE-END'=> { Name => 'ObservationDateEnd', Groups => { 2 => 'Time' } },
|
38
38
|
'TIME-END'=> { Name => 'ObservationTimeEnd', Groups => { 2 => 'Time' } },
|
39
|
+
COMMENT => { Name => 'Comment', PrintConv => '$val =~ s/^ +//; $val',
|
40
|
+
Notes => 'leading spaces are removed if L<PrintConv|../ExifTool.html#PrintConv> is enabled' },
|
41
|
+
HISTORY => { Name => 'History', PrintConv => '$val =~ s/^ +//; $val',
|
42
|
+
Notes => 'leading spaces are removed if L<PrintConv|../ExifTool.html#PrintConv> is enabled' },
|
39
43
|
);
|
40
44
|
|
41
45
|
#------------------------------------------------------------------------------
|
@@ -67,7 +71,14 @@ sub ProcessFITS($$)
|
|
67
71
|
last if $key eq 'END';
|
68
72
|
# make sure the key is valid
|
69
73
|
$key =~ /^[-_A-Z0-9]*$/ or $et->Warn('Format error in FITS header'), last;
|
70
|
-
|
74
|
+
if ($key eq 'COMMENT' or $key eq 'HISTORY') {
|
75
|
+
my $val = substr($buff, 8); # comments start in column 9
|
76
|
+
$val =~ s/ +$//; # remove trailing spaces
|
77
|
+
$et->HandleTag($tagTablePtr, $key, $val);
|
78
|
+
next;
|
79
|
+
}
|
80
|
+
# ignore other lines that aren't tags
|
81
|
+
next unless substr($buff,8,2) eq '= ';
|
71
82
|
# save tag name (avoiding potential conflict with ExifTool variables)
|
72
83
|
$tag = $Image::ExifTool::specialTags{$key} ? "_$key" : $key;
|
73
84
|
# add to tag table if necessary
|
@@ -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.39';
|
25
25
|
|
26
26
|
sub ProcessFPX($$);
|
27
27
|
sub ProcessFPXR($$$);
|
@@ -1369,29 +1369,48 @@ sub ReadFPXValue($$$$$;$$)
|
|
1369
1369
|
my $flags = $type & 0xf000;
|
1370
1370
|
if ($flags) {
|
1371
1371
|
if ($flags == VT_VECTOR) {
|
1372
|
-
$noPad = 1; # values
|
1372
|
+
$noPad = 1; # values sometimes aren't padded inside vectors!!
|
1373
1373
|
my $size = $oleFormatSize{VT_VECTOR};
|
1374
|
-
|
1374
|
+
if ($valPos + $size > $dirEnd) {
|
1375
|
+
$et->WarnOnce('Incorrect FPX VT_VECTOR size');
|
1376
|
+
last;
|
1377
|
+
}
|
1375
1378
|
$count = Get32u($dataPt, $valPos);
|
1376
1379
|
push @vals, '' if $count == 0; # allow zero-element vector
|
1377
1380
|
$valPos += 4;
|
1378
1381
|
} else {
|
1379
1382
|
# can't yet handle this property flag
|
1383
|
+
$et->WarnOnce('Unknown FPX property');
|
1380
1384
|
last;
|
1381
1385
|
}
|
1382
1386
|
}
|
1383
1387
|
unless ($format =~ /^VT_/) {
|
1384
1388
|
my $size = Image::ExifTool::FormatSize($format) * $count;
|
1385
|
-
|
1389
|
+
if ($valPos + $size > $dirEnd) {
|
1390
|
+
$et->WarnOnce("Incorrect FPX $format size");
|
1391
|
+
last;
|
1392
|
+
}
|
1386
1393
|
@vals = ReadValue($dataPt, $valPos, $format, $count, $size);
|
1387
1394
|
# update position to end of value plus padding
|
1388
1395
|
$valPos += ($count * $size + 3) & 0xfffffffc;
|
1389
1396
|
last;
|
1390
1397
|
}
|
1391
1398
|
my $size = $oleFormatSize{$format};
|
1392
|
-
my ($item, $val);
|
1399
|
+
my ($item, $val, $len);
|
1393
1400
|
for ($item=0; $item<$count; ++$item) {
|
1394
|
-
|
1401
|
+
if ($valPos + $size > $dirEnd) {
|
1402
|
+
$et->WarnOnce("Truncated FPX $format value");
|
1403
|
+
last;
|
1404
|
+
}
|
1405
|
+
# sometimes VT_VECTOR items are padded to even 4-byte boundaries, and sometimes they aren't
|
1406
|
+
if ($noPad and defined $len and $len & 0x03) {
|
1407
|
+
my $pad = 4 - ($len & 0x03);
|
1408
|
+
if ($valPos + $pad + $size <= $dirEnd) {
|
1409
|
+
# skip padding if all zeros
|
1410
|
+
$valPos += $pad if substr($$dataPt, $valPos, $pad) eq "\0" x $pad;
|
1411
|
+
}
|
1412
|
+
}
|
1413
|
+
undef $len;
|
1395
1414
|
if ($format eq 'VT_VARIANT') {
|
1396
1415
|
my $subType = Get32u($dataPt, $valPos);
|
1397
1416
|
$valPos += $size;
|
@@ -1429,9 +1448,12 @@ sub ReadFPXValue($$$$$;$$)
|
|
1429
1448
|
$val = ($val - 25569) * 24 * 3600 if $val != 0;
|
1430
1449
|
$val = Image::ExifTool::ConvertUnixTime($val);
|
1431
1450
|
} elsif ($format =~ /STR$/) {
|
1432
|
-
|
1451
|
+
$len = Get32u($dataPt, $valPos);
|
1433
1452
|
$len *= 2 if $format eq 'VT_LPWSTR'; # convert to byte count
|
1434
|
-
|
1453
|
+
if ($valPos + $len + 4 > $dirEnd) {
|
1454
|
+
$et->WarnOnce("Truncated $format value");
|
1455
|
+
last;
|
1456
|
+
}
|
1435
1457
|
$val = substr($$dataPt, $valPos + 4, $len);
|
1436
1458
|
if ($format eq 'VT_LPWSTR') {
|
1437
1459
|
# convert wide string from Unicode
|
@@ -1450,8 +1472,11 @@ sub ReadFPXValue($$$$$;$$)
|
|
1450
1472
|
# on even 32-bit boundaries, but this isn't always the case)
|
1451
1473
|
$valPos += $noPad ? $len : ($len + 3) & 0xfffffffc;
|
1452
1474
|
} elsif ($format eq 'VT_BLOB' or $format eq 'VT_CF') {
|
1453
|
-
my $len = Get32u($dataPt, $valPos);
|
1454
|
-
|
1475
|
+
my $len = Get32u($dataPt, $valPos); # (use local $len because we always expect padding)
|
1476
|
+
if ($valPos + $len + 4 > $dirEnd) {
|
1477
|
+
$et->WarnOnce("Truncated $format value");
|
1478
|
+
last;
|
1479
|
+
}
|
1455
1480
|
$val = substr($$dataPt, $valPos + 4, $len);
|
1456
1481
|
# update position for data length plus padding
|
1457
1482
|
# (does this padding disappear in arrays too?)
|
@@ -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.80';
|
35
35
|
|
36
36
|
sub ProcessFujiDir($$$);
|
37
37
|
sub ProcessFaceRec($$$);
|
@@ -489,6 +489,7 @@ my %faceCategories = (
|
|
489
489
|
3 => 'Electronic Front Curtain', #10
|
490
490
|
},
|
491
491
|
},
|
492
|
+
# 0x1100 - This may not work well for newer cameras (ref forum12682)
|
492
493
|
0x1100 => [{
|
493
494
|
Name => 'AutoBracketing',
|
494
495
|
Condition => '$$self{Model} eq "X-T3"',
|
@@ -507,6 +508,7 @@ my %faceCategories = (
|
|
507
508
|
0 => 'Off',
|
508
509
|
1 => 'On',
|
509
510
|
2 => 'No flash & flash', #3
|
511
|
+
6 => 'Pixel Shift', #IB (GFX100S)
|
510
512
|
},
|
511
513
|
}],
|
512
514
|
0x1101 => {
|
@@ -517,6 +519,8 @@ my %faceCategories = (
|
|
517
519
|
Name => 'DriveSettings',
|
518
520
|
SubDirectory => { TagTable => 'Image::ExifTool::FujiFilm::DriveSettings' },
|
519
521
|
},
|
522
|
+
0x1105 => { Name => 'PixelShiftShots', Writable => 'int16u' }, #IB
|
523
|
+
0x1106 => { Name => 'PixelShiftOffset', Writable => 'rational64s', Count => 2 }, #IB
|
520
524
|
# (0x1150-0x1152 exist only for Pro Low-light and Pro Focus PictureModes)
|
521
525
|
# 0x1150 - Pro Low-light - val=1; Pro Focus - val=2 (ref 7); HDR - val=128 (forum10799)
|
522
526
|
# 0x1151 - Pro Low-light - val=4 (number of pictures taken?); Pro Focus - val=2,3 (ref 7); HDR - val=3 (forum10799)
|
@@ -915,15 +919,22 @@ my %faceCategories = (
|
|
915
919
|
WRITABLE => 1,
|
916
920
|
0.1 => {
|
917
921
|
Name => 'FocusMode2',
|
918
|
-
Mask =>
|
922
|
+
Mask => 0x0000000f,
|
919
923
|
PrintConv => {
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
0x11 => 'AF-S (Auto)',
|
924
|
+
0x0 => 'AF-M',
|
925
|
+
0x1 => 'AF-S',
|
926
|
+
0x2 => 'AF-C',
|
924
927
|
},
|
925
928
|
},
|
926
929
|
0.2 => {
|
930
|
+
Name => 'PreAF',
|
931
|
+
Mask => 0x00f0,
|
932
|
+
PrintConv => {
|
933
|
+
0 => 'Off',
|
934
|
+
1 => 'On',
|
935
|
+
},
|
936
|
+
},
|
937
|
+
0.3 => {
|
927
938
|
Name => 'AFAreaMode',
|
928
939
|
Mask => 0x0f00,
|
929
940
|
PrintConv => {
|
@@ -932,7 +943,7 @@ my %faceCategories = (
|
|
932
943
|
2 => 'Wide/Tracking',
|
933
944
|
},
|
934
945
|
},
|
935
|
-
0.
|
946
|
+
0.4 => {
|
936
947
|
Name => 'AFAreaPointSize',
|
937
948
|
Mask => 0xf000,
|
938
949
|
PrintConv => {
|
@@ -940,7 +951,7 @@ my %faceCategories = (
|
|
940
951
|
OTHER => sub { return $_[0] },
|
941
952
|
},
|
942
953
|
},
|
943
|
-
0.
|
954
|
+
0.5 => {
|
944
955
|
Name => 'AFAreaZoneSize',
|
945
956
|
Mask => 0xf0000,
|
946
957
|
PrintConv => {
|
@@ -12,13 +12,12 @@ use strict;
|
|
12
12
|
use vars qw($VERSION);
|
13
13
|
use Image::ExifTool::Exif;
|
14
14
|
|
15
|
-
$VERSION = '1.
|
15
|
+
$VERSION = '1.53';
|
16
16
|
|
17
17
|
my %coordConv = (
|
18
18
|
ValueConv => 'Image::ExifTool::GPS::ToDegrees($val)',
|
19
19
|
ValueConvInv => 'Image::ExifTool::GPS::ToDMS($self, $val)',
|
20
20
|
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
|
21
|
-
PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val)',
|
22
21
|
);
|
23
22
|
|
24
23
|
%Image::ExifTool::GPS::Main = (
|
@@ -41,7 +40,7 @@ my %coordConv = (
|
|
41
40
|
Notes => q{
|
42
41
|
tags 0x0001-0x0006 used for camera location according to MWG 2.0. ExifTool
|
43
42
|
will also accept a number when writing GPSLatitudeRef, positive for north
|
44
|
-
latitudes or negative for south, or a string
|
43
|
+
latitudes or negative for south, or a string containing N, North, S or South
|
45
44
|
},
|
46
45
|
Count => 2,
|
47
46
|
PrintConv => {
|
@@ -50,7 +49,7 @@ my %coordConv = (
|
|
50
49
|
OTHER => sub {
|
51
50
|
my ($val, $inv) = @_;
|
52
51
|
return undef unless $inv;
|
53
|
-
return uc $
|
52
|
+
return uc $2 if $val =~ /(^|[^A-Z])([NS])(orth|outh)?\b/i;
|
54
53
|
return $1 eq '-' ? 'S' : 'N' if $val =~ /([-+]?)\d+/;
|
55
54
|
return undef;
|
56
55
|
},
|
@@ -63,6 +62,7 @@ my %coordConv = (
|
|
63
62
|
Writable => 'rational64u',
|
64
63
|
Count => 3,
|
65
64
|
%coordConv,
|
65
|
+
PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val,undef,"lat")',
|
66
66
|
},
|
67
67
|
0x0003 => {
|
68
68
|
Name => 'GPSLongitudeRef',
|
@@ -70,7 +70,7 @@ my %coordConv = (
|
|
70
70
|
Count => 2,
|
71
71
|
Notes => q{
|
72
72
|
ExifTool will also accept a number when writing this tag, positive for east
|
73
|
-
longitudes or negative for west, or a string
|
73
|
+
longitudes or negative for west, or a string containing E, East, W or West
|
74
74
|
},
|
75
75
|
PrintConv => {
|
76
76
|
# extract E/W if written from Composite:GPSLongitude
|
@@ -78,7 +78,7 @@ my %coordConv = (
|
|
78
78
|
OTHER => sub {
|
79
79
|
my ($val, $inv) = @_;
|
80
80
|
return undef unless $inv;
|
81
|
-
return uc $
|
81
|
+
return uc $2 if $val =~ /(^|[^A-Z])([EW])(ast|est)?\b/i;
|
82
82
|
return $1 eq '-' ? 'W' : 'E' if $val =~ /([-+]?)\d+/;
|
83
83
|
return undef;
|
84
84
|
},
|
@@ -91,6 +91,7 @@ my %coordConv = (
|
|
91
91
|
Writable => 'rational64u',
|
92
92
|
Count => 3,
|
93
93
|
%coordConv,
|
94
|
+
PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val,undef,"lon")',
|
94
95
|
},
|
95
96
|
0x0005 => {
|
96
97
|
Name => 'GPSAltitudeRef',
|
@@ -238,6 +239,7 @@ my %coordConv = (
|
|
238
239
|
Writable => 'rational64u',
|
239
240
|
Count => 3,
|
240
241
|
%coordConv,
|
242
|
+
PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val,undef,"lat")',
|
241
243
|
},
|
242
244
|
0x0015 => {
|
243
245
|
Name => 'GPSDestLongitudeRef',
|
@@ -250,6 +252,7 @@ my %coordConv = (
|
|
250
252
|
Writable => 'rational64u',
|
251
253
|
Count => 3,
|
252
254
|
%coordConv,
|
255
|
+
PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val,undef,"lon")',
|
253
256
|
},
|
254
257
|
0x0017 => {
|
255
258
|
Name => 'GPSDestBearingRef',
|
@@ -529,18 +532,26 @@ sub ToDMS($$;$$)
|
|
529
532
|
#------------------------------------------------------------------------------
|
530
533
|
# Convert to decimal degrees
|
531
534
|
# Inputs: 0) a string containing 1-3 decimal numbers and any amount of other garbage
|
532
|
-
# 1) true if value should be negative if coordinate ends in 'S' or 'W'
|
533
|
-
#
|
534
|
-
|
535
|
+
# 1) true if value should be negative if coordinate ends in 'S' or 'W',
|
536
|
+
# 2) 'lat' or 'lon' to extract lat or lon from GPSCoordinates string
|
537
|
+
# Returns: Coordinate in degrees, or '' on error
|
538
|
+
sub ToDegrees($;$$)
|
535
539
|
{
|
536
|
-
my ($val, $doSign) = @_;
|
540
|
+
my ($val, $doSign, $coord) = @_;
|
537
541
|
return '' if $val =~ /\b(inf|undef)\b/; # ignore invalid values
|
542
|
+
# use only lat or lon part of combined GPSCoordinates inputs
|
543
|
+
if ($coord and ($coord eq 'lat' or $coord eq 'lon') and
|
544
|
+
# (two formatted coordinate values with cardinal directions, separated by a comma)
|
545
|
+
$val =~ /^(.*(?:N(?:orth)?|S(?:outh)?)),\s*(.*(?:E(?:ast)?|W(?:est)?))$/i)
|
546
|
+
{
|
547
|
+
$val = $coord eq 'lat' ? $1 : $2;
|
548
|
+
}
|
538
549
|
# extract decimal or floating point values out of any other garbage
|
539
550
|
my ($d, $m, $s) = ($val =~ /((?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee][+-]\d+)?)/g);
|
540
551
|
return '' unless defined $d;
|
541
552
|
my $deg = $d + (($m || 0) + ($s || 0)/60) / 60;
|
542
553
|
# make negative if S or W coordinate
|
543
|
-
$deg = -$deg if $doSign ? $val =~ /[^A-Z](S
|
554
|
+
$deg = -$deg if $doSign ? $val =~ /[^A-Z](S(outh)?|W(est)?)\s*$/i : $deg < 0;
|
544
555
|
return $deg;
|
545
556
|
}
|
546
557
|
|
@@ -28,7 +28,7 @@ use vars qw($VERSION);
|
|
28
28
|
use Image::ExifTool qw(:Public);
|
29
29
|
use Image::ExifTool::GPS;
|
30
30
|
|
31
|
-
$VERSION = '1.
|
31
|
+
$VERSION = '1.65';
|
32
32
|
|
33
33
|
sub JITTER() { return 2 } # maximum time jitter
|
34
34
|
|
@@ -262,8 +262,10 @@ sub LoadTrackLog($$;$)
|
|
262
262
|
$param = 'time';
|
263
263
|
} elsif (/^(Pos)?Lat/i) {
|
264
264
|
$param = 'lat';
|
265
|
+
/ref$/i and $param .= 'ref';
|
265
266
|
} elsif (/^(Pos)?Lon/i) {
|
266
267
|
$param = 'lon';
|
268
|
+
/ref$/i and $param .= 'ref';
|
267
269
|
} elsif (/^(Pos)?Alt/i) {
|
268
270
|
$param = 'alt';
|
269
271
|
} elsif (/^(Angle)?(Heading|Track)/i) {
|
@@ -453,7 +455,7 @@ DoneFix: $isDate = 1;
|
|
453
455
|
# (ExifTool enhancements allow for standard tag names or descriptions as the column headings,
|
454
456
|
# add support for time zones and flexible coordinates, and allow new DateTime and Shift columns)
|
455
457
|
#
|
456
|
-
my ($param, $date, $secs);
|
458
|
+
my ($param, $date, $secs, %neg);
|
457
459
|
foreach $param (@csvHeadings) {
|
458
460
|
my $val = shift @vals;
|
459
461
|
last unless defined $val;
|
@@ -479,6 +481,10 @@ DoneFix: $isDate = 1;
|
|
479
481
|
}
|
480
482
|
} elsif ($param eq 'lat' or $param eq 'lon') {
|
481
483
|
$$fix{$param} = Image::ExifTool::GPS::ToDegrees($val, 1);
|
484
|
+
} elsif ($param eq 'latref') {
|
485
|
+
$neg{lat} = 1 if $val =~ /^S/i;
|
486
|
+
} elsif ($param eq 'lonref') {
|
487
|
+
$neg{lon} = 1 if $val =~ /^W/i;
|
482
488
|
} elsif ($param eq 'runtime') {
|
483
489
|
$date = $trackTime;
|
484
490
|
$secs = $val;
|
@@ -486,6 +492,11 @@ DoneFix: $isDate = 1;
|
|
486
492
|
$$fix{$param} = $val;
|
487
493
|
}
|
488
494
|
}
|
495
|
+
# make coordinate negative according to reference direction if necessary
|
496
|
+
foreach $param (keys %neg) {
|
497
|
+
next unless defined $$fix{$param};
|
498
|
+
$$fix{$param} = -abs($$fix{$param});
|
499
|
+
}
|
489
500
|
if ($date and defined $secs and defined $$fix{lat} and defined $$fix{lon}) {
|
490
501
|
$time = $date + $secs;
|
491
502
|
$$has{alt} = 1 if defined $$fix{alt};
|