exiftool-vendored.exe 13.30.0 → 13.31.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 (26) hide show
  1. package/bin/exiftool.exe +0 -0
  2. package/bin/exiftool_files/exiftool.pl +1 -1
  3. package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +7 -4
  4. package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +3 -2
  5. package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +3 -0
  6. package/bin/exiftool_files/lib/Image/ExifTool/GoPro.pm +10 -3
  7. package/bin/exiftool_files/lib/Image/ExifTool/LNK.pm +21 -3
  8. package/bin/exiftool_files/lib/Image/ExifTool/Lang/de.pm +2 -1
  9. package/bin/exiftool_files/lib/Image/ExifTool/Lang/fr.pm +2 -1
  10. package/bin/exiftool_files/lib/Image/ExifTool/LigoGPS.pm +14 -6
  11. package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +10 -3
  12. package/bin/exiftool_files/lib/Image/ExifTool/PDF.pm +1 -0
  13. package/bin/exiftool_files/lib/Image/ExifTool/Panasonic.pm +1 -1
  14. package/bin/exiftool_files/lib/Image/ExifTool/Parrot.pm +1 -1
  15. package/bin/exiftool_files/lib/Image/ExifTool/Pentax.pm +6 -4
  16. package/bin/exiftool_files/lib/Image/ExifTool/Plot.pm +2 -3
  17. package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +3 -2
  18. package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +41 -17
  19. package/bin/exiftool_files/lib/Image/ExifTool/Sigma.pm +19 -1
  20. package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +5 -2
  21. package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +11 -6
  22. package/bin/exiftool_files/lib/Image/ExifTool/WritePDF.pl +1 -0
  23. package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +127 -128
  24. package/bin/exiftool_files/lib/Image/ExifTool.pm +6 -4
  25. package/bin/exiftool_files/windows_exiftool.txt +12 -9
  26. package/package.json +10 -5
package/bin/exiftool.exe CHANGED
Binary file
@@ -11,7 +11,7 @@ use strict;
11
11
  use warnings;
12
12
  require 5.004;
13
13
 
14
- my $version = '13.30';
14
+ my $version = '13.31';
15
15
 
16
16
  $^W = 1; # enable global warnings
17
17
 
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
88
88
  sub ProcessExifInfo($$$);
89
89
  sub SwapWords($);
90
90
 
91
- $VERSION = '4.91';
91
+ $VERSION = '4.92';
92
92
 
93
93
  # Note: Removed 'USM' from 'L' lenses since it is redundant - PH
94
94
  # (or is it? Ref 32 shows 5 non-USM L-type lenses)
@@ -636,9 +636,10 @@ $VERSION = '4.91';
636
636
  '61182.58' => 'Canon RF 70-200mm F2.8 L IS USM Z + RF1.4x', #42
637
637
  '61182.59' => 'Canon RF 70-200mm F2.8 L IS USM Z + RF2x', #42
638
638
  '61182.60' => 'Canon RF 16-28mm F2.8 IS STM', #42
639
- '61182.61' => 'Canon RF 50mm F1.4 L VCM', #42
640
- '61182.62' => 'Canon RF 24mm F1.4 L VCM', #42
641
- '61182.63' => 'Canon RF 20mm F1.4 L VCM', #42
639
+ '61182.61' => 'Canon RF-S 14-30mm F4-6.3 IS STM PZ', #42
640
+ '61182.62' => 'Canon RF 50mm F1.4 L VCM', #42
641
+ '61182.63' => 'Canon RF 24mm F1.4 L VCM', #42
642
+ '61182.64' => 'Canon RF 20mm F1.4 L VCM', #42
642
643
  65535 => 'n/a',
643
644
  );
644
645
 
@@ -1006,6 +1007,7 @@ $VERSION = '4.91';
1006
1007
  0x80000495 => 'EOS R1', #PH
1007
1008
  0x80000496 => 'R5 Mark II', #forum16406
1008
1009
  0x80000498 => 'EOS R100', #25
1010
+ 0x80000516 => 'EOS R50 V', #42
1009
1011
  0x80000520 => 'EOS D2000C', #IB
1010
1012
  0x80000560 => 'EOS D6000C', #PH (guess)
1011
1013
  );
@@ -7032,6 +7034,7 @@ my %ciMaxFocal = (
7032
7034
  320 => 'Canon RF 70-200mm F2.8 L IS USM Z + RF1.4x', #42
7033
7035
  321 => 'Canon RF 70-200mm F2.8 L IS USM Z + RF2x', #42
7034
7036
  323 => 'Canon RF 16-28mm F2.8 IS STM', #42
7037
+ 324 => 'Canon RF-S 14-30mm F4-6.3 IS STM PZ', #42
7035
7038
  325 => 'Canon RF 50mm F1.4 L VCM', #42
7036
7039
  326 => 'Canon RF 24mm F1.4 L VCM', #42
7037
7040
  327 => 'Canon RF 20mm F1.4 L VCM', #42
@@ -57,7 +57,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
57
57
  use Image::ExifTool qw(:DataAccess :Utils);
58
58
  use Image::ExifTool::MakerNotes;
59
59
 
60
- $VERSION = '4.57';
60
+ $VERSION = '4.58';
61
61
 
62
62
  sub ProcessExif($$$);
63
63
  sub WriteExif($$$);
@@ -2081,7 +2081,7 @@ my %opcodeInfo = (
2081
2081
  0x8822 => {
2082
2082
  Name => 'ExposureProgram',
2083
2083
  Groups => { 2 => 'Camera' },
2084
- Notes => 'the value of 9 is not standard EXIF, but is used by the Canon EOS 7D',
2084
+ Notes => 'the value of 9 is not standard EXIF, but is used by some Canon models',
2085
2085
  Writable => 'int16u',
2086
2086
  PrintConv => {
2087
2087
  0 => 'Not Defined',
@@ -4350,6 +4350,7 @@ my %opcodeInfo = (
4350
4350
  Writable => 'undef',
4351
4351
  WriteGroup => 'IFD0',
4352
4352
  Protected => 1,
4353
+ Binary => 1,
4353
4354
  },
4354
4355
  0xcd40 => { # DNG 1.7
4355
4356
  Name => 'ProfileGainTableMap2',
@@ -629,6 +629,9 @@ my %faceCategories = (
629
629
  0x70000 => 'Soft Focus',
630
630
  0x90000 => 'Low Key',
631
631
  0x100000 => 'Light Leak', #forum17392
632
+ 0x130000 => 'Expired Film Green', #forum17392
633
+ 0x130001 => 'Expired Film Red', #forum17392 (NC)
634
+ 0x130002 => 'Expired Film Neutral', #forum17392
632
635
  },
633
636
  },
634
637
  0x1210 => { #2
@@ -17,7 +17,7 @@ use vars qw($VERSION);
17
17
  use Image::ExifTool qw(:DataAccess :Utils);
18
18
  use Image::ExifTool::QuickTime;
19
19
 
20
- $VERSION = '1.12';
20
+ $VERSION = '1.13';
21
21
 
22
22
  sub ProcessGoPro($$$);
23
23
  sub ProcessString($$$);
@@ -762,7 +762,7 @@ sub ProcessString($$$)
762
762
  }
763
763
 
764
764
  #------------------------------------------------------------------------------
765
- # Process "GP\x06\0" records in MP4 'mdat'atom
765
+ # Process "GP\x06\0" records in MP4 'mdat' atom
766
766
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref (RAF and DirLen)
767
767
  # Returns: size of GoPro record, or 0 on error
768
768
  sub ProcessGP6($$)
@@ -815,9 +815,16 @@ sub ProcessGoPro($$$)
815
815
 
816
816
  for (; $pos+8<=$dirEnd; $pos+=($size+3)&0xfffffffc) {
817
817
  my ($tag,$fmt,$len,$count) = unpack("x${pos}a4CCn", $$dataPt);
818
+ if ($tag =~ /[^-_a-zA-Z0-9 ]/) {
819
+ $et->Warn('Unrecognized GoPro record') unless $tag eq "\0\0\0\0";
820
+ last;
821
+ }
818
822
  $size = $len * $count;
819
823
  $pos += 8;
820
- last if $pos + $size > $dirEnd;
824
+ if ($pos + $size > $dirEnd) {
825
+ $et->Warn('Truncated GoPro record');
826
+ last;
827
+ }
821
828
  my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
822
829
  last if $tag eq "\0\0\0\0"; # stop at null tag
823
830
  next unless $size or $verbose; # don't save empty values unless verbose
@@ -7,6 +7,7 @@
7
7
  #
8
8
  # References: 1) http://msdn.microsoft.com/en-us/library/dd871305(PROT.10).aspx
9
9
  # 2) http://www.i2s-lab.com/Papers/The_Windows_Shortcut_File_Format.pdf
10
+ # 3) https://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/#tid_specifications_ignored
10
11
  #------------------------------------------------------------------------------
11
12
 
12
13
  package Image::ExifTool::LNK;
@@ -15,7 +16,7 @@ use strict;
15
16
  use vars qw($VERSION);
16
17
  use Image::ExifTool qw(:DataAccess :Utils);
17
18
 
18
- $VERSION = '1.09';
19
+ $VERSION = '1.10';
19
20
 
20
21
  sub ProcessItemID($$$);
21
22
  sub ProcessLinkInfo($$$);
@@ -647,17 +648,32 @@ sub ProcessLNK($$)
647
648
  my @strings = qw(Description RelativePath WorkingDirectory
648
649
  CommandLineArguments IconFileName);
649
650
  for ($i=0; $i<@strings; ++$i) {
651
+ my ($val, $limit);
650
652
  my $mask = 0x04 << $i;
651
653
  next unless $flags & $mask;
652
654
  $raf->Read($buff, 2) or return 1;
655
+ my $pos = $raf->Tell();
653
656
  $len = unpack('v', $buff) or next;
657
+ # Windows doesn't follow their own specification and limits the length
658
+ # for most of these strings (ref 3)
659
+ if ($i != 3 and $len >= 260) {
660
+ $limit = 1;
661
+ if ($len > 260) {
662
+ $len = 260;
663
+ $et->Warn('LNK string data overrun! Possible security issue');
664
+ }
665
+ }
654
666
  $len *= 2 if $flags & 0x80; # characters are 2 bytes if Unicode flag is set
655
667
  $raf->Read($buff, $len) or return 1;
656
- my $val;
668
+ # remove last character if string is at length limit (Windows treats this as a null)
669
+ if ($limit) {
670
+ $len -= $flags & 0x80 ? 2 : 1;
671
+ $buff = substr($buff, 0, $len);
672
+ }
657
673
  $val = $et->Decode($buff, 'UCS2') if $flags & 0x80;
658
674
  $et->HandleTag($tagTablePtr, 0x30000 | $mask, $val,
659
675
  DataPt => \$buff,
660
- DataPos => $raf->Tell() - $len,
676
+ DataPos => $pos,
661
677
  Size => $len,
662
678
  );
663
679
  }
@@ -716,6 +732,8 @@ under the same terms as Perl itself.
716
732
 
717
733
  =item L<http://www.i2s-lab.com/Papers/The_Windows_Shortcut_File_Format.pdf>
718
734
 
735
+ =item L<https://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/#tid_specifications_ignored>
736
+
719
737
  =back
720
738
 
721
739
  =head1 SEE ALSO
@@ -11,7 +11,7 @@ package Image::ExifTool::Lang::de;
11
11
  use strict;
12
12
  use vars qw($VERSION);
13
13
 
14
- $VERSION = '1.37';
14
+ $VERSION = '1.38';
15
15
 
16
16
  %Image::ExifTool::Lang::de::Translate = (
17
17
  'AEAperture' => 'AE-Blende',
@@ -5126,6 +5126,7 @@ $VERSION = '1.37';
5126
5126
  'LensType' => {
5127
5127
  Description => 'Objektivtyp',
5128
5128
  PrintConv => {
5129
+ 'None' => 'Keiner',
5129
5130
  'Uncoded lens' => 'Nicht kodiertes Objektiv',
5130
5131
  },
5131
5132
  },
@@ -11,7 +11,7 @@ package Image::ExifTool::Lang::fr;
11
11
  use strict;
12
12
  use vars qw($VERSION);
13
13
 
14
- $VERSION = '1.36';
14
+ $VERSION = '1.37';
15
15
 
16
16
  %Image::ExifTool::Lang::fr::Translate = (
17
17
  'AEAperture' => 'Ouverture AE',
@@ -6607,6 +6607,7 @@ $VERSION = '1.36';
6607
6607
  'LensType' => {
6608
6608
  Description => 'Type d\'objectif',
6609
6609
  PrintConv => {
6610
+ 'None' => 'Aucun',
6610
6611
  'n/a' => 'Non applicable',
6611
6612
  'smc PENTAX-F 100-300mm F4.5-5.6 or Sigma Lens' => 'smc PENTAX-F 100-300mm F4.5-5.6 ou objectif Sigma',
6612
6613
  'smc PENTAX-F 28-80mm F3.5-4.5 or Tokina Lens' => 'smc PENTAX-F 28-80mm F3.5-4.5 ou objectif Tokina',
@@ -11,7 +11,7 @@ use strict;
11
11
  use vars qw($VERSION);
12
12
  use Image::ExifTool;
13
13
 
14
- $VERSION = '1.05';
14
+ $VERSION = '1.06';
15
15
 
16
16
  sub ProcessLigoGPS($$$;$);
17
17
  sub ProcessLigoJSON($$$);
@@ -223,11 +223,12 @@ sub DecipherLigoGPS($$$;$)
223
223
  #------------------------------------------------------------------------------
224
224
  # Parse decrypted/deciphered (but not defuzzed) LIGOGPSINFO record
225
225
  # (record starts with 4-byte int32u counter followed by date/time, etc)
226
- # Inputs: 0) ExifTool ref, 1) GPS string, 2) tag table ref, 3) not fuzzed
226
+ # Inputs: 0) ExifTool ref, 1) GPS string, 2) tag table ref,
227
+ # 3) flags: 0x01=not fuzzed, 0x02=spd in km/h
227
228
  # Returns: nothing
228
229
  sub ParseLigoGPS($$$;$)
229
230
  {
230
- my ($et, $str, $tagTbl, $noFuzz) = @_;
231
+ my ($et, $str, $tagTbl, $flags) = @_;
231
232
 
232
233
  # example string input
233
234
  # "....2022/09/19 12:45:24 N:31.285065 W:124.759483 46.93 km/h x:-0.000 y:-0.000 z:-0.000"
@@ -235,15 +236,16 @@ sub ParseLigoGPS($$$;$)
235
236
  $et->Warn('LIGOGPSINFO format error');
236
237
  return;
237
238
  }
239
+ $flags or $flags = 0;
238
240
  my ($time,$latRef,$latNeg,$lat,$lonRef,$lonNeg,$lon,$spd) = ($1,$2,$3,$4,$5,$6,$7,$8);
239
241
  my %gpsScl = ( 1 => 1.524855137, 2 => 1.456027985, 3 => 1.15368 );
240
- my $spdScl = $noFuzz ? $knotsToKph : 1.85407333;
242
+ my $spdScl = $flags & 0x01 ? ($flags & 0x02 ? 1 : $knotsToKph) : 1.85407333;
241
243
  $$et{DOC_NUM} = ++$$et{DOC_COUNT};
242
244
  $time =~ tr(/)(:);
243
245
  # convert from DDMM.MMMMMM to DD.DDDDDD if necessary
244
246
  # (speed wasn't scaled in my 1 sample with this format)
245
247
  $lat =~ /^\d{3}/ and Image::ExifTool::QuickTime::ConvertLatLon($lat,$lon), $spdScl = 1;
246
- unless ($noFuzz) { # unfuzz the coordinates if necessary
248
+ unless ($flags & 0x01) { # unfuzz the coordinates if necessary
247
249
  my $scl = $$et{OPTIONS}{LigoGPSScale} || $$et{LigoGPSScale} || 1;
248
250
  $scl = $gpsScl{$scl} if $gpsScl{$scl};
249
251
  ($lat, $lon) = UnfuzzLigoGPS($lat, $lon, $scl);
@@ -298,7 +300,13 @@ sub ProcessLigoGPS($$$;$)
298
300
  $et->VerboseDir($dirName);
299
301
  for (; $pos + 0x84 <= length($$dataPt); $pos+=0x84) {
300
302
  my $dat = substr($$dataPt, $pos, 0x84);
301
- $dat =~ /^####/ or next; # (have seen blank records filled with zeros, so keep trying)
303
+ unless ($dat =~ /^####/) {
304
+ next unless $dat =~ m(^.{4}\d{4}/\d{2}/\d{2} )s; # (have seen blank records filled with zeros, so keep trying)
305
+ # non-encrypted format written by Redtiger F9 4K
306
+ $dat =~ s/\0+$//; # remove trailing nulls
307
+ ParseLigoGPS($et, $dat, $tagTbl, 0x03);
308
+ next;
309
+ }
302
310
  # decipher if we already know the encryption
303
311
  $cipherInfo and $$cipherInfo{decipher} and DecipherLigoGPS($et, $dat, $tagTbl, $noFuzz) and next;
304
312
  my $str = DecryptLigoGPS($dat);
@@ -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.46';
68
+ $VERSION = '4.47';
69
69
 
70
70
  sub LensIDConv($$$);
71
71
  sub ProcessNikonAVI($$$);
@@ -5856,6 +5856,7 @@ my %nikonFocalConversions = (
5856
5856
  46 => 'Nikkor Z 135mm f/1.8 S Plena', #28
5857
5857
  47 => 'Nikkor Z 35mm f/1.2 S', #28
5858
5858
  48 => 'Nikkor Z 28-400mm f/4-8 VR', #30
5859
+ 49 => 'Nikkor Z 28-135mm f/4 PZ', #28
5859
5860
  51 => 'Nikkor Z 35mm f/1.4', #28
5860
5861
  52 => 'Nikkor Z 50mm f/1.4', #28
5861
5862
  2305 => 'Laowa FFII 10mm F2.8 C&D Dreamer', #30
@@ -12791,7 +12792,7 @@ my %nikonFocalConversions = (
12791
12792
  Name => 'UnknownInfo',
12792
12793
  SubDirectory => { TagTable => 'Image::ExifTool::Nikon::UnknownInfo' },
12793
12794
  },
12794
- # 0x200002d - int16u[3]: "512 0 0"
12795
+ # 0x200002d - int16u[3]: "512 0 0", "512 1 14", "512 3 10"
12795
12796
  0x2000032 => {
12796
12797
  Name => 'UnknownInfo2',
12797
12798
  SubDirectory => { TagTable => 'Image::ExifTool::Nikon::UnknownInfo2' },
@@ -12804,10 +12805,12 @@ my %nikonFocalConversions = (
12804
12805
  # 0x200003f - rational64s[2]: "0 0"
12805
12806
  # 0x2000042 - undef[6]: "0100\x03\0"
12806
12807
  # 0x2000043 - undef[12]: all zeros
12808
+ # 0x200004d - undef[84]: "0100\0\0\0\0x020100\0\0\0\x010100\0\0\0\x05\0\0\..."
12807
12809
  0x200004e => {
12808
12810
  Name => 'NikonSettings',
12809
12811
  SubDirectory => { TagTable => 'Image::ExifTool::NikonSettings::Main' },
12810
12812
  },
12813
+ # 0x2000055 - undef[8]: "0100\x01\0\0\0"
12811
12814
  0x2000083 => {
12812
12815
  Name => 'LensType',
12813
12816
  # credit to Tom Christiansen (ref 7) for figuring this out...
@@ -13011,7 +13014,11 @@ my %nikonFocalConversions = (
13011
13014
  Condition => '$$valPt =~ /^040[012]/',
13012
13015
  SubDirectory => { TagTable => 'Image::ExifTool::Nikon::AFInfo2V0400' },
13013
13016
  }],
13014
- # 0x20000c0 - undef[8]
13017
+ # 0x20000c0 - undef[8]:
13018
+ # 34 01 0c 00 90 01 0c 00
13019
+ # 34 01 0c 00 9c 01 0c 00
13020
+ # 3c 01 0c 00 9c 01 0c 00
13021
+ # 3c 01 0c 00 a8 01 0c 00
13015
13022
  0x20000c3 => {
13016
13023
  Name => 'BarometerInfo',
13017
13024
  SubDirectory => {
@@ -234,6 +234,7 @@ my %supportedFilter = (
234
234
  Kids => {
235
235
  SubDirectory => { TagTable => 'Image::ExifTool::PDF::Kids' },
236
236
  },
237
+ MediaBox => { Name => 'MediaBox', List => 1 },
237
238
  );
238
239
 
239
240
  # tags in PDF Perms dictionary
@@ -1439,7 +1439,7 @@ my %shootingMode = (
1439
1439
  0xde => { #forum17299
1440
1440
  Name => 'AFAreaSize',
1441
1441
  Writable => 'rational64u',
1442
- Notes => 'relative to size of image',
1442
+ Notes => 'relative to size of image. "n/a" for manual focus',
1443
1443
  Count => 2,
1444
1444
  PrintConv => '$val =~ /^4194303.999/ ? "n/a" : $val',
1445
1445
  PrintConvInv => '$val eq "n/a" ? "4194303.999 4194303.999" : $val',
@@ -56,7 +56,7 @@ sub Process_mett($$$);
56
56
  Name => 'ParrotAutomation',
57
57
  SubDirectory => { TagTable => 'Image::ExifTool::Parrot::Automation' },
58
58
  },
59
- # timed metadata written by ARCore (see forum13653)
59
+ # MetaType of timed metadata written by ARCore (see forum13653)
60
60
  'application/arcore-accel' => {
61
61
  Name => 'ARCoreAccel',
62
62
  SubDirectory => { TagTable => 'Image::ExifTool::Parrot::ARCoreAccel', ByteOrder => 'II' },
@@ -58,7 +58,7 @@ use Image::ExifTool::Exif;
58
58
  use Image::ExifTool::GPS;
59
59
  use Image::ExifTool::HP;
60
60
 
61
- $VERSION = '3.51';
61
+ $VERSION = '3.52';
62
62
 
63
63
  sub CryptShutterCount($$);
64
64
  sub PrintFilter($$$);
@@ -1354,6 +1354,7 @@ my %binaryDataAttrs = (
1354
1354
  0xfffd => 'Automatic Tracking AF', #JD
1355
1355
  0xfffc => 'Face Detect AF', #JD
1356
1356
  0xfffb => 'AF Select', #PH (Q select from 25-areas)
1357
+ 0xfffa => 'Auto 2', #KarstenGieselmann
1357
1358
  0 => 'None', #PH (Q in manual focus mode)
1358
1359
  1 => 'Upper-left',
1359
1360
  2 => 'Top',
@@ -5792,21 +5793,21 @@ my %binaryDataAttrs = (
5792
5793
  },
5793
5794
  4 => {
5794
5795
  Name => 'AFPointsInFocus',
5795
- Condition => '$$self{Model} =~ /K-1\b/',
5796
+ Condition => '$$self{Model} =~ /K(P|-1|-70)\b/',
5796
5797
  Format => 'int8u[int(($val{2}+3)/4)]',
5797
5798
  Writable => 0,
5798
5799
  PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,$$self{NumAFPoints},2,0x02)',
5799
5800
  },
5800
5801
  4.1 => {
5801
5802
  Name => 'AFPointsSelected',
5802
- Condition => '$$self{Model} =~ /K-1\b/',
5803
+ Condition => '$$self{Model} =~ /K(P|-1|-70)\b/',
5803
5804
  Format => 'int8u[int(($val{2}+3)/4)]',
5804
5805
  Writable => 0,
5805
5806
  PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,$$self{NumAFPoints},2,0x03)',
5806
5807
  },
5807
5808
  4.2 => {
5808
5809
  Name => 'AFPointsSpecial',
5809
- Condition => '$$self{Model} =~ /K-1\b/',
5810
+ Condition => '$$self{Model} =~ /K(P|-1|-70)\b/',
5810
5811
  Format => 'int8u[int(($val{2}+3)/4)]',
5811
5812
  Writable => 0,
5812
5813
  PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,$$self{NumAFPoints},2,0x03,0x03)',
@@ -6437,6 +6438,7 @@ sub DecodeAFPoints($$$$;$)
6437
6438
  {
6438
6439
  my ($val, $num, $bits, $mask, $bitVal) = @_;
6439
6440
  my @bytes = split ' ', $val;
6441
+ return '(none)' unless @bytes;
6440
6442
  my $i = 1; # (starts at AF point number 1)
6441
6443
  my $shift = 8 - $bits;
6442
6444
  my $byte = shift @bytes;
@@ -11,7 +11,7 @@ package Image::ExifTool::Plot;
11
11
  use strict;
12
12
  use vars qw($VERSION);
13
13
 
14
- $VERSION = '1.03';
14
+ $VERSION = '1.05';
15
15
 
16
16
  # default plot settings (lower-case settings may be overridden by the user)
17
17
  my %defaults = (
@@ -201,7 +201,7 @@ sub AddPoints($$$)
201
201
  $$data{$name}[$xmax - $xmin] = $val if $xmax >= $xmin;
202
202
  next;
203
203
  }
204
- if ($docNum and $num{$name} < $docNum) {
204
+ if ($docNum and defined $num{$name} and $num{$name} < $docNum) {
205
205
  $num{$name} = $docNum; # keep documents synchronized if some tags are missing
206
206
  } else {
207
207
  $num{$name} = $xmax unless defined $num{$name};
@@ -321,7 +321,6 @@ sub Draw($$)
321
321
  foreach (0 .. (($multi[$plotNum] || 1) - 1)) {
322
322
  push @{$$self{Name}}, shift(@names);
323
323
  }
324
- warn "@{$$self{Name}}\n";
325
324
  undef $min; undef $max;
326
325
  foreach ($scat .. (@{$$self{Name}} - 1)) {
327
326
  my $dat = $$self{Data}{$$self{Name}[$_]};
@@ -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.17';
52
+ $VERSION = '3.18';
53
53
 
54
54
  sub ProcessMOV($$;$);
55
55
  sub ProcessKeys($$$);
@@ -10522,12 +10522,13 @@ QTLang: foreach $tag (@{$$et{QTLang}}) {
10522
10522
  for (; $trailer; $trailer=$$trailer[3]) {
10523
10523
  next if $lastPos > $$trailer[1]; # skip if we have already processed this as an atom
10524
10524
  last unless $raf->Seek($$trailer[1], 0);
10525
- if ($$trailer[0] eq 'LigoGPS' and $raf->Read($buff, 8) == 8 and $buff =~ /skip$/) {
10525
+ if ($$trailer[0] eq 'LigoGPS' and $raf->Read($buff, 8) == 8 and $buff =~ /skip$/i) {
10526
10526
  $ee or $et->Warn('Use the ExtractEmbedded option to decode timed GPS',3), next;
10527
10527
  my $len = Get32u(\$buff, 0) - 16;
10528
10528
  if ($len > 0 and $raf->Read($buff, $len) == $len and $buff =~ /^LIGOGPSINFO\0/) {
10529
10529
  my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
10530
10530
  my %dirInfo = ( DataPt => \$buff, DataPos => $$trailer[1] + 8, DirName => 'LigoGPSTrailer' );
10531
+ $et->VerboseDump(\$buff, DataPos => $dirInfo{DataPos});
10531
10532
  Image::ExifTool::LigoGPS::ProcessLigoGPS($et, \%dirInfo, $tbl);
10532
10533
  } else {
10533
10534
  $et->Warn('Unrecognized data in LigoGPS trailer');
@@ -111,7 +111,7 @@ my %insvLimit = (
111
111
  The tags below are extracted from timed metadata in QuickTime and other
112
112
  formats of video files when the ExtractEmbedded option is used. Although
113
113
  most of these tags are combined into the single table below, ExifTool
114
- currently reads 107 different types of timed GPS metadata from video files.
114
+ currently reads 110 different types of timed GPS metadata from video files.
115
115
  },
116
116
  GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
117
117
  GPSLongitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")' },
@@ -210,8 +210,8 @@ my %insvLimit = (
210
210
  ProcessProc => \&ProcessFMAS,
211
211
  },
212
212
  },{
213
- Name => 'gpmd_Wolfbox', # Wolfbox G900 Dashcam
214
- Condition => '$$valPt =~ /^.{136}0{16}HYTH/s',
213
+ Name => 'gpmd_Wolfbox', # Wolfbox G900 Dashcam and Redtiger F9 4K
214
+ Condition => '$$valPt =~ /^.{136}0{16}(HYTH|XXXX)/s',
215
215
  SubDirectory => {
216
216
  TagTable => 'Image::ExifTool::QuickTime::Stream',
217
217
  ProcessProc => \&ProcessWolfbox,
@@ -317,6 +317,8 @@ my %insvLimit = (
317
317
  ByteOrder => 'Little-Endian',
318
318
  },
319
319
  }],
320
+ # (have also seen unknown mett from Google Pixel with MetaType 'application/meta'
321
+ # and 'application/microvideo-image-meta')
320
322
  mett => { # Parrot drones and iPhone/Android using ARCore
321
323
  Name => 'mett',
322
324
  SubDirectory => { TagTable => 'Image::ExifTool::Parrot::mett' },
@@ -2288,6 +2290,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
2288
2290
  $lon = ($lon - 2199.19873715495) / 2;
2289
2291
  $ddd = 1;
2290
2292
  } elsif (Get32u($dataPt,0) == 0x400000 and abs($lat) <= 90 and abs($lon) <= 180) {
2293
+ $debug and $et->FoundTag(GPSType => '17c');
2291
2294
  # Transcend Drive Body Camera 70
2292
2295
  # 0000: 00 00 40 00 66 72 65 65 47 50 53 20 4c 00 00 00 [..@.freeGPS L...]
2293
2296
  # 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
@@ -3567,14 +3570,14 @@ sub ProcessFMAS($$$)
3567
3570
  }
3568
3571
 
3569
3572
  #------------------------------------------------------------------------------
3570
- # Process GPS from Wolfbox G900 Dashcam
3573
+ # Process GPS from Wolfbox G900 Dashcam and Redtiger F9 4K
3571
3574
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
3572
3575
  # Returns: 1 on success
3573
3576
  sub ProcessWolfbox($$$)
3574
3577
  {
3575
3578
  my ($et, $dirInfo, $tagTbl) = @_;
3576
3579
  my $dataPt = $$dirInfo{DataPt};
3577
- return 0 if length($$dataPt) < 0xc8;
3580
+ return 0 if length($$dataPt) < 0xf8;
3578
3581
  $et->VerboseDir('Wolfbox', undef, length($$dataPt));
3579
3582
  # 0000: 65 00 00 00 00 00 00 00 31 01 01 00 e3 ff 00 00 [e.......1.......]
3580
3583
  # 0010: 04 00 00 00 10 00 00 00 2a 00 00 00 00 00 00 00 [........*.......]
@@ -3593,22 +3596,43 @@ sub ProcessWolfbox($$$)
3593
3596
  # 00e0: 0a 00 00 00 00 00 00 00 e8 03 00 00 00 00 00 00 [................]
3594
3597
  # 00f0: 0a 00 00 00 00 00 00 00 4d 00 00 00 00 00 00 00 [........M.......]
3595
3598
  # lat/lon at 0xb0/0xc0 and 0x128/0x138
3596
- # h/m/s at 0x10 and 0xa0 and 0x148 (the first imprinted on the video, the latter 2 presumed UTC)
3599
+ # h/m/s at 0x10 and 0xa0 and 0x148 (the first imprinted on the video, and
3600
+ # the latter 2 presumed UTC, but there is a 1 second offset for the Redtiger)
3597
3601
  # spd at 0x48, dir at 0x58, alt at 0xe8
3602
+ # Redtiger F9 4K Dual Front and Rear Mini Dash Cam
3603
+ # 0000: 01 00 00 00 00 00 00 00 f4 ff 5d fe 24 00 00 00 [..........].$...]
3604
+ # 0010: 10 00 00 00 2d 00 00 00 25 00 00 00 00 00 00 00 [....-...%.......]
3605
+ # 0020: 01 00 00 00 00 00 00 00 44 eb 8f 00 00 00 00 00 [........D.......]
3606
+ # 0030: 10 27 00 00 00 00 00 00 1b 94 8a 04 00 00 00 00 [.'..............]
3607
+ # 0040: 10 27 00 00 00 00 00 00 8c 69 00 00 00 00 00 00 [.'.......i......]
3608
+ # 0050: e8 03 00 00 00 00 00 00 ba 47 00 00 00 00 00 00 [.........G......]
3609
+ # 0060: 64 00 00 00 00 00 00 00 19 00 00 00 05 00 00 00 [d...............]
3610
+ # 0070: e9 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
3611
+ # 0080: 00 00 00 00 00 00 00 00 30 30 30 30 30 30 30 30 [........00000000]
3612
+ # 0090: 30 30 30 30 30 30 30 30 58 58 58 58 00 00 00 00 [00000000XXXX....]
3613
+ # 00a0: 08 00 00 00 2d 00 00 00 24 00 00 00 00 00 00 00 [....-...$.......]
3614
+ # 00b0: 90 eb 8f 00 00 00 00 00 10 27 00 00 00 00 00 00 [.........'......]
3615
+ # 00c0: 20 94 8a 04 00 00 00 00 10 27 00 00 00 00 00 00 [ ........'......]
3616
+ # 00d0: 01 00 00 00 11 00 00 00 40 00 00 00 00 00 00 00 [........@.......]
3617
+ # 00e0: 64 00 00 00 00 00 00 00 8a 00 00 00 00 00 00 00 [d...............]
3618
+ # 00f0: 0a 00 00 00 00 00 00 00 4d 00 00 00 00 00 00 00 [........M.......]
3598
3619
  SetByteOrder('II');
3599
- my ($spd,$dir,$d,$mo,$yr,$h,$m,$s) = unpack('x72Vx12Vx12V3x44V3',$$dataPt);
3600
- # offset 0xa0 also stores hh mm ss, but is out by 8 hours!
3620
+ my ($d,$mo,$yr,$h,$m,$s) = unpack('x104V3x44V3',$$dataPt);
3601
3621
  my $time = sprintf '%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ', $yr, $mo, $d, $h, $m, $s;
3602
- my ($lat, $lon) = (Get32s($dataPt, 0xb0) / 1e5, Get32s($dataPt, 0xc0) / 1e5);
3603
- my $alt = Get32s($dataPt, 0xe8);
3604
- ConvertLatLon($lat, $lon);
3622
+ my ($pos, @a);
3623
+ # 0=spd 1=dir 2=lat 3=lon 4=alt
3624
+ foreach $pos (0x48, 0x58, 0xb0, 0xc0, 0xe8) {
3625
+ my $val = Get64s($dataPt, $pos);
3626
+ my $scl = Get64s($dataPt, $pos + 8);
3627
+ push @a, $val / ($scl || 1);
3628
+ }
3629
+ ConvertLatLon($a[2], $a[3]);
3605
3630
  $et->HandleTag($tagTbl, GPSDateTime => $time);
3606
- $et->HandleTag($tagTbl, GPSLatitude => $lat);
3607
- $et->HandleTag($tagTbl, GPSLongitude => $lon);
3608
- $et->HandleTag($tagTbl, GPSSpeed => $spd * $knotsToKph / 100);
3609
- $et->HandleTag($tagTbl, GPSTrack => $dir / 100);
3610
- $et->HandleTag($tagTbl, GPSAltitude => $alt / 10); # (NC)
3611
- SetByteOrder('MM');
3631
+ $et->HandleTag($tagTbl, GPSLatitude => $a[2]);
3632
+ $et->HandleTag($tagTbl, GPSLongitude => $a[3]);
3633
+ $et->HandleTag($tagTbl, GPSSpeed => $a[0] * $knotsToKph);
3634
+ $et->HandleTag($tagTbl, GPSTrack => $a[1]);
3635
+ $et->HandleTag($tagTbl, GPSAltitude => $a[4]);
3612
3636
  return 1;
3613
3637
  }
3614
3638
 
@@ -19,7 +19,7 @@ use strict;
19
19
  use vars qw($VERSION %sigmaLensTypes);
20
20
  use Image::ExifTool::Exif;
21
21
 
22
- $VERSION = '1.35';
22
+ $VERSION = '1.36';
23
23
 
24
24
  # sigma LensType lookup (ref IB)
25
25
  %sigmaLensTypes = (
@@ -704,6 +704,12 @@ $VERSION = '1.35';
704
704
  Name => 'PictureMode',
705
705
  Notes => 'same as ColorMode, but "Standard" when ColorMode is Sepia or B&W',
706
706
  },
707
+ 0x0047 => { #forum17338
708
+ Name => 'ExposureCompensation',
709
+ Writable => 'rational64s',
710
+ PrintConv => '$val and $val =~ s/^(\d)/\+$1/; $val',
711
+ PrintConvInv => '$val',
712
+ },
707
713
  0x0048 => { #PH
708
714
  Name => 'LensApertureRange',
709
715
  Condition => '$$self{MakerNoteSigmaVer} >= 3',
@@ -797,6 +803,10 @@ $VERSION = '1.35';
797
803
  0x0087 => 'ResolutionMode', #PH (Quattro models)
798
804
  0x0088 => 'WhiteBalance', #PH (Quattro models)
799
805
  0x008c => 'Firmware', #PH (Quattro models)
806
+ 0x0113 => { #forum17338
807
+ Name => 'PictureModeStrength',
808
+ Writable => 'int32s',
809
+ },
800
810
  0x011f => { #IB (FP DNG images)
801
811
  Name => 'CameraCalibration',
802
812
  Writable => 'float',
@@ -810,6 +820,14 @@ $VERSION = '1.35';
810
820
  Name => 'WBSettings2',
811
821
  SubDirectory => { TagTable => 'Image::ExifTool::Sigma::WBSettings2' },
812
822
  },
823
+ 0x0138 => { #forum17338
824
+ Name => 'Fade',
825
+ Writable => 'rational64u',
826
+ },
827
+ 0x0139 => { #forum17338
828
+ Name => 'Vignette',
829
+ Writable => 'rational64u',
830
+ },
813
831
  );
814
832
 
815
833
  # WB settings (ref IB)
@@ -2822,7 +2822,7 @@ my %tagLookup = (
2822
2822
  'exposurebracketstepsize' => { 375 => 0x8 },
2823
2823
  'exposurebracketvalue' => { 246 => 0x19 },
2824
2824
  'exposurecompautocancel' => { 90 => 0x113 },
2825
- 'exposurecompensation' => { 82 => 0x6, 99 => 0x0, 125 => 0x9204, 147 => 0x24, 163 => 'ExposureComp', 183 => 'ExposureCompensation', 188 => 0xd, 189 => 0x53, 190 => 0x1e, 194 => 0x49c0, 339 => 0x1006, 395 => 0x16, 404 => 0x402, 436 => 0xa013, 439 => [0xc,0x35,0x4d], 472 => 0x114c, 473 => 0x114c, 474 => 0x1128, 476 => 0x1180, 477 => 0x1038, 478 => 0x230, 479 => 0x230, 480 => 0x223, 534 => 'ExposureBiasValue' },
2825
+ 'exposurecompensation' => { 82 => 0x6, 99 => 0x0, 125 => 0x9204, 147 => 0x24, 163 => 'ExposureComp', 183 => 'ExposureCompensation', 188 => 0xd, 189 => 0x53, 190 => 0x1e, 194 => 0x49c0, 339 => 0x1006, 395 => 0x16, 404 => 0x402, 436 => 0xa013, 439 => [0xc,0x35,0x47,0x4d], 472 => 0x114c, 473 => 0x114c, 474 => 0x1128, 476 => 0x1180, 477 => 0x1038, 478 => 0x230, 479 => 0x230, 480 => 0x223, 534 => 'ExposureBiasValue' },
2826
2826
  'exposurecompensation2' => { 468 => [0x24,0x26,0x2a] },
2827
2827
  'exposurecompensationbutton' => { 257 => 0x794 },
2828
2828
  'exposurecompensationmode' => { 191 => 0x47, 194 => 0x2a },
@@ -2978,7 +2978,7 @@ my %tagLookup = (
2978
2978
  'facesdetected' => { 58 => 0x2, 59 => 0x2, 60 => 0x3, 116 => 0x0, 117 => 0x2, 119 => 0x211c, 133 => 0x4100, 222 => 0x3, 338 => 0x1200, 358 => 0x3f, 378 => 0x0, 426 => 0xb5, 437 => 0x0, 456 => 0x0, 459 => 0x3, 471 => 0x30 },
2979
2979
  'facesrecognized' => { 351 => 0x0 },
2980
2980
  'facewidth' => { 59 => 0x1 },
2981
- 'fade' => { 463 => 0x2034 },
2981
+ 'fade' => { 439 => 0x138, 463 => 0x2034 },
2982
2982
  'faithfuloutputhighlightpoint' => { 115 => 0x38 },
2983
2983
  'faithfuloutputshadowpoint' => { 115 => 0x39 },
2984
2984
  'faithfulrawcolortone' => { 115 => 0x31 },
@@ -5667,6 +5667,7 @@ my %tagLookup = (
5667
5667
  'picturemodehue' => { 334 => 0x522 },
5668
5668
  'picturemodesaturation' => { 334 => 0x521 },
5669
5669
  'picturemodesharpness' => { 334 => 0x524 },
5670
+ 'picturemodestrength' => { 439 => 0x113 },
5670
5671
  'picturemodetone' => { 334 => 0x526 },
5671
5672
  'pictureprofile' => { 472 => [0x115e,0x115f], 473 => [0x1162,0x1163], 474 => [0x113e,0x113f], 475 => [0x11ba,0x11bb], 476 => [0x1196,0x1197], 477 => [0x104e,0x104f], 478 => [0x246,0x247], 479 => [0x246,0x247], 480 => [0x237,0x238] },
5672
5673
  'picturestyle' => { 8 => [0x4b,0x51], 9 => 0xf4, 10 => 0x6c, 11 => 0x86, 12 => 0x73, 16 => 0xab, 17 => 0xa7, 18 => 0xb0, 19 => 0x6c, 20 => 0xa7, 21 => 0xf4, 22 => 0xb3, 24 => 0xf4, 25 => 0xfa, 27 => 0x169, 79 => 0xa, 109 => 0x20301, 115 => 0x2 },
@@ -7302,6 +7303,7 @@ my %tagLookup = (
7302
7303
  'viewingmode2' => { 451 => [0x85,0x285] },
7303
7304
  'viewmodeshoweffectsofsettings' => { 257 => 0x7d2, 330 => 0x2a9 },
7304
7305
  'viewpoint' => { 547 => 'viewpoint' },
7306
+ 'vignette' => { 439 => 0x139 },
7305
7307
  'vignetteamount' => { 528 => 'VignetteAmount', 530 => 'VignetteAmount' },
7306
7308
  'vignettecoefficient1' => { 297 => 0x24 },
7307
7309
  'vignettecoefficient2' => { 297 => 0x34 },
@@ -10858,6 +10860,7 @@ my %tagExists = (
10858
10860
  'mebx' => 1,
10859
10861
  'media' => 1,
10860
10862
  'mediablackpoint' => 1,
10863
+ 'mediabox' => 1,
10861
10864
  'mediacolor' => 1,
10862
10865
  'mediacontenttypes' => 1,
10863
10866
  'mediacreated' => 1,
@@ -12,7 +12,7 @@ meta information extracted from or written to a file.
12
12
  =head1 TAG TABLES
13
13
 
14
14
  The tables listed below give the names of all tags recognized by ExifTool.
15
- They contain a total of 28450 tags, with 17673 unique tag names.
15
+ They contain a total of 28455 tags, with 17676 unique tag names.
16
16
 
17
17
  B<Tag ID>, B<Index#> or B<Sequence> is given in the first column of each
18
18
  table. A B<Tag ID> is the computer-readable equivalent of a tag name, and
@@ -21811,6 +21811,7 @@ are less than consistent about their metadata formats.
21811
21811
  0x003b Firmware string
21812
21812
  0x003c WhiteBalance string
21813
21813
  0x003d PictureMode string
21814
+ 0x0047 ExposureCompensation rational64s
21814
21815
  0x0048 LensApertureRange string
21815
21816
  0x0049 FNumber rational64u
21816
21817
  0x004a ExposureTime rational64u
@@ -21826,9 +21827,12 @@ are less than consistent about their metadata formats.
21826
21827
  0x0087 ResolutionMode string
21827
21828
  0x0088 WhiteBalance string
21828
21829
  0x008c Firmware string
21830
+ 0x0113 PictureModeStrength int32s
21829
21831
  0x011f CameraCalibration float[9]
21830
21832
  0x0120 WBSettings Sigma WBSettings
21831
21833
  0x0121 WBSettings2 Sigma WBSettings2
21834
+ 0x0138 Fade rational64u
21835
+ 0x0139 Vignette rational64u
21832
21836
 
21833
21837
  =head3 Sigma WBSettings Tags
21834
21838
 
@@ -29664,10 +29668,11 @@ C2PA JUMBF metadata extracted from "/C2PA_Manifest" file.
29664
29668
 
29665
29669
  =head3 PDF Pages Tags
29666
29670
 
29667
- Tag ID Tag Name Writable
29668
- ------ -------- --------
29669
- 'Count' PageCount no
29670
- 'Kids' Kids PDF Kids
29671
+ Tag ID Tag Name Writable
29672
+ ------ -------- --------
29673
+ 'Count' PageCount no
29674
+ 'Kids' Kids PDF Kids
29675
+ 'MediaBox' MediaBox no+
29671
29676
 
29672
29677
  =head3 PDF Kids Tags
29673
29678
 
@@ -30380,7 +30385,7 @@ for the official QuickTime specification.
30380
30385
  The tags below are extracted from timed metadata in QuickTime and other
30381
30386
  formats of video files when the ExtractEmbedded option is used. Although
30382
30387
  most of these tags are combined into the single table below, ExifTool
30383
- currently reads 107 different types of timed GPS metadata from video files.
30388
+ currently reads 110 different types of timed GPS metadata from video files.
30384
30389
 
30385
30390
  Tag ID Tag Name Writable
30386
30391
  ------ -------- --------
@@ -81,6 +81,7 @@ sub WritePDFValue($$$)
81
81
  EncodeString(\$val);
82
82
  } elsif ($format eq 'date') {
83
83
  # convert date to "D:YYYYmmddHHMMSS+-HH'MM'" format
84
+ $val =~ s/(:\d{2})\.\d*/$1/; # remove sub-seconds
84
85
  $val =~ s/([-+]\d{2}):(\d{2})/${1}'${2}'/; # change timezone delimiters if necessary
85
86
  $val =~ tr/ ://d; # remove spaces and colons
86
87
  $val = "D:$val"; # add leading "D:"
@@ -4741,10 +4741,11 @@ sub DumpUnknownTrailer($$)
4741
4741
  my $pos = $$dirInfo{DataPos};
4742
4742
  my $endPos = $pos + $$dirInfo{DirLen};
4743
4743
  # account for preview/MPF image trailer
4744
- my $prePos = $$self{VALUE}{PreviewImageStart} || $$self{PreviewImageStart};
4745
- my $preLen = $$self{VALUE}{PreviewImageLength} || $$self{PreviewImageLength};
4746
- my $hidPos = $$self{VALUE}{HiddenDataOffset};
4747
- my $hidLen = $$self{VALUE}{HiddenDataLength};
4744
+ my $value = $$self{VALUE};
4745
+ my $prePos = $$value{PreviewImageStart} || $$self{PreviewImageStart};
4746
+ my $preLen = $$value{PreviewImageLength} || $$self{PreviewImageLength};
4747
+ my $hidPos = $$value{HiddenDataOffset};
4748
+ my $hidLen = $$value{HiddenDataLength};
4748
4749
  my $tag = 'PreviewImage';
4749
4750
  my $mpImageNum = 0;
4750
4751
  my (%image, $lastOne);
@@ -4761,12 +4762,12 @@ sub DumpUnknownTrailer($$)
4761
4762
  last if $lastOne; # checked all images
4762
4763
  # look for MPF images (in the proper order)
4763
4764
  ++$mpImageNum;
4764
- $prePos = $$self{VALUE}{"MPImageStart ($mpImageNum)"};
4765
+ $prePos = $$value{"MPImageStart ($mpImageNum)"};
4765
4766
  if (defined $prePos) {
4766
- $preLen = $$self{VALUE}{"MPImageLength ($mpImageNum)"};
4767
+ $preLen = $$value{"MPImageLength ($mpImageNum)"};
4767
4768
  } else {
4768
- $prePos = $$self{VALUE}{'MPImageStart'};
4769
- $preLen = $$self{VALUE}{'MPImageLength'};
4769
+ $prePos = $$value{MPImageStart};
4770
+ $preLen = $$value{MPImageLength};
4770
4771
  $lastOne = 1;
4771
4772
  }
4772
4773
  $tag = "MPImage$mpImageNum";
@@ -5887,10 +5888,10 @@ sub WriteJPEG($$)
5887
5888
  $writeBuffer = '';
5888
5889
  $oldOutfile = $outfile;
5889
5890
  $outfile = \$writeBuffer;
5890
- # account for segment, EXIF and TIFF headers
5891
- $$self{PREVIEW_INFO}{Fixup}{Start} += 18 if $$self{PREVIEW_INFO};
5892
- $$self{LeicaTrailer}{Fixup}{Start} += 18 if $$self{LeicaTrailer};
5893
- $$self{HiddenData}{Fixup}{Start} += 18 if $$self{HiddenData};
5891
+ # must account for segment, EXIF and TIFF headers
5892
+ foreach (qw(PREVIEW_INFO LeicaTrailer HiddenData)) {
5893
+ $$self{$_}{Fixup}{Start} += 18 if $$self{$_};
5894
+ }
5894
5895
  }
5895
5896
  # write as multi-segment
5896
5897
  my $n = WriteMultiSegment($outfile, 0xe1, $exifAPP1hdr, \$buff, 'EXIF');
@@ -6036,8 +6037,8 @@ sub WriteJPEG($$)
6036
6037
  my $delPreview = $$self{DEL_PREVIEW};
6037
6038
  $trailInfo = $self->IdentifyTrailer($raf) unless $$delGroup{Trailer};
6038
6039
  my $nvTrail = $self->GetNewValueHash($Image::ExifTool::Extra{Trailer});
6039
- unless ($oldOutfile or $delPreview or $trailInfo or $$delGroup{Trailer} or $nvTrail or
6040
- $$self{HiddenData})
6040
+ unless ($oldOutfile or $delPreview or $trailInfo or $$delGroup{Trailer} or
6041
+ $nvTrail or $$self{HiddenData})
6041
6042
  {
6042
6043
  # blindly copy the rest of the file
6043
6044
  while ($raf->Read($buff, 65536)) {
@@ -6082,35 +6083,7 @@ sub WriteJPEG($$)
6082
6083
  }
6083
6084
  last; # all done
6084
6085
  }
6085
- # copy HiddenData if necessary
6086
- if ($$self{HiddenData}) {
6087
- my $pad;
6088
- my $hd = $$self{HiddenData};
6089
- my $hdOff = $$hd{Offset} + $$hd{Base};
6090
- require Image::ExifTool::Sony;
6091
- # read HiddenData, updating $hdOff with actual offset if necessary
6092
- my $dataPt = Image::ExifTool::Sony::ReadHiddenData($self, $hdOff, $$hd{Size});
6093
- if ($dataPt) {
6094
- # preserve padding to avoid invalidating MPF pointers (yuk!)
6095
- my $padLen = $hdOff - $endPos;
6096
- unless ($padLen >= 0 and $raf->Seek($endPos,0) and $raf->Read($pad,$padLen)==$padLen) {
6097
- $self->Error('Error reading HiddenData padding',1);
6098
- $pad = '';
6099
- }
6100
- $endPos += length($pad) + length($$dataPt); # update end position
6101
- } else {
6102
- $$dataPt = $pad = '';
6103
- }
6104
- my $fixup = $$self{HiddenData}{Fixup};
6105
- # set MakerNote pointer and size (subtract 10 for segment and EXIF headers)
6106
- $fixup->SetMarkerPointers($outfile, 'HiddenData', length($$outfile) + length($pad) - 10);
6107
- # clean up and write the buffered data
6108
- $outfile = $oldOutfile;
6109
- undef $oldOutfile;
6110
- Write($outfile, $writeBuffer, $pad, $$dataPt) or $err = 1;
6111
- undef $writeBuffer;
6112
- }
6113
- # rewrite existing trailers
6086
+ # rewrite existing trailers into buffer
6114
6087
  if ($trailInfo) {
6115
6088
  my $tbuf = '';
6116
6089
  $raf->Seek(-length($buff), 1); # seek back to just after EOI
@@ -6118,100 +6091,126 @@ sub WriteJPEG($$)
6118
6091
  $$trailInfo{ScanForTrailer} = 1;# scan if necessary
6119
6092
  $self->ProcessTrailers($trailInfo) or undef $trailInfo;
6120
6093
  }
6121
- if (not $oldOutfile) {
6122
- # do nothing special
6123
- } elsif ($$self{LeicaTrailer}) {
6124
- my $trailLen;
6125
- if ($trailInfo) {
6126
- $trailLen = $$trailInfo{DataPos} - $endPos;
6127
- } else {
6128
- $raf->Seek(0, 2) or $err = 1;
6129
- $trailLen = $raf->Tell() - $endPos;
6130
- }
6131
- my $fixup = $$self{LeicaTrailer}{Fixup};
6132
- $$self{LeicaTrailer}{TrailPos} = $endPos;
6133
- $$self{LeicaTrailer}{TrailLen} = $trailLen;
6134
- # get _absolute_ position of new Leica trailer
6135
- my $absPos = Tell($oldOutfile) + length($$outfile);
6136
- require Image::ExifTool::Panasonic;
6137
- my $dat = Image::ExifTool::Panasonic::ProcessLeicaTrailer($self, $absPos);
6138
- # allow some junk before Leica trailer (just in case)
6139
- my $junk = $$self{LeicaTrailerPos} - $endPos;
6140
- # set MakerNote pointer and size (subtract 10 for segment and EXIF headers)
6141
- $fixup->SetMarkerPointers($outfile, 'LeicaTrailer', length($$outfile) - 10 + $junk);
6142
- # use this fixup to set the size too (sneaky)
6143
- my $trailSize = defined($dat) ? length($dat) - $junk : $$self{LeicaTrailer}{Size};
6144
- $$fixup{Start} -= 4; $$fixup{Shift} += 4;
6145
- $fixup->SetMarkerPointers($outfile, 'LeicaTrailer', $trailSize) if defined $trailSize;
6146
- $$fixup{Start} += 4; $$fixup{Shift} -= 4;
6147
- # clean up and write the buffered data
6148
- $outfile = $oldOutfile;
6149
- undef $oldOutfile;
6150
- Write($outfile, $writeBuffer) or $err = 1;
6151
- undef $writeBuffer;
6152
- if (defined $dat) {
6153
- Write($outfile, $dat) or $err = 1; # write new Leica trailer
6154
- $delPreview = 1; # delete existing Leica trailer
6094
+ if ($oldOutfile) {
6095
+ my $previewInfo;
6096
+ # copy HiddenData if necessary
6097
+ if ($$self{HiddenData}) {
6098
+ my $pad;
6099
+ my $hd = $$self{HiddenData};
6100
+ my $hdOff = $$hd{Offset} + $$hd{Base};
6101
+ require Image::ExifTool::Sony;
6102
+ # read HiddenData, updating $hdOff with actual offset if necessary
6103
+ my $dataPt = Image::ExifTool::Sony::ReadHiddenData($self, $hdOff, $$hd{Size});
6104
+ if ($dataPt) {
6105
+ # preserve padding to avoid invalidating MPF pointers (yuk!)
6106
+ my $padLen = $hdOff - $endPos;
6107
+ unless ($padLen >= 0 and $raf->Seek($endPos,0) and $raf->Read($pad,$padLen)==$padLen) {
6108
+ $self->Error('Error reading HiddenData padding',1);
6109
+ $pad = '';
6110
+ }
6111
+ $endPos += length($pad) + length($$dataPt); # update end position
6112
+ } else {
6113
+ $$dataPt = $pad = '';
6114
+ }
6115
+ my $fixup = $$self{HiddenData}{Fixup};
6116
+ # set MakerNote pointer and size (subtract 10 for segment and EXIF headers)
6117
+ $fixup->SetMarkerPointers($outfile, 'HiddenData', length($$outfile) + length($pad) - 10);
6118
+ $writeBuffer .= $pad . $$dataPt; # keep padding for now
6155
6119
  }
6156
- } else {
6157
- # locate preview image and fix up preview offsets
6158
- my $scanLen = $$self{Make} =~ /^SONY/i ? 65536 : 1024;
6159
- if (length($buff) < $scanLen) { # make sure we have enough trailer to scan
6160
- my $buf2;
6161
- $buff .= $buf2 if $raf->Read($buf2, $scanLen - length($buff));
6120
+ if ($$self{LeicaTrailer}) {
6121
+ my $trailLen;
6122
+ if ($trailInfo) {
6123
+ $trailLen = $$trailInfo{DataPos} - $endPos;
6124
+ } else {
6125
+ $raf->Seek(0, 2) or $err = 1;
6126
+ $trailLen = $raf->Tell() - $endPos;
6127
+ }
6128
+ my $fixup = $$self{LeicaTrailer}{Fixup};
6129
+ $$self{LeicaTrailer}{TrailPos} = $endPos;
6130
+ $$self{LeicaTrailer}{TrailLen} = $trailLen;
6131
+ # get _absolute_ position of new Leica trailer
6132
+ my $absPos = Tell($oldOutfile) + length($$outfile);
6133
+ require Image::ExifTool::Panasonic;
6134
+ my $dat = Image::ExifTool::Panasonic::ProcessLeicaTrailer($self, $absPos);
6135
+ # allow some junk before Leica trailer (just in case)
6136
+ my $junk = $$self{LeicaTrailerPos} - $endPos;
6137
+ # set MakerNote pointer and size (subtract 10 for segment and EXIF headers)
6138
+ $fixup->SetMarkerPointers($outfile, 'LeicaTrailer', length($$outfile) - 10 + $junk);
6139
+ # use this fixup to set the size too (sneaky)
6140
+ my $trailSize = defined($dat) ? length($dat) - $junk : $$self{LeicaTrailer}{Size};
6141
+ $$fixup{Start} -= 4; $$fixup{Shift} += 4;
6142
+ $fixup->SetMarkerPointers($outfile, 'LeicaTrailer', $trailSize) if defined $trailSize;
6143
+ $$fixup{Start} += 4; $$fixup{Shift} -= 4;
6144
+ if (defined $dat) {
6145
+ Write($outfile, $dat) or $err = 1; # write new Leica trailer
6146
+ $delPreview = 1; # delete existing Leica trailer
6147
+ }
6162
6148
  }
6163
- # get new preview image position, relative to EXIF base
6164
- my $newPos = length($$outfile) - 10; # (subtract 10 for segment and EXIF headers)
6165
- my $junkLen;
6166
- # adjust position if image isn't at the start (eg. Olympus E-1/E-300)
6167
- if ($buff =~ /(\xff\xd8\xff.|.\xd8\xff\xdb)(..)/sg) {
6168
- my ($jpegHdr, $segLen) = ($1, $2);
6169
- $junkLen = pos($buff) - 6;
6170
- # Sony previewimage trailer has a 32 byte header
6171
- if ($$self{Make} =~ /^SONY/i and $junkLen > 32) {
6172
- # with some newer Sony models, the makernotes preview pointer
6173
- # points to JPEG at end of EXIF inside MPImage preview (what a pain!)
6174
- if ($jpegHdr eq "\xff\xd8\xff\xe1") { # is the first segment EXIF?
6175
- $segLen = unpack('n', $segLen); # the EXIF segment length
6176
- # Sony PreviewImage starts with last 2 bytes of EXIF segment
6177
- # (and first byte is usually "\0", not "\xff", so don't check this)
6178
- if (length($buff) > $junkLen + $segLen + 6 and
6179
- substr($buff, $junkLen + $segLen + 3, 3) eq "\xd8\xff\xdb")
6180
- {
6181
- $junkLen += $segLen + 2;
6182
- # (note: this will not copy the trailer after PreviewImage,
6183
- # which is a 14kB block full of zeros for the A77)
6149
+ # handle preview image last
6150
+ if ($$self{PREVIEW_INFO}) {
6151
+ # locate preview image and fix up preview offsets
6152
+ my $scanLen = $$self{Make} =~ /^SONY/i ? 65536 : 1024;
6153
+ if (length($buff) < $scanLen) { # make sure we have enough trailer to scan
6154
+ my $buf2;
6155
+ $buff .= $buf2 if $raf->Read($buf2, $scanLen - length($buff));
6156
+ }
6157
+ # get new preview image position, relative to EXIF base
6158
+ my $newPos = length($$outfile) - 10; # (subtract 10 for segment and EXIF headers)
6159
+ my $junkLen;
6160
+ # adjust position if image isn't at the start (eg. Olympus E-1/E-300)
6161
+ if ($buff =~ /(\xff\xd8\xff.|.\xd8\xff\xdb)(..)/sg) {
6162
+ my ($jpegHdr, $segLen) = ($1, $2);
6163
+ $junkLen = pos($buff) - 6;
6164
+ # Sony previewimage trailer has a 32 byte header
6165
+ if ($$self{Make} =~ /^SONY/i and $junkLen > 32) {
6166
+ # with some newer Sony models, the makernotes preview pointer
6167
+ # points to JPEG at end of EXIF inside MPImage preview (what a pain!)
6168
+ if ($jpegHdr eq "\xff\xd8\xff\xe1") { # is the first segment EXIF?
6169
+ $segLen = unpack('n', $segLen); # the EXIF segment length
6170
+ # Sony PreviewImage starts with last 2 bytes of EXIF segment
6171
+ # (and first byte is usually "\0", not "\xff", so don't check this)
6172
+ if (length($buff) > $junkLen + $segLen + 6 and
6173
+ substr($buff, $junkLen + $segLen + 3, 3) eq "\xd8\xff\xdb")
6174
+ {
6175
+ $junkLen += $segLen + 2;
6176
+ # (note: this will not copy the trailer after PreviewImage,
6177
+ # which is a 14kB block full of zeros for the A77)
6178
+ }
6184
6179
  }
6180
+ $junkLen -= 32;
6185
6181
  }
6186
- $junkLen -= 32;
6182
+ $newPos += $junkLen;
6183
+ }
6184
+ # fix up the preview offsets to point to the start of the new image
6185
+ $previewInfo = $$self{PREVIEW_INFO};
6186
+ delete $$self{PREVIEW_INFO};
6187
+ my $fixup = $$previewInfo{Fixup};
6188
+ $newPos += ($$previewInfo{BaseShift} || 0);
6189
+ # adjust to absolute file offset if necessary (Samsung STMN)
6190
+ $newPos += Tell($oldOutfile) + 10 if $$previewInfo{Absolute};
6191
+ if ($$previewInfo{Relative}) {
6192
+ # adjust for our base by looking at how far the pointer got shifted
6193
+ $newPos -= ($fixup->GetMarkerPointers($outfile, 'PreviewImage') || 0);
6194
+ } elsif ($$previewInfo{ChangeBase}) {
6195
+ # Leica S2 uses relative offsets for the preview only (leica sucks)
6196
+ my $makerOffset = $fixup->GetMarkerPointers($outfile, 'LeicaTrailer');
6197
+ $newPos -= $makerOffset if $makerOffset;
6198
+ }
6199
+ $fixup->SetMarkerPointers($outfile, 'PreviewImage', $newPos);
6200
+ if ($$previewInfo{Data} ne 'LOAD_PREVIEW') {
6201
+ # write any junk that existed before the preview image
6202
+ $$previewInfo{Junk} = substr($buff,0,$junkLen) if $junkLen;
6187
6203
  }
6188
- $newPos += $junkLen;
6189
- }
6190
- # fix up the preview offsets to point to the start of the new image
6191
- my $previewInfo = $$self{PREVIEW_INFO};
6192
- delete $$self{PREVIEW_INFO};
6193
- my $fixup = $$previewInfo{Fixup};
6194
- $newPos += ($$previewInfo{BaseShift} || 0);
6195
- # adjust to absolute file offset if necessary (Samsung STMN)
6196
- $newPos += Tell($oldOutfile) + 10 if $$previewInfo{Absolute};
6197
- if ($$previewInfo{Relative}) {
6198
- # adjust for our base by looking at how far the pointer got shifted
6199
- $newPos -= ($fixup->GetMarkerPointers($outfile, 'PreviewImage') || 0);
6200
- } elsif ($$previewInfo{ChangeBase}) {
6201
- # Leica S2 uses relative offsets for the preview only (leica sucks)
6202
- my $makerOffset = $fixup->GetMarkerPointers($outfile, 'LeicaTrailer');
6203
- $newPos -= $makerOffset if $makerOffset;
6204
6204
  }
6205
- $fixup->SetMarkerPointers($outfile, 'PreviewImage', $newPos);
6206
6205
  # clean up and write the buffered data
6207
6206
  $outfile = $oldOutfile;
6208
6207
  undef $oldOutfile;
6209
6208
  Write($outfile, $writeBuffer) or $err = 1;
6210
6209
  undef $writeBuffer;
6211
6210
  # write preview image
6212
- if ($$previewInfo{Data} ne 'LOAD_PREVIEW') {
6211
+ if ($previewInfo and $$previewInfo{Data} ne 'LOAD_PREVIEW') {
6213
6212
  # write any junk that existed before the preview image
6214
- Write($outfile, substr($buff,0,$junkLen)) or $err = 1 if $junkLen;
6213
+ Write($outfile, $$previewInfo{Junk}) or $err = 1 if defined $$previewInfo{Junk};
6215
6214
  # write the saved preview image
6216
6215
  Write($outfile, $$previewInfo{Data}) or $err = 1;
6217
6216
  delete $$previewInfo{Data};
@@ -6224,7 +6223,7 @@ sub WriteJPEG($$)
6224
6223
  my $extra;
6225
6224
  if ($trailInfo) {
6226
6225
  # copy everything up to start of first processed trailer
6227
- $extra = $$trailInfo{DataPos} - $endPos;
6226
+ $extra = defined $$trailInfo{DataPos} ? ($$trailInfo{DataPos} - $endPos) : 0;
6228
6227
  } else {
6229
6228
  # copy everything up to end of file
6230
6229
  $raf->Seek(0, 2) or $err = 1;
@@ -6393,9 +6392,9 @@ sub WriteJPEG($$)
6393
6392
  $oldOutfile = $outfile;
6394
6393
  $outfile = \$writeBuffer;
6395
6394
  # must account for segment, EXIF and TIFF headers
6396
- $$self{PREVIEW_INFO}{Fixup}{Start} += 18 if $$self{PREVIEW_INFO};
6397
- $$self{LeicaTrailer}{Fixup}{Start} += 18 if $$self{LeicaTrailer};
6398
- $$self{HiddenData}{Fixup}{Start} += 18 if $$self{HiddenData};
6395
+ foreach (qw(PREVIEW_INFO LeicaTrailer HiddenData)) {
6396
+ $$self{$_}{Fixup}{Start} += 18 if $$self{$_};
6397
+ }
6399
6398
  }
6400
6399
  # write as multi-segment
6401
6400
  my $n = WriteMultiSegment($outfile, $marker, $exifAPP1hdr, $segDataPt, 'EXIF');
@@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
29
29
  %jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
30
30
  %static_vars $advFmtSelf $configFile @configFiles $noConfig);
31
31
 
32
- $VERSION = '13.30';
32
+ $VERSION = '13.31';
33
33
  $RELEASE = '';
34
34
  @ISA = qw(Exporter);
35
35
  %EXPORT_TAGS = (
@@ -42,7 +42,7 @@ $RELEASE = '';
42
42
  # exports not part of the public API, but used by ExifTool modules:
43
43
  DataAccess => [qw(
44
44
  ReadValue GetByteOrder SetByteOrder ToggleByteOrder Get8u Get8s Get16u
45
- Get16s Get32u Get32s Get64u GetFloat GetDouble GetFixed32s Write
45
+ Get16s Get32u Get32s Get64u Get64s GetFloat GetDouble GetFixed32s Write
46
46
  WriteValue Tell Set8u Set8s Set16u Set32u Set64u Set64s
47
47
  )],
48
48
  Utils => [qw(GetTagTable TagTableKeys GetTagInfoList AddTagToTable HexDump)],
@@ -9719,8 +9719,10 @@ sub ExtractBinary($$$;$)
9719
9719
  $isPreview = 1;
9720
9720
  }
9721
9721
  my $lcTag = lc $tag;
9722
- if ((not $$self{OPTIONS}{Binary} or $$self{EXCL_TAG_LOOKUP}{$lcTag}) and
9723
- not $$self{OPTIONS}{Verbose} and not $$self{REQ_TAG_LOOKUP}{$lcTag})
9722
+ my $options = $$self{OPTIONS};
9723
+ if ((not $$options{Binary} or $$self{EXCL_TAG_LOOKUP}{$lcTag}) and
9724
+ not $$options{Verbose} and not $$options{Validate} and
9725
+ not $$self{REQ_TAG_LOOKUP}{$lcTag})
9724
9726
  {
9725
9727
  return "Binary data $length bytes";
9726
9728
  }
@@ -611,11 +611,13 @@ OPTIONS
611
611
  useful for some text strings since control characters (such as
612
612
  newlines) are not replaced by '.' as they are in the default
613
613
  output. By default, list items are separated by a newline when
614
- extracted with the -b option, but this may be changed (see the -sep
615
- option for details). May be combined with -j, -php or -X to extract
616
- binary data in JSON, PHP or XML format, but note that "Unsafe" tags
617
- are not extracted as binary unless they are specified explicitly or
618
- the API RequestAll option is set to 3 or higher.
614
+ extracted with the -b option and no terminator is added after each
615
+ tag value, but the list separator may be changed with a -sep option
616
+ and a terminator may be set by adding a second -sep option (see the
617
+ -sep option for details). May be combined with -j, -php or -X to
618
+ extract binary data in JSON, PHP or XML format, but note that
619
+ "Unsafe" tags are not extracted as binary unless they are specified
620
+ explicitly or the API RequestAll option is set to 3 or higher.
619
621
 
620
622
  With a leading double dash (--b or --binary), tags which contain
621
623
  binary data are suppressed in the output when reading.
@@ -1079,7 +1081,7 @@ OPTIONS
1079
1081
 
1080
1082
  produces output like this:
1081
1083
 
1082
- -- Generated by ExifTool 13.30 --
1084
+ -- Generated by ExifTool 13.31 --
1083
1085
  File: a.jpg - 2003:10:31 15:44:19
1084
1086
  (f/5.6, 1/60s, ISO 100)
1085
1087
  File: b.jpg - 2006:05:23 11:57:38
@@ -1895,9 +1897,10 @@ OPTIONS
1895
1897
  with -listf, -listr or -listwf to add file descriptions to the
1896
1898
  list. The -lang option may be combined with -listx to output
1897
1899
  descriptions in a single language, and the -sort and/or -lang
1898
- options may be combined with -listgeo. Also, the API GeolocMinPop,
1899
- GeolocFeature and GeolocAltNames options apply to the -listgeo
1900
- output. Here are some examples:
1900
+ options may be combined with -listgeo (installation of the
1901
+ alternate database is required for the additional languages). Also,
1902
+ the API GeolocMinPop, GeolocFeature and GeolocAltNames options
1903
+ apply to the -listgeo output. Here are some examples:
1901
1904
 
1902
1905
  -list # list all tag names
1903
1906
  -list -EXIF:All # list all EXIF tags
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "exiftool-vendored.exe",
3
- "version": "13.30.0",
3
+ "version": "13.31.0",
4
4
  "description": "Vendored win32 ExifTool for Node.js",
5
5
  "main": "./index.js",
6
6
  "homepage": "https://github.com/photostructure/exiftool-vendored.exe#readme",
@@ -27,7 +27,11 @@
27
27
  "scripts": {
28
28
  "prettier": "prettier --write *.js test/*.js",
29
29
  "test": "mocha",
30
- "update-exiftool": "node update-exiftool.js",
30
+ "update": "run-p update:*",
31
+ "update:deps": "ncu -u",
32
+ "update:exiftool": "node update-exiftool.js",
33
+ "install:pinact": "go install github.com/suzuki-shunsuke/pinact/cmd/pinact@latest",
34
+ "update:actions": "pinact run -u",
31
35
  "release": "release-it"
32
36
  },
33
37
  "release-it": {
@@ -44,10 +48,11 @@
44
48
  }
45
49
  },
46
50
  "devDependencies": {
47
- "axios": "^1.8.4",
48
- "mocha": "^11.1.0",
51
+ "axios": "^1.10.0",
52
+ "mocha": "^11.7.0",
53
+ "npm-run-all": "4.1.5",
49
54
  "prettier": "^3.5.3",
50
- "release-it": "^19.0.2",
55
+ "release-it": "^19.0.3",
51
56
  "unzipper": "^0.12.3",
52
57
  "xml2js": "^0.6.2"
53
58
  }