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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +44 -1
  3. data/bin/MANIFEST +2 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +48 -48
  7. data/bin/config_files/example.config +5 -2
  8. data/bin/exiftool +96 -84
  9. data/bin/lib/Image/ExifTool/Apple.pm +0 -1
  10. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +4 -4
  11. data/bin/lib/Image/ExifTool/Canon.pm +24 -1
  12. data/bin/lib/Image/ExifTool/CanonCustom.pm +1 -1
  13. data/bin/lib/Image/ExifTool/DarwinCore.pm +2 -2
  14. data/bin/lib/Image/ExifTool/EXE.pm +1 -1
  15. data/bin/lib/Image/ExifTool/Exif.pm +4 -2
  16. data/bin/lib/Image/ExifTool/FLIR.pm +1 -1
  17. data/bin/lib/Image/ExifTool/FlashPix.pm +1 -1
  18. data/bin/lib/Image/ExifTool/FujiFilm.pm +2 -2
  19. data/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
  20. data/bin/lib/Image/ExifTool/Geolocation.pm +1 -1
  21. data/bin/lib/Image/ExifTool/Geotag.pm +3 -3
  22. data/bin/lib/Image/ExifTool/Google.pm +2 -2
  23. data/bin/lib/Image/ExifTool/ICC_Profile.pm +0 -1
  24. data/bin/lib/Image/ExifTool/Import.pm +1 -1
  25. data/bin/lib/Image/ExifTool/JPEG.pm +5 -1
  26. data/bin/lib/Image/ExifTool/Jpeg2000.pm +1 -1
  27. data/bin/lib/Image/ExifTool/Kandao.pm +399 -0
  28. data/bin/lib/Image/ExifTool/LNK.pm +1 -1
  29. data/bin/lib/Image/ExifTool/MRC.pm +4 -4
  30. data/bin/lib/Image/ExifTool/MWG.pm +1 -1
  31. data/bin/lib/Image/ExifTool/MacOS.pm +1 -2
  32. data/bin/lib/Image/ExifTool/Matroska.pm +56 -15
  33. data/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
  34. data/bin/lib/Image/ExifTool/Nikon.pm +13 -15
  35. data/bin/lib/Image/ExifTool/NikonCustom.pm +10 -8
  36. data/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
  37. data/bin/lib/Image/ExifTool/PPM.pm +1 -1
  38. data/bin/lib/Image/ExifTool/Panasonic.pm +30 -6
  39. data/bin/lib/Image/ExifTool/Pentax.pm +9 -1
  40. data/bin/lib/Image/ExifTool/PhaseOne.pm +17 -1
  41. data/bin/lib/Image/ExifTool/Plot.pm +2 -2
  42. data/bin/lib/Image/ExifTool/Protobuf.pm +42 -16
  43. data/bin/lib/Image/ExifTool/QuickTime.pm +48 -8
  44. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +2 -2
  45. data/bin/lib/Image/ExifTool/README +5 -5
  46. data/bin/lib/Image/ExifTool/RIFF.pm +5 -4
  47. data/bin/lib/Image/ExifTool/Reconyx.pm +2 -2
  48. data/bin/lib/Image/ExifTool/Samsung.pm +11 -1
  49. data/bin/lib/Image/ExifTool/Sony.pm +29 -3
  50. data/bin/lib/Image/ExifTool/TNEF.pm +2 -2
  51. data/bin/lib/Image/ExifTool/TagLookup.pm +7129 -7108
  52. data/bin/lib/Image/ExifTool/TagNames.pod +259 -111
  53. data/bin/lib/Image/ExifTool/Text.pm +1 -1
  54. data/bin/lib/Image/ExifTool/Trailer.pm +1 -1
  55. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +10 -2
  56. data/bin/lib/Image/ExifTool/Writer.pl +9 -5
  57. data/bin/lib/Image/ExifTool/XMP.pm +4 -2
  58. data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
  59. data/bin/lib/Image/ExifTool.pm +33 -26
  60. data/bin/lib/Image/ExifTool.pod +88 -79
  61. data/bin/perl-Image-ExifTool.spec +47 -47
  62. data/lib/exiftool_vendored/version.rb +1 -1
  63. 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';
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 => { Name => 'TargetTypeValue', Format => 'unsigned' },
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
- VARS => { LONG_TAGS => 1 },
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, $struct, %seekInfo, %seek);
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 ($$tagInfo{Name} eq 'Cluster' and $processAll < 2) {
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
- $et->VerboseDir($$tagTablePtr{$tag}{Name}, undef, $size);
1085
- $dirName = $$tagInfo{Name};
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
- if ($$tagInfo{Name} eq 'ChapterAtom') {
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
- # set group1 to Track/Chapter number
1174
- if ($$tagInfo{Name} eq 'TrackNumber') {
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{$$tagInfo{Name}} = $val if $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;
@@ -970,7 +970,7 @@ sub ReadXtraValue($$)
970
970
  {
971
971
  my ($et, $data) = @_;
972
972
  my ($format, $i, @vals);
973
-
973
+
974
974
  return undef if length($data) < 10;
975
975
 
976
976
  # (version flags according to the reference, but looks more like a count - PH)
@@ -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.51';
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', # 209/233 focus point cameras
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', #273/299 focus point cameras
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', #405/493 focus point cameras
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', #github#250
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
- PrintConv => {
9350
- 0 => 'Auto (all)',
9351
- 1 => 'People',
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.27';
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',
@@ -95,7 +95,7 @@ sub ProcessPPM($$)
95
95
  } elsif ($seal and $$et{DEL_GROUP}{SEAL}) {
96
96
  # delete SEAL comment
97
97
  $et->VerboseValue('- Comment', $oldComment);
98
- ++$$et{CHANGED};
98
+ ++$$et{CHANGED};
99
99
  } else {
100
100
  $newComment = $oldComment; # use existing comment
101
101
  }
@@ -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.26';
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 => 'X Y coordinates of primary AF area center, in the range 0.0 to 1.0',
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 => '$val eq "none" ? "16777216 16777216" : $val',
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.999/ ? "n/a" : $val',
1445
- PrintConvInv => '$val eq "n/a" ? "4194303.999 4194303.999" : $val',
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.11';
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.05';
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 $val = 0;
50
- my $shift = 0;
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
- $shift += 7;
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 Pos to start of next record
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
- $val = ($val & 1) ? -($val >> 1)-1 : ($val >> 1);
174
- } elsif ($$tagInfo{Format} eq 'int64s' and $val > 0xffffffff) {
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
- $val = ($val & 0xffffffff) - 4294967296;
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 (length($hex) == 16 and $hex =~ /^ffffffff/) {
191
- my $s64 = hex(substr($hex, 8)) - 4294967296;
211
+ if ($val >= $int64sMin) {
212
+ my $s64 = $val - $int64sMin - 4294967296;
192
213
  $val .= " (0x$hex, int64s $s64)";
193
214
  } else {
194
- my $signed = ($val & 1) ? -($val >> 1)-1 : ($val >> 1);
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