exiftool_vendored 13.06.0 → 13.08.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +29 -3
  3. data/bin/META.json +1 -1
  4. data/bin/META.yml +1 -1
  5. data/bin/README +2 -2
  6. data/bin/exiftool +6 -5
  7. data/bin/lib/Image/ExifTool/AIFF.pm +1 -1
  8. data/bin/lib/Image/ExifTool/APE.pm +1 -1
  9. data/bin/lib/Image/ExifTool/ASF.pm +1 -1
  10. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +4 -3
  11. data/bin/lib/Image/ExifTool/Canon.pm +19 -1
  12. data/bin/lib/Image/ExifTool/DJI.pm +1 -1
  13. data/bin/lib/Image/ExifTool/Exif.pm +2 -2
  14. data/bin/lib/Image/ExifTool/FITS.pm +2 -2
  15. data/bin/lib/Image/ExifTool/FLIF.pm +2 -2
  16. data/bin/lib/Image/ExifTool/FlashPix.pm +11 -11
  17. data/bin/lib/Image/ExifTool/Font.pm +1 -1
  18. data/bin/lib/Image/ExifTool/HP.pm +1 -1
  19. data/bin/lib/Image/ExifTool/ID3.pm +3 -3
  20. data/bin/lib/Image/ExifTool/IPTC.pm +2 -2
  21. data/bin/lib/Image/ExifTool/InDesign.pm +1 -1
  22. data/bin/lib/Image/ExifTool/Jpeg2000.pm +6 -6
  23. data/bin/lib/Image/ExifTool/M2TS.pm +39 -9
  24. data/bin/lib/Image/ExifTool/MXF.pm +2 -2
  25. data/bin/lib/Image/ExifTool/Matroska.pm +1 -1
  26. data/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
  27. data/bin/lib/Image/ExifTool/PDF.pm +15 -15
  28. data/bin/lib/Image/ExifTool/PLIST.pm +1 -1
  29. data/bin/lib/Image/ExifTool/PNG.pm +4 -4
  30. data/bin/lib/Image/ExifTool/Panasonic.pm +1 -1
  31. data/bin/lib/Image/ExifTool/PhaseOne.pm +3 -3
  32. data/bin/lib/Image/ExifTool/Photoshop.pm +63 -3
  33. data/bin/lib/Image/ExifTool/Protobuf.pm +4 -4
  34. data/bin/lib/Image/ExifTool/QuickTime.pm +23 -14
  35. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +336 -91
  36. data/bin/lib/Image/ExifTool/README +4 -1
  37. data/bin/lib/Image/ExifTool/RIFF.pm +3 -3
  38. data/bin/lib/Image/ExifTool/RTF.pm +1 -1
  39. data/bin/lib/Image/ExifTool/Ricoh.pm +3 -3
  40. data/bin/lib/Image/ExifTool/Sony.pm +2 -2
  41. data/bin/lib/Image/ExifTool/TagInfoXML.pm +4 -3
  42. data/bin/lib/Image/ExifTool/TagLookup.pm +6979 -6970
  43. data/bin/lib/Image/ExifTool/TagNames.pod +26 -5
  44. data/bin/lib/Image/ExifTool/VCard.pm +2 -2
  45. data/bin/lib/Image/ExifTool/Validate.pm +3 -3
  46. data/bin/lib/Image/ExifTool/WriteExif.pl +2 -2
  47. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +4 -4
  48. data/bin/lib/Image/ExifTool/WriteXMP.pl +2 -2
  49. data/bin/lib/Image/ExifTool/Writer.pl +16 -16
  50. data/bin/lib/Image/ExifTool/XMP.pm +9 -9
  51. data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
  52. data/bin/lib/Image/ExifTool.pm +58 -57
  53. data/bin/lib/Image/ExifTool.pod +1 -1
  54. data/bin/perl-Image-ExifTool.spec +1 -1
  55. data/lib/exiftool_vendored/version.rb +1 -1
  56. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 277daacb61b45f8ffcf01c45e8a2ae6c7814aa878af57ce5e700433e37a73a89
4
- data.tar.gz: c27dc0342c61725b98adb52806417396827df205172ae6793f14bb6eb9d3949b
3
+ metadata.gz: 53adc02bd5bb808506a883f10c449fd0172d7d82c099a4c5d5a4dbbcb9971d68
4
+ data.tar.gz: 76a6795061f0128324568a9907804699dd0635e94bc7042bf5ba1cb3c40c92e2
5
5
  SHA512:
6
- metadata.gz: acb79bdb9f29cb00439ad4006faba198b460abed0c655e1cce6d7a3845ec14c8fe19a778dcbdb5401bb5f77b51329329e9ab8a6932c98a9d04ff63ca04be9af0
7
- data.tar.gz: 2771ca21af4d53e1d2138b4b94dd187f1e59c9f9c6230f8d3a8d83be61979b320570084a50f5ae5a3d038114a46cca518dca35e517d8304ed98087c73ceeb163
6
+ metadata.gz: bd68829340a5e18d410b4485e0789bef799d78d2fb7d6ff49612fa4a596b918c86b3515c2cd0ef0d90a0a04c72403a7a2113b86d882c93d5a4e0495d01573bbd
7
+ data.tar.gz: d44cfcbc7dd21d7e74bc26ea46fcdf19f724ccffcb08e7375f21ae58f1544fcc753804348bb61f3dc706b984e5b8bdc43437f296e85a7e8767c1a168be879df9
data/bin/Changes CHANGED
@@ -7,14 +7,40 @@ RSS feed: https://exiftool.org/rss.xml
7
7
  Note: The most recent production release is Version 13.00. (Other versions are
8
8
  considered development releases, and are not uploaded to MetaCPAN.)
9
9
 
10
+ Dec. 14, 2024 - Version 13.08
11
+
12
+ - Decode ShutterCount for Canon EOS R6 Mark II (thanks Agoston Kapitany)
13
+ - Decode a few new Photoshop tags
14
+ - Suppress all duplicate Warning tags and add count to end of message
15
+ - Changed format of bitmask keys in -list x output
16
+ - Internal streamlining of LIGOGPSINFO decoding
17
+ - Fixed issue where some tags were incorrectly shown as writable in -listx
18
+ output
19
+ - Fixed incorrect scaling for GPSSpeed in one LIGOGPSINFO variant
20
+ - Fixed an issue with filename encoding when the -L option is used and the API
21
+ WindowsLongPath option is active
22
+
23
+ Dec. 11, 2024 - Version 13.07
24
+
25
+ - Decode a number of LIGOGPSINFO encrypted and enciphered timed GPS types
26
+ (long overdue, but it took me a couple of years to acquire enough sample
27
+ videos to have a good cross-section of the different formats)
28
+ - Fixed another place where FileSequence could be incremented twice when a -if
29
+ condition was used
30
+ - Fixed a few places where character 0x7f may not have been escaped in string
31
+ values
32
+ - API Changes:
33
+ - Changed default WindowsLongPath option back to 1 after adding a patch to
34
+ fix issue with piping from stdin
35
+
10
36
  Dec. 5, 2024 - Version 13.06
11
37
 
12
38
  - Decode timed metadata from MP4 videos of yet another dashcam model
13
39
  - Patched issue where FileSequence could increment twice for each file when a
14
40
  -if condition was used
15
41
  - API Changes:
16
- - Revert default WindowsLongPath option until we can solve the pipe
17
- problem)
42
+ - Revert default WindowsLongPath option to the pre-13.05 setting
43
+ until we can solve the pipe problem
18
44
 
19
45
  Dec. 4, 2024 - Version 13.05
20
46
 
@@ -24,7 +50,7 @@ Dec. 4, 2024 - Version 13.05
24
50
  - Decode APP10 AROT HDRGainCurve and APP2 URN UniformResourceName
25
51
  - Decode a couple of new GoPro tags
26
52
  - API Changes:
27
- - Changed default WindowsLongPath option to 1 (please report if this
53
+ - Changed default WindowsLongPath option to 1 (please report if this
28
54
  causes any problems)
29
55
 
30
56
  Nov. 26, 2024 - Version 13.04
data/bin/META.json CHANGED
@@ -50,5 +50,5 @@
50
50
  }
51
51
  },
52
52
  "release_status" : "stable",
53
- "version" : "13.06"
53
+ "version" : "13.08"
54
54
  }
data/bin/META.yml CHANGED
@@ -31,4 +31,4 @@ recommends:
31
31
  Time::HiRes: '0'
32
32
  requires:
33
33
  perl: '5.004'
34
- version: '13.06'
34
+ version: '13.08'
data/bin/README CHANGED
@@ -109,8 +109,8 @@ your home directory, then you would type the following commands in a
109
109
  terminal window to extract and run ExifTool:
110
110
 
111
111
  cd ~/Desktop
112
- gzip -dc Image-ExifTool-13.06.tar.gz | tar -xf -
113
- cd Image-ExifTool-13.06
112
+ gzip -dc Image-ExifTool-13.08.tar.gz | tar -xf -
113
+ cd Image-ExifTool-13.08
114
114
  ./exiftool t/images/ExifTool.jpg
115
115
 
116
116
  Note: These commands extract meta information from one of the test images.
data/bin/exiftool CHANGED
@@ -11,7 +11,7 @@ use strict;
11
11
  use warnings;
12
12
  require 5.004;
13
13
 
14
- my $version = '13.06';
14
+ my $version = '13.08';
15
15
 
16
16
  # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
17
17
  my $exePath;
@@ -2172,7 +2172,8 @@ sub GetImageInfo($$)
2172
2172
  }
2173
2173
  # can't make use of $info if verbose because we must reprocess
2174
2174
  # the file anyway to generate the verbose output
2175
- if ($verbose or defined $fastCondition or defined $diff) {
2175
+ # (also if writing just to avoid double-incrementing FileSequence)
2176
+ if ($isWriting or $verbose or defined $fastCondition or defined $diff) {
2176
2177
  undef $info;
2177
2178
  --$$et{FILE_SEQUENCE};
2178
2179
  }
@@ -3639,7 +3640,7 @@ sub EscapeJSON($;$)
3639
3640
  if ($json < 2) { # JSON
3640
3641
  $str =~ tr/\0//d; # remove all nulls
3641
3642
  # escape other control characters with \u
3642
- $str =~ s/([\0-\x1f])/sprintf("\\u%.4X",ord $1)/sge;
3643
+ $str =~ s/([\0-\x1f\x7f])/sprintf("\\u%.4X",ord $1)/sge;
3643
3644
  # JSON strings must be valid UTF8
3644
3645
  Image::ExifTool::XMP::FixUTF8(\$str) unless $altEnc;
3645
3646
  } else { # PHP
@@ -3647,7 +3648,7 @@ sub EscapeJSON($;$)
3647
3648
  # must escape "$" too for PHP
3648
3649
  $str =~ s/\$/\\\$/sg;
3649
3650
  # escape other control characters with \x
3650
- $str =~ s/([\0-\x1f])/sprintf("\\x%.2X",ord $1)/sge;
3651
+ $str =~ s/([\0-\x1f\x7f])/sprintf("\\x%.2X",ord $1)/sge;
3651
3652
  }
3652
3653
  return '"' . $str . '"'; # return the quoted string
3653
3654
  }
@@ -5912,7 +5913,7 @@ with this command:
5912
5913
 
5913
5914
  produces output like this:
5914
5915
 
5915
- -- Generated by ExifTool 13.06 --
5916
+ -- Generated by ExifTool 13.08 --
5916
5917
  File: a.jpg - 2003:10:31 15:44:19
5917
5918
  (f/5.6, 1/60s, ISO 100)
5918
5919
  File: b.jpg - 2006:05:23 11:57:38
@@ -231,7 +231,7 @@ sub ProcessAIFF($$)
231
231
  $et->Warn('End of processing at large chunk (LargeFileSupport not enabled)');
232
232
  last;
233
233
  } elsif ($et->Options('LargeFileSupport') eq '2') {
234
- $et->WarnOnce('Skipping large chunk (LargeFileSupport is 2)');
234
+ $et->Warn('Skipping large chunk (LargeFileSupport is 2)');
235
235
  }
236
236
  }
237
237
  if ($tagInfo) {
@@ -217,7 +217,7 @@ sub ProcessAPE($$)
217
217
  $val = \$buf2;
218
218
  # extract cover art description separately (hackitty hack)
219
219
  if ($tag =~ /^Cover Art/) {
220
- $buf2 =~ s/^([\x20-\x7f]*)\0//;
220
+ $buf2 =~ s/^([\x20-\x7e]*)\0//;
221
221
  if ($1) {
222
222
  my $t = "$tag Desc";
223
223
  my $v = $1;
@@ -781,7 +781,7 @@ sub ProcessASF($$;$)
781
781
  $err = 'Invalid ASF object size';
782
782
  } elsif ($et->Options('LargeFileSupport')) {
783
783
  if ($et->Options('LargeFileSupport') eq '2') {
784
- $et->WarnOnce('Skipping large ASF object (LargeFileSupport is 2)');
784
+ $et->Warn('Skipping large ASF object (LargeFileSupport is 2)');
785
785
  }
786
786
  if ($raf->Seek($size, 1)) {
787
787
  $et->VPrint(0, " Skipped large ASF object ($size bytes)\n");
@@ -35,7 +35,7 @@ use Image::ExifTool::Sony;
35
35
  use Image::ExifTool::Validate;
36
36
  use Image::ExifTool::MacOS;
37
37
 
38
- $VERSION = '3.58';
38
+ $VERSION = '3.59';
39
39
  @ISA = qw(Exporter);
40
40
 
41
41
  sub NumbersFirst($$);
@@ -869,7 +869,8 @@ sub new
869
869
  my $processBinaryData = ($$table{PROCESS_PROC} and (
870
870
  $$table{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData or
871
871
  $$table{PROCESS_PROC} eq \&Image::ExifTool::Nikon::ProcessNikonEncrypted or
872
- $$table{PROCESS_PROC} eq \&Image::ExifTool::Sony::ProcessEnciphered));
872
+ $$table{PROCESS_PROC} eq \&Image::ExifTool::Sony::ProcessEnciphered) or
873
+ $$table{VARS} and $$table{VARS}{IS_BINARY});
873
874
  if ($$vars{ID_LABEL} or $processBinaryData) {
874
875
  my $s = $$table{FORMAT} ? Image::ExifTool::FormatSize($$table{FORMAT}) || 1 : 1;
875
876
  $binaryTable = 1;
@@ -1248,7 +1249,7 @@ TagID: foreach $tagID (@keys) {
1248
1249
  }
1249
1250
  } elsif ($$tagInfo{PrintString} or not /^[+-]?(?=\d|\.\d)\d*(\.\d*)?$/) {
1250
1251
  # translate unprintable values
1251
- if ($index =~ s/([\x00-\x1f\x80-\xff])/sprintf("\\x%.2x",ord $1)/eg) {
1252
+ if ($index =~ s/([\x00-\x1f\x7f-\xff])/sprintf("\\x%.2x",ord $1)/eg) {
1252
1253
  $index = qq{"$index"};
1253
1254
  } else {
1254
1255
  $index = qq{'${index}'};
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
88
88
  sub ProcessExifInfo($$$);
89
89
  sub SwapWords($);
90
90
 
91
- $VERSION = '4.85';
91
+ $VERSION = '4.86';
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)
@@ -1404,6 +1404,11 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
1404
1404
  Condition => '$$self{Model} =~ /\bEOS R[56]$/',
1405
1405
  SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoR6' },
1406
1406
  },
1407
+ {
1408
+ Name => 'CanonCameraInfoR6m2',
1409
+ Condition => '$$self{Model} =~ /\bEOS R6m2$/',
1410
+ SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoR6m2' },
1411
+ },
1407
1412
  {
1408
1413
  Name => 'CanonCameraInfoG5XII',
1409
1414
  Condition => '$$self{Model} =~ /\bG5 X Mark II$/',
@@ -4752,6 +4757,19 @@ my %ciMaxFocal = (
4752
4757
  # 0x0bb7 - counts down during focus stack (ref forum16111)
4753
4758
  );
4754
4759
 
4760
+ %Image::ExifTool::Canon::CameraInfoR6m2 = (
4761
+ %binaryDataAttrs,
4762
+ FIRST_ENTRY => 0,
4763
+ PRIORITY => 0,
4764
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4765
+ NOTES => 'CameraInfo tags for the EOS R6 Mark II.',
4766
+ 0x0d29 => { #AgostonKapitany
4767
+ Name => 'ShutterCount',
4768
+ Format => 'int32u',
4769
+ Notes => 'includes electronic + mechanical shutter',
4770
+ },
4771
+ );
4772
+
4755
4773
  # ref https://exiftool.org/forum/index.php?topic=15356.0
4756
4774
  %Image::ExifTool::Canon::CameraInfoG5XII = (
4757
4775
  %binaryDataAttrs,
@@ -295,7 +295,7 @@ sub ProcessDJIInfo($$$)
295
295
  while ($$dataPt =~ /\G\[(.*?)\](?=(\[|$))/sg) {
296
296
  my ($tag, $val) = split /:/, $1, 2;
297
297
  next unless defined $tag and defined $val;
298
- if ($val =~ /^([\x20-\x7f]+)\0*$/) {
298
+ if ($val =~ /^([\x20-\x7e]+)\0*$/) {
299
299
  $val = $1;
300
300
  } else {
301
301
  my $buff = $val;
@@ -6186,7 +6186,7 @@ sub ProcessExif($$$)
6186
6186
  if ($$dirInfo{DirName} eq 'MakerNotes' and $$et{FileType} eq 'CR3' and
6187
6187
  $$dirInfo{Parent} and $$dirInfo{Parent} eq 'ExifIFD')
6188
6188
  {
6189
- $et->WarnOnce("MakerNotes shouldn't exist ExifIFD of CR3 image", 1);
6189
+ $et->Warn("MakerNotes shouldn't exist ExifIFD of CR3 image", 1);
6190
6190
  }
6191
6191
  # set flag to calculate image data hash if requested
6192
6192
  $doHash = 1 if $$et{ImageDataHash} and (($$et{FILE_TYPE} eq 'TIFF' and not $base and not $inMakerNotes) or
@@ -6656,7 +6656,7 @@ sub ProcessExif($$$)
6656
6656
  if ($count > 500 and $formatStr !~ /^(undef|string|binary)$/ and
6657
6657
  (not $tagInfo or $$tagInfo{LongBinary} or $warned) and not $$et{OPTIONS}{IgnoreMinorErrors})
6658
6658
  {
6659
- $et->WarnOnce('Not decoding some large array(s). Ignore minor errors to decode', 2) unless $warned;
6659
+ $et->Warn('Not decoding some large array(s). Ignore minor errors to decode', 2) unless $warned;
6660
6660
  next if $$et{TAGS_FROM_FILE}; # don't generate bogus value when copying tags
6661
6661
  $val = "(large array of $count $formatStr values)";
6662
6662
  } else {
@@ -61,7 +61,7 @@ sub ProcessFITS($$)
61
61
  my $key = substr($buff, 0, 8);
62
62
  $key =~ s/ +$//; # remove trailing space from key
63
63
  if ($key eq 'CONTINUE') {
64
- defined $continue or $et->WarnOnce('Unexpected FITS CONTINUE keyword'), next;
64
+ defined $continue or $et->Warn('Unexpected FITS CONTINUE keyword'), next;
65
65
  } else {
66
66
  if (defined $continue) {
67
67
  # the previous value wasn't continued, so store with the trailing '&'
@@ -104,7 +104,7 @@ sub ProcessFITS($$)
104
104
  # check for possible continuation, removing trailing '&'
105
105
  $val =~ s/\&$// and $continue = $val, next;
106
106
  } elsif (defined $continue) {
107
- $et->WarnOnce('Invalid FITS CONTINUE value');
107
+ $et->Warn('Invalid FITS CONTINUE value');
108
108
  next;
109
109
  } else {
110
110
  $val =~ s/ *(\/.*)?$//; # remove trailing spaces and comment
@@ -244,7 +244,7 @@ sub WriteFLIF($$)
244
244
  }
245
245
  }
246
246
  } else {
247
- $et->WarnOnce('Install IO::Compress::RawDeflate to write FLIF metadata');
247
+ $et->Warn('Install IO::Compress::RawDeflate to write FLIF metadata');
248
248
  }
249
249
  Write($outfile, $tag, SetVarInt(length $buff), $buff) or return -1;
250
250
  } elsif (not defined $soi) {
@@ -301,7 +301,7 @@ sub ProcessFLIF($$)
301
301
  $et->Warn("Error inflating FLIF $tag chunk");
302
302
  }
303
303
  } else {
304
- $et->WarnOnce('Install IO::Uncompress::RawInflate to decode FLIF metadata');
304
+ $et->Warn('Install IO::Uncompress::RawInflate to decode FLIF metadata');
305
305
  }
306
306
  } else {
307
307
  $raf->Seek($size, 1) or $et->Warn('Seek error'), last;
@@ -1449,7 +1449,7 @@ sub ReadFPXValue($$$$$;$$)
1449
1449
  $noPad = 1; # values sometimes aren't padded inside vectors!!
1450
1450
  my $size = $oleFormatSize{VT_VECTOR};
1451
1451
  if ($valPos + $size > $dirEnd) {
1452
- $et->WarnOnce('Incorrect FPX VT_VECTOR size');
1452
+ $et->Warn('Incorrect FPX VT_VECTOR size');
1453
1453
  last;
1454
1454
  }
1455
1455
  $count = Get32u($dataPt, $valPos);
@@ -1457,14 +1457,14 @@ sub ReadFPXValue($$$$$;$$)
1457
1457
  $valPos += 4;
1458
1458
  } else {
1459
1459
  # can't yet handle this property flag
1460
- $et->WarnOnce('Unknown FPX property');
1460
+ $et->Warn('Unknown FPX property');
1461
1461
  last;
1462
1462
  }
1463
1463
  }
1464
1464
  unless ($format =~ /^VT_/) {
1465
1465
  my $size = Image::ExifTool::FormatSize($format) * $count;
1466
1466
  if ($valPos + $size > $dirEnd) {
1467
- $et->WarnOnce("Incorrect FPX $format size");
1467
+ $et->Warn("Incorrect FPX $format size");
1468
1468
  last;
1469
1469
  }
1470
1470
  @vals = ReadValue($dataPt, $valPos, $format, $count, $size);
@@ -1476,7 +1476,7 @@ sub ReadFPXValue($$$$$;$$)
1476
1476
  my ($item, $val, $len);
1477
1477
  for ($item=0; $item<$count; ++$item) {
1478
1478
  if ($valPos + $size > $dirEnd) {
1479
- $et->WarnOnce("Truncated FPX $format value");
1479
+ $et->Warn("Truncated FPX $format value");
1480
1480
  last;
1481
1481
  }
1482
1482
  # sometimes VT_VECTOR items are padded to even 4-byte boundaries, and sometimes they aren't
@@ -1528,7 +1528,7 @@ sub ReadFPXValue($$$$$;$$)
1528
1528
  $len = Get32u($dataPt, $valPos);
1529
1529
  $len *= 2 if $format eq 'VT_LPWSTR'; # convert to byte count
1530
1530
  if ($valPos + $len + 4 > $dirEnd) {
1531
- $et->WarnOnce("Truncated $format value");
1531
+ $et->Warn("Truncated $format value");
1532
1532
  last;
1533
1533
  }
1534
1534
  $val = substr($$dataPt, $valPos + 4, $len);
@@ -1551,7 +1551,7 @@ sub ReadFPXValue($$$$$;$$)
1551
1551
  } elsif ($format eq 'VT_BLOB' or $format eq 'VT_CF') {
1552
1552
  my $len = Get32u($dataPt, $valPos); # (use local $len because we always expect padding)
1553
1553
  if ($valPos + $len + 4 > $dirEnd) {
1554
- $et->WarnOnce("Truncated $format value");
1554
+ $et->Warn("Truncated $format value");
1555
1555
  last;
1556
1556
  }
1557
1557
  $val = substr($$dataPt, $valPos + 4, $len);
@@ -1627,7 +1627,7 @@ sub ProcessContents($$$)
1627
1627
  while ($$dataPt =~ /\x0bTargetRole1(?:.\x80|\xff\xff.\0.\0Vn(\w+))\0\0\x01.{4}(.{24})/sg) {
1628
1628
  my ($index, @coords) = unpack('Vx4V4', $2);
1629
1629
  next if $index == 0xffffffff;
1630
- $$et{IeImg_lkup}{$index} and $et->WarnOnce('Duplicate image index');
1630
+ $$et{IeImg_lkup}{$index} and $et->Warn('Duplicate image index');
1631
1631
  $$et{IeImg_lkup}{$index} = "@coords";
1632
1632
  $$et{IeImg_class}{$index} = $1 if $1;
1633
1633
  }
@@ -1661,7 +1661,7 @@ sub ProcessWordDocument($$$)
1661
1661
  my $dirLen = length $$dataPt;
1662
1662
  # validate the FIB signature
1663
1663
  unless ($dirLen > 2 and Get16u($dataPt,0) == 0xa5ec) {
1664
- $et->WarnOnce('Invalid FIB signature', 1);
1664
+ $et->Warn('Invalid FIB signature', 1);
1665
1665
  return 0;
1666
1666
  }
1667
1667
  $et->ProcessBinaryData($dirInfo, $tagTablePtr); # process FIB
@@ -2098,7 +2098,7 @@ sub ProcessFPXR($$$)
2098
2098
  my $overlap = length($$obj{Stream}) - $offset;
2099
2099
  my $start = $dirStart + 13;
2100
2100
  if ($overlap < 0 or $dirLen - $overlap < 13) {
2101
- $et->WarnOnce("Bad FPXR stream $index offset",1);
2101
+ $et->Warn("Bad FPXR stream $index offset",1);
2102
2102
  } else {
2103
2103
  # ignore any overlapping data in this segment
2104
2104
  # (this seems to be the convention)
@@ -2338,7 +2338,7 @@ sub ProcessFPX($$)
2338
2338
  $tag =~ s/\0.*//s; # truncate at null (in case length was wrong)
2339
2339
 
2340
2340
  if ($tag eq '0' and not defined $ee) {
2341
- $et->WarnOnce('Use the ExtractEmbedded option to extract embedded information', 3);
2341
+ $et->Warn('Use the ExtractEmbedded option to extract embedded information', 3);
2342
2342
  }
2343
2343
  my $sect = Get32u(\$dir, $pos + 0x74); # start sector number
2344
2344
  my $size = Get32u(\$dir, $pos + 0x78); # stream length
@@ -2441,7 +2441,7 @@ sub ProcessFPX($$)
2441
2441
  my $subTablePtr = GetTagTable($$subdir{TagTable});
2442
2442
  $et->ProcessDirectory(\%dirInfo, $subTablePtr, $$subdir{ProcessProc});
2443
2443
  } elsif (defined $size and $size > length($buff)) {
2444
- $et->WarnOnce('Truncated object');
2444
+ $et->Warn('Truncated object');
2445
2445
  } else {
2446
2446
  $buff = substr($buff, 0, $size) if defined $size and $size < length($buff);
2447
2447
  if ($tag =~ /^IeImg_0*(\d+)$/) {
@@ -405,7 +405,7 @@ sub ProcessOTF($$)
405
405
  next;
406
406
  }
407
407
  if ($verbose) {
408
- $tag =~ s/([\0-\x1f\x80-\xff])/sprintf('\x%.2x',ord $1)/ge;
408
+ $tag =~ s/([\0-\x1f\x7f-\xff])/sprintf('\x%.2x',ord $1)/ge;
409
409
  my $str = sprintf("%s%d) Tag '%s' (offset 0x%.4x, %d bytes)\n",
410
410
  $$et{INDENT}, $pos/16, $tag, $offset, $size);
411
411
  $et->VPrint(0, $str);
@@ -225,7 +225,7 @@ sub ProcessHP($$$)
225
225
  # scan for other tag ID's
226
226
  foreach $tagID (sort(TagTableKeys($tagTablePtr))) {
227
227
  next if $tagID eq 'PreviewImage';
228
- next unless $$dataPt =~ /$tagID:\s*([\x20-\x7f]+)/i;
228
+ next unless $$dataPt =~ /$tagID:\s*([\x20-\x7e]+)/i;
229
229
  $et->HandleTag($tagTablePtr, $tagID, $1);
230
230
  }
231
231
  return 1;
@@ -1169,7 +1169,7 @@ sub ProcessID3v2($$$)
1169
1169
  }
1170
1170
  $tagInfo = $et->GetTagInfo($otherTable, $id) if $otherTable;
1171
1171
  if ($tagInfo) {
1172
- $et->WarnOnce("Frame '${id}' is not valid for this ID3 version", 1);
1172
+ $et->Warn("Frame '${id}' is not valid for this ID3 version", 1);
1173
1173
  } else {
1174
1174
  next unless $verbose or $et->Options('Unknown');
1175
1175
  $id =~ tr/-A-Za-z0-9_//dc;
@@ -1198,7 +1198,7 @@ sub ProcessID3v2($$$)
1198
1198
  }
1199
1199
  }
1200
1200
  if ($flags{Encrypt}) {
1201
- $et->WarnOnce('Encrypted frames currently not supported');
1201
+ $et->Warn('Encrypted frames currently not supported');
1202
1202
  next;
1203
1203
  }
1204
1204
  # extract the value
@@ -1232,7 +1232,7 @@ sub ProcessID3v2($$$)
1232
1232
  next;
1233
1233
  }
1234
1234
  } else {
1235
- $et->WarnOnce('Install Compress::Zlib to decode compressed frames');
1235
+ $et->Warn('Install Compress::Zlib to decode compressed frames');
1236
1236
  next;
1237
1237
  }
1238
1238
  }
@@ -1025,7 +1025,7 @@ sub TranslateCodedString($$$$)
1025
1025
  $$valPtr = $et->Decode($$valPtr, $$xlatPtr);
1026
1026
  } else {
1027
1027
  # don't yet support reading ISO 2022 shifted character sets
1028
- $et->WarnOnce('Some IPTC characters not converted (ISO 2022 shifting not supported)');
1028
+ $et->Warn('Some IPTC characters not converted (ISO 2022 shifting not supported)');
1029
1029
  }
1030
1030
  }
1031
1031
 
@@ -1164,7 +1164,7 @@ sub ProcessIPTC($$$)
1164
1164
  }
1165
1165
  my $tableInfo = $tagTablePtr->{$rec};
1166
1166
  unless ($tableInfo) {
1167
- $et->WarnOnce("Unrecognized IPTC record $rec (ignored)");
1167
+ $et->Warn("Unrecognized IPTC record $rec (ignored)");
1168
1168
  $pos += $len;
1169
1169
  next; # ignore this entry
1170
1170
  }
@@ -78,7 +78,7 @@ sub ProcessIND($$)
78
78
  $err = 'InDesign files larger than 2 GB not supported (LargeFileSupport not set)';
79
79
  goto DONE;
80
80
  } elsif ($et->Options('LargeFileSupport') eq '2') {
81
- $et->WarnOnce('Processing large file (LargeFileSupport is 2)');
81
+ $et->Warn('Processing large file (LargeFileSupport is 2)');
82
82
  }
83
83
  }
84
84
  if ($outfile) {
@@ -866,8 +866,8 @@ sub BrotliWarn($$;$)
866
866
  {
867
867
  my ($et, $type, $uncompress) = @_;
868
868
  my ($enc, $mod) = $uncompress ? qw(decoding Uncompress) : qw(encoding Compress);
869
- $et->WarnOnce("Error $enc '${type}' brob box");
870
- $et->WarnOnce("Try updating to IO::${mod}::Brotli 0.004 or later");
869
+ $et->Warn("Error $enc '${type}' brob box");
870
+ $et->Warn("Try updating to IO::${mod}::Brotli 0.004 or later");
871
871
  }
872
872
 
873
873
  #------------------------------------------------------------------------------
@@ -933,7 +933,7 @@ sub CreateNewBoxes($$)
933
933
  $tag = 'brob';
934
934
  }
935
935
  } else {
936
- $et->WarnOnce('Install IO::Compress::Brotli to create Brotli-compressed metadata');
936
+ $et->Warn('Install IO::Compress::Brotli to create Brotli-compressed metadata');
937
937
  }
938
938
  }
939
939
  my $boxhdr = pack('N', length($newdir) + length($pad) + 8) . $tag;
@@ -1285,7 +1285,7 @@ sub ProcessJpeg2000Box($$$)
1285
1285
  ++$$et{CHANGED};
1286
1286
  }
1287
1287
  } else {
1288
- $et->WarnOnce('Install IO::Compress::Brotli to write Brotli-compressed metadata');
1288
+ $et->Warn('Install IO::Compress::Brotli to write Brotli-compressed metadata');
1289
1289
  }
1290
1290
  } elsif (not $compress and $boxID eq 'brob') {
1291
1291
  # (in this case, ProcessBrotli has returned uncompressed data,
@@ -1410,7 +1410,7 @@ sub ProcessBrotli($$$)
1410
1410
  }
1411
1411
  if (eval { require IO::Uncompress::Brotli }) {
1412
1412
  if ($isWriting and not eval { require IO::Compress::Brotli }) {
1413
- $et->WarnOnce('Install IO::Compress::Brotli to write Brotli-compressed metadata');
1413
+ $et->Warn('Install IO::Compress::Brotli to write Brotli-compressed metadata');
1414
1414
  return undef;
1415
1415
  }
1416
1416
  my $compress = $et->Options('Compress');
@@ -1455,7 +1455,7 @@ sub ProcessBrotli($$$)
1455
1455
  return $type . $dat;
1456
1456
  }
1457
1457
  } else {
1458
- $et->WarnOnce('Install IO::Uncompress::Brotli to decode Brotli-compressed metadata');
1458
+ $et->Warn('Install IO::Uncompress::Brotli to decode Brotli-compressed metadata');
1459
1459
  return undef if $isWriting;
1460
1460
  }
1461
1461
  return 1;
@@ -32,7 +32,7 @@ use strict;
32
32
  use vars qw($VERSION);
33
33
  use Image::ExifTool qw(:DataAccess :Utils);
34
34
 
35
- $VERSION = '1.26';
35
+ $VERSION = '1.28';
36
36
 
37
37
  # program map table "stream_type" lookup (ref 6/1/9)
38
38
  my %streamType = (
@@ -305,6 +305,15 @@ sub ParsePID($$$$$)
305
305
  # MPEG-1/MPEG-2 Audio
306
306
  require Image::ExifTool::MPEG;
307
307
  Image::ExifTool::MPEG::ParseMPEGAudio($et, $dataPt);
308
+ } elsif ($type == 6 and $pid == 0x0300) {
309
+ # LIGOGPSINFO from unknown dashcam (../testpics/gps_video/Wrong Way pass.ts)
310
+ if ($$dataPt =~ /^LIGOGPSINFO/s) {
311
+ my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
312
+ my %dirInfo = ( DataPt => $dataPt, DirName => 'Ligo0x0300' );
313
+ Image::ExifTool::QuickTime::ProcessLigoGPS($et, \%dirInfo, $tbl, 1);
314
+ $$et{FoundGoodGPS} = 1;
315
+ $more = 1;
316
+ }
308
317
  } elsif ($type == 0x1b) {
309
318
  # H.264 Video
310
319
  require Image::ExifTool::H264;
@@ -313,7 +322,7 @@ sub ParsePID($$$$$)
313
322
  if ($$et{OPTIONS}{ExtractEmbedded}) {
314
323
  $more = 1;
315
324
  } elsif (not $$et{OPTIONS}{Validate}) {
316
- $et->WarnOnce('The ExtractEmbedded option may find more tags in the video data',3);
325
+ $et->Warn('The ExtractEmbedded option may find more tags in the video data',3);
317
326
  }
318
327
  } elsif ($type == 0x81 or $type == 0x87 or $type == 0x91) {
319
328
  # AC-3 audio
@@ -459,11 +468,11 @@ sub ParsePID($$$$$)
459
468
  $bad = 1 if $_ < 0x30 or $_ > 0x39;
460
469
  }
461
470
  if ($bad) {
462
- $et->WarnOnce('Error decrypting GPS degrees');
471
+ $et->Warn('Error decrypting GPS degrees');
463
472
  } else {
464
473
  my $la = pack('C*', @chars[0,1]);
465
474
  my $lo = pack('C*', @chars[2,3,4]);
466
- $et->WarnOnce('Decryption of this GPS is highly experimental. More testing samples are required');
475
+ $et->Warn('Decryption of this GPS is highly experimental. More testing samples are required');
467
476
  $et->HandleTag($tagTbl, GPSLatitude => (($la || 0) + (($6-85.95194)/2.43051724137931+42.2568)/60) * ($7 eq 'N' ? 1 : -1));
468
477
  $et->HandleTag($tagTbl, GPSLongitude => (($lo || 0) + (($9-70.14674)/1.460987654320988+9.2028)/60) * ($10 eq 'E' ? 1 : -1));
469
478
  }
@@ -476,7 +485,7 @@ sub ParsePID($$$$$)
476
485
  my $lon = abs(GetFloat($dataPt, 56)); # (abs just to be safe)
477
486
  my $spd = GetFloat($dataPt, 64);
478
487
  my $trk = GetFloat($dataPt, 68);
479
- $et->WarnOnce('GPSLatitude/Longitude encryption is not yet known, so these will be wrong');
488
+ $et->Warn('GPSLatitude/Longitude encryption is not yet known, so these will be wrong');
480
489
  $$et{DOC_NUM} = ++$$et{DOC_COUNT};
481
490
  my @date = unpack('x32V3x28V3', $$dataPt);
482
491
  $date[3] += 2000;
@@ -514,9 +523,16 @@ sub ParsePID($$$$$)
514
523
  $et->HandleTag($tagTbl, GPSTrack => $a[2] / 100);
515
524
  }
516
525
  # Note: 10 bytes after last GPS record look like a single 3-axis accelerometer reading:
517
- # eg. fd ff 00 00 ff ff 00 00 01 00
526
+ # eg. fd ff 00 00 ff ff 00 00 01 00
518
527
  $$et{FoundGoodGPS} = 1; # so we skip over unrecognized packets
519
528
  $more = 1;
529
+ } elsif ($$dataPt =~ /^skip.{4}LIGOGPSINFO\0/s) {
530
+ # (this record contains 2 copies of the same 'skip' atom in my sample --
531
+ # only extract data from the first one)
532
+ my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
533
+ my %dirInfo = ( DataPt => $dataPt, DirStart => 8, DirName => sprintf('Ligo0x%.4x',$pid));
534
+ Image::ExifTool::QuickTime::ProcessLigoGPS($et, \%dirInfo, $tbl, 1);
535
+ $$et{FoundGoodGPS} = 1;
520
536
  } elsif ($$et{FoundGoodGPS}) {
521
537
  $more = 1;
522
538
  }
@@ -694,7 +710,7 @@ sub ProcessM2TS($$)
694
710
  # or if we are just looking for the last timestamp
695
711
  next unless $payload_data_exists and not defined $backScan;
696
712
 
697
- # decode payload data
713
+ # decode payload data
698
714
  if ($pid == 0 or # program association table
699
715
  defined $pmt{$pid}) # program map table(s)
700
716
  {
@@ -787,7 +803,7 @@ sub ProcessM2TS($$)
787
803
  last if $j + $descriptor_length > $program_info_length;
788
804
  my $desc = substr($buf2, $pos+$j, $descriptor_length);
789
805
  $j += $descriptor_length;
790
- $desc =~ s/([\x00-\x1f\x80-\xff])/sprintf("\\x%.2x",ord $1)/eg;
806
+ $desc =~ s/([\x00-\x1f\x7f-\xff])/sprintf("\\x%.2x",ord $1)/eg;
791
807
  printf $out " Program Descriptor: Type=0x%.2x \"$desc\"\n", $descriptor_tag;
792
808
  }}
793
809
  $pos += $program_info_length; # skip descriptors (for now)
@@ -822,7 +838,7 @@ sub ProcessM2TS($$)
822
838
  $j += $descriptor_length;
823
839
  if ($verbose > 1) {
824
840
  my $dstr = $desc;
825
- $dstr =~ s/([\x00-\x1f\x80-\xff])/sprintf("\\x%.2x",ord $1)/eg;
841
+ $dstr =~ s/([\x00-\x1f\x7f-\xff])/sprintf("\\x%.2x",ord $1)/eg;
826
842
  printf $out " ES Descriptor: Type=0x%.2x \"$dstr\"\n", $descriptor_tag;
827
843
  }
828
844
  # parse type-specific descriptor information (once)
@@ -954,6 +970,20 @@ sub ProcessM2TS($$)
954
970
  ParsePID($et, $pid, $pidType{$pid}, $pidName{$pid}, \$data{$pid});
955
971
  delete $data{$pid};
956
972
  }
973
+
974
+ # look for LIGOGPSINFO trailer
975
+ if ($et->Options('ExtractEmbedded') and
976
+ $raf->Seek(-8, 2) and $raf->Read($buff, 8) == 8 and
977
+ $buff =~ /^&&&&/)
978
+ {
979
+ my $len = unpack('x4N', $buff);
980
+ if ($len < $raf->Tell() and $raf->Seek(-$len, 2) and $raf->Read($buff,$len) == $len) {
981
+ my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
982
+ my %dirInfo = ( DataPt => \$buff, DirStart => 8, DirName => 'LigoTrailer' );
983
+ Image::ExifTool::QuickTime::ProcessLigoGPS($et, \%dirInfo, $tbl);
984
+ }
985
+ }
986
+
957
987
  return 1;
958
988
  }
959
989