exiftool_vendored 13.42.0 → 13.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/Changes +44 -1
- data/bin/MANIFEST +2 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +48 -48
- data/bin/config_files/example.config +5 -2
- data/bin/exiftool +96 -84
- data/bin/lib/Image/ExifTool/Apple.pm +0 -1
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +4 -4
- data/bin/lib/Image/ExifTool/Canon.pm +24 -1
- data/bin/lib/Image/ExifTool/CanonCustom.pm +1 -1
- data/bin/lib/Image/ExifTool/DarwinCore.pm +2 -2
- data/bin/lib/Image/ExifTool/EXE.pm +1 -1
- data/bin/lib/Image/ExifTool/Exif.pm +4 -2
- data/bin/lib/Image/ExifTool/FLIR.pm +1 -1
- data/bin/lib/Image/ExifTool/FlashPix.pm +1 -1
- data/bin/lib/Image/ExifTool/FujiFilm.pm +2 -2
- data/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- data/bin/lib/Image/ExifTool/Geolocation.pm +1 -1
- data/bin/lib/Image/ExifTool/Geotag.pm +3 -3
- data/bin/lib/Image/ExifTool/Google.pm +2 -2
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +0 -1
- data/bin/lib/Image/ExifTool/Import.pm +1 -1
- data/bin/lib/Image/ExifTool/JPEG.pm +5 -1
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +1 -1
- data/bin/lib/Image/ExifTool/Kandao.pm +399 -0
- data/bin/lib/Image/ExifTool/LNK.pm +1 -1
- data/bin/lib/Image/ExifTool/MRC.pm +4 -4
- data/bin/lib/Image/ExifTool/MWG.pm +1 -1
- data/bin/lib/Image/ExifTool/MacOS.pm +1 -2
- data/bin/lib/Image/ExifTool/Matroska.pm +56 -15
- data/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
- data/bin/lib/Image/ExifTool/Nikon.pm +13 -15
- data/bin/lib/Image/ExifTool/NikonCustom.pm +10 -8
- data/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
- data/bin/lib/Image/ExifTool/PPM.pm +1 -1
- data/bin/lib/Image/ExifTool/Panasonic.pm +30 -6
- data/bin/lib/Image/ExifTool/Pentax.pm +9 -1
- data/bin/lib/Image/ExifTool/PhaseOne.pm +17 -1
- data/bin/lib/Image/ExifTool/Plot.pm +2 -2
- data/bin/lib/Image/ExifTool/Protobuf.pm +42 -16
- data/bin/lib/Image/ExifTool/QuickTime.pm +48 -8
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +2 -2
- data/bin/lib/Image/ExifTool/README +5 -5
- data/bin/lib/Image/ExifTool/RIFF.pm +5 -4
- data/bin/lib/Image/ExifTool/Reconyx.pm +2 -2
- data/bin/lib/Image/ExifTool/Samsung.pm +11 -1
- data/bin/lib/Image/ExifTool/Sony.pm +29 -3
- data/bin/lib/Image/ExifTool/TNEF.pm +2 -2
- data/bin/lib/Image/ExifTool/TagLookup.pm +7129 -7108
- data/bin/lib/Image/ExifTool/TagNames.pod +259 -111
- data/bin/lib/Image/ExifTool/Text.pm +1 -1
- data/bin/lib/Image/ExifTool/Trailer.pm +1 -1
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +10 -2
- data/bin/lib/Image/ExifTool/Writer.pl +9 -5
- data/bin/lib/Image/ExifTool/XMP.pm +4 -2
- data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
- data/bin/lib/Image/ExifTool.pm +33 -26
- data/bin/lib/Image/ExifTool.pod +88 -79
- data/bin/perl-Image-ExifTool.spec +47 -47
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -1
|
@@ -15,7 +15,7 @@ use strict;
|
|
|
15
15
|
use vars qw($VERSION);
|
|
16
16
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
17
17
|
|
|
18
|
-
$VERSION = '1.
|
|
18
|
+
$VERSION = '1.19';
|
|
19
19
|
|
|
20
20
|
sub HandleStruct($$;$$$$);
|
|
21
21
|
|
|
@@ -42,8 +42,8 @@ my %uidInfo = (
|
|
|
42
42
|
GROUPS => { 2 => 'Video' },
|
|
43
43
|
VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
|
|
44
44
|
NOTES => q{
|
|
45
|
-
The following tags are extracted from Matroska multimedia container files.
|
|
46
|
-
This container format is used by file types such as MKA, MKV, MKS and WEBM.
|
|
45
|
+
The following tags are extracted from Matroska multimedia container files.
|
|
46
|
+
This container format is used by file types such as MKA, MKV, MKS and WEBM.
|
|
47
47
|
For speed, by default ExifTool extracts tags only up to the first Cluster
|
|
48
48
|
unless a Seek element specifies the position of a Tags element after this.
|
|
49
49
|
However, the L<Verbose|../ExifTool.html#Verbose> (-v) and L<Unknown|../ExifTool.html#Unknown> = 2 (-U) options force processing of
|
|
@@ -167,7 +167,7 @@ my %uidInfo = (
|
|
|
167
167
|
0x489 => {
|
|
168
168
|
Name => 'Duration',
|
|
169
169
|
Format => 'float',
|
|
170
|
-
ValueConv => '$$self{TimecodeScale} ? $val * $$self{TimecodeScale} / 1e9 : $val',
|
|
170
|
+
ValueConv => '$$self{TimecodeScale} ? $val * $$self{TimecodeScale} / 1e9 : $val / 1000',
|
|
171
171
|
PrintConv => '$$self{TimecodeScale} ? ConvertDuration($val) : $val',
|
|
172
172
|
},
|
|
173
173
|
0x461 => {
|
|
@@ -661,7 +661,19 @@ my %uidInfo = (
|
|
|
661
661
|
SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
|
|
662
662
|
},
|
|
663
663
|
# Targets elements
|
|
664
|
-
0x28ca => {
|
|
664
|
+
0x28ca => {
|
|
665
|
+
Name => 'TargetTypeValue',
|
|
666
|
+
Format => 'unsigned',
|
|
667
|
+
PrintConv => {
|
|
668
|
+
10 => 'Shot',
|
|
669
|
+
20 => 'Scene/Subtrack',
|
|
670
|
+
30 => 'Chapter/Track',
|
|
671
|
+
40 => 'Session',
|
|
672
|
+
50 => 'Movie/Album',
|
|
673
|
+
60 => 'Season/Edition',
|
|
674
|
+
70 => 'Collection',
|
|
675
|
+
},
|
|
676
|
+
},
|
|
665
677
|
0x23ca => { Name => 'TargetType', Format => 'string' },
|
|
666
678
|
0x23c5 => { Name => 'TagTrackUID', %uidInfo },
|
|
667
679
|
0x23c9 => { Name => 'TagEditionUID', %uidInfo },
|
|
@@ -737,7 +749,8 @@ my %uidInfo = (
|
|
|
737
749
|
# standardized tag names (ref 2)
|
|
738
750
|
%Image::ExifTool::Matroska::StdTag = (
|
|
739
751
|
GROUPS => { 2 => 'Video' },
|
|
740
|
-
|
|
752
|
+
PRIORITY => 0, # (don't want named tags to override numbered tags, eg. "DURATION")
|
|
753
|
+
VARS => { LONG_TAGS => 3 },
|
|
741
754
|
NOTES => q{
|
|
742
755
|
Standardized Matroska tags, stored in a SimpleTag structure (see
|
|
743
756
|
L<https://www.matroska.org/technical/tagging.html>).
|
|
@@ -866,6 +879,15 @@ my %uidInfo = (
|
|
|
866
879
|
ProcessProc => 'Image::ExifTool::XMP::ProcessGSpherical',
|
|
867
880
|
},
|
|
868
881
|
},
|
|
882
|
+
#
|
|
883
|
+
# other tags seen
|
|
884
|
+
#
|
|
885
|
+
_STATISTICS_WRITING_DATE_UTC => { Name => 'StatisticsWritingDateUTC', %dateInfo },
|
|
886
|
+
_STATISTICS_WRITING_APP => 'StatisticsWritingApp',
|
|
887
|
+
_STATISTICS_TAGS => 'StatisticsTags',
|
|
888
|
+
DURATION => 'Duration',
|
|
889
|
+
NUMBER_OF_FRAMES => 'NumberOfFrames',
|
|
890
|
+
NUMBER_OF_BYTES => 'NumberOfBytes',
|
|
869
891
|
);
|
|
870
892
|
|
|
871
893
|
#------------------------------------------------------------------------------
|
|
@@ -885,6 +907,7 @@ sub HandleStruct($$;$$$$)
|
|
|
885
907
|
$name =~ tr/0-9a-zA-Z_//dc;
|
|
886
908
|
$name =~ s/_([a-z])/\U$1/g;
|
|
887
909
|
$name = "Tag_$name" if length $name < 2;
|
|
910
|
+
$et->VPrint(0, " [adding $tag = $name]\n");
|
|
888
911
|
$tagInfo = AddTagToTable($tagTbl, $tag, { Name => $name });
|
|
889
912
|
}
|
|
890
913
|
my ($id, $nm);
|
|
@@ -894,6 +917,7 @@ sub HandleStruct($$;$$$$)
|
|
|
894
917
|
unless ($$tagTbl{$id}) {
|
|
895
918
|
my %copy = %$tagInfo;
|
|
896
919
|
$copy{Name} = $nm;
|
|
920
|
+
$et->VPrint(0, " [adding $id = $nm]\n");
|
|
897
921
|
$tagInfo = AddTagToTable($tagTbl, $id, \%copy);
|
|
898
922
|
}
|
|
899
923
|
} else {
|
|
@@ -965,7 +989,8 @@ sub ProcessMKV($$)
|
|
|
965
989
|
{
|
|
966
990
|
my ($et, $dirInfo) = @_;
|
|
967
991
|
my $raf = $$dirInfo{RAF};
|
|
968
|
-
my ($buff, $buf2, @dirEnd, $trackIndent, %trackTypes,
|
|
992
|
+
my ($buff, $buf2, @dirEnd, $trackIndent, %trackTypes, %trackNum,
|
|
993
|
+
$struct, %seekInfo, %seek);
|
|
969
994
|
|
|
970
995
|
$raf->Read($buff, 4) == 4 or return 0;
|
|
971
996
|
return 0 unless $buff =~ /^\x1a\x45\xdf\xa3/;
|
|
@@ -1024,6 +1049,7 @@ sub ProcessMKV($$)
|
|
|
1024
1049
|
# use INDENT to decide whether or not we are done this Track element
|
|
1025
1050
|
delete $$et{SET_GROUP1} if $trackIndent and $trackIndent eq $$et{INDENT};
|
|
1026
1051
|
$$et{INDENT} = substr($$et{INDENT}, 0, -2);
|
|
1052
|
+
pop @{$$et{PATH}};
|
|
1027
1053
|
} else {
|
|
1028
1054
|
$dirName = $dirEnd[-1][1];
|
|
1029
1055
|
last;
|
|
@@ -1043,7 +1069,7 @@ sub ProcessMKV($$)
|
|
|
1043
1069
|
$$et{SeekHeadOffset} = $pos if $tag == 0x14d9b74; # save offset of seek head
|
|
1044
1070
|
my $size = GetVInt($buff, $pos);
|
|
1045
1071
|
last unless defined $size;
|
|
1046
|
-
my ($unknownSize, $seekInfoOnly);
|
|
1072
|
+
my ($unknownSize, $seekInfoOnly, $tagName);
|
|
1047
1073
|
$size < 0 and $unknownSize = 1, $size = 1e20;
|
|
1048
1074
|
if (@dirEnd and $pos + $dataPos + $size > $dirEnd[-1][0]) {
|
|
1049
1075
|
$et->Warn("Invalid or corrupted $dirEnd[-1][1] master element");
|
|
@@ -1063,10 +1089,11 @@ sub ProcessMKV($$)
|
|
|
1063
1089
|
$seekInfoOnly = 1;
|
|
1064
1090
|
}
|
|
1065
1091
|
if ($tagInfo) {
|
|
1092
|
+
$tagName = $$tagInfo{Name};
|
|
1066
1093
|
if ($$tagInfo{SubDirectory} and not $$tagInfo{NotEBML}) {
|
|
1067
1094
|
# stop processing at first cluster unless we are using -v -U or -ee
|
|
1068
1095
|
# or there are Tags after this
|
|
1069
|
-
if (
|
|
1096
|
+
if ($tagName eq 'Cluster' and $processAll < 2) {
|
|
1070
1097
|
# jump to Tags if possible
|
|
1071
1098
|
unless ($processAll) {
|
|
1072
1099
|
if ($seek{Tags} and $seek{Tags} > $pos + $dataPos and $raf->Seek($seek{Tags},0)) {
|
|
@@ -1081,13 +1108,18 @@ sub ProcessMKV($$)
|
|
|
1081
1108
|
} else {
|
|
1082
1109
|
# just fall through into the contained EBML elements
|
|
1083
1110
|
$$et{INDENT} .= '| ';
|
|
1084
|
-
$
|
|
1085
|
-
$dirName
|
|
1111
|
+
$dirName = $tagName;
|
|
1112
|
+
$et->VerboseDir($dirName, undef, $size);
|
|
1113
|
+
push @{$$et{PATH}}, $dirName;
|
|
1086
1114
|
push @dirEnd, [ $pos + $dataPos + $size, $dirName, $struct ];
|
|
1087
1115
|
$struct = { } if $dirName eq 'SimpleTag'; # keep track of SimpleTag elements
|
|
1088
|
-
|
|
1116
|
+
# set Chapter# and Info family 1 group names
|
|
1117
|
+
if ($tagName eq 'ChapterAtom') {
|
|
1089
1118
|
$$et{SET_GROUP1} = 'Chapter' . (++$chapterNum);
|
|
1090
1119
|
$trackIndent = $$et{INDENT};
|
|
1120
|
+
} elsif ($tagName eq 'Info' and not $$et{SET_GROUP1}) {
|
|
1121
|
+
$$et{SET_GROUP1} = 'Info';
|
|
1122
|
+
$trackIndent = $$et{INDENT};
|
|
1091
1123
|
}
|
|
1092
1124
|
next;
|
|
1093
1125
|
}
|
|
@@ -1170,10 +1202,19 @@ sub ProcessMKV($$)
|
|
|
1170
1202
|
$val = $val * 256 + $_ foreach @vals;
|
|
1171
1203
|
}
|
|
1172
1204
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1205
|
+
if ($tagName eq 'TrackNumber') {
|
|
1206
|
+
# set Track# family 1 group name for tags directly in the track
|
|
1175
1207
|
$$et{SET_GROUP1} = 'Track' . $val;
|
|
1176
1208
|
$trackIndent = $$et{INDENT};
|
|
1209
|
+
} elsif ($tagName eq 'TrackUID' and $$et{SET_GROUP1}) {
|
|
1210
|
+
# save the Track# group associated with this TrackUID
|
|
1211
|
+
$trackNum{$val} = $$et{SET_GROUP1};
|
|
1212
|
+
} elsif ($tagName eq 'TagTrackUID' and $trackNum{$val}) {
|
|
1213
|
+
# set Track# group for associated SimpleTags tags
|
|
1214
|
+
$$et{SET_GROUP1} = $trackNum{$val};
|
|
1215
|
+
# we're already one deeper than the level where we want to
|
|
1216
|
+
# reset the group name, so trigger at one indent level higher
|
|
1217
|
+
$trackIndent = substr($$et{INDENT}, 0, -2);
|
|
1177
1218
|
}
|
|
1178
1219
|
}
|
|
1179
1220
|
my %parms = (
|
|
@@ -1184,7 +1225,7 @@ sub ProcessMKV($$)
|
|
|
1184
1225
|
);
|
|
1185
1226
|
if ($$tagInfo{NoSave} or $struct) {
|
|
1186
1227
|
$et->VerboseInfo($tag, $tagInfo, Value => $val, %parms) if $verbose;
|
|
1187
|
-
$$struct{
|
|
1228
|
+
$$struct{$tagName} = $val if $struct;
|
|
1188
1229
|
} elsif ($$tagInfo{SeekInfo}) {
|
|
1189
1230
|
my $p = $pos;
|
|
1190
1231
|
$val = GetVInt($buff, $p) unless defined $val;
|
|
@@ -65,7 +65,7 @@ use Image::ExifTool::Exif;
|
|
|
65
65
|
use Image::ExifTool::GPS;
|
|
66
66
|
use Image::ExifTool::XMP;
|
|
67
67
|
|
|
68
|
-
$VERSION = '4.
|
|
68
|
+
$VERSION = '4.52';
|
|
69
69
|
|
|
70
70
|
sub LensIDConv($$$);
|
|
71
71
|
sub ProcessNikonAVI($$$);
|
|
@@ -1352,6 +1352,7 @@ my %subjectDetectionZ9 = (
|
|
|
1352
1352
|
4 => 'Vehicles',
|
|
1353
1353
|
5 => 'Birds',
|
|
1354
1354
|
6 => 'Airplanes',
|
|
1355
|
+
7 => 'Faces', #introduced with Z9 firmware 5.30 as an Auto Capture option
|
|
1355
1356
|
);
|
|
1356
1357
|
|
|
1357
1358
|
my %timeZoneZ9 = (
|
|
@@ -4848,17 +4849,17 @@ my %base64coord = (
|
|
|
4848
4849
|
},
|
|
4849
4850
|
0x31 => [
|
|
4850
4851
|
{
|
|
4851
|
-
Name => 'FocusPositionVertical',
|
|
4852
|
+
Name => 'FocusPositionVertical', # 209/233 focus point cameras
|
|
4852
4853
|
Condition => '$$self{Model} =~ /^NIKON (Z 30|Z 50|Z fc)\b/i and $$self{AFAreaYPosition}', #models Z30, Z50, Zfc
|
|
4853
4854
|
ValueConv => 'int($$self{AFAreaYPosition} / 286 )', #divisor is an estimate (chosen to cause center point to report 'C')
|
|
4854
4855
|
PrintConv => sub { my ($val) = @_; PrintAFPointsUpDown($val, 11 ) },
|
|
4855
4856
|
},{
|
|
4856
|
-
Name => 'FocusPositionVertical',
|
|
4857
|
+
Name => 'FocusPositionVertical', # 273/299 focus point cameras
|
|
4857
4858
|
Condition => '$$self{Model} =~ /^NIKON (Z 5|Z 6|Z 6_2|D780)\b/i and $$self{AFAreaYPosition}', #models Z5, Z6, Z6ii, D780
|
|
4858
4859
|
ValueConv => 'int($$self{AFAreaYPosition} / 286 )', #divisor is an estimate (chosen to cause center point to report 'C')
|
|
4859
4860
|
PrintConv => sub { my ($val) = @_; PrintAFPointsUpDown($val, 13 ) },
|
|
4860
4861
|
},{
|
|
4861
|
-
Name => 'FocusPositionVertical',
|
|
4862
|
+
Name => 'FocusPositionVertical', # 405/493 focus point cameras
|
|
4862
4863
|
Condition => '$$self{Model} =~ /^NIKON (Z 7|Z 7_2)\b/i and $$self{AFAreaYPosition}', #models Z7/Z7ii
|
|
4863
4864
|
ValueConv => 'int($$self{AFAreaYPosition} / 292 )', #divisor is the measured vertical pixel separation between adjacent points
|
|
4864
4865
|
PrintConv => sub { my ($val) = @_; PrintAFPointsUpDown($val, 17 ) },
|
|
@@ -5843,7 +5844,7 @@ my %nikonFocalConversions = (
|
|
|
5843
5844
|
28 => 'Nikkor Z 100-400mm f/4.5-5.6 VR S', #28
|
|
5844
5845
|
29 => 'Nikkor Z 28mm f/2.8', #IB
|
|
5845
5846
|
30 => 'Nikkor Z 400mm f/2.8 TC VR S', #28
|
|
5846
|
-
31 => 'Nikkor Z 24-120mm f/4 S', #
|
|
5847
|
+
31 => 'Nikkor Z 24-120mm f/4 S', #github250
|
|
5847
5848
|
32 => 'Nikkor Z 800mm f/6.3 VR S', #28
|
|
5848
5849
|
35 => 'Nikkor Z 28-75mm f/2.8', #IB
|
|
5849
5850
|
36 => 'Nikkor Z 400mm f/4.5 VR S', #IB
|
|
@@ -9010,7 +9011,7 @@ my %nikonFocalConversions = (
|
|
|
9010
9011
|
RawConv => '$$self{FocusShiftShooting} = $val',
|
|
9011
9012
|
PrintConv => q{
|
|
9012
9013
|
return 'Off' if $val == 0 ;
|
|
9013
|
-
my $i = sprintf("Frame %.0f of %.0f",$val, $$self{FocusShiftNumberShots}); # something like Frame 1 of 100"
|
|
9014
|
+
my $i = sprintf("Frame %.0f of %.0f",$val, $$self{FocusShiftNumberShots}); # something like Frame 1 of 100"
|
|
9014
9015
|
if ($$self{PixelShiftActive} and $$self{PixelShiftActive} eq 1) {$i = sprintf("Frame %.0f",$val);} #for the Z8 fw3 with PixelShift Enabled, the frame count is correct, but the frame total needs to be multiplied by the number of PixelShift frames (which I cannot find)
|
|
9015
9016
|
return "On: $i"
|
|
9016
9017
|
},
|
|
@@ -9018,7 +9019,7 @@ my %nikonFocalConversions = (
|
|
|
9018
9019
|
},
|
|
9019
9020
|
#
|
|
9020
9021
|
# Note: Offsets after this are shifted by +2 for Z8 firmware 3.0 (see Hook above)
|
|
9021
|
-
#
|
|
9022
|
+
#
|
|
9022
9023
|
0x0028 => {
|
|
9023
9024
|
Name => 'IntervalShooting', #will be 'On' when Interval Shooting is selected via the Photo Shooting Menu and also when a non-zero interval is specified when using Focus Shift and/or Pixel Shift Shooting
|
|
9024
9025
|
Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
|
|
@@ -9346,12 +9347,9 @@ my %nikonFocalConversions = (
|
|
|
9346
9347
|
106 => {
|
|
9347
9348
|
Name => 'AutoCaptureCriteriaSubjectType',
|
|
9348
9349
|
Condition => '$$self{AutoCapturedFrame} and $$self{AutoCapturedFrame} ne 0',
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
2 => 'Animals',
|
|
9353
|
-
3 => 'Vehicle'
|
|
9354
|
-
},
|
|
9350
|
+
ValueConv => '$val + 1', # change value range to align with %subjectDetectionZ9
|
|
9351
|
+
ValueConvInv => '$val - 1',
|
|
9352
|
+
PrintConv => \%subjectDetectionZ9,
|
|
9355
9353
|
},
|
|
9356
9354
|
);
|
|
9357
9355
|
|
|
@@ -9929,14 +9927,14 @@ my %nikonFocalConversions = (
|
|
|
9929
9927
|
618 => { Name => 'ToneMap', PrintConv => { 0 => 'SDR', 1 => 'HLG' }, Unknown => 1 },
|
|
9930
9928
|
622 => { Name => 'PortraitImpressionBalance', PrintConv => \%portraitImpressionBalanceZ8 },
|
|
9931
9929
|
636 => {
|
|
9932
|
-
Name => 'HighFrequencyFlickerReduction',
|
|
9930
|
+
Name => 'HighFrequencyFlickerReduction',
|
|
9933
9931
|
PrintConv => \%offOn,
|
|
9934
9932
|
Unknown => 1,
|
|
9935
9933
|
Hook => '$varSize += 4 if $$self{FirmwareVersion} and $$self{FirmwareVersion} ge "03.00"',
|
|
9936
9934
|
},
|
|
9937
9935
|
#
|
|
9938
9936
|
# firmware 3.00 adds 4 bytes somewhere in the range 638-730 (hence the Hook above)
|
|
9939
|
-
#
|
|
9937
|
+
#
|
|
9940
9938
|
730 => {
|
|
9941
9939
|
Name => 'MovieImageArea',
|
|
9942
9940
|
Unknown => 1,
|
|
@@ -15,7 +15,7 @@ package Image::ExifTool::NikonCustom;
|
|
|
15
15
|
use strict;
|
|
16
16
|
use vars qw($VERSION @ISA @EXPORT_OK %buttonsZ8 %buttonsZ9);
|
|
17
17
|
|
|
18
|
-
$VERSION = '1.
|
|
18
|
+
$VERSION = '1.28';
|
|
19
19
|
|
|
20
20
|
@ISA = qw(Exporter);
|
|
21
21
|
@EXPORT_OK = qw(%buttonsZ8 %buttonsZ9);
|
|
@@ -115,10 +115,10 @@ my %buttonsCommonZ8Z9 = ( #button roles shared by the Z8 & Z9. Assigments bega
|
|
|
115
115
|
SeparateTable => 'ButtonsZ8',
|
|
116
116
|
PrintConv => {
|
|
117
117
|
%buttonsCommonZ8Z9,
|
|
118
|
-
116 => 'Pixel Shift Shooting',
|
|
118
|
+
116 => 'Pixel Shift Shooting',
|
|
119
119
|
117 => 'Cycle AF-area Mode',
|
|
120
120
|
119 => 'Focus Limiter',
|
|
121
|
-
120 => 'Jump to Source Image',
|
|
121
|
+
120 => 'Jump to Source Image',
|
|
122
122
|
121 => 'Raw Processing (Current)',
|
|
123
123
|
122 => 'Raw Processing (Multiple)',
|
|
124
124
|
123 => 'Trim',
|
|
@@ -140,9 +140,9 @@ my %buttonsCommonZ8Z9 = ( #button roles shared by the Z8 & Z9. Assigments bega
|
|
|
140
140
|
SeparateTable => 'ButtonsZ9',
|
|
141
141
|
PrintConv => {
|
|
142
142
|
%buttonsCommonZ8Z9,
|
|
143
|
-
116 => 'Save and Load Power Zoom Position',
|
|
143
|
+
116 => 'Save and Load Power Zoom Position',
|
|
144
144
|
117 => 'Cycle AF-area Mode',
|
|
145
|
-
118 => 'Raw Processing (Current)', #118-131 are Playback Retouch options
|
|
145
|
+
118 => 'Raw Processing (Current)', #118-131 and 135 are Playback Retouch options
|
|
146
146
|
119 => 'Raw Processing (Multiple)',
|
|
147
147
|
120 => 'Trim',
|
|
148
148
|
121 => 'Resize (Current)',
|
|
@@ -156,6 +156,9 @@ my %buttonsCommonZ8Z9 = ( #button roles shared by the Z8 & Z9. Assigments bega
|
|
|
156
156
|
129 => 'Lighten',
|
|
157
157
|
130 => 'Darken',
|
|
158
158
|
131 => 'Motion Blend',
|
|
159
|
+
133 => 'Focus Limiter',
|
|
160
|
+
134 => 'Cycle Subject Detection Options',
|
|
161
|
+
135 => 'Jump To Source Image',
|
|
159
162
|
},
|
|
160
163
|
);
|
|
161
164
|
my %buttonsZ6III= (
|
|
@@ -9880,11 +9883,10 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
|
9880
9883
|
17 => { Name => 'LimitAF-AreaModeSelPinpoint', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa8
|
|
9881
9884
|
19 => { Name => 'LimitAF-AreaModeSelWideAF_S', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa8
|
|
9882
9885
|
20 => { Name => 'LimitAF-AreaModeSelWideAF_L', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa8
|
|
9883
|
-
21 => { Name => 'LimitAFAreaModeSelAuto', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa8
|
|
9886
|
+
21 => { Name => 'LimitAFAreaModeSelAuto', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa8
|
|
9884
9887
|
22 => { Name => 'FocusPointWrap', PrintConv => { 0 => 'No Wrap', 1 => 'Wrap' }, Unknown => 1 }, # CSa10
|
|
9885
9888
|
23 => { Name => 'ManualFocusPointIllumination', PrintConv => {0 => 'On During Focus Point Selection Only', 1 => 'On', }, Unknown => 1 }, # CSa10a
|
|
9886
9889
|
24 => { Name => 'DynamicAreaAFAssist', PrintConv => { 0 => 'Focus Point Only',1 => 'Focus and Surrounding Points',}, Unknown => 1 }, # CSa10b
|
|
9887
|
-
|
|
9888
9890
|
26 => { Name => 'AF-AssistIlluminator', PrintConv => \%offOn }, # CSa11
|
|
9889
9891
|
27 => { Name => 'ManualFocusRingInAFMode', PrintConv => \%offOn }, # CSa14
|
|
9890
9892
|
29 => { Name => 'ExposureControlStepSize', PrintConv => \%thirdHalfFull }, # CSb2
|
|
@@ -9999,7 +10001,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
|
9999
10001
|
},
|
|
10000
10002
|
},
|
|
10001
10003
|
85 => { Name => 'ContinuousModeDisplay', PrintConv => \%offOn }, # CSd14
|
|
10002
|
-
87 => { # CSe1-a Previous cameras reported this with HighSpeedSync indicator appended as '(Auto FP)'.
|
|
10004
|
+
87 => { # CSe1-a Previous cameras reported this with HighSpeedSync indicator appended as '(Auto FP)'.
|
|
10003
10005
|
Name => 'FlashSyncSpeed',
|
|
10004
10006
|
ValueConv => '($val-144)/8',
|
|
10005
10007
|
PrintConv => {
|
|
@@ -53,7 +53,7 @@ my %formatType = (
|
|
|
53
53
|
L<http://www.openexr.com/> for the official specification.
|
|
54
54
|
},
|
|
55
55
|
_ver => { Name => 'EXRVersion', Notes => 'low byte of Flags word' },
|
|
56
|
-
_flags => { Name => 'Flags',
|
|
56
|
+
_flags => { Name => 'Flags',
|
|
57
57
|
PrintConv => { BITMASK => {
|
|
58
58
|
9 => 'Tiled',
|
|
59
59
|
10 => 'Long names',
|
|
@@ -37,7 +37,7 @@ use vars qw($VERSION %leicaLensTypes);
|
|
|
37
37
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
38
38
|
use Image::ExifTool::Exif;
|
|
39
39
|
|
|
40
|
-
$VERSION = '2.
|
|
40
|
+
$VERSION = '2.28';
|
|
41
41
|
|
|
42
42
|
sub ProcessLeicaLEIC($$$);
|
|
43
43
|
sub WhiteBalanceConv($;$$);
|
|
@@ -916,13 +916,21 @@ my %shootingMode = (
|
|
|
916
916
|
Name => 'AFPointPosition',
|
|
917
917
|
Writable => 'rational64u',
|
|
918
918
|
Count => 2,
|
|
919
|
-
Notes =>
|
|
919
|
+
Notes => q{
|
|
920
|
+
X Y coordinates of primary AF area center, in the range 0.0 to 1.0, or
|
|
921
|
+
"n/a" or "none" for invalid values
|
|
922
|
+
},
|
|
920
923
|
PrintConv => q{
|
|
921
924
|
return 'none' if $val eq '16777216 16777216';
|
|
925
|
+
return 'n/a' if $val =~ /^4194303\.9/;
|
|
922
926
|
my @a = split ' ', $val;
|
|
923
927
|
sprintf("%.2g %.2g",@a);
|
|
924
928
|
},
|
|
925
|
-
PrintConvInv =>
|
|
929
|
+
PrintConvInv => q{
|
|
930
|
+
return '16777216 16777216' if $val eq 'none';
|
|
931
|
+
return '4294967295/1024 4294967295/1024' if $val eq 'n/a';
|
|
932
|
+
return $val;
|
|
933
|
+
},
|
|
926
934
|
},
|
|
927
935
|
0x4e => { #PH
|
|
928
936
|
Name => 'FaceDetInfo',
|
|
@@ -1441,8 +1449,8 @@ my %shootingMode = (
|
|
|
1441
1449
|
Writable => 'rational64u',
|
|
1442
1450
|
Notes => 'relative to size of image. "n/a" for manual focus',
|
|
1443
1451
|
Count => 2,
|
|
1444
|
-
PrintConv => '$val =~ /^4194303
|
|
1445
|
-
PrintConvInv => '$val eq "n/a" ? "
|
|
1452
|
+
PrintConv => '$val =~ /^4194303\.9/ ? "n/a" : $val',
|
|
1453
|
+
PrintConvInv => '$val eq "n/a" ? "4294967295/1024 4294967295/1024" : $val',
|
|
1446
1454
|
},
|
|
1447
1455
|
0xe4 => { #IB
|
|
1448
1456
|
Name => 'LensTypeModel',
|
|
@@ -1485,6 +1493,22 @@ my %shootingMode = (
|
|
|
1485
1493
|
Writable => 'int16u',
|
|
1486
1494
|
PrintConv => { 0 => 'Off', 1 => 'On' },
|
|
1487
1495
|
},
|
|
1496
|
+
0xf1 => { #github365
|
|
1497
|
+
Name => 'LUT1Name',
|
|
1498
|
+
Writable => 'string',
|
|
1499
|
+
},
|
|
1500
|
+
0xf3 => { #github365
|
|
1501
|
+
Name => 'LUT1Opacity',
|
|
1502
|
+
Writable => 'int8u', # (percent)
|
|
1503
|
+
},
|
|
1504
|
+
0xf4 => { #github365
|
|
1505
|
+
Name => 'LUT2Name',
|
|
1506
|
+
Writable => 'string',
|
|
1507
|
+
},
|
|
1508
|
+
0xf5 => { #github365
|
|
1509
|
+
Name => 'LUT2Opacity',
|
|
1510
|
+
Writable => 'int8u', # (percent)
|
|
1511
|
+
},
|
|
1488
1512
|
0x0e00 => {
|
|
1489
1513
|
Name => 'PrintIM',
|
|
1490
1514
|
Description => 'Print Image Matching',
|
|
@@ -2271,7 +2295,7 @@ my %shootingMode = (
|
|
|
2271
2295
|
Format => 'int16u[4]',
|
|
2272
2296
|
RawConv => '$$self{NumFacePositions} < 1 ? undef : $val',
|
|
2273
2297
|
Notes => q{
|
|
2274
|
-
4 numbers: X/Y coordinates of the face center and width/height of face.
|
|
2298
|
+
4 numbers: X/Y coordinates of the face center and width/height of face.
|
|
2275
2299
|
Coordinates are relative to an image twice the size of the thumbnail, or 320
|
|
2276
2300
|
pixels wide
|
|
2277
2301
|
},
|
|
@@ -909,10 +909,18 @@ my %binaryDataAttrs = (
|
|
|
909
909
|
# 11.3.0.0 - K-S1
|
|
910
910
|
# 11.5.0.0 - K-S2
|
|
911
911
|
# 11.6.1.0 - K-3 II
|
|
912
|
-
# 11.7.5.0 - WG-M2
|
|
912
|
+
# 11.7.5.0 - Ricoh WG-M2
|
|
913
913
|
# 12.0.0.0 - K-1
|
|
914
914
|
# 12.1.3.0 - K-70
|
|
915
915
|
# 12.1.5.0 - KP
|
|
916
|
+
# 12.3.2.0 - K-1 Mark II
|
|
917
|
+
# 12.7.5.0 - Ricoh WG-M2
|
|
918
|
+
# 13.0.0.0 - Ricoh GR III / G900SE
|
|
919
|
+
# 13.1.1.0 - Ricoh WG-70
|
|
920
|
+
# 14.0.0.0 - K-3 Mark III
|
|
921
|
+
# 14.0.1.0 - Ricoh GR IIIx
|
|
922
|
+
# 14.2.0.0 - KF
|
|
923
|
+
# 15.2.3.0 - Ricoh GR IV
|
|
916
924
|
},
|
|
917
925
|
0x0001 => { #PH
|
|
918
926
|
Name => 'PentaxModelType',
|
|
@@ -15,7 +15,7 @@ use vars qw($VERSION);
|
|
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
16
16
|
use Image::ExifTool::Exif;
|
|
17
17
|
|
|
18
|
-
$VERSION = '1.
|
|
18
|
+
$VERSION = '1.12';
|
|
19
19
|
|
|
20
20
|
sub WritePhaseOne($$$);
|
|
21
21
|
sub ProcessPhaseOne($$$);
|
|
@@ -193,6 +193,22 @@ my @formatName = ( undef, 'string', 'int16s', undef, 'int32s' );
|
|
|
193
193
|
Flags => ['Unknown','Hidden'],
|
|
194
194
|
PrintConv => \&Image::ExifTool::LimitLongValues,
|
|
195
195
|
},
|
|
196
|
+
0x0262 => { Name => 'SequenceID', Format => 'string' },
|
|
197
|
+
0x0263 => {
|
|
198
|
+
Name => 'SequenceKind',
|
|
199
|
+
PrintConv => {
|
|
200
|
+
0 => 'Bracketing: Shutter Speed',
|
|
201
|
+
1 => 'Bracketing: Aperture',
|
|
202
|
+
2 => 'Bracketing: ISO',
|
|
203
|
+
3 => 'Hyperfocal',
|
|
204
|
+
4 => 'Time Lapse',
|
|
205
|
+
5 => 'HDR',
|
|
206
|
+
6 => 'Focus Stacking',
|
|
207
|
+
},
|
|
208
|
+
PrintConvInv => '$val',
|
|
209
|
+
},
|
|
210
|
+
0x0264 => 'SequenceFrameNumber',
|
|
211
|
+
0x0265 => 'SequenceFrameCount',
|
|
196
212
|
# 0x0300 - int32u: 100,101,102
|
|
197
213
|
0x0301 => { Name => 'FirmwareVersions', Format => 'string' },
|
|
198
214
|
# 0x0304 - int32u: 8,3073,3076
|
|
@@ -461,7 +461,7 @@ sub Draw($$)
|
|
|
461
461
|
$mark = $markerData{$m[0]};
|
|
462
462
|
$mark or $markID{$mark} = '', next; # skip 'none' or unrecognized marker name
|
|
463
463
|
if ($fill and $fill ne 'none') {
|
|
464
|
-
my $op = $m[3] || ($$cols[$i] eq 'none' ? 50 : 20);
|
|
464
|
+
my $op = $m[3] || ($$cols[$i] eq 'none' ? 50 : 20);
|
|
465
465
|
$mark .= qq( fill="$fill" style="fill-opacity: $op%");
|
|
466
466
|
} else {
|
|
467
467
|
$mark .= ' fill="none"';
|
|
@@ -573,7 +573,7 @@ sub Draw($$)
|
|
|
573
573
|
$xsclr = int($xscl * 100 + 0.5) / 100;
|
|
574
574
|
if ($style =~ /\bf/) {
|
|
575
575
|
my @m = split /-/, $$marks[0];
|
|
576
|
-
my $op = $m[3] || ($style =~ /\bl/ ? 20 : 50);
|
|
576
|
+
my $op = $m[3] || ($style =~ /\bl/ ? 20 : 50);
|
|
577
577
|
$fill = " fill='$$cols[0]'";
|
|
578
578
|
$fill .= " style='fill-opacity: $op%'" if $$cols[0] ne 'none';
|
|
579
579
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
# and 'int64s' formats for VARINT (type 0) values, 'int64u',
|
|
10
10
|
# 'int64s', 'rational64u', 'rational64s' and 'double' for I64
|
|
11
11
|
# (type 1), 'undef', 'string' and 'rational' for LEN (type 2),
|
|
12
|
-
# and 'int32u', 'int32s', 'rational32u', 'rational32s',
|
|
12
|
+
# and 'int32u', 'int32s', 'rational32u', 'rational32s',
|
|
13
13
|
# 'fixed32u', 'fixed32s' and 'float' for I32 (type 5) values.
|
|
14
14
|
#
|
|
15
15
|
# References: 1) https://protobuf.dev/programming-guides/encoding/
|
|
@@ -21,10 +21,16 @@ use strict;
|
|
|
21
21
|
use vars qw($VERSION);
|
|
22
22
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
23
23
|
|
|
24
|
-
$VERSION = '1.
|
|
24
|
+
$VERSION = '1.06';
|
|
25
25
|
|
|
26
26
|
sub ProcessProtobuf($$$;$);
|
|
27
27
|
|
|
28
|
+
# largest unsigned integer on this system (2^32 or 2^64 - 1)
|
|
29
|
+
my $intMax = ~0;
|
|
30
|
+
|
|
31
|
+
# smallest unsigned integer that we interpret as int64s (0xffffffff00000000)
|
|
32
|
+
my $int64sMin = 18446744069414584320;
|
|
33
|
+
|
|
28
34
|
#------------------------------------------------------------------------------
|
|
29
35
|
# Read bytes from dirInfo object
|
|
30
36
|
# Inputs: 0) dirInfo ref (with DataPt and Pos set), 1) number of bytes
|
|
@@ -43,17 +49,23 @@ sub GetBytes($$)
|
|
|
43
49
|
# Read variable-length integer
|
|
44
50
|
# Inputs: 0) dirInfo ref
|
|
45
51
|
# Returns: integer value
|
|
52
|
+
# - sets $$dirInfo{Bit0} according to bit 0 of returned value
|
|
53
|
+
# (necessary for cases where a signed integer exceeds $intMax)
|
|
46
54
|
sub VarInt($)
|
|
47
55
|
{
|
|
48
56
|
my $dirInfo = shift;
|
|
49
|
-
my $
|
|
50
|
-
|
|
57
|
+
my $buff = GetBytes($dirInfo, 1);
|
|
58
|
+
return undef unless defined $buff;
|
|
59
|
+
my $val = ord($buff) & 0x7f;
|
|
60
|
+
$$dirInfo{Bit0} = $val & 0x01;
|
|
61
|
+
my $mult = 128;
|
|
51
62
|
for (;;) {
|
|
52
|
-
my $buff = GetBytes($dirInfo, 1);
|
|
53
|
-
defined $buff or return undef;
|
|
54
|
-
$val += (ord($buff) & 0x7f) << $shift;
|
|
55
63
|
last unless ord($buff) & 0x80;
|
|
56
|
-
$
|
|
64
|
+
$buff = GetBytes($dirInfo, 1);
|
|
65
|
+
return undef unless defined $buff;
|
|
66
|
+
$val += (ord($buff) & 0x7f) * $mult;
|
|
67
|
+
last unless ord($buff) & 0x80;
|
|
68
|
+
$mult *= 128; # (Note: don't use integer bit shift to avoid integer overflow)
|
|
57
69
|
}
|
|
58
70
|
return $val;
|
|
59
71
|
}
|
|
@@ -62,7 +74,8 @@ sub VarInt($)
|
|
|
62
74
|
# Read protobuf record
|
|
63
75
|
# Inputs: 0) dirInfo ref
|
|
64
76
|
# Returns: 0) record payload (plus tag id and format type in list context)
|
|
65
|
-
# Notes: Updates dirInfo
|
|
77
|
+
# Notes: Updates $$dirInfo{Pos} to start of next record, and sets $$dirInfo{Bit0}
|
|
78
|
+
# according to the least significant bit of type 0 (varInt) records
|
|
66
79
|
sub ReadRecord($)
|
|
67
80
|
{
|
|
68
81
|
my $dirInfo = shift;
|
|
@@ -133,7 +146,7 @@ sub ProcessProtobuf($$$;$)
|
|
|
133
146
|
}
|
|
134
147
|
# prefix for unknown tags
|
|
135
148
|
my $unkPre = $$tagTbl{TAG_PREFIX} ? $$tagTbl{TAG_PREFIX} . '_' : 'Protobuf ';
|
|
136
|
-
|
|
149
|
+
|
|
137
150
|
# loop through protobuf records
|
|
138
151
|
for (;;) {
|
|
139
152
|
my $pos = $$dirInfo{Pos};
|
|
@@ -170,11 +183,19 @@ sub ProcessProtobuf($$$;$)
|
|
|
170
183
|
if ($type == 0) {
|
|
171
184
|
$val = $buff;
|
|
172
185
|
if ($$tagInfo{Format} eq 'signed') {
|
|
173
|
-
|
|
174
|
-
|
|
186
|
+
if ($val > $intMax) {
|
|
187
|
+
# use double math (15 decimal digits precision)
|
|
188
|
+
$val = $$dirInfo{Bit0} ? -int($val / 2) - 1 : $val / 2;
|
|
189
|
+
} else {
|
|
190
|
+
# use integer math
|
|
191
|
+
$val = ($val & 1) ? -($val >> 1)-1 : ($val >> 1);
|
|
192
|
+
}
|
|
193
|
+
} elsif ($$tagInfo{Format} eq 'int64s' and $val >= $int64sMin) {
|
|
175
194
|
# hack for DJI drones which store 64-bit signed integers improperly
|
|
176
195
|
# (just toss upper 32 bits which should be all 1's anyway)
|
|
177
|
-
|
|
196
|
+
# Note: do the two subtractions because $int64sMin + 4294967296
|
|
197
|
+
# is too large for a 64-bit integer
|
|
198
|
+
$val = $val - $int64sMin - 4294967296;
|
|
178
199
|
}
|
|
179
200
|
} elsif ($type == 2 and $$tagInfo{Format} eq 'rational') {
|
|
180
201
|
my $dir = { DataPt => \$buff, Pos => 0 };
|
|
@@ -187,11 +208,16 @@ sub ProcessProtobuf($$$;$)
|
|
|
187
208
|
} elsif ($type == 0) { # varInt
|
|
188
209
|
$val = $buff;
|
|
189
210
|
my $hex = sprintf('%x', $val);
|
|
190
|
-
if (
|
|
191
|
-
my $s64 =
|
|
211
|
+
if ($val >= $int64sMin) {
|
|
212
|
+
my $s64 = $val - $int64sMin - 4294967296;
|
|
192
213
|
$val .= " (0x$hex, int64s $s64)";
|
|
193
214
|
} else {
|
|
194
|
-
my $signed
|
|
215
|
+
my $signed;
|
|
216
|
+
if ($val > $intMax) {
|
|
217
|
+
$signed = $$dirInfo{Bit0} ? -int($val / 2) - 1 : $val / 2;
|
|
218
|
+
} else {
|
|
219
|
+
$signed = ($val & 1) ? -($val >> 1)-1 : ($val >> 1);
|
|
220
|
+
}
|
|
195
221
|
$val .= " (0x$hex, signed $signed)";
|
|
196
222
|
}
|
|
197
223
|
} elsif ($type == 1) { # 64-bit number
|