exiftool_vendored 12.58.0 → 12.60.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +45 -3
  3. data/bin/MANIFEST +4 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +2 -2
  7. data/bin/config_files/example.config +1 -0
  8. data/bin/exiftool +81 -54
  9. data/bin/lib/Image/ExifTool/CanonRaw.pm +5 -1
  10. data/bin/lib/Image/ExifTool/DJI.pm +2 -2
  11. data/bin/lib/Image/ExifTool/Exif.pm +53 -14
  12. data/bin/lib/Image/ExifTool/FlashPix.pm +27 -9
  13. data/bin/lib/Image/ExifTool/FujiFilm.pm +6 -3
  14. data/bin/lib/Image/ExifTool/Geotag.pm +30 -7
  15. data/bin/lib/Image/ExifTool/LIF.pm +10 -2
  16. data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -1
  17. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -1
  18. data/bin/lib/Image/ExifTool/Nikon.pm +6 -5
  19. data/bin/lib/Image/ExifTool/Olympus.pm +87 -7
  20. data/bin/lib/Image/ExifTool/PNG.pm +10 -2
  21. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
  22. data/bin/lib/Image/ExifTool/PhaseOne.pm +14 -1
  23. data/bin/lib/Image/ExifTool/QuickTime.pm +21 -6
  24. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +37 -5
  25. data/bin/lib/Image/ExifTool/RIFF.pm +32 -11
  26. data/bin/lib/Image/ExifTool/Ricoh.pm +2 -1
  27. data/bin/lib/Image/ExifTool/SigmaRaw.pm +9 -3
  28. data/bin/lib/Image/ExifTool/Sony.pm +2 -1
  29. data/bin/lib/Image/ExifTool/TagLookup.pm +2254 -2246
  30. data/bin/lib/Image/ExifTool/TagNames.pod +45 -25
  31. data/bin/lib/Image/ExifTool/WriteExif.pl +13 -13
  32. data/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
  33. data/bin/lib/Image/ExifTool/Writer.pl +111 -19
  34. data/bin/lib/Image/ExifTool/XMP.pm +18 -3
  35. data/bin/lib/Image/ExifTool/XMP2.pl +2 -1
  36. data/bin/lib/Image/ExifTool.pm +109 -17
  37. data/bin/lib/Image/ExifTool.pod +40 -5
  38. data/bin/perl-Image-ExifTool.spec +1 -1
  39. data/lib/exiftool_vendored/version.rb +1 -1
  40. metadata +2 -2
@@ -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.43';
59
+ $VERSION = '4.44';
60
60
 
61
61
  sub ProcessExif($$$);
62
62
  sub WriteExif($$$);
@@ -1511,9 +1511,10 @@ my %opcodeInfo = (
1511
1511
  0x7031 => {
1512
1512
  Name => 'VignettingCorrection',
1513
1513
  Notes => 'found in Sony ARW images',
1514
- Protected => 1,
1515
1514
  Writable => 'int16s',
1516
1515
  WriteGroup => 'SubIFD',
1516
+ Permanent => 1,
1517
+ Protected => 1,
1517
1518
  PrintConv => {
1518
1519
  256 => 'Off',
1519
1520
  257 => 'Auto',
@@ -1524,17 +1525,19 @@ my %opcodeInfo = (
1524
1525
  0x7032 => {
1525
1526
  Name => 'VignettingCorrParams', #forum7640
1526
1527
  Notes => 'found in Sony ARW images',
1527
- Protected => 1,
1528
1528
  Writable => 'int16s',
1529
1529
  WriteGroup => 'SubIFD',
1530
1530
  Count => 17,
1531
+ Permanent => 1,
1532
+ Protected => 1,
1531
1533
  },
1532
1534
  0x7034 => {
1533
1535
  Name => 'ChromaticAberrationCorrection',
1534
1536
  Notes => 'found in Sony ARW images',
1535
- Protected => 1,
1536
1537
  Writable => 'int16s',
1537
1538
  WriteGroup => 'SubIFD',
1539
+ Permanent => 1,
1540
+ Protected => 1,
1538
1541
  PrintConv => {
1539
1542
  0 => 'Off',
1540
1543
  1 => 'Auto',
@@ -1544,17 +1547,19 @@ my %opcodeInfo = (
1544
1547
  0x7035 => {
1545
1548
  Name => 'ChromaticAberrationCorrParams', #forum6509
1546
1549
  Notes => 'found in Sony ARW images',
1547
- Protected => 1,
1548
1550
  Writable => 'int16s',
1549
1551
  WriteGroup => 'SubIFD',
1550
1552
  Count => 33,
1553
+ Permanent => 1,
1554
+ Protected => 1,
1551
1555
  },
1552
1556
  0x7036 => {
1553
1557
  Name => 'DistortionCorrection',
1554
1558
  Notes => 'found in Sony ARW images',
1555
- Protected => 1,
1556
1559
  Writable => 'int16s',
1557
1560
  WriteGroup => 'SubIFD',
1561
+ Permanent => 1,
1562
+ Protected => 1,
1558
1563
  PrintConv => {
1559
1564
  0 => 'Off',
1560
1565
  1 => 'Auto',
@@ -1565,10 +1570,38 @@ my %opcodeInfo = (
1565
1570
  0x7037 => {
1566
1571
  Name => 'DistortionCorrParams', #forum6509
1567
1572
  Notes => 'found in Sony ARW images',
1568
- Protected => 1,
1569
1573
  Writable => 'int16s',
1570
1574
  WriteGroup => 'SubIFD',
1571
1575
  Count => 17,
1576
+ Permanent => 1,
1577
+ Protected => 1,
1578
+ },
1579
+ 0x7038 => { #github#195 (Sony ARW)
1580
+ Name => 'SonyRawImageSize',
1581
+ Notes => 'size of actual image in Sony ARW files',
1582
+ Writable => 'int32u',
1583
+ WriteGroup => 'SubIFD',
1584
+ Count => 2,
1585
+ Permanent => 1,
1586
+ Protected => 1,
1587
+ },
1588
+ 0x7310 => { #github#195 (Sony ARW)
1589
+ Name => 'BlackLevel',
1590
+ Notes => 'found in Sony ARW images',
1591
+ Writable => 'int16u',
1592
+ WriteGroup => 'SubIFD',
1593
+ Count => 4,
1594
+ Permanent => 1,
1595
+ Protected => 1,
1596
+ },
1597
+ 0x7313 => { #github#195 (Sony ARW)
1598
+ Name => 'WB_RGGBLevels',
1599
+ Notes => 'found in Sony ARW images',
1600
+ Writable => 'int16s',
1601
+ WriteGroup => 'SubIFD',
1602
+ Count => 4,
1603
+ Permanent => 1,
1604
+ Protected => 1,
1572
1605
  },
1573
1606
  0x74c7 => { #IB (in ARW images from some Sony cameras)
1574
1607
  Name => 'SonyCropTopLeft',
@@ -5893,9 +5926,7 @@ sub ProcessExif($$$)
5893
5926
  my $base = $$dirInfo{Base} || 0;
5894
5927
  my $firstBase = $base;
5895
5928
  my $raf = $$dirInfo{RAF};
5896
- my $verbose = $et->Options('Verbose');
5897
- my $validate = $et->Options('Validate');
5898
- my $saveFormat = $et->Options('SaveFormat');
5929
+ my ($verbose,$validate,$saveFormat) = @{$$et{OPTIONS}}{qw(Verbose Validate SaveFormat)};
5899
5930
  my $htmlDump = $$et{HTML_DUMP};
5900
5931
  my $success = 1;
5901
5932
  my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffName, $doMD5);
@@ -5914,7 +5945,12 @@ sub ProcessExif($$$)
5914
5945
  $isExif and $$et{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/)
5915
5946
  {
5916
5947
  my $path = $et->MetadataPath();
5917
- unless ($path =~ /^(JPEG-APP1-IFD0|TIFF-IFD0|PSD-EXIFInfo-IFD0)$/) {
5948
+ if ($path =~ /^(JPEG-APP1-IFD0|TIFF-IFD0|PSD-EXIFInfo-IFD0)$/) {
5949
+ unless ($$et{DOC_NUM}) {
5950
+ $et->Warn("Duplicate EXIF at $path") if $$et{HasExif};
5951
+ $$et{HasExif} = 1;
5952
+ }
5953
+ } else {
5918
5954
  if ($Image::ExifTool::MWG::strict) {
5919
5955
  $et->Warn("Ignored non-standard EXIF at $path");
5920
5956
  return 0;
@@ -6378,10 +6414,10 @@ sub ProcessExif($$$)
6378
6414
  $tval .= " ($rational)" if defined $rational;
6379
6415
  if ($htmlDump) {
6380
6416
  my ($tagName, $colName);
6381
- if ($tagID == 0x927c and $dirName eq 'ExifIFD') {
6382
- $tagName = 'MakerNotes';
6383
- } elsif ($tagInfo) {
6417
+ if ($tagInfo) {
6384
6418
  $tagName = $$tagInfo{Name};
6419
+ } elsif ($tagID == 0x927c and $dirName eq 'ExifIFD') {
6420
+ $tagName = 'MakerNotes';
6385
6421
  } else {
6386
6422
  $tagName = sprintf("Tag 0x%.4x",$tagID);
6387
6423
  }
@@ -6456,6 +6492,9 @@ sub ProcessExif($$$)
6456
6492
  }
6457
6493
  # add value data block (underlining maker notes data)
6458
6494
  $et->HDump($exifDumpPos,$size,"$tagName value",'SAME', $flag, $sid);
6495
+ if ($subdir and $$tagInfo{MakerNotes} and $$tagInfo{NotIFD}) {
6496
+ $et->HDump($exifDumpPos,$size,"$tagName value",undef,undef,$$dirInfo{OffsetName});
6497
+ }
6459
6498
  }
6460
6499
  } else {
6461
6500
  if ($tagID <= $lastID and not $inMakerNotes) {
@@ -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.43';
24
+ $VERSION = '1.44';
25
25
 
26
26
  sub ProcessFPX($$);
27
27
  sub ProcessFPXR($$$);
@@ -488,16 +488,27 @@ my %fpxFileType = (
488
488
  IeImg => {
489
489
  Name => 'EmbeddedImage',
490
490
  Notes => q{
491
- embedded images in Scene7 vignette VNT files. EmbeddedImageRectangle is
492
- generated for applicable images, and may be associated with the
493
- corresponding EmbeddedImage via the family 3 group name
491
+ embedded images in Scene7 vignette VNT files. The EmbeddedImage Class and
492
+ Rectangle are also extracted for applicable images, and may be associated
493
+ with the corresponding EmbeddedImage via the family 3 group name
494
494
  },
495
495
  Groups => { 2 => 'Preview' },
496
496
  Binary => 1,
497
497
  },
498
- IeImg_rect => { # (not a real tag -- extracted from Contents of VNT file)
498
+ IeImg_class => {
499
+ Name => 'EmbeddedImageClass',
500
+ Notes => q{
501
+ not a real tag. This information is extracted if available for the
502
+ corresponding EmbeddedImage from the Contents of a VNT file
503
+ },
504
+ # eg. "Cache", "Mask"
505
+ },
506
+ IeImg_rect => { #
499
507
  Name => 'EmbeddedImageRectangle',
500
- Hidden => 1,
508
+ Notes => q{
509
+ not a real tag. This information is extracted if available for the
510
+ corresponding EmbeddedImage from the Contents of a VNT file
511
+ },
501
512
  },
502
513
  );
503
514
 
@@ -1577,13 +1588,16 @@ sub ProcessContents($$$)
1577
1588
  pos($$dataPt) += $size;
1578
1589
  }
1579
1590
  $$et{IeImg_lkup} = { };
1580
- # - the byte after TargetRole1 is 0x0d or 0x11 for separate images in my samples,
1591
+ $$et{IeImg_class} = { };
1592
+ # - the byte before \x80 is 0x0d, 0x11 or 0x1f for separate images in my samples,
1581
1593
  # and 0x1c or 0x23 for inline masks
1582
- while ($$dataPt =~ /\x0bTargetRole1.\x80\0\0\x01.{4}(.{24})/sg) {
1583
- my ($index, @coords) = unpack('Vx4V4', $1);
1594
+ # - the byte after \xff\xff is 0x3b in my samples for $1 containing 'VnMask' or 'VnCache'
1595
+ while ($$dataPt =~ /\x0bTargetRole1(?:.\x80|\xff\xff.\0.\0Vn(\w+))\0\0\x01.{4}(.{24})/sg) {
1596
+ my ($index, @coords) = unpack('Vx4V4', $2);
1584
1597
  next if $index == 0xffffffff;
1585
1598
  $$et{IeImg_lkup}{$index} and $et->WarnOnce('Duplicate image index');
1586
1599
  $$et{IeImg_lkup}{$index} = "@coords";
1600
+ $$et{IeImg_class}{$index} = $1 if $1;
1587
1601
  }
1588
1602
  }
1589
1603
  }
@@ -2395,6 +2409,10 @@ sub ProcessFPX($$)
2395
2409
  # save position of this image
2396
2410
  $et->HandleTag($tagTablePtr, IeImg_rect => $$et{IeImg_lkup}{$num});
2397
2411
  delete $$et{IeImg_lkup}{$num};
2412
+ if ($$et{IeImg_class} and $$et{IeImg_class}{$num}) {
2413
+ $et->HandleTag($tagTablePtr, IeImg_class => $$et{IeImg_class}{$num});
2414
+ delete $$et{IeImg_class}{$num};
2415
+ }
2398
2416
  }
2399
2417
  delete $$et{DOC_NUM};
2400
2418
  } else {
@@ -1671,11 +1671,11 @@ sub ProcessRAF($$)
1671
1671
  my ($rafNum, $ifdNum) = ('','');
1672
1672
  foreach $offset (0x5c, 0x64, 0x78, 0x80) {
1673
1673
  last if $offset >= $jpos;
1674
- unless ($raf->Seek($offset, 0) and $raf->Read($buff, 4)) {
1674
+ unless ($raf->Seek($offset, 0) and $raf->Read($buff, 8)) {
1675
1675
  $warn = 1;
1676
1676
  last;
1677
1677
  }
1678
- my $start = unpack('N',$buff);
1678
+ my ($start, $len) = unpack('N2',$buff);
1679
1679
  next unless $start;
1680
1680
  if ($offset == 0x64 or $offset == 0x80) {
1681
1681
  # parse FujiIFD directory
@@ -1686,7 +1686,10 @@ sub ProcessRAF($$)
1686
1686
  $$et{SET_GROUP1} = "FujiIFD$ifdNum";
1687
1687
  my $tagTablePtr = GetTagTable('Image::ExifTool::FujiFilm::IFD');
1688
1688
  # this is TIFF-format data only for some models, so no warning if it fails
1689
- $et->ProcessTIFF(\%dirInfo, $tagTablePtr, \&Image::ExifTool::ProcessTIFF);
1689
+ unless ($et->ProcessTIFF(\%dirInfo, $tagTablePtr, \&Image::ExifTool::ProcessTIFF)) {
1690
+ # do MD5 of image data if necessary
1691
+ $et->ImageDataMD5($raf, $len, 'raw') if $$et{ImageDataMD5} and $raf->Seek($start,0);
1692
+ }
1690
1693
  delete $$et{SET_GROUP1};
1691
1694
  $ifdNum = ($ifdNum || 1) + 1;
1692
1695
  } else {
@@ -29,7 +29,7 @@ use vars qw($VERSION);
29
29
  use Image::ExifTool qw(:Public);
30
30
  use Image::ExifTool::GPS;
31
31
 
32
- $VERSION = '1.70';
32
+ $VERSION = '1.71';
33
33
 
34
34
  sub JITTER() { return 2 } # maximum time jitter
35
35
 
@@ -92,7 +92,7 @@ my %isOrient = ( dir => 1, pitch => 1, roll => 1 ); # test for orientation key
92
92
  # tags which may exist separately in some formats (eg. CSV)
93
93
  my %sepTags = ( dir => 1, pitch => 1, roll => 1, track => 1, speed => 1 );
94
94
 
95
- # conversion factors for GPSSpeed
95
+ # conversion factors for GPSSpeed (standard EXIF units only)
96
96
  my %speedConv = (
97
97
  'K' => 1.852, # km/h per knot
98
98
  'M' => 1.150779448, # mph per knot
@@ -102,7 +102,14 @@ my %speedConv = (
102
102
  'mph' => 'M',
103
103
  );
104
104
 
105
- my $secPerDay = 24 * 3600; # a useful constant
105
+ # all recognized speed conversion factors (non-EXIF included)
106
+ my %otherConv = (
107
+ 'km/h' => 1.852,
108
+ 'mph' => 1.150779448,
109
+ 'm/s' => 0.514444,
110
+ );
111
+
112
+ my $secPerDay = 24 * 3600; # a useful constant
106
113
 
107
114
  #------------------------------------------------------------------------------
108
115
  # Load GPS track log file
@@ -140,6 +147,7 @@ sub LoadTrackLog($$;$)
140
147
  my ($raf, $from, $time, $isDate, $noDate, $noDateChanged, $lastDate, $dateFlarm);
141
148
  my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings, $sortFixes);
142
149
  my ($canCut, $cutPDOP, $cutHDOP, $cutSats, $e0, $e1, @tmp, $trackFile, $trackTime);
150
+ my $scaleSpeed;
143
151
 
144
152
  unless (eval { require Time::Local }) {
145
153
  return 'Geotag feature requires Time::Local installed';
@@ -246,7 +254,9 @@ sub LoadTrackLog($$;$)
246
254
  $format = 'CSV';
247
255
  # convert recognized headings to our parameter names
248
256
  foreach (@csvHeadings) {
257
+ my $head = $_;
249
258
  my $param;
259
+ my $xtra = '';
250
260
  s/^GPS ?//; # remove leading "GPS" to simplify regex patterns
251
261
  if (/^Time ?\(seconds\)$/i) { # DJI
252
262
  # DJI CSV log files have a column "Time(seconds)" which is seconds since
@@ -274,7 +284,16 @@ sub LoadTrackLog($$;$)
274
284
  /ref$/i and $param .= 'ref';
275
285
  } elsif (/^(Pos)?Alt/i) {
276
286
  $param = 'alt';
277
- } elsif (/^(Angle)?(Heading|Track)/i) {
287
+ } elsif (/^Speed/i) {
288
+ $param = 'speed';
289
+ # (recognize units in brackets)
290
+ if (m{\((mph|km/h|m/s)\)}) {
291
+ $scaleSpeed = $otherConv{$1};
292
+ $xtra = " in $1";
293
+ } else {
294
+ $xtra = ' in knots';
295
+ }
296
+ } elsif (/^(Angle)?(Heading|Track|Bearing)/i) {
278
297
  $param = 'track';
279
298
  } elsif (/^(Angle)?Pitch/i or /^Camera ?Elevation ?Angle/i) {
280
299
  $param = 'pitch';
@@ -284,10 +303,10 @@ sub LoadTrackLog($$;$)
284
303
  $param = 'dir';
285
304
  }
286
305
  if ($param) {
287
- $et->VPrint(2, "CSV column '${_}' is $param\n");
306
+ $et->VPrint(2, "CSV column '${head}' is $param$xtra\n");
288
307
  $_ = $param;
289
308
  } else {
290
- $et->VPrint(2, "CSV column '${_}' ignored\n");
309
+ $et->VPrint(2, "CSV column '${head}' ignored\n");
291
310
  $_ = ''; # ignore this column
292
311
  }
293
312
  }
@@ -479,9 +498,11 @@ DoneFix: $isDate = 1;
479
498
  my ($param, $date, $secs, %neg);
480
499
  foreach $param (@csvHeadings) {
481
500
  my $val = shift @vals;
482
- last unless defined $val;
501
+ last unless defined $val and length($val);
483
502
  next unless $param;
484
503
  if ($param eq 'datetime') {
504
+ # (fix formats like "24.07.2016 13:47:30")
505
+ $val =~ s/^(\d{2})[^\d](\d{2})[^\d](\d{4}) /$3:$2:$1 /;
485
506
  local $SIG{'__WARN__'} = sub { };
486
507
  my $dateTime = $et->InverseDateTime($val);
487
508
  if ($dateTime) {
@@ -510,6 +531,7 @@ DoneFix: $isDate = 1;
510
531
  $date = $trackTime;
511
532
  $secs = $val;
512
533
  } else {
534
+ $val /= $scaleSpeed if $scaleSpeed and $param eq 'speed';
513
535
  $$fix{$param} = $val;
514
536
  $$has{$param} = 1 if $sepTags{$param};
515
537
  }
@@ -1204,6 +1226,7 @@ Category: foreach $category (qw{pos track alt orient atemp}) {
1204
1226
  @r = $et->SetNewValue(GPSTrackRef => (defined $$tFix{track} ? 'T' : undef), %opts);
1205
1227
  my ($spd, $ref);
1206
1228
  if (defined($spd = $$tFix{speed})) {
1229
+ # convert to specified units if necessary
1207
1230
  $ref = $$et{OPTIONS}{GeoSpeedRef};
1208
1231
  if ($ref and defined $speedConv{$ref}) {
1209
1232
  $ref = $speedConv{$ref} if $speedConv{$speedConv{$ref}};
@@ -13,7 +13,7 @@ use vars qw($VERSION);
13
13
  use Image::ExifTool qw(:DataAccess :Utils);
14
14
  use Image::ExifTool::XMP;
15
15
 
16
- $VERSION = '1.00';
16
+ $VERSION = '1.01';
17
17
 
18
18
  %Image::ExifTool::LIF::Main = (
19
19
  GROUPS => { 0 => 'XML', 1 => 'XML', 2 => 'Image' },
@@ -30,7 +30,15 @@ $VERSION = '1.00';
30
30
  my $unixTimeZero = 134774 * 24 * 3600;
31
31
  my @vals = split ' ', $val;
32
32
  foreach (@vals) {
33
- $_ = 1e-7 * hex($_);
33
+ if (/[^0-9a-f]/i) {
34
+ $_ = '0000:00:00 00:00:00';
35
+ } elsif (length $_ > 8) {
36
+ my $lo = hex substr($_, -8);
37
+ my $hi = hex substr($_, 0, -8);
38
+ $_ = 1e-7 * ($hi * 4294967296 + $lo);
39
+ } else {
40
+ $_ = 1e-7 * hex($_);
41
+ }
34
42
  # shift from Jan 1, 1601 to Jan 1, 1970
35
43
  $_ = Image::ExifTool::ConvertUnixTime($_ - $unixTimeZero);
36
44
  }
@@ -21,7 +21,7 @@ sub ProcessKodakPatch($$$);
21
21
  sub WriteUnknownOrPreview($$$);
22
22
  sub FixLeicaBase($$;$);
23
23
 
24
- $VERSION = '2.13';
24
+ $VERSION = '2.14';
25
25
 
26
26
  my $debug; # set to 1 to enable debugging code
27
27
 
@@ -92,6 +92,7 @@ my $debug; # set to 1 to enable debugging code
92
92
  {
93
93
  Name => 'MakerNoteDJIInfo',
94
94
  Condition => '$$valPt =~ /^\[ae_dbg_info:/',
95
+ NotIFD => 1,
95
96
  SubDirectory => { TagTable => 'Image::ExifTool::DJI::Info' },
96
97
  },
97
98
  {
@@ -17,7 +17,7 @@ use vars qw($VERSION);
17
17
  use Image::ExifTool qw(:DataAccess :Utils);
18
18
  use Image::ExifTool::Minolta;
19
19
 
20
- $VERSION = '1.16';
20
+ $VERSION = '1.17';
21
21
 
22
22
  sub ProcessMRW($$;$);
23
23
  sub WriteMRW($$;$);
@@ -489,6 +489,7 @@ sub ProcessMRW($$;$)
489
489
  $err and $et->Error("MRW format error", $$et{TIFF_TYPE} eq 'ARW');
490
490
  } else {
491
491
  $err and $et->Warn("MRW format error");
492
+ $et->ImageDataMD5($raf, undef, 'raw');
492
493
  }
493
494
  return $rtnVal;
494
495
  }
@@ -64,7 +64,7 @@ use Image::ExifTool::Exif;
64
64
  use Image::ExifTool::GPS;
65
65
  use Image::ExifTool::XMP;
66
66
 
67
- $VERSION = '4.20';
67
+ $VERSION = '4.21';
68
68
 
69
69
  sub LensIDConv($$$);
70
70
  sub ProcessNikonAVI($$$);
@@ -5298,6 +5298,7 @@ my %nikonFocalConversions = (
5298
5298
  35 => 'Nikkor Z 28-75mm f/2.8', #IB
5299
5299
  36 => 'Nikkor Z 400mm f/4.5 VR S', #IB
5300
5300
  37 => 'Nikkor Z 600mm f/4 TC VR S', #28
5301
+ 38 => 'Nikkor Z 85mm f/1.2 S', #28
5301
5302
  39 => 'Nikkor Z 17-28mm f/2.8', #IB
5302
5303
  32768 => 'Nikkor Z 400mm f/2.8 TC VR S TC-1.4x', #28
5303
5304
  32769 => 'Nikkor Z 600mm f/4 TC VR S TC-1.4x', #28
@@ -11836,19 +11837,19 @@ sub ProcessNikonApp($;$)
11836
11837
  my $trailerLen = unpack('N', $buff);
11837
11838
  $trailerLen > $fileEnd and $et->Warn('Bad NikonApp trailer size'), return 0;
11838
11839
  if ($dirInfo) {
11839
- $$dirInfo{DirLen} = $trailerLen if $dirInfo;
11840
+ $$dirInfo{DirLen} = $trailerLen;
11840
11841
  $$dirInfo{DataPos} = $fileEnd - $trailerLen;
11841
11842
  if ($$dirInfo{OutFile}) {
11842
11843
  if ($$et{DEL_GROUP}{NikonApp}) {
11844
+ $et->VPrint(0, " Deleting NikonApp trailer ($trailerLen bytes)\n");
11843
11845
  ++$$et{CHANGED};
11844
- # just copy the trailer when writing
11846
+ # just copy the trailer when writing (read directly into output buffer)
11845
11847
  } elsif ($trailerLen > $fileEnd or not $raf->Seek($$dirInfo{DataPos}, 0) or
11846
11848
  $raf->Read(${$$dirInfo{OutFile}}, $trailerLen) != $trailerLen)
11847
11849
  {
11848
11850
  return 0;
11849
- } else {
11850
- return 1;
11851
11851
  }
11852
+ return 1;
11852
11853
  }
11853
11854
  $et->DumpTrailer($dirInfo) if $verbose or $$et{HTML_DUMP};
11854
11855
  }
@@ -40,7 +40,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
40
40
  use Image::ExifTool::Exif;
41
41
  use Image::ExifTool::APP12;
42
42
 
43
- $VERSION = '2.80';
43
+ $VERSION = '2.81';
44
44
 
45
45
  sub PrintLensInfo($$$);
46
46
 
@@ -3165,21 +3165,38 @@ my %indexInfo = (
3165
3165
  PrintHex => 1,
3166
3166
  ValueConv => '($val & 0x1f) . " " . ($val & 0xffe0)',
3167
3167
  ValueConvInv => 'my @v=split(" ",$val); @v == 2 ? $v[0] + $v[1] : $val',
3168
- PrintConv => [
3168
+ PrintConv => [ # herb values added:
3169
+ # based on code of W.P. in https://exiftool.org/forum/index.php?topic=14144.0
3169
3170
  {
3170
- 0x00 => '(none)',
3171
- 0x01 => 'Center',
3171
+ # 0x00 => '(none)',
3172
+ # 0x01 => 'Center',
3172
3173
  # need to fill this in...
3174
+ 0x00 => '(none)',
3175
+ 0x02 => 'Top-center (horizontal)',
3176
+ 0x04 => 'Right (horizontal)',
3177
+ 0x05 => 'Mid-right (horizontal)',
3178
+ 0x06 => 'Center (horizontal)',
3179
+ 0x07 => 'Mid-left (horizontal)',
3180
+ 0x08 => 'Left (horizontal)',
3181
+ 0x0a => 'Bottom-center (horizontal)',
3182
+ 0x0c => 'Top-center (vertical)',
3183
+ 0x0f => 'Right (vertical)',
3184
+ 0x15 => 'Bottom-center (vertical)',
3185
+ 0x10 => 'Mid-right (vertical)',
3186
+ 0x11 => 'Center (vertical)',
3187
+ 0x12 => 'Mid-left (vertical)',
3188
+ 0x13 => 'Left (vertical)',
3173
3189
  },
3174
3190
  {
3175
3191
  0x00 => 'Single Target',
3176
3192
  0x40 => 'All Target', # (guess)
3177
3193
  },
3178
3194
  ]
3179
- },{ #11
3195
+ },{ #herb all camera model except E-Mxxx and OM-x
3180
3196
  Name => 'AFPoint',
3197
+ Condition => '$$self{Model} !~ /^(E-M|OM-)/ ',
3181
3198
  Writable => 'int16u',
3182
- Notes => 'other models',
3199
+ Notes => 'models other than E-Mxxx and OM-x',
3183
3200
  RawConv => '($val or $$self{Model} ne "E-P1") ? $val : undef',
3184
3201
  PrintConv => {
3185
3202
  # (E-P1 always writes 0, maybe other models do too - PH)
@@ -3189,10 +3206,73 @@ my %indexInfo = (
3189
3206
  3 => 'Center (vertical)', #6 (E-510)
3190
3207
  255 => 'None',
3191
3208
  },
3209
+ },{ #herb all newer models E-Mxxx and OM-x; we do not know details
3210
+ Name => 'AFPoint',
3211
+ Writable => 'int16u',
3212
+ Notes => 'other models',
3192
3213
  }
3193
3214
  ],
3194
3215
  # 0x31a Continuous AF parameters?
3195
- # 0x31b ContinuousFocusMode? (ref forum78245)
3216
+ 0x31b => [ #herb, based on investigations of abgestumpft: https://exiftool.org/forum/index.php?topic=14527.0
3217
+ # for newer models E-Mxxx and OM-x
3218
+ {
3219
+ Name => 'AFPointDetails',
3220
+ Condition => '$$self{Model} =~ m/^E-M|^OM-/ ',
3221
+ Writable => 'int16u',
3222
+ Notes => 'models E-Mxxx and OM-x',
3223
+ PrintHex => 1,
3224
+ ValueConv => '(($val >> 13) & 0x7) . " " . (($val >> 12) & 0x1) . " " . (($val >> 11) & 0x1) . " " .
3225
+ # subject detect face and eye half press
3226
+ (($val >> 8) & 0x3) . " " . (($val >> 7) & 0x1) . " " . (($val >> 5) & 0x1) . " " .
3227
+ # eye AF face detect x-AF with MF
3228
+ (($val >> 4) & 0x1) . " " . (($val >> 3) & 0x1) . " " . ($val & 0x7)',
3229
+ # release object found MF...
3230
+ PrintConvColumns => 4,
3231
+ PrintConv => [
3232
+ {
3233
+ # should be identical to AISubjectTrackingMode
3234
+ 0 => 'No Subject Detection',
3235
+ 1 => 'Motorsports',
3236
+ 2 => 'Airplanes',
3237
+ 3 => 'Trains',
3238
+ 4 => 'Birds',
3239
+ 5 => 'Dogs & Cats',
3240
+ },{
3241
+ 0 => 'Face Priority',
3242
+ 1 => 'Target Priority',
3243
+ },{
3244
+ 0 => 'Normal AF',
3245
+ 1 => 'AF on Half Press',
3246
+ },{
3247
+ 0 => 'No Eye-AF',
3248
+ 1 => 'Right Eye Priority',
3249
+ 2 => 'Left Eye Priority',
3250
+ 3 => 'Both Eyes Priority',
3251
+ },{
3252
+ 0 => 'No Face Detection',
3253
+ 1 => 'Face Detection',
3254
+ },{
3255
+ 0 => 'No MF',
3256
+ 1 => 'With MF',
3257
+ },{
3258
+ 0 => 'AF Priority',
3259
+ 1 => 'Release Priority',
3260
+ },{
3261
+ 0 => 'No Object found',
3262
+ 1 => 'Object found',
3263
+ },{
3264
+ 0 => 'MF',
3265
+ 1 => 'S-AF',
3266
+ 2 => 'C-AF',
3267
+ 6 => 'C-AF + TR',
3268
+ },
3269
+ ],
3270
+ },{ # for older models
3271
+ Name => 'AFPointDetails',
3272
+ Writable => 'int16u',
3273
+ Notes => 'other models',
3274
+ }
3275
+ ],
3196
3276
  0x328 => { #PH
3197
3277
  Name => 'AFInfo',
3198
3278
  SubDirectory => { TagTable => 'Image::ExifTool::Olympus::AFInfo' },
@@ -36,7 +36,7 @@ use strict;
36
36
  use vars qw($VERSION $AUTOLOAD %stdCase);
37
37
  use Image::ExifTool qw(:DataAccess :Utils);
38
38
 
39
- $VERSION = '1.62';
39
+ $VERSION = '1.63';
40
40
 
41
41
  sub ProcessPNG_tEXt($$$);
42
42
  sub ProcessPNG_iTXt($$$);
@@ -1374,6 +1374,7 @@ sub ProcessPNG($$)
1374
1374
  my $datCount = 0;
1375
1375
  my $datBytes = 0;
1376
1376
  my $fastScan = $et->Options('FastScan');
1377
+ my $md5 = $$et{ImageDataMD5};
1377
1378
  my ($n, $sig, $err, $hbuf, $dbuf, $cbuf);
1378
1379
  my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset);
1379
1380
 
@@ -1453,6 +1454,7 @@ sub ProcessPNG($$)
1453
1454
  if ($datCount and $chunk ne $datChunk) {
1454
1455
  my $s = $datCount > 1 ? 's' : '';
1455
1456
  print $out "$fileType $datChunk ($datCount chunk$s, total $datBytes bytes)\n";
1457
+ print $out "$$et{INDENT}(ImageDataMD5: $datBytes bytes of $datChunk data)\n" if $md5;
1456
1458
  $datCount = $datBytes = 0;
1457
1459
  }
1458
1460
  }
@@ -1539,7 +1541,12 @@ sub ProcessPNG($$)
1539
1541
  }
1540
1542
  # skip over data chunks if possible/necessary
1541
1543
  } elsif (not $validate or $len > $chunkSizeLimit) {
1542
- $raf->Seek($len + 4, 1) or $et->Warn('Seek error'), last;
1544
+ if ($md5) {
1545
+ $et->ImageDataMD5($raf, $len);
1546
+ $raf->Read($cbuf, 4) == 4 or $et->Warn('Truncated data'), last;
1547
+ } else {
1548
+ $raf->Seek($len + 4, 1) or $et->Warn('Seek error'), last;
1549
+ }
1543
1550
  next;
1544
1551
  }
1545
1552
  } elsif ($wasDat and $isTxtChunk{$chunk}) {
@@ -1558,6 +1565,7 @@ sub ProcessPNG($$)
1558
1565
  $et->Warn("Corrupted $fileType image") unless $wasEnd;
1559
1566
  last;
1560
1567
  }
1568
+ $md5->add($dbuf) if $md5 and $datChunk; # add to MD5 if necessary
1561
1569
  if ($verbose or $validate or ($outfile and not $fastScan)) {
1562
1570
  # check CRC when in verbose mode (since we don't care about speed)
1563
1571
  my $crc = CalculateCRC(\$hbuf, undef, 4);