exiftool_vendored 13.06.0 → 13.08.0

Sign up to get free protection for your applications and to get access to all the features.
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