exiftool-vendored.exe 13.42.0 → 13.44.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 (54) hide show
  1. package/bin/exiftool.exe +0 -0
  2. package/bin/exiftool_files/exiftool.pl +2 -2
  3. package/bin/exiftool_files/lib/Image/ExifTool/Apple.pm +0 -1
  4. package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +2 -2
  5. package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +23 -1
  6. package/bin/exiftool_files/lib/Image/ExifTool/CanonCustom.pm +1 -1
  7. package/bin/exiftool_files/lib/Image/ExifTool/DarwinCore.pm +2 -2
  8. package/bin/exiftool_files/lib/Image/ExifTool/EXE.pm +1 -1
  9. package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +1 -0
  10. package/bin/exiftool_files/lib/Image/ExifTool/FLIR.pm +1 -1
  11. package/bin/exiftool_files/lib/Image/ExifTool/FlashPix.pm +1 -1
  12. package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +2 -2
  13. package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.dat +0 -0
  14. package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.pm +1 -1
  15. package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +1 -1
  16. package/bin/exiftool_files/lib/Image/ExifTool/Google.pm +2 -2
  17. package/bin/exiftool_files/lib/Image/ExifTool/ICC_Profile.pm +0 -1
  18. package/bin/exiftool_files/lib/Image/ExifTool/Import.pm +1 -1
  19. package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +1 -1
  20. package/bin/exiftool_files/lib/Image/ExifTool/Kandao.pm +399 -0
  21. package/bin/exiftool_files/lib/Image/ExifTool/LNK.pm +1 -1
  22. package/bin/exiftool_files/lib/Image/ExifTool/MRC.pm +4 -4
  23. package/bin/exiftool_files/lib/Image/ExifTool/MWG.pm +1 -1
  24. package/bin/exiftool_files/lib/Image/ExifTool/MacOS.pm +1 -2
  25. package/bin/exiftool_files/lib/Image/ExifTool/Matroska.pm +56 -15
  26. package/bin/exiftool_files/lib/Image/ExifTool/Microsoft.pm +1 -1
  27. package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +5 -5
  28. package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +5 -6
  29. package/bin/exiftool_files/lib/Image/ExifTool/OpenEXR.pm +1 -1
  30. package/bin/exiftool_files/lib/Image/ExifTool/PPM.pm +1 -1
  31. package/bin/exiftool_files/lib/Image/ExifTool/Panasonic.pm +30 -6
  32. package/bin/exiftool_files/lib/Image/ExifTool/PhaseOne.pm +17 -1
  33. package/bin/exiftool_files/lib/Image/ExifTool/Plot.pm +2 -2
  34. package/bin/exiftool_files/lib/Image/ExifTool/Protobuf.pm +2 -2
  35. package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +48 -8
  36. package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +2 -2
  37. package/bin/exiftool_files/lib/Image/ExifTool/README +5 -5
  38. package/bin/exiftool_files/lib/Image/ExifTool/RIFF.pm +5 -4
  39. package/bin/exiftool_files/lib/Image/ExifTool/Reconyx.pm +2 -2
  40. package/bin/exiftool_files/lib/Image/ExifTool/Samsung.pm +11 -1
  41. package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +13 -3
  42. package/bin/exiftool_files/lib/Image/ExifTool/TNEF.pm +2 -2
  43. package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +7129 -7108
  44. package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +257 -110
  45. package/bin/exiftool_files/lib/Image/ExifTool/Text.pm +1 -1
  46. package/bin/exiftool_files/lib/Image/ExifTool/Trailer.pm +1 -1
  47. package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +10 -2
  48. package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +3 -2
  49. package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +4 -2
  50. package/bin/exiftool_files/lib/Image/ExifTool/ZIP.pm +1 -1
  51. package/bin/exiftool_files/lib/Image/ExifTool.pm +5 -2
  52. package/bin/exiftool_files/lib/Image/ExifTool.pod +79 -79
  53. package/bin/exiftool_files/windows_exiftool.txt +55 -51
  54. package/package.json +4 -4
@@ -22,7 +22,7 @@ $VERSION = '1.00';
22
22
 
23
23
  my %bool = (
24
24
  Format => 'int8u',
25
- PrintConv => { 0 => 'No', 1 => 'Yes' }
25
+ PrintConv => { 0 => 'No', 1 => 'Yes' }
26
26
  );
27
27
 
28
28
  %Image::ExifTool::MRC::Main = (
@@ -31,7 +31,7 @@ my %bool = (
31
31
  VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
32
32
  FORMAT => 'int32u',
33
33
  NOTES => q{
34
- Tags extracted from Medical Research Council (MRC) format imaging files.
34
+ Tags extracted from Medical Research Council (MRC) format imaging files.
35
35
  See L<https://www.ccpem.ac.uk/mrc_format/mrc2014.php> for the specification.
36
36
  },
37
37
  0 => 'ImageWidth',
@@ -104,7 +104,7 @@ my %bool = (
104
104
  },
105
105
  12 => {
106
106
  Name => 'TimeStamp',
107
- Format => 'double',
107
+ Format => 'double',
108
108
  Condition => '$$self{BitM} & 0x01',
109
109
  Groups => { 2 => 'Time'},
110
110
  # shift from days since Dec 30, 1899 to Unix epoch of Jan 1, 1970
@@ -269,7 +269,7 @@ sub ProcessMRC($$)
269
269
  # (I don't have any samples with extended headers for testing, so these are not yet decoded)
270
270
  if ($$et{ExtendedHeaderSize} and $$et{ExtendedHeaderType} =~ /^FEI[12]/) {
271
271
  unless ($raf->Read($buff,4)==4 and $raf->Seek(-4,1)) { # read metadata size
272
- $et->Warn('Error reading extended header');
272
+ $et->Warn('Error reading extended header');
273
273
  return 1;
274
274
  }
275
275
  my $size = Get32u(\$buff, 0);
@@ -487,7 +487,7 @@ my %sKeywordStruct;
487
487
  GROUPS => { 0 => 'XMP', 1 => 'XMP-mwg-kw', 2 => 'Image' },
488
488
  NAMESPACE => 'mwg-kw',
489
489
  NOTES => q{
490
- Hierarchical keywords metadata defined by the MWG 2.0 specification.
490
+ Hierarchical keywords metadata defined by the MWG 2.0 specification.
491
491
  ExifTool unrolls keyword structures to an arbitrary depth of 6 to allow
492
492
  individual levels to be accessed with different tag names, and to avoid
493
493
  infinite recursion. See
@@ -528,7 +528,6 @@ sub ExtractMDItemTags($$)
528
528
  $$et{INDENT} =~ s/\| $//;
529
529
  }
530
530
 
531
-
532
531
  #------------------------------------------------------------------------------
533
532
  # Read MacOS XAttr value
534
533
  # Inputs: 0) ExifTool object ref, 1) file name
@@ -732,7 +731,7 @@ This module is used by Image::ExifTool
732
731
  This module contains definitions required by Image::ExifTool to extract
733
732
  MDItem* and XAttr* tags on MacOS systems using the "mdls" and "xattr"
734
733
  utilities respectively. It also reads metadata directly from the MacOS "_."
735
- sidecar files that are used on some filesystems to store file attributes.
734
+ sidecar files that are used on some filesystems to store file attributes.
736
735
  Writable tags use "xattr", "setfile" or "osascript" for writing.
737
736
 
738
737
  =head1 AUTHOR
@@ -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)
@@ -5843,7 +5843,7 @@ my %nikonFocalConversions = (
5843
5843
  28 => 'Nikkor Z 100-400mm f/4.5-5.6 VR S', #28
5844
5844
  29 => 'Nikkor Z 28mm f/2.8', #IB
5845
5845
  30 => 'Nikkor Z 400mm f/2.8 TC VR S', #28
5846
- 31 => 'Nikkor Z 24-120mm f/4 S', #github#250
5846
+ 31 => 'Nikkor Z 24-120mm f/4 S', #github250
5847
5847
  32 => 'Nikkor Z 800mm f/6.3 VR S', #28
5848
5848
  35 => 'Nikkor Z 28-75mm f/2.8', #IB
5849
5849
  36 => 'Nikkor Z 400mm f/4.5 VR S', #IB
@@ -9010,7 +9010,7 @@ my %nikonFocalConversions = (
9010
9010
  RawConv => '$$self{FocusShiftShooting} = $val',
9011
9011
  PrintConv => q{
9012
9012
  return 'Off' if $val == 0 ;
9013
- my $i = sprintf("Frame %.0f of %.0f",$val, $$self{FocusShiftNumberShots}); # something like Frame 1 of 100"
9013
+ my $i = sprintf("Frame %.0f of %.0f",$val, $$self{FocusShiftNumberShots}); # something like Frame 1 of 100"
9014
9014
  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
9015
  return "On: $i"
9016
9016
  },
@@ -9018,7 +9018,7 @@ my %nikonFocalConversions = (
9018
9018
  },
9019
9019
  #
9020
9020
  # Note: Offsets after this are shifted by +2 for Z8 firmware 3.0 (see Hook above)
9021
- #
9021
+ #
9022
9022
  0x0028 => {
9023
9023
  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
9024
  Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
@@ -9929,14 +9929,14 @@ my %nikonFocalConversions = (
9929
9929
  618 => { Name => 'ToneMap', PrintConv => { 0 => 'SDR', 1 => 'HLG' }, Unknown => 1 },
9930
9930
  622 => { Name => 'PortraitImpressionBalance', PrintConv => \%portraitImpressionBalanceZ8 },
9931
9931
  636 => {
9932
- Name => 'HighFrequencyFlickerReduction',
9932
+ Name => 'HighFrequencyFlickerReduction',
9933
9933
  PrintConv => \%offOn,
9934
9934
  Unknown => 1,
9935
9935
  Hook => '$varSize += 4 if $$self{FirmwareVersion} and $$self{FirmwareVersion} ge "03.00"',
9936
9936
  },
9937
9937
  #
9938
9938
  # firmware 3.00 adds 4 bytes somewhere in the range 638-730 (hence the Hook above)
9939
- #
9939
+ #
9940
9940
  730 => {
9941
9941
  Name => 'MovieImageArea',
9942
9942
  Unknown => 1,
@@ -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,7 +140,7 @@ 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
145
  118 => 'Raw Processing (Current)', #118-131 are Playback Retouch options
146
146
  119 => 'Raw Processing (Multiple)',
@@ -9880,11 +9880,10 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
9880
9880
  17 => { Name => 'LimitAF-AreaModeSelPinpoint', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa8
9881
9881
  19 => { Name => 'LimitAF-AreaModeSelWideAF_S', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa8
9882
9882
  20 => { Name => 'LimitAF-AreaModeSelWideAF_L', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa8
9883
- 21 => { Name => 'LimitAFAreaModeSelAuto', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa8
9883
+ 21 => { Name => 'LimitAFAreaModeSelAuto', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa8
9884
9884
  22 => { Name => 'FocusPointWrap', PrintConv => { 0 => 'No Wrap', 1 => 'Wrap' }, Unknown => 1 }, # CSa10
9885
9885
  23 => { Name => 'ManualFocusPointIllumination', PrintConv => {0 => 'On During Focus Point Selection Only', 1 => 'On', }, Unknown => 1 }, # CSa10a
9886
9886
  24 => { Name => 'DynamicAreaAFAssist', PrintConv => { 0 => 'Focus Point Only',1 => 'Focus and Surrounding Points',}, Unknown => 1 }, # CSa10b
9887
-
9888
9887
  26 => { Name => 'AF-AssistIlluminator', PrintConv => \%offOn }, # CSa11
9889
9888
  27 => { Name => 'ManualFocusRingInAFMode', PrintConv => \%offOn }, # CSa14
9890
9889
  29 => { Name => 'ExposureControlStepSize', PrintConv => \%thirdHalfFull }, # CSb2
@@ -9999,7 +9998,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
9999
9998
  },
10000
9999
  },
10001
10000
  85 => { Name => 'ContinuousModeDisplay', PrintConv => \%offOn }, # CSd14
10002
- 87 => { # CSe1-a Previous cameras reported this with HighSpeedSync indicator appended as '(Auto FP)'.
10001
+ 87 => { # CSe1-a Previous cameras reported this with HighSpeedSync indicator appended as '(Auto FP)'.
10003
10002
  Name => 'FlashSyncSpeed',
10004
10003
  ValueConv => '($val-144)/8',
10005
10004
  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
  },
@@ -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/
@@ -133,7 +133,7 @@ sub ProcessProtobuf($$$;$)
133
133
  }
134
134
  # prefix for unknown tags
135
135
  my $unkPre = $$tagTbl{TAG_PREFIX} ? $$tagTbl{TAG_PREFIX} . '_' : 'Protobuf ';
136
-
136
+
137
137
  # loop through protobuf records
138
138
  for (;;) {
139
139
  my $pos = $$dirInfo{Pos};
@@ -49,7 +49,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
49
49
  use Image::ExifTool::Exif;
50
50
  use Image::ExifTool::GPS;
51
51
 
52
- $VERSION = '3.23';
52
+ $VERSION = '3.25';
53
53
 
54
54
  sub ProcessMOV($$;$);
55
55
  sub ProcessKeys($$$);
@@ -494,6 +494,7 @@ my %qtFlags = ( #12
494
494
  ispe => 1, # primary item must have an ispe and pixi, so no need to inherit these
495
495
  pixi => 1,
496
496
  irot => 1, # (tmap may have a different irot)
497
+ imir => 1, # (ditto)
497
498
  pasp => 1, # (NC)
498
499
  hvcC => 2, # (hvcC is a property of hvc1 referred to by primary grid)
499
500
  colr => 2, # (colr is a property of primary grid or hvc1 referred to by primary)
@@ -600,7 +601,7 @@ my %userDefined = (
600
601
  # 0010: 73 6e 61 6c 00 00 00 00 00 f7 b6 d2 00 0a 46 e0 [snal..........F.]
601
602
  # 0020: 68 67 6c 67 00 00 00 00 01 02 0a a2 00 00 00 21 [hglg...........!]
602
603
  # 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
603
- # (also Samsung WB750 uncompressed thumbnail data starting with "SDIC\0")
604
+ # (also Samsung WB750 uncompressed thumbnail data starting with "SDIC\0")
604
605
  ],
605
606
  # fre1 - 4 bytes: "june" (Kodak PixPro SP360)
606
607
  frea => {
@@ -987,6 +988,25 @@ my %userDefined = (
987
988
  ProcessProc => \&ProcessInsta360,
988
989
  },
989
990
  },
991
+ # Kandao tags (Kandao QooCam 3 Ultra)
992
+ kvar => {
993
+ Name => 'KVAR',
994
+ BlockExtract => 1,
995
+ Notes => q{
996
+ by default, data in this tag is parsed to extract some embedded metadata,
997
+ but it may also be extracted as a KVAR file via the "KVAR" tag or by setting
998
+ the API BlockExtract option
999
+ },
1000
+ SubDirectory => { TagTable => 'Image::ExifTool::Kandao::Main' },
1001
+ },
1002
+ kfix => {
1003
+ Name => 'KFIX',
1004
+ SubDirectory => { TagTable => 'Image::ExifTool::Kandao::Main' },
1005
+ },
1006
+ kstb => { # (NC)
1007
+ Name => 'KSTB',
1008
+ SubDirectory => { TagTable => 'Image::ExifTool::Kandao::Main' },
1009
+ },
990
1010
  );
991
1011
 
992
1012
  # stuff seen in 'skip' atom (70mai Pro Plus+ MP4 videos)
@@ -2667,6 +2687,7 @@ my %userDefined = (
2667
2687
  ByteOrder => 'BigEndian',
2668
2688
  },
2669
2689
  },
2690
+ # PREX - seen written by Sony ILCE-7M5 (apparently contains another video profile?)
2670
2691
  );
2671
2692
 
2672
2693
  # FPRF atom information (ref 11)
@@ -2970,7 +2991,6 @@ my %userDefined = (
2970
2991
  Condition => '$$valPt =~ /^(prof|rICC)/',
2971
2992
  # (don't do this because Apple Preview won't display an HEIC with a 0-length profile)
2972
2993
  # Permanent => 0, # (in QuickTime, this writes a zero-length box instead of deleting)
2973
- Permanent => 1,
2974
2994
  SubDirectory => {
2975
2995
  TagTable => 'Image::ExifTool::ICC_Profile::Main',
2976
2996
  Start => 4,
@@ -2991,6 +3011,22 @@ my %userDefined = (
2991
3011
  3 => 'Rotate 90 CW',
2992
3012
  },
2993
3013
  },
3014
+ imir => { # (applied before rotation)
3015
+ Name => 'Mirroring',
3016
+ Format => 'int8u',
3017
+ # yes, I realize this making this writable is useless without the ability to
3018
+ # create/delete this box because it is the existence of this box that is
3019
+ # significant. (The people who wrote the specification succeeded in making
3020
+ # this as complicated as possible because creating/deleting boxes from the
3021
+ # item property container is a real pain in the ass!)
3022
+ Writable => 'int8u',
3023
+ Protected => 1,
3024
+ PrintConv => {
3025
+ 0 => 'Vertical',
3026
+ 1 => 'Horizontal',
3027
+ # (it would have been great if the specification allowed for a "no mirroring" value)
3028
+ },
3029
+ },
2994
3030
  ispe => {
2995
3031
  Name => 'ImageSpatialExtent',
2996
3032
  Condition => '$$valPt =~ /^\0{4}/', # (version/flags == 0/0)
@@ -3405,7 +3441,7 @@ my %userDefined = (
3405
3441
  ssrc => { Name => 'Non-primarySourceTrack', Format => 'int32u' }, #29
3406
3442
  sync => { Name => 'SyncronizedTrack', Format => 'int32u' }, #29
3407
3443
  # hint - Original media for hint track (ref 29)
3408
- # cdep (Structural Dependency QT tag?)
3444
+ # cdep (Structural Dependency QT tag?)
3409
3445
  );
3410
3446
 
3411
3447
  # track aperture mode dimensions atoms
@@ -6622,7 +6658,7 @@ my %userDefined = (
6622
6658
  This directory contains a list of key names which are used to decode tags
6623
6659
  written by the "mdta" handler. Also in this table are a few tags found in
6624
6660
  timed metadata that are not yet writable by ExifTool. The prefix of
6625
- "com.apple.quicktime." has been removed from the TagID's below. These tags
6661
+ "com.apple.quicktime." has been removed from most TagID's below. These tags
6626
6662
  support alternate languages in the same way as the
6627
6663
  L<ItemList|Image::ExifTool::TagNames/QuickTime ItemList Tags> tags. Note
6628
6664
  that by default,
@@ -6716,14 +6752,17 @@ my %userDefined = (
6716
6752
  'encoder' => { }, # forum15418 (written by ffmpeg)
6717
6753
  #
6718
6754
  # the following tags aren't in the com.apple.quicktime namespace:
6755
+ # (Note: must add any non-'com' prefix to %fullKeysID in WriteQuickTime.pl
6756
+ # to avoid adding the 'com.apple.quicktime' prefix when writing)
6719
6757
  #
6720
6758
  'com.android.version' => 'AndroidVersion',
6721
6759
  'com.android.capture.fps' => { Name => 'AndroidCaptureFPS', Writable => 'float' },
6722
6760
  'com.android.manufacturer' => 'AndroidMake',
6723
6761
  'com.android.model' => 'AndroidModel',
6724
6762
  'com.xiaomi.preview_video_cover' => { Name => 'XiaomiPreviewVideoCover', Writable => 'int32s' },
6725
- 'xiaomi.exifInfo.videoinfo' => 'XiaomiExifInfo',
6726
6763
  'com.xiaomi.hdr10' => { Name => 'XiaomiHDR10', Writable => 'int32s' },
6764
+ 'xiaomi.exifInfo.videoinfo' => 'XiaomiExifInfo',
6765
+ 'samsung.android.utc_offset' => { Name => 'AndroidTimeZone', Groups => { 2 => 'Time' } },
6727
6766
  #
6728
6767
  # also seen
6729
6768
  #
@@ -9007,13 +9046,13 @@ sub GetString($$)
9007
9046
  sub PrintableTagID($;$)
9008
9047
  {
9009
9048
  my $tag = $_[0];
9010
- my $n = ($tag =~ s/([\x00-\x1f\x7f-\xff])/'x'.unpack('H*',$1)/eg);
9049
+ my $n = ($tag =~ s/([^-_a-zA-Z0-9])/'x'.unpack('H*',$1)/eg);
9011
9050
  if ($n and $_[1]) {
9012
9051
  if ($n > 2 and $_[1] & 0x01) {
9013
9052
  $tag = '0x' . unpack('H8', $_[0]);
9014
9053
  $tag =~ s/^0x0000/0x/;
9015
9054
  } elsif ($_[1] & 0x02) {
9016
- ($tag = $_[0]) =~ s/([\x00-\x1f\x7f-\xff])/'\\x'.unpack('H*',$1)/eg;
9055
+ ($tag = $_[0]) =~ s/([^-_a-zA-Z0-9])/'\\x'.unpack('H*',$1)/eg;
9017
9056
  }
9018
9057
  }
9019
9058
  return $tag;
@@ -9776,6 +9815,7 @@ sub ProcessKeys($$$)
9776
9815
  $name = "Tag_$name" if length $name < 2;
9777
9816
  $newInfo = { Name => $name, Groups => { 1 => 'Keys' } };
9778
9817
  $msg = ' (Unknown)';
9818
+ $et->VPrint(0, $$et{INDENT}, "[adding Keys:$tag]\n");
9779
9819
  }
9780
9820
  # substitute this tag in the ItemList table with the given index
9781
9821
  my $id = $$et{KeysCount} . '.' . $index;