exiftool_vendored 12.25.0 → 12.35.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +174 -7
  3. data/bin/MANIFEST +11 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +44 -43
  7. data/bin/arg_files/xmp2exif.args +2 -1
  8. data/bin/config_files/convert_regions.config +25 -14
  9. data/bin/config_files/example.config +1 -1
  10. data/bin/exiftool +118 -92
  11. data/bin/fmt_files/gpx.fmt +1 -1
  12. data/bin/fmt_files/gpx_wpt.fmt +1 -1
  13. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +16 -3
  14. data/bin/lib/Image/ExifTool/CBOR.pm +331 -0
  15. data/bin/lib/Image/ExifTool/Canon.pm +52 -20
  16. data/bin/lib/Image/ExifTool/Charset.pm +2 -0
  17. data/bin/lib/Image/ExifTool/DPX.pm +13 -2
  18. data/bin/lib/Image/ExifTool/Exif.pm +107 -8
  19. data/bin/lib/Image/ExifTool/FLIR.pm +33 -8
  20. data/bin/lib/Image/ExifTool/FlashPix.pm +35 -10
  21. data/bin/lib/Image/ExifTool/FujiFilm.pm +1 -0
  22. data/bin/lib/Image/ExifTool/Geotag.pm +13 -2
  23. data/bin/lib/Image/ExifTool/GoPro.pm +16 -1
  24. data/bin/lib/Image/ExifTool/ICC_Profile.pm +96 -4
  25. data/bin/lib/Image/ExifTool/ID3.pm +15 -3
  26. data/bin/lib/Image/ExifTool/JPEG.pm +68 -2
  27. data/bin/lib/Image/ExifTool/JSON.pm +7 -3
  28. data/bin/lib/Image/ExifTool/Jpeg2000.pm +164 -36
  29. data/bin/lib/Image/ExifTool/LIF.pm +153 -0
  30. data/bin/lib/Image/ExifTool/Lang/nl.pm +60 -59
  31. data/bin/lib/Image/ExifTool/M2TS.pm +103 -7
  32. data/bin/lib/Image/ExifTool/MIE.pm +2 -1
  33. data/bin/lib/Image/ExifTool/MRC.pm +1 -1
  34. data/bin/lib/Image/ExifTool/MacOS.pm +2 -2
  35. data/bin/lib/Image/ExifTool/Nikon.pm +50 -6
  36. data/bin/lib/Image/ExifTool/NikonSettings.pm +10 -2
  37. data/bin/lib/Image/ExifTool/Olympus.pm +9 -2
  38. data/bin/lib/Image/ExifTool/Other.pm +93 -0
  39. data/bin/lib/Image/ExifTool/PDF.pm +11 -12
  40. data/bin/lib/Image/ExifTool/PNG.pm +7 -6
  41. data/bin/lib/Image/ExifTool/Panasonic.pm +14 -2
  42. data/bin/lib/Image/ExifTool/Pentax.pm +28 -5
  43. data/bin/lib/Image/ExifTool/Photoshop.pm +6 -0
  44. data/bin/lib/Image/ExifTool/QuickTime.pm +123 -25
  45. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +203 -121
  46. data/bin/lib/Image/ExifTool/README +9 -2
  47. data/bin/lib/Image/ExifTool/RIFF.pm +7 -2
  48. data/bin/lib/Image/ExifTool/Samsung.pm +47 -10
  49. data/bin/lib/Image/ExifTool/Sony.pm +113 -42
  50. data/bin/lib/Image/ExifTool/TagLookup.pm +4599 -4451
  51. data/bin/lib/Image/ExifTool/TagNames.pod +276 -41
  52. data/bin/lib/Image/ExifTool/Torrent.pm +18 -11
  53. data/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
  54. data/bin/lib/Image/ExifTool/WritePDF.pl +1 -0
  55. data/bin/lib/Image/ExifTool/WritePNG.pl +2 -0
  56. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +21 -4
  57. data/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
  58. data/bin/lib/Image/ExifTool/Writer.pl +47 -2
  59. data/bin/lib/Image/ExifTool/XMP.pm +32 -12
  60. data/bin/lib/Image/ExifTool/XMP2.pl +5 -2
  61. data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
  62. data/bin/lib/Image/ExifTool/ZISRAW.pm +121 -2
  63. data/bin/lib/Image/ExifTool.pm +153 -52
  64. data/bin/lib/Image/ExifTool.pod +70 -60
  65. data/bin/perl-Image-ExifTool.spec +43 -42
  66. data/lib/exiftool_vendored/version.rb +1 -1
  67. metadata +6 -3
@@ -56,7 +56,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
56
56
  use Image::ExifTool qw(:DataAccess :Utils);
57
57
  use Image::ExifTool::MakerNotes;
58
58
 
59
- $VERSION = '4.34';
59
+ $VERSION = '4.37';
60
60
 
61
61
  sub ProcessExif($$$);
62
62
  sub WriteExif($$$);
@@ -265,6 +265,7 @@ sub BINARY_DATA_LIMIT { return 10 * 1024 * 1024; }
265
265
  32892 => 'Sequential Color Filter', #JR (Sony ARQ)
266
266
  34892 => 'Linear Raw', #2
267
267
  51177 => 'Depth Map', # (DNG 1.5)
268
+ 52527 => 'Semantic Mask', # (DNG 1.6)
268
269
  );
269
270
 
270
271
  %orientation = (
@@ -291,6 +292,7 @@ sub BINARY_DATA_LIMIT { return 10 * 1024 * 1024; }
291
292
  9 => 'Depth map of reduced-resolution image', # (DNG 1.5)
292
293
  16 => 'Enhanced image data', # (DNG 1.5)
293
294
  0x10001 => 'Alternate reduced-resolution image', # (DNG 1.2)
295
+ 0x10004 => 'Semantic Mask', # (DNG 1.6)
294
296
  0xffffffff => 'invalid', #(found in E5700 NEF's)
295
297
  BITMASK => {
296
298
  0 => 'Reduced resolution',
@@ -366,6 +368,7 @@ my %opcodeInfo = (
366
368
  11 => 'DeltaPerColumn',
367
369
  12 => 'ScalePerRow',
368
370
  13 => 'ScalePerColumn',
371
+ 14 => 'WarpRectilinear2', # (DNG 1.6)
369
372
  },
370
373
  PrintConvInv => undef, # (so the inverse conversion is not performed)
371
374
  );
@@ -2581,7 +2584,7 @@ my %opcodeInfo = (
2581
2584
  0xa301 => {
2582
2585
  Name => 'SceneType',
2583
2586
  Writable => 'undef',
2584
- ValueConvInv => 'chr($val)',
2587
+ ValueConvInv => 'chr($val & 0xff)',
2585
2588
  PrintConv => {
2586
2589
  1 => 'Directly photographed',
2587
2590
  },
@@ -3038,12 +3041,12 @@ my %opcodeInfo = (
3038
3041
  },
3039
3042
  },
3040
3043
  #
3041
- # DNG tags 0xc6XX and 0xc7XX (ref 2 unless otherwise stated)
3044
+ # DNG tags 0xc6XX, 0xc7XX and 0xcdXX (ref 2 unless otherwise stated)
3042
3045
  #
3043
3046
  0xc612 => {
3044
3047
  Name => 'DNGVersion',
3045
3048
  Notes => q{
3046
- tags 0xc612-0xc7b5 are defined by the DNG specification unless otherwise
3049
+ tags 0xc612-0xcd3b are defined by the DNG specification unless otherwise
3047
3050
  noted. See L<https://helpx.adobe.com/photoshop/digital-negative.html> for
3048
3051
  the specification
3049
3052
  },
@@ -4041,6 +4044,97 @@ my %opcodeInfo = (
4041
4044
  Protected => 1,
4042
4045
  WriteGroup => 'IFD0',
4043
4046
  },
4047
+ 0xcd2d => { # DNG 1.6
4048
+ Name => 'ProfileGainTableMap',
4049
+ Writable => 'undef',
4050
+ WriteGroup => 'SubIFD',
4051
+ Protected => 1,
4052
+ Binary => 1,
4053
+ },
4054
+ 0xcd2e => { # DNG 1.6
4055
+ Name => 'SemanticName',
4056
+ # Writable => 'string',
4057
+ WriteGroup => 'SubIFD' #? (NC) Semantic Mask IFD (only for Validate)
4058
+ },
4059
+ 0xcd30 => { # DNG 1.6
4060
+ Name => 'SemanticInstanceIFD',
4061
+ # Writable => 'string',
4062
+ WriteGroup => 'SubIFD' #? (NC) Semantic Mask IFD (only for Validate)
4063
+ },
4064
+ 0xcd31 => { # DNG 1.6
4065
+ Name => 'CalibrationIlluminant3',
4066
+ Writable => 'int16u',
4067
+ WriteGroup => 'IFD0',
4068
+ Protected => 1,
4069
+ SeparateTable => 'LightSource',
4070
+ PrintConv => \%lightSource,
4071
+ },
4072
+ 0xcd32 => { # DNG 1.6
4073
+ Name => 'CameraCalibration3',
4074
+ Writable => 'rational64s',
4075
+ WriteGroup => 'IFD0',
4076
+ Count => -1,
4077
+ Protected => 1,
4078
+ },
4079
+ 0xcd33 => { # DNG 1.6
4080
+ Name => 'ColorMatrix3',
4081
+ Writable => 'rational64s',
4082
+ WriteGroup => 'IFD0',
4083
+ Count => -1,
4084
+ Protected => 1,
4085
+ },
4086
+ 0xcd34 => { # DNG 1.6
4087
+ Name => 'ForwardMatrix3',
4088
+ Writable => 'rational64s',
4089
+ WriteGroup => 'IFD0',
4090
+ Count => -1,
4091
+ Protected => 1,
4092
+ },
4093
+ 0xcd35 => { # DNG 1.6
4094
+ Name => 'IlluminantData1',
4095
+ Writable => 'undef',
4096
+ WriteGroup => 'IFD0',
4097
+ Protected => 1,
4098
+ },
4099
+ 0xcd36 => { # DNG 1.6
4100
+ Name => 'IlluminantData2',
4101
+ Writable => 'undef',
4102
+ WriteGroup => 'IFD0',
4103
+ Protected => 1,
4104
+ },
4105
+ 0xcd37 => { # DNG 1.6
4106
+ Name => 'IlluminantData3',
4107
+ Writable => 'undef',
4108
+ WriteGroup => 'IFD0',
4109
+ Protected => 1,
4110
+ },
4111
+ 0xcd38 => { # DNG 1.6
4112
+ Name => 'MaskSubArea',
4113
+ # Writable => 'int32u',
4114
+ WriteGroup => 'SubIFD', #? (NC) Semantic Mask IFD (only for Validate)
4115
+ Count => 4,
4116
+ },
4117
+ 0xcd39 => { # DNG 1.6
4118
+ Name => 'ProfileHueSatMapData3',
4119
+ %longBin,
4120
+ Writable => 'float',
4121
+ WriteGroup => 'IFD0',
4122
+ Count => -1,
4123
+ Protected => 1,
4124
+ },
4125
+ 0xcd3a => { # DNG 1.6
4126
+ Name => 'ReductionMatrix3',
4127
+ Writable => 'rational64s',
4128
+ WriteGroup => 'IFD0',
4129
+ Count => -1,
4130
+ Protected => 1,
4131
+ },
4132
+ 0xcd3b => { # DNG 1.6
4133
+ Name => 'RGBTables',
4134
+ Writable => 'undef',
4135
+ WriteGroup => 'IFD0',
4136
+ Protected => 1,
4137
+ },
4044
4138
  0xea1c => { #13
4045
4139
  Name => 'Padding',
4046
4140
  Binary => 1,
@@ -5918,7 +6012,7 @@ sub ProcessExif($$$)
5918
6012
  my $size = $count * $formatSize[$format];
5919
6013
  my $readSize = $size;
5920
6014
  if ($size > 4) {
5921
- if ($size > 0x7fffffff) {
6015
+ if ($size > 0x7fffffff and (not $tagInfo or not $$tagInfo{ReadFromRAF})) {
5922
6016
  $et->Warn(sprintf("Invalid size (%u) for %s %s",$size,$dir,TagName($tagID,$tagInfo)), $inMakerNotes);
5923
6017
  ++$warnCount;
5924
6018
  next;
@@ -6171,18 +6265,23 @@ sub ProcessExif($$$)
6171
6265
  unless ($bad) {
6172
6266
  # limit maximum length of data to reformat
6173
6267
  # (avoids long delays when processing some corrupted files)
6268
+ my $warned;
6174
6269
  if ($count > 100000 and $formatStr !~ /^(undef|string|binary)$/) {
6175
6270
  my $tagName = $tagInfo ? $$tagInfo{Name} : sprintf('tag 0x%.4x', $tagID);
6176
6271
  # (count of 196608 is typical for ColorMap)
6177
6272
  if ($tagName ne 'TransferFunction' or $count != 196608) {
6178
6273
  my $minor = $count > 2000000 ? 0 : 2;
6179
- next if $et->Warn("Ignoring $dirName $tagName with excessive count", $minor);
6274
+ if ($et->Warn("Ignoring $dirName $tagName with excessive count", $minor)) {
6275
+ next unless $$et{OPTIONS}{HtmlDump};
6276
+ $warned = 1;
6277
+ }
6180
6278
  }
6181
6279
  }
6182
6280
  if ($count > 500 and $formatStr !~ /^(undef|string|binary)$/ and
6183
- (not $tagInfo or $$tagInfo{LongBinary}) and not $$et{OPTIONS}{IgnoreMinorErrors})
6281
+ (not $tagInfo or $$tagInfo{LongBinary} or $warned) and not $$et{OPTIONS}{IgnoreMinorErrors})
6184
6282
  {
6185
- $et->WarnOnce('Not decoding some large array(s). Ignore minor errors to decode', 2);
6283
+ $et->WarnOnce('Not decoding some large array(s). Ignore minor errors to decode', 2) unless $warned;
6284
+ next if $$et{TAGS_FROM_FILE}; # don't generate bogus value when copying tags
6186
6285
  $val = "(large array of $count $formatStr values)";
6187
6286
  } else {
6188
6287
  # convert according to specified format
@@ -24,7 +24,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
24
24
  use Image::ExifTool::Exif;
25
25
  use Image::ExifTool::GPS;
26
26
 
27
- $VERSION = '1.18';
27
+ $VERSION = '1.19';
28
28
 
29
29
  sub ProcessFLIR($$;$);
30
30
  sub ProcessFLIRText($$$);
@@ -99,7 +99,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' );
99
99
  NOTES => q{
100
100
  Information extracted from FLIR FFF images and the APP1 FLIR segment of JPEG
101
101
  images. These tags may also be extracted from the first frame of an FLIR
102
- SEQ file.
102
+ SEQ file, or all frames if the ExtractEmbedded option is used.
103
103
  },
104
104
  "_header" => {
105
105
  Name => 'FFFHeader',
@@ -1457,6 +1457,7 @@ sub ProcessFLIR($$;$)
1457
1457
  my $raf = $$dirInfo{RAF} || new File::RandomAccess($$dirInfo{DataPt});
1458
1458
  my $verbose = $et->Options('Verbose');
1459
1459
  my $out = $et->Options('TextOut');
1460
+ my $base = $raf->Tell();
1460
1461
  my ($i, $hdr, $buff, $rec);
1461
1462
 
1462
1463
  # read and verify FFF header
@@ -1485,15 +1486,18 @@ sub ProcessFLIR($$;$)
1485
1486
  my $ver = Get32u(\$hdr, 0x14);
1486
1487
  last if $ver >= 100 and $ver < 200; # (have seen 100 and 101 - PH)
1487
1488
  ToggleByteOrder();
1488
- $i and $et->Warn("Unsupported FLIR $type version"), return 1;
1489
+ next unless $i;
1490
+ return 0 if $$et{DOC_NUM};
1491
+ $et->Warn("Unsupported FLIR $type version");
1492
+ return 1;
1489
1493
  }
1490
1494
 
1491
1495
  # read the FLIR record directory
1492
1496
  my $pos = Get32u(\$hdr, 0x18);
1493
1497
  my $num = Get32u(\$hdr, 0x1c);
1494
- unless ($raf->Seek($pos) and $raf->Read($buff, $num * 0x20) == $num * 0x20) {
1498
+ unless ($raf->Seek($base+$pos) and $raf->Read($buff, $num * 0x20) == $num * 0x20) {
1495
1499
  $et->Warn('Truncated FLIR FFF directory');
1496
- return 1;
1500
+ return $$et{DOC_NUM} ? 0 : 1;
1497
1501
  }
1498
1502
 
1499
1503
  unless ($tagTablePtr) {
@@ -1504,6 +1508,7 @@ sub ProcessFLIR($$;$)
1504
1508
  # process the header data
1505
1509
  $et->HandleTag($tagTablePtr, '_header', $hdr);
1506
1510
 
1511
+ my $success = 1;
1507
1512
  my $oldIndent = $$et{INDENT};
1508
1513
  $$et{INDENT} .= '| ';
1509
1514
  $et->VerboseDir($type, $num);
@@ -1533,12 +1538,22 @@ sub ProcessFLIR($$;$)
1533
1538
  $verbose and printf $out "%s%d) FLIR Record 0x%.2x, offset 0x%.4x, length 0x%.4x\n",
1534
1539
  $$et{INDENT}, $i, $recType, $recPos, $recLen;
1535
1540
 
1536
- unless ($raf->Seek($recPos) and $raf->Read($rec, $recLen) == $recLen) {
1537
- $et->Warn('Invalid FLIR record');
1541
+ # skip RawData records for embedded documents
1542
+ if ($recType == 1 and $$et{DOC_NUM}) {
1543
+ $raf->Seek($base+$recPos+$recLen) or $success = 0, last;
1544
+ next;
1545
+ }
1546
+ unless ($raf->Seek($base+$recPos) and $raf->Read($rec, $recLen) == $recLen) {
1547
+ if ($$et{DOC_NUM}) {
1548
+ $success = 0; # abort processing more documents
1549
+ } else {
1550
+ $et->Warn('Invalid FLIR record');
1551
+ }
1538
1552
  last;
1539
1553
  }
1540
1554
  if ($$tagTablePtr{$recType}) {
1541
1555
  $et->HandleTag($tagTablePtr, $recType, undef,
1556
+ Base => $base,
1542
1557
  DataPt => \$rec,
1543
1558
  DataPos => $recPos,
1544
1559
  Start => 0,
@@ -1550,7 +1565,17 @@ sub ProcessFLIR($$;$)
1550
1565
  }
1551
1566
  delete $$et{SET_GROUP0};
1552
1567
  $$et{INDENT} = $oldIndent;
1553
- return 1;
1568
+
1569
+ # extract information from subsequent frames in SEQ file if ExtractEmbedded is used
1570
+ if ($$dirInfo{RAF} and $et->Options('ExtractEmbedded') and not $$et{DOC_NUM}) {
1571
+ for (;;) {
1572
+ $$et{DOC_NUM} = $$et{DOC_COUNT} + 1;
1573
+ last unless ProcessFLIR($et, $dirInfo, $tagTablePtr);
1574
+ # (DOC_COUNT will be incremented automatically if we extracted any tags)
1575
+ }
1576
+ delete $$et{DOC_NUM};
1577
+ }
1578
+ return $success;
1554
1579
  }
1555
1580
 
1556
1581
  #------------------------------------------------------------------------------
@@ -21,7 +21,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
21
21
  use Image::ExifTool::Exif;
22
22
  use Image::ExifTool::ASF; # for GetGUID()
23
23
 
24
- $VERSION = '1.38';
24
+ $VERSION = '1.39';
25
25
 
26
26
  sub ProcessFPX($$);
27
27
  sub ProcessFPXR($$$);
@@ -1369,29 +1369,48 @@ sub ReadFPXValue($$$$$;$$)
1369
1369
  my $flags = $type & 0xf000;
1370
1370
  if ($flags) {
1371
1371
  if ($flags == VT_VECTOR) {
1372
- $noPad = 1; # values don't seem to be padded inside vectors
1372
+ $noPad = 1; # values sometimes aren't padded inside vectors!!
1373
1373
  my $size = $oleFormatSize{VT_VECTOR};
1374
- last if $valPos + $size > $dirEnd;
1374
+ if ($valPos + $size > $dirEnd) {
1375
+ $et->WarnOnce('Incorrect FPX VT_VECTOR size');
1376
+ last;
1377
+ }
1375
1378
  $count = Get32u($dataPt, $valPos);
1376
1379
  push @vals, '' if $count == 0; # allow zero-element vector
1377
1380
  $valPos += 4;
1378
1381
  } else {
1379
1382
  # can't yet handle this property flag
1383
+ $et->WarnOnce('Unknown FPX property');
1380
1384
  last;
1381
1385
  }
1382
1386
  }
1383
1387
  unless ($format =~ /^VT_/) {
1384
1388
  my $size = Image::ExifTool::FormatSize($format) * $count;
1385
- last if $valPos + $size > $dirEnd;
1389
+ if ($valPos + $size > $dirEnd) {
1390
+ $et->WarnOnce("Incorrect FPX $format size");
1391
+ last;
1392
+ }
1386
1393
  @vals = ReadValue($dataPt, $valPos, $format, $count, $size);
1387
1394
  # update position to end of value plus padding
1388
1395
  $valPos += ($count * $size + 3) & 0xfffffffc;
1389
1396
  last;
1390
1397
  }
1391
1398
  my $size = $oleFormatSize{$format};
1392
- my ($item, $val);
1399
+ my ($item, $val, $len);
1393
1400
  for ($item=0; $item<$count; ++$item) {
1394
- last if $valPos + $size > $dirEnd;
1401
+ if ($valPos + $size > $dirEnd) {
1402
+ $et->WarnOnce("Truncated FPX $format value");
1403
+ last;
1404
+ }
1405
+ # sometimes VT_VECTOR items are padded to even 4-byte boundaries, and sometimes they aren't
1406
+ if ($noPad and defined $len and $len & 0x03) {
1407
+ my $pad = 4 - ($len & 0x03);
1408
+ if ($valPos + $pad + $size <= $dirEnd) {
1409
+ # skip padding if all zeros
1410
+ $valPos += $pad if substr($$dataPt, $valPos, $pad) eq "\0" x $pad;
1411
+ }
1412
+ }
1413
+ undef $len;
1395
1414
  if ($format eq 'VT_VARIANT') {
1396
1415
  my $subType = Get32u($dataPt, $valPos);
1397
1416
  $valPos += $size;
@@ -1429,9 +1448,12 @@ sub ReadFPXValue($$$$$;$$)
1429
1448
  $val = ($val - 25569) * 24 * 3600 if $val != 0;
1430
1449
  $val = Image::ExifTool::ConvertUnixTime($val);
1431
1450
  } elsif ($format =~ /STR$/) {
1432
- my $len = Get32u($dataPt, $valPos);
1451
+ $len = Get32u($dataPt, $valPos);
1433
1452
  $len *= 2 if $format eq 'VT_LPWSTR'; # convert to byte count
1434
- last if $valPos + $len + 4 > $dirEnd;
1453
+ if ($valPos + $len + 4 > $dirEnd) {
1454
+ $et->WarnOnce("Truncated $format value");
1455
+ last;
1456
+ }
1435
1457
  $val = substr($$dataPt, $valPos + 4, $len);
1436
1458
  if ($format eq 'VT_LPWSTR') {
1437
1459
  # convert wide string from Unicode
@@ -1450,8 +1472,11 @@ sub ReadFPXValue($$$$$;$$)
1450
1472
  # on even 32-bit boundaries, but this isn't always the case)
1451
1473
  $valPos += $noPad ? $len : ($len + 3) & 0xfffffffc;
1452
1474
  } elsif ($format eq 'VT_BLOB' or $format eq 'VT_CF') {
1453
- my $len = Get32u($dataPt, $valPos);
1454
- last if $valPos + $len + 4 > $dirEnd;
1475
+ my $len = Get32u($dataPt, $valPos); # (use local $len because we always expect padding)
1476
+ if ($valPos + $len + 4 > $dirEnd) {
1477
+ $et->WarnOnce("Truncated $format value");
1478
+ last;
1479
+ }
1455
1480
  $val = substr($$dataPt, $valPos + 4, $len);
1456
1481
  # update position for data length plus padding
1457
1482
  # (does this padding disappear in arrays too?)
@@ -489,6 +489,7 @@ my %faceCategories = (
489
489
  3 => 'Electronic Front Curtain', #10
490
490
  },
491
491
  },
492
+ # 0x1100 - This may not work well for newer cameras (ref forum12682)
492
493
  0x1100 => [{
493
494
  Name => 'AutoBracketing',
494
495
  Condition => '$$self{Model} eq "X-T3"',
@@ -28,7 +28,7 @@ use vars qw($VERSION);
28
28
  use Image::ExifTool qw(:Public);
29
29
  use Image::ExifTool::GPS;
30
30
 
31
- $VERSION = '1.64';
31
+ $VERSION = '1.65';
32
32
 
33
33
  sub JITTER() { return 2 } # maximum time jitter
34
34
 
@@ -262,8 +262,10 @@ sub LoadTrackLog($$;$)
262
262
  $param = 'time';
263
263
  } elsif (/^(Pos)?Lat/i) {
264
264
  $param = 'lat';
265
+ /ref$/i and $param .= 'ref';
265
266
  } elsif (/^(Pos)?Lon/i) {
266
267
  $param = 'lon';
268
+ /ref$/i and $param .= 'ref';
267
269
  } elsif (/^(Pos)?Alt/i) {
268
270
  $param = 'alt';
269
271
  } elsif (/^(Angle)?(Heading|Track)/i) {
@@ -453,7 +455,7 @@ DoneFix: $isDate = 1;
453
455
  # (ExifTool enhancements allow for standard tag names or descriptions as the column headings,
454
456
  # add support for time zones and flexible coordinates, and allow new DateTime and Shift columns)
455
457
  #
456
- my ($param, $date, $secs);
458
+ my ($param, $date, $secs, %neg);
457
459
  foreach $param (@csvHeadings) {
458
460
  my $val = shift @vals;
459
461
  last unless defined $val;
@@ -479,6 +481,10 @@ DoneFix: $isDate = 1;
479
481
  }
480
482
  } elsif ($param eq 'lat' or $param eq 'lon') {
481
483
  $$fix{$param} = Image::ExifTool::GPS::ToDegrees($val, 1);
484
+ } elsif ($param eq 'latref') {
485
+ $neg{lat} = 1 if $val =~ /^S/i;
486
+ } elsif ($param eq 'lonref') {
487
+ $neg{lon} = 1 if $val =~ /^W/i;
482
488
  } elsif ($param eq 'runtime') {
483
489
  $date = $trackTime;
484
490
  $secs = $val;
@@ -486,6 +492,11 @@ DoneFix: $isDate = 1;
486
492
  $$fix{$param} = $val;
487
493
  }
488
494
  }
495
+ # make coordinate negative according to reference direction if necessary
496
+ foreach $param (keys %neg) {
497
+ next unless defined $$fix{$param};
498
+ $$fix{$param} = -abs($$fix{$param});
499
+ }
489
500
  if ($date and defined $secs and defined $$fix{lat} and defined $$fix{lon}) {
490
501
  $time = $date + $secs;
491
502
  $$has{alt} = 1 if defined $$fix{alt};
@@ -16,7 +16,7 @@ use vars qw($VERSION);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
  use Image::ExifTool::QuickTime;
18
18
 
19
- $VERSION = '1.06';
19
+ $VERSION = '1.07';
20
20
 
21
21
  sub ProcessGoPro($$$);
22
22
  sub ProcessString($$$);
@@ -386,6 +386,21 @@ my %addUnits = (
386
386
  Binary => 1,
387
387
  },
388
388
  # ZFOV (APP6,GPMF) - seen: 148.34, 0 (fmt f, Hero8, Max)
389
+ # the following ref forum12825
390
+ MUID => {
391
+ Name => 'MediaUniqueID',
392
+ PrintConv => q{
393
+ my @a = split ' ', $val;
394
+ $_ = sprintf('%.8x',$_) foreach @a;
395
+ return join('', @a);
396
+ },
397
+ },
398
+ EXPT => 'MaximumShutterAngle',
399
+ MTRX => 'AccelerometerMatrix',
400
+ ORIN => 'InputOrientation',
401
+ ORIO => 'OutputOrientation',
402
+ UNIF => 'InputUniformity',
403
+ SROT => 'SensorReadoutTime',
389
404
  );
390
405
 
391
406
  # GoPro GPS5 tags (ref 2) (Hero5,Hero6)
@@ -11,6 +11,7 @@
11
11
  # 4) http://www.color.org/privatetag2007-01.pdf
12
12
  # 5) http://www.color.org/icc_specs2.xalter (approved revisions, 2010-07-16)
13
13
  # 6) Eef Vreeland private communication
14
+ # 7) https://color.org/specification/ICC.2-2019.pdf
14
15
  #
15
16
  # Notes: The ICC profile information is different: the format of each
16
17
  # tag is embedded in the information instead of in the directory
@@ -24,7 +25,7 @@ use strict;
24
25
  use vars qw($VERSION);
25
26
  use Image::ExifTool qw(:DataAccess :Utils);
26
27
 
27
- $VERSION = '1.36';
28
+ $VERSION = '1.38';
28
29
 
29
30
  sub ProcessICC($$);
30
31
  sub ProcessICC_Profile($$$);
@@ -52,6 +53,11 @@ my %profileClass = (
52
53
  abst => 'Abstract Profile',
53
54
  nmcl => 'NamedColor Profile',
54
55
  nkpf => 'Nikon Input Device Profile (NON-STANDARD!)', # (written by Nikon utilities)
56
+ # additions in v5 (ref 7)
57
+ cenc => 'ColorEncodingSpace Profile',
58
+ 'mid '=> 'MultiplexIdentification Profile',
59
+ mlnk => 'MultiplexLink Profile',
60
+ mvis => 'MultiplexVisualization Profile',
55
61
  );
56
62
  my %manuSig = ( #6
57
63
  'NONE' => 'none',
@@ -539,6 +545,90 @@ my %manuSig = ( #6
539
545
  Binary => 1, # (NC)
540
546
  },
541
547
 
548
+ # new tags in v5 (ref 7)
549
+ A2B3 => 'AToB3',
550
+ A2M0 => 'AToM0',
551
+ B2A3 => 'BToA3',
552
+ bcp0 => 'BRDFColorimetricParam0',
553
+ bcp1 => 'BRDFColorimetricParam1',
554
+ bcp2 => 'BRDFColorimetricParam2',
555
+ bcp3 => 'BRDFColorimetricParam3',
556
+ bsp0 => 'BRDFSpectralParam0',
557
+ bsp1 => 'BRDFSpectralParam1',
558
+ bsp2 => 'BRDFSpectralParam2',
559
+ bsp3 => 'BRDFSpectralParam3',
560
+ bAB0 => 'BRDFAToB0',
561
+ bAB1 => 'BRDFAToB1',
562
+ bAB2 => 'BRDFAToB2',
563
+ bAB3 => 'BRDFAToB3',
564
+ bBA0 => 'BRDFBToA0',
565
+ bBA1 => 'BRDFBToA1',
566
+ bBA2 => 'BRDFBToA2',
567
+ bBA3 => 'BRDFBToA3',
568
+ bBD0 => 'BRDFBToD0',
569
+ bBD1 => 'BRDFBToD1',
570
+ bBD2 => 'BRDFBToD2',
571
+ bBD3 => 'BRDFBToD3',
572
+ bDB0 => 'BRDFDToB0',
573
+ bDB1 => 'BRDFDToB1',
574
+ bDB2 => 'BRDFDToB2',
575
+ bDB3 => 'BRDFDToB3',
576
+ bMB0 => 'BRDFMToB0',
577
+ bMB1 => 'BRDFMToB1',
578
+ bMB2 => 'BRDFMToB2',
579
+ bMB3 => 'BRDFMToB3',
580
+ bMS0 => 'BRDFMToS0',
581
+ bMS1 => 'BRDFMToS1',
582
+ bMS2 => 'BRDFMToS2',
583
+ bMS3 => 'BRDFMToS3',
584
+ dAB0 => 'DirectionalAToB0',
585
+ dAB1 => 'DirectionalAToB1',
586
+ dAB2 => 'DirectionalAToB2',
587
+ dAB3 => 'DirectionalAToB3',
588
+ dBA0 => 'DirectionalBToA0',
589
+ dBA1 => 'DirectionalBToA1',
590
+ dBA2 => 'DirectionalBToA2',
591
+ dBA3 => 'DirectionalBToA3',
592
+ dBD0 => 'DirectionalBToD0',
593
+ dBD1 => 'DirectionalBToD1',
594
+ dBD2 => 'DirectionalBToD2',
595
+ dBD3 => 'DirectionalBToD3',
596
+ dDB0 => 'DirectionalDToB0',
597
+ dDB1 => 'DirectionalDToB1',
598
+ dDB2 => 'DirectionalDToB2',
599
+ dDB3 => 'DirectionalDToB3',
600
+ gdb0 => 'GamutBoundaryDescription0',
601
+ gdb1 => 'GamutBoundaryDescription1',
602
+ gdb2 => 'GamutBoundaryDescription2',
603
+ gdb3 => 'GamutBoundaryDescription3',
604
+ 'mdv '=> 'MultiplexDefaultValues',
605
+ mcta => 'MultiplexTypeArray',
606
+ minf => 'MeasurementInfo',
607
+ miin => 'MeasurementInputInfo',
608
+ M2A0 => 'MToA0',
609
+ M2B0 => 'MToB0',
610
+ M2B1 => 'MToB1',
611
+ M2B2 => 'MToB2',
612
+ M2B3 => 'MToB3',
613
+ M2S0 => 'MToS0',
614
+ M2S1 => 'MToS1',
615
+ M2S2 => 'MToS2',
616
+ M2S3 => 'MToS3',
617
+ cept => 'ColorEncodingParams',
618
+ csnm => 'ColorSpaceName',
619
+ cloo => 'ColorantOrderOut',
620
+ clio => 'ColorantInfoOut',
621
+ c2sp => 'CustomToStandardPcc',
622
+ 'CxF '=> 'CXF',
623
+ nmcl => 'NamedColor',
624
+ psin => 'ProfileSequenceInfo',
625
+ rfnm => 'ReferenceName',
626
+ svcn => 'SpectralViewingConditions',
627
+ swpt => 'SpectralWhitePoint',
628
+ s2cp => 'StandardToCustomPcc',
629
+ smap => 'SurfaceMap',
630
+ # smwp ? (seen in some v5 samples)
631
+
542
632
  # the following entry represents the ICC profile header, and doesn't
543
633
  # exist as a tag in the directory. It is only in this table to provide
544
634
  # a link so ExifTool can locate the header tags
@@ -850,7 +940,7 @@ sub FormatICCTag($$$)
850
940
  # dataType
851
941
  if ($type eq 'data' and $size >= 12) {
852
942
  my $form = Get32u($dataPt, $offset+8);
853
- # format 0 is ASCII data
943
+ # format 0 is UTF-8 data
854
944
  $form == 0 and return substr($$dataPt, $offset+12, $size-12);
855
945
  # binary data and other data types treat as binary (ie. don't format)
856
946
  }
@@ -1022,7 +1112,7 @@ sub ValidateICC($)
1022
1112
  $profileClass{substr($$valPtr, 12, 4)} or $err = 'profile class';
1023
1113
  my $col = substr($$valPtr, 16, 4); # ColorSpaceData
1024
1114
  my $con = substr($$valPtr, 20, 4); # ConnectionSpace
1025
- my $match = '(XYZ |Lab |Luv |YCbr|Yxy |RGB |GRAY|HSV |HLS |CMYK|CMY |[2-9A-F]CLR)';
1115
+ my $match = '(XYZ |Lab |Luv |YCbr|Yxy |RGB |GRAY|HSV |HLS |CMYK|CMY |[2-9A-F]CLR|nc..|\0{4})';
1026
1116
  $col =~ /$match/ or $err = 'color space';
1027
1117
  $con =~ /$match/ or $err = 'connection space';
1028
1118
  return $err ? "Invalid ICC profile (bad $err)" : undef;
@@ -1134,7 +1224,7 @@ sub ProcessICC_Profile($$$)
1134
1224
  my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID);
1135
1225
  # unknown tags aren't generated automatically by GetTagInfo()
1136
1226
  # if the tagID's aren't numeric, so we must do this manually:
1137
- if (not $tagInfo and $$et{OPTIONS}{Unknown}) {
1227
+ if (not $tagInfo and ($$et{OPTIONS}{Unknown} or $verbose)) {
1138
1228
  $tagInfo = { Unknown => 1 };
1139
1229
  AddTagToTable($tagTablePtr, $tagID, $tagInfo);
1140
1230
  }
@@ -1277,6 +1367,8 @@ under the same terms as Perl itself.
1277
1367
 
1278
1368
  =item L<http://developer.apple.com/documentation/GraphicsImaging/Reference/ColorSync_Manager/ColorSync_Manager.pdf>
1279
1369
 
1370
+ =item L<https://color.org/specification/ICC.2-2019.pdf>
1371
+
1280
1372
  =back
1281
1373
 
1282
1374
  =head1 SEE ALSO
@@ -18,11 +18,12 @@ use strict;
18
18
  use vars qw($VERSION);
19
19
  use Image::ExifTool qw(:DataAccess :Utils);
20
20
 
21
- $VERSION = '1.55';
21
+ $VERSION = '1.57';
22
22
 
23
23
  sub ProcessID3v2($$$);
24
24
  sub ProcessPrivate($$$);
25
25
  sub ProcessSynText($$$);
26
+ sub ProcessID3Dir($$$);
26
27
  sub ConvertID3v1Text($$);
27
28
  sub ConvertTimeStamp($);
28
29
 
@@ -69,9 +70,10 @@ my %dateTimeConv = (
69
70
  # This table is just for documentation purposes
70
71
  %Image::ExifTool::ID3::Main = (
71
72
  VARS => { NO_ID => 1 },
73
+ PROCESS_PROC => \&ProcessID3Dir, # (used to process 'id3 ' chunk in WAV files)
72
74
  NOTES => q{
73
- ExifTool extracts ID3 and Lyrics3 information from MP3, MPEG, AIFF, OGG,
74
- FLAC, APE, MPC and RealAudio files. ID3v2 tags which support multiple
75
+ ExifTool extracts ID3 and Lyrics3 information from MP3, MPEG, WAV, AIFF,
76
+ OGG, FLAC, APE, MPC and RealAudio files. ID3v2 tags which support multiple
75
77
  languages (eg. Comment and Lyrics) are extracted by specifying the tag name,
76
78
  followed by a dash ('-'), then a 3-character ISO 639-2 language code (eg.
77
79
  "Comment-spa"). See L<http://www.id3.org/> for the official ID3
@@ -1570,6 +1572,16 @@ sub ProcessID3($$)
1570
1572
  return $rtnVal;
1571
1573
  }
1572
1574
 
1575
+ #------------------------------------------------------------------------------
1576
+ # Process ID3 directory
1577
+ # Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) dummy tag table ref
1578
+ sub ProcessID3Dir($$$)
1579
+ {
1580
+ my ($et, $dirInfo, $tagTablePtr) = @_;
1581
+ $et->VerboseDir('ID3', undef, length ${$$dirInfo{DataPt}});
1582
+ return ProcessID3($et, $dirInfo);
1583
+ }
1584
+
1573
1585
  #------------------------------------------------------------------------------
1574
1586
  # Extract ID3 information from an MP3 audio file
1575
1587
  # Inputs: 0) ExifTool object reference, 1) dirInfo reference