exiftool_vendored 11.94.0 → 12.06.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.

Potentially problematic release.


This version of exiftool_vendored might be problematic. Click here for more details.

Files changed (62) hide show
  1. checksums.yaml +5 -5
  2. data/bin/Changes +163 -3
  3. data/bin/MANIFEST +5 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +32 -32
  7. data/bin/exiftool +152 -52
  8. data/bin/lib/Image/ExifTool.pm +166 -115
  9. data/bin/lib/Image/ExifTool.pod +108 -81
  10. data/bin/lib/Image/ExifTool/AIFF.pm +2 -2
  11. data/bin/lib/Image/ExifTool/APE.pm +2 -2
  12. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +13 -7
  13. data/bin/lib/Image/ExifTool/Canon.pm +6 -3
  14. data/bin/lib/Image/ExifTool/CanonCustom.pm +82 -16
  15. data/bin/lib/Image/ExifTool/DPX.pm +56 -2
  16. data/bin/lib/Image/ExifTool/DarwinCore.pm +16 -3
  17. data/bin/lib/Image/ExifTool/Exif.pm +15 -6
  18. data/bin/lib/Image/ExifTool/Font.pm +9 -2
  19. data/bin/lib/Image/ExifTool/GIF.pm +5 -0
  20. data/bin/lib/Image/ExifTool/GeoTiff.pm +2 -0
  21. data/bin/lib/Image/ExifTool/Geotag.pm +69 -21
  22. data/bin/lib/Image/ExifTool/GoPro.pm +10 -1
  23. data/bin/lib/Image/ExifTool/H264.pm +1 -1
  24. data/bin/lib/Image/ExifTool/HtmlDump.pm +2 -2
  25. data/bin/lib/Image/ExifTool/ID3.pm +91 -12
  26. data/bin/lib/Image/ExifTool/Lang/de.pm +3 -1
  27. data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
  28. data/bin/lib/Image/ExifTool/M2TS.pm +44 -24
  29. data/bin/lib/Image/ExifTool/MWG.pm +9 -1
  30. data/bin/lib/Image/ExifTool/MacOS.pm +1 -1
  31. data/bin/lib/Image/ExifTool/Minolta.pm +3 -2
  32. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +11 -10
  33. data/bin/lib/Image/ExifTool/Nikon.pm +156 -18
  34. data/bin/lib/Image/ExifTool/Olympus.pm +34 -17
  35. data/bin/lib/Image/ExifTool/PNG.pm +14 -3
  36. data/bin/lib/Image/ExifTool/PPM.pm +5 -5
  37. data/bin/lib/Image/ExifTool/Panasonic.pm +147 -13
  38. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +33 -0
  39. data/bin/lib/Image/ExifTool/Parrot.pm +2 -1
  40. data/bin/lib/Image/ExifTool/Pentax.pm +3 -1
  41. data/bin/lib/Image/ExifTool/Photoshop.pm +2 -1
  42. data/bin/lib/Image/ExifTool/QuickTime.pm +277 -33
  43. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +460 -67
  44. data/bin/lib/Image/ExifTool/README +21 -20
  45. data/bin/lib/Image/ExifTool/RIFF.pm +123 -3
  46. data/bin/lib/Image/ExifTool/RTF.pm +12 -7
  47. data/bin/lib/Image/ExifTool/Ricoh.pm +19 -1
  48. data/bin/lib/Image/ExifTool/Shift.pl +1 -0
  49. data/bin/lib/Image/ExifTool/SigmaRaw.pm +40 -33
  50. data/bin/lib/Image/ExifTool/Sony.pm +379 -12
  51. data/bin/lib/Image/ExifTool/TagLookup.pm +1959 -1874
  52. data/bin/lib/Image/ExifTool/TagNames.pod +346 -55
  53. data/bin/lib/Image/ExifTool/Validate.pm +4 -4
  54. data/bin/lib/Image/ExifTool/WriteExif.pl +3 -2
  55. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +26 -15
  56. data/bin/lib/Image/ExifTool/Writer.pl +52 -23
  57. data/bin/lib/Image/ExifTool/XMP.pm +41 -4
  58. data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
  59. data/bin/lib/Image/ExifTool/ZISRAW.pm +123 -0
  60. data/bin/perl-Image-ExifTool.spec +31 -31
  61. data/lib/exiftool_vendored/version.rb +1 -1
  62. metadata +4 -4
@@ -763,25 +763,26 @@ numerical, and generated automatically otherwise.
763
763
  conditionally deleted.
764
764
 
765
765
  Writable : Indicates this tag can be written (or not written if Writable
766
- is set to zero), and for EXIF-type tables gives format for
767
- writing. Writable may be set to 1 for MakerNotes information
768
- because the existing format is always used, however providing
769
- a format is desirable because it is used in validating the
770
- value. Set to 2 for tag to show "yes" in the Writable column
771
- of the tag name documentation even when there is no WRITE_PROC
772
- defined (eg. if it is written via an Extra tag). For EXIF
773
- tables, the Writable flag may be different than the Format
774
- flag, in which case Format is used for converting the binary
775
- value and Writable specifies the format code written to the
776
- EXIF IFD. For SubDirectories in EXIF information, this flag
777
- is only defined if the SubDirectory is writable as a block, or
778
- if the SubDirectory can not be edited (in which case Writable
779
- is set to 0). If non-zero, the SubDirectory is also extracted
780
- as a block, so the Binary and Protected flags should usually
781
- set as well. There is currently no way to specify a write
782
- format for a SubDirectory that is not writable as a block (the
783
- default is 'int32u' for IFD-type SubDirectories, and 'undef'
784
- for all others).
766
+ is set to zero), and for EXIF and QuickTime tables gives
767
+ format for writing. Writable may be set to 1 for MakerNotes
768
+ information because the existing format is always used,
769
+ however providing a format is desirable because it is used in
770
+ validating the value. Set to 2 for tag to show "yes" in the
771
+ Writable column of the tag name documentation even when there
772
+ is no WRITE_PROC defined (eg. if it is written via an Extra
773
+ tag). For EXIF and QuickTime tables, the Writable flag may be
774
+ different than the Format flag, in which case Format is used
775
+ for converting the binary value and Writable specifies the
776
+ format code written to the EXIF IFD. For SubDirectories in
777
+ EXIF information, this flag is only defined if the
778
+ SubDirectory is writable as a block, or if the SubDirectory
779
+ can not be edited (in which case Writable is set to 0). If
780
+ non-zero, the SubDirectory is also extracted as a block, so
781
+ the Binary and Protected flags should usually set as well.
782
+ There is currently no way to specify a write format for a
783
+ SubDirectory that is not writable as a block (the default is
784
+ 'int32u' for IFD-type SubDirectories, and 'undef' for all
785
+ others).
785
786
 
786
787
  WriteAlso : Used for writable tag to specify other tags to write when this
787
788
  tag is written. The value is a hash reference. The hash keys
@@ -1083,7 +1084,7 @@ The contained structure field information hashes are similar to tag information
1083
1084
  hashes, except that only the following elements are used:
1084
1085
 
1085
1086
  Raw/Value/PrintConv (and their inverses), TagID (optional), Groups, List,
1086
- Writable, Struct, Namespace, LangCode, PropertyPath, Notes.
1087
+ Writable, Struct, Namespace, FlatName, LangCode, PropertyPath, Notes.
1087
1088
 
1088
1089
  But note that for PropertyPath, only the element of the path corresponding to
1089
1090
  the specific field is stored (including any necessary list properties). The
@@ -29,11 +29,12 @@ use strict;
29
29
  use vars qw($VERSION);
30
30
  use Image::ExifTool qw(:DataAccess :Utils);
31
31
 
32
- $VERSION = '1.54';
32
+ $VERSION = '1.56';
33
33
 
34
34
  sub ConvertTimecode($);
35
35
  sub ProcessSGLT($$$);
36
36
  sub ProcessSLLT($$$);
37
+ sub ProcessLucas($$$);
37
38
 
38
39
  # recognized RIFF variants
39
40
  my %riffType = (
@@ -433,6 +434,14 @@ my %code2charset = (
433
434
  Condition => '$$valPt =~ /^PENTDigital Camera/',
434
435
  SubDirectory => { TagTable => 'Image::ExifTool::Pentax::Junk2' },
435
436
  },
437
+ {
438
+ Name => 'LucasJunk', # (Lucas LK-7900 Ace)
439
+ Condition => '$$valPt =~ /^0G(DA|PS)/',
440
+ SubDirectory => {
441
+ TagTable => 'Image::ExifTool::QuickTime::Stream',
442
+ ProcessProc => \&ProcessLucas,
443
+ },
444
+ },
436
445
  {
437
446
  Name => 'TextJunk',
438
447
  # try to interpret unknown junk as an ASCII string
@@ -476,14 +485,26 @@ my %code2charset = (
476
485
  #
477
486
  # WebP-specific tags
478
487
  #
479
- EXIF => { # (WebP)
488
+ EXIF => [{ # (WebP)
480
489
  Name => 'EXIF',
490
+ Condition => '$$valPt =~ /^(II\x2a\0|MM\0\x2a)/',
481
491
  Notes => 'WebP files',
482
492
  SubDirectory => {
483
493
  TagTable => 'Image::ExifTool::Exif::Main',
484
494
  ProcessProc => \&Image::ExifTool::ProcessTIFF,
485
495
  },
486
- },
496
+ },{ # (WebP) - have also seen with "Exif\0\0" header - PH
497
+ Name => 'EXIF',
498
+ Condition => '$$valPt =~ /^Exif\0\0(II\x2a\0|MM\0\x2a)/',
499
+ SubDirectory => {
500
+ TagTable => 'Image::ExifTool::Exif::Main',
501
+ ProcessProc => \&Image::ExifTool::ProcessTIFF,
502
+ Start => 6,
503
+ },
504
+ },{
505
+ Name => 'UnknownEXIF',
506
+ Binary => 1,
507
+ }],
487
508
  'XMP ' => { #14 (WebP)
488
509
  Name => 'XMP',
489
510
  Notes => 'WebP files',
@@ -1621,6 +1642,105 @@ sub ProcessSLLT($$$)
1621
1642
  return 1;
1622
1643
  }
1623
1644
 
1645
+ #------------------------------------------------------------------------------
1646
+ # Process Lucas streaming GPS information (Lucas LK-7900 Ace) (ref PH)
1647
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
1648
+ # Returns: 1 on success
1649
+ sub ProcessLucas($$$)
1650
+ {
1651
+ my ($et, $dirInfo, $tagTbl) = @_;
1652
+ my $dataPt = $$dirInfo{DataPt};
1653
+ my $dataLen = length $$dataPt;
1654
+
1655
+ unless ($et->Options('ExtractEmbedded')) {
1656
+ $et->Warn('Use ExtractEmbedded option to extract timed GPS', 3);
1657
+ return 1;
1658
+ }
1659
+ my %recLen = ( # record lengths (not including 4-byte ID)
1660
+ '0GDA' => 24,
1661
+ '0GPS' => 48,
1662
+ );
1663
+ my ($date,$time,$lat,$lon,$alt,$spd,$sat,$dop,$ew,$ns);
1664
+ $$et{SET_GROUP0} = $$et{SET_GROUP1} = 'RIFF';
1665
+ while ($$dataPt =~ /(0GDA|0GPS)/g) {
1666
+ my ($rec, $pos) = ($1, pos $$dataPt);
1667
+ $pos + $recLen{$rec} > $dataLen and $et->Warn("Truncated $1 record"), last;
1668
+ $$et{DOC_NUM} = ++$$et{DOC_COUNT};
1669
+ # records start with int64u sample date/time in ms since 1970
1670
+ $et->HandleTag($tagTbl, SampleDateTime => Get64u($dataPt, $pos) / 1000);
1671
+ if ($rec eq '0GPS') {
1672
+ my $len = Get32u($dataPt, $pos+8);
1673
+ my $endPos = $pos + $recLen{$rec} + $len;
1674
+ $endPos > $dataLen and $et->Warn('Truncated 0GPS record'), last;
1675
+ my $buff = substr($$dataPt, $pos+$recLen{$rec}, $len);
1676
+ while ($buff =~ /\$(GC|GA),(\d+),/g) {
1677
+ my $p = pos $buff;
1678
+ $time = $2;
1679
+ if ($1 eq 'GC') {
1680
+ # time date dist ? sat dop alt A
1681
+ # $GC,052350,180914,0000955,1,08,1.1,0017,,A*45\x0d\x0a\0
1682
+ if ($buff =~ /\G(\d+),\d*,\d*,(\d+),([-\d.]+),(\d+),\d*,A/g) {
1683
+ ($date,$sat,$dop,$alt) = ($1,$2,$3,$4);
1684
+ }
1685
+ } else {
1686
+ # time A lat lon spd N W
1687
+ # $GA,052351,A,0949.6626,07635.4439,049,N,E,*4C\x0d\x0a\0
1688
+ if ($buff =~ /\GA,([\d.]+),([\d.]+),(\d+),([NS]),([EW])/g) {
1689
+ ($lat,$lon,$spd,$ns,$ew) = ($1,$2,$3,$4,$5,$6);
1690
+ # lat/long are in DDDMM.MMMM format
1691
+ my $deg = int($lat / 100);
1692
+ $lat = $deg + ($lat - $deg * 100) / 60;
1693
+ $deg = int($lon / 100);
1694
+ $lon = $deg + ($lon - $deg * 100) / 60;
1695
+ $lat *= -1 if $ns eq 'S';
1696
+ $lon *= -1 if $ew eq 'W';
1697
+ }
1698
+ }
1699
+ # look ahead to next NMEA-like sentence, and store the fix
1700
+ # now only if the next sentence is not at the same time
1701
+ if ($buff !~ /\$(GC|GA),$time,/g) {
1702
+ pos($$dataPt) = $endPos;
1703
+ if ($$dataPt !~ /\$(GC|GA),(\d+)/ or $1 ne $time) {
1704
+ $time =~ s/(\d{2})(\d{2})(\d{2})/$1:$2:$3Z/;
1705
+ if ($date) {
1706
+ $date =~ s/(\d{2})(\d{2})(\d{2})/20$3:$2:$1/;
1707
+ $et->HandleTag($tagTbl, GPSDateTime => "$date $time");
1708
+ } else {
1709
+ $et->HandleTag($tagTbl, GPSTimeStamp => $time);
1710
+ }
1711
+ if (defined $lat) {
1712
+ $et->HandleTag($tagTbl, GPSLatitude => $lat);
1713
+ $et->HandleTag($tagTbl, GPSLongitude => $lon);
1714
+ $et->HandleTag($tagTbl, GPSSpeed => $spd);
1715
+ }
1716
+ if (defined $alt) {
1717
+ $et->HandleTag($tagTbl, GPSAltitude => $alt);
1718
+ $et->HandleTag($tagTbl, GPSSatellites => $sat);
1719
+ $et->HandleTag($tagTbl, GPSDOP => $dop);
1720
+ }
1721
+ undef $lat;
1722
+ undef $alt;
1723
+ }
1724
+ }
1725
+ pos($buff) = $p;
1726
+ }
1727
+ $pos += $len;
1728
+ } else { # this is an accelerometer (0GDA) record
1729
+ # record has 4 more int32s values (the last is always 57 or 58 --
1730
+ # maybe related to sample time in ms? -- not extracted)
1731
+ my @acc = unpack('x'.($pos+8).'V3', $$dataPt);
1732
+ # change to signed integer and divide by 256
1733
+ map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
1734
+ $et->HandleTag($tagTbl, Accelerometer => "@acc");
1735
+ }
1736
+ pos($$dataPt) = $pos + $recLen{$rec};
1737
+ }
1738
+ delete $$et{SET_GROUP0};
1739
+ delete $$et{SET_GROUP1};
1740
+ $$et{DOC_NUM} = 0;
1741
+ return 1;
1742
+ }
1743
+
1624
1744
  #------------------------------------------------------------------------------
1625
1745
  # Extract information from a RIFF file
1626
1746
  # Inputs: 0) ExifTool object reference, 1) DirInfo reference
@@ -15,7 +15,7 @@ use strict;
15
15
  use vars qw($VERSION);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
 
18
- $VERSION = '1.03';
18
+ $VERSION = '1.04';
19
19
 
20
20
  sub ProcessUserProps($$$);
21
21
 
@@ -181,12 +181,17 @@ sub UnescapeRTF($$$)
181
181
  if ($1 eq 'uc') { # \ucN
182
182
  $skip = $2;
183
183
  } elsif ($1 eq 'u') { # \uN
184
- require Image::ExifTool::Charset;
185
- $rtnVal .= Image::ExifTool::Charset::Recompose($et, [$2]);
186
- if ($skip) {
187
- # must skip the specified number of characters
188
- # (not simple because RTF control words count as a single character)
189
- last unless $val =~ /\G([^\\]|\\([a-zA-Z]+)(-?\d+)? ?|\\'.{2}|\\.){$skip}/g;
184
+ if ($2 < 0) {
185
+ $et->WarnOnce('Invalid Unicode character(s) in text');
186
+ $rtnVal .= '?';
187
+ } else {
188
+ require Image::ExifTool::Charset;
189
+ $rtnVal .= Image::ExifTool::Charset::Recompose($et, [$2]);
190
+ if ($skip) {
191
+ # must skip the specified number of characters
192
+ # (not simple because RTF control words count as a single character)
193
+ last unless $val =~ /\G([^\\]|\\([a-zA-Z]+)(-?\d+)? ?|\\'.{2}|\\.){$skip}/g;
194
+ }
190
195
  }
191
196
  } elsif ($rtfEntity{$1}) {
192
197
  require Image::ExifTool::Charset;
@@ -19,7 +19,7 @@ use vars qw($VERSION);
19
19
  use Image::ExifTool qw(:DataAccess :Utils);
20
20
  use Image::ExifTool::Exif;
21
21
 
22
- $VERSION = '1.34';
22
+ $VERSION = '1.35';
23
23
 
24
24
  sub ProcessRicohText($$$);
25
25
  sub ProcessRicohRMETA($$$);
@@ -875,6 +875,7 @@ my %ricohLensIDs = (
875
875
  Name => 'SoundFile',
876
876
  Notes => 'audio data recorded in JPEG images by the G700SE',
877
877
  },
878
+ _barcode => { Name => 'Barcodes', List => 1 },
878
879
  );
879
880
 
880
881
  # information stored in Ricoh AVI images (ref PH)
@@ -1004,6 +1005,23 @@ sub ProcessRicohRMETA($$$)
1004
1005
  # (but it looks like the int16u at $dirStart+6 is the next block number
1005
1006
  # if the data is continued, or 0 for the last block)
1006
1007
  $dirLen < 14 and $et->Warn('Short Ricoh RMETA block', 1), return 0;
1008
+ if ($$dataPt =~ /^.{20}BARCODE/s) {
1009
+ my $val = substr($$dataPt, 20);
1010
+ $val =~ s/\0.*//s;
1011
+ $val =~ s/^BARCODE\w+,\d{2},//;
1012
+ my @codes;
1013
+ for (;;) {
1014
+ $val =~ s/(\d+),// and length $val >= $1 or last;
1015
+ push @codes, substr($val, 0, $1);
1016
+ last unless length $val > $1;
1017
+ $val = substr($val, $1+1);
1018
+ }
1019
+ $et->HandleTag($tagTablePtr, '_barcode', \@codes) if @codes;
1020
+ return 1;
1021
+ } elsif ($$dataPt =~ /^.{18}ASCII/s) {
1022
+ # (ignore barcode tag names for now)
1023
+ return 1;
1024
+ }
1007
1025
  my $audioLen = Get16u($dataPt, $dirStart+12);
1008
1026
  $audioLen + 14 > $dirLen and $et->Warn('Truncated Ricoh RMETA audio data', 1), return 0;
1009
1027
  my $buff = substr($$dataPt, $dirStart + 14, $audioLen);
@@ -300,6 +300,7 @@ sub ShiftTime($;$$$)
300
300
  #
301
301
  SplitTime($val, \@time) or return "Invalid time string ($val)";
302
302
  if (defined $time[0]) {
303
+ return "Can't shift from year 0000" if $time[0] eq '0000';
303
304
  $mode = defined $time[3] ? 'DateTime' : 'Date';
304
305
  } elsif (defined $time[3]) {
305
306
  $mode = 'Time';
@@ -16,7 +16,7 @@ use vars qw($VERSION);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
  use Image::ExifTool::Sigma;
18
18
 
19
- $VERSION = '1.26';
19
+ $VERSION = '1.27';
20
20
 
21
21
  sub ProcessX3FHeader($$$);
22
22
  sub ProcessX3FDirectory($$$);
@@ -427,36 +427,43 @@ sub WriteX3F($$)
427
427
  $len -= 28;
428
428
 
429
429
  # only rewrite full-sized JpgFromRaw (version 2.0, type 2, format 18)
430
- if ($buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/ and
431
- $$et{ImageWidth} == unpack('x16V', $buff))
432
- {
430
+ if ($buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/) {
433
431
  $raf->Read($buff, $len) == $len or return 'Error reading JpgFromRaw';
434
- # use same write directories as JPEG
435
- $et->InitWriteDirs('JPEG');
436
- # rewrite the embedded JPEG in memory
437
- my $newData;
438
- my %jpegInfo = (
439
- Parent => 'X3F',
440
- RAF => new File::RandomAccess(\$buff),
441
- OutFile => \$newData,
442
- );
443
- $$et{FILE_TYPE} = 'JPEG';
444
- my $success = $et->WriteJPEG(\%jpegInfo);
445
- $$et{FILE_TYPE} = 'X3F';
446
- SetByteOrder('II');
447
- return 'Error writing X3F JpgFromRaw' unless $success and $newData;
448
- return -1 if $success < 0;
449
- # write new data if anything changed, otherwise copy old image
450
- my $outPt = $$et{CHANGED} ? \$newData : \$buff;
451
- Write($outfile, $$outPt) or return -1;
452
- # set $len to the total subsection data length
453
- $len = length($$outPt) + 28;
454
- $didContain = 1;
432
+ if ($buff =~ /^\xff\xd8\xff\xe1/) { # does this preview contain EXIF?
433
+ # use same write directories as JPEG
434
+ $et->InitWriteDirs('JPEG');
435
+ # make sure we don't add APP0 JFIF because it would mess up our preview identification
436
+ delete $$et{ADD_DIRS}{APP0};
437
+ delete $$et{ADD_DIRS}{JFIF};
438
+ # rewrite the embedded JPEG in memory
439
+ my $newData;
440
+ my %jpegInfo = (
441
+ Parent => 'X3F',
442
+ RAF => new File::RandomAccess(\$buff),
443
+ OutFile => \$newData,
444
+ );
445
+ $$et{FILE_TYPE} = 'JPEG';
446
+ my $success = $et->WriteJPEG(\%jpegInfo);
447
+ $$et{FILE_TYPE} = 'X3F';
448
+ SetByteOrder('II');
449
+ return 'Error writing X3F JpgFromRaw' unless $success and $newData;
450
+ return -1 if $success < 0;
451
+ # (this shouldn't happen unless someone tries to delete the EXIF...)
452
+ return 'EXIF segment must come first in X3F JpgFromRaw' unless $newData =~ /^\xff\xd8\xff\xe1/;
453
+ # write new data if anything changed, otherwise copy old image
454
+ my $outPt = $$et{CHANGED} ? \$newData : \$buff;
455
+ Write($outfile, $$outPt) or return -1;
456
+ # set $len to the total subsection data length
457
+ $len = length($$outPt);
458
+ $didContain = 1;
459
+ } else {
460
+ Write($outfile, $buff) or return -1;
461
+ }
455
462
  } else {
456
463
  # copy original image data
457
464
  Image::ExifTool::CopyBlock($raf, $outfile, $len) or return 'Corrupted X3F image';
458
- $len += 28;
459
465
  }
466
+ $len += 28; # add back header length
460
467
  } else {
461
468
  # copy data for this subsection
462
469
  Image::ExifTool::CopyBlock($raf, $outfile, $len) or return 'Corrupted X3F directory';
@@ -516,16 +523,18 @@ sub ProcessX3FDirectory($$$)
516
523
  $raf->Read($buff, 28) == 28 or return 'Error reading PreviewImage header';
517
524
  # ignore all image data but JPEG compressed (version 2.0, type 2, format 18)
518
525
  next unless $buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/;
519
- # check preview image size and extract full-sized preview as JpgFromRaw
520
- if ($$et{ImageWidth} == unpack('x16V', $buff)) {
526
+ $offset += 28;
527
+ $len -= 28;
528
+ $raf->Read($buff, $len) == $len or return "Error reading PreviewImage data";
529
+ # check fore EXIF segment, and extract this image as the JpgFromRaw
530
+ if ($buff =~ /^\xff\xd8\xff\xe1/) {
521
531
  $$et{IsJpgFromRaw} = 1;
522
532
  $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
523
533
  delete $$et{IsJpgFromRaw};
524
534
  }
525
- $offset += 28;
526
- $len -= 28;
535
+ } else {
536
+ $raf->Read($buff, $len) == $len or return "Error reading $$tagInfo{Name} data";
527
537
  }
528
- $raf->Read($buff, $len) == $len or return "Error reading $$tagInfo{Name} data";
529
538
  my $subdir = $$tagInfo{SubDirectory};
530
539
  if ($subdir) {
531
540
  my %dirInfo = ( DataPt => \$buff );
@@ -591,8 +600,6 @@ sub ProcessX3F($$)
591
600
  $buff .= $buf2;
592
601
  }
593
602
  my ($widPos, $hdrType) = $ver < 4 ? (28, 'Header') : (40, 'Header4');
594
- # extract ImageWidth for later
595
- $$et{ImageWidth} = Get32u(\$buff, $widPos);
596
603
  # process header information
597
604
  my $tagTablePtr = GetTagTable('Image::ExifTool::SigmaRaw::Main');
598
605
  unless ($outfile) {
@@ -34,7 +34,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
34
34
  use Image::ExifTool::Exif;
35
35
  use Image::ExifTool::Minolta;
36
36
 
37
- $VERSION = '3.23';
37
+ $VERSION = '3.28';
38
38
 
39
39
  sub ProcessSRF($$$);
40
40
  sub ProcessSR2($$$);
@@ -143,6 +143,7 @@ sub PrintInvLensSpec($;$$);
143
143
  32854 => 'Sony E 70-350mm F4.5-6.3 G OSS', #IB/JR
144
144
  32858 => 'Sony FE 35mm F1.8', #JR/IB
145
145
  32859 => 'Sony FE 20mm F1.8 G', #IB/JR
146
+ 32860 => 'Sony FE 12-24mm F2.8 GM', #JR/IB
146
147
 
147
148
  # (comment this out so LensID will report the LensModel, which is more useful)
148
149
  # 32952 => 'Metabones Canon EF Speed Booster Ultra', #JR (corresponds to 184, but 'Advanced' mode, LensMount reported as E-mount)
@@ -180,6 +181,7 @@ sub PrintInvLensSpec($;$$);
180
181
  49460 => 'Tamron 24mm F2.8 Di III OSD M1:2', #JR (Model F051)
181
182
  49461 => 'Tamron 20mm F2.8 Di III OSD M1:2', #JR (Model F050)
182
183
  49462 => 'Tamron 70-180mm F2.8 Di III VXD', #JR (Model A056)
184
+ 49463 => 'Tamron 28-200mm F2.8-5.6 Di III RXD', #JR (Model A071)
183
185
 
184
186
  49712 => 'Tokina FiRIN 20mm F2 FE AF', # (firmware Ver.01)
185
187
  49713 => 'Tokina FiRIN 100mm F2.8 FE MACRO', # (firmware Ver.01)
@@ -209,6 +211,8 @@ sub PrintInvLensSpec($;$$);
209
211
  50515 => 'Sigma 35mm F1.2 DG DN | A', #IB/JR (019)
210
212
  50516 => 'Sigma 14-24mm F2.8 DG DN | A', #IB/JR (019)
211
213
  50517 => 'Sigma 24-70mm F2.8 DG DN | A', #JR (019)
214
+ 50518 => 'Sigma 100-400mm F5-6.3 DG DN OS | C', #JR (020)
215
+ 50521 => 'Sigma 85mm F1.4 DG DN | A', #JR (020)
212
216
 
213
217
  50992 => 'Voigtlander SUPER WIDE-HELIAR 15mm F4.5 III', #JR
214
218
  50993 => 'Voigtlander HELIAR-HYPER WIDE 10mm F5.6', #IB
@@ -221,18 +225,21 @@ sub PrintInvLensSpec($;$$);
221
225
  51000 => 'Voigtlander NOKTON 50mm F1.2 Aspherical', #JR
222
226
  51001 => 'Voigtlander NOKTON 21mm F1.4 Aspherical', #JR
223
227
  51002 => 'Voigtlander APO-LANTHAR 50mm F2 Aspherical', #JR
228
+ 51003 => 'Voigtlander NOKTON 35mm F1.2 Aspherical SE', #JR
224
229
 
225
230
  # lenses listed in the Sigma MC-11 list, but not yet seen:
226
231
  # 504xx => 'Sigma 18-200mm F3.5-6.3 DC MACRO OS HSM | C + MC-11', # (014)
227
232
  # 504xx => 'Sigma 30mm F1.4 DC HSM | A + MC-11', # (013)
228
233
 
234
+ # Note: For Samyang lenses, the "FE" designation isn't written to
235
+ # EXIF:LensModel, so it isn't included in these strings either - JR/PH
229
236
  51504 => 'Samyang AF 50mm F1.4', #IB
230
237
  51505 => 'Samyang AF 14mm F2.8 or Samyang AF 35mm F2.8', #forum3833
231
238
  51505.1 => 'Samyang AF 35mm F2.8', #PH (also 32794)
232
239
  51507 => 'Samyang AF 35mm F1.4', #IB
233
240
  51508 => 'Samyang AF 45mm F1.8',
234
241
  51510 => 'Samyang AF 18mm F2.8', #JR
235
-
242
+ 51512 => 'Samyang AF 75mm F1.8', #IB/JR
236
243
  );
237
244
 
238
245
  # ExposureProgram values (ref PH, mainly decoded from A200)
@@ -993,7 +1000,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
993
1000
  SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010h' },
994
1001
  },{
995
1002
  Name => 'Tag2010i', # ?
996
- Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2)|DSC-(RX10M4|RX100M6|RX100M5A|RX100M7|HX99|RX0M2))\b/',
1003
+ Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2)|DSC-(RX10M4|RX100M6|RX100M5A|RX100M7|HX99|RX0M2)|ZV-1)\b/',
997
1004
  SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010i' },
998
1005
  },{
999
1006
  Name => 'Tag_0x2010',
@@ -1378,6 +1385,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1378
1385
  '1 0' => 'Off',
1379
1386
  '1 1' => 'Standard',
1380
1387
  '1 2' => 'High',
1388
+ '65535 65535' => 'n/a', # ILCE-7SM3
1381
1389
  },
1382
1390
  },
1383
1391
  0x2029 => { # uncompressed 14-bit RAW file type setting introduced 2015
@@ -1386,6 +1394,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1386
1394
  PrintConv => {
1387
1395
  0 => 'Compressed RAW',
1388
1396
  1 => 'Uncompressed RAW',
1397
+ 65535 => 'n/a', # seen for ILCE-7SM3 JPEG-only
1389
1398
  },
1390
1399
  },
1391
1400
  # 0x202a - first seen for ILCE-6300: 66 bytes
@@ -1484,6 +1493,13 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1484
1493
  PrintConv => 'sprintf("%.8d",$val)',
1485
1494
  PrintConvInv => '$val',
1486
1495
  },
1496
+ # 0x2032 - first seen for ILCE-7SM3, July 2020
1497
+ # 0x2033 - first seen for ILCE-7SM3, July 2020
1498
+ # 0x2034 - first seen for ILCE-7SM3, July 2020
1499
+ # 0x2035 - first seen for ILCE-7SM3, July 2020
1500
+ # 0x2036 - first seen for ILCE-7SM3, July 2020
1501
+ # 0x2037 - first seen for ILCE-7SM3, July 2020
1502
+ # 0x2039 - first seen for ILCE-7SM3, July 2020
1487
1503
  0x3000 => {
1488
1504
  Name => 'ShotInfo',
1489
1505
  SubDirectory => { TagTable => 'Image::ExifTool::Sony::ShotInfo' },
@@ -1512,7 +1528,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1512
1528
  # from mid-2015: ILCE-7RM2/7SM2/6300 and newer models use different offsets
1513
1529
  {
1514
1530
  Name => 'Tag9050a',
1515
- Condition => '$$self{Model} !~ /^(DSC-|Stellar|ILCE-(6100|6300|6400|6500|6600|7M3|7RM2|7RM3|7RM4|7SM2|9|9M2)|ILCA-99M2)/',
1531
+ Condition => '$$self{Model} !~ /^(DSC-|Stellar|ILCE-(6100|6300|6400|6500|6600|7M3|7RM2|7RM3|7RM4|7SM2|7SM3|9|9M2)|ILCA-99M2|ZV-)/',
1516
1532
  SubDirectory => {
1517
1533
  TagTable => 'Image::ExifTool::Sony::Tag9050a',
1518
1534
  ByteOrder => 'LittleEndian',
@@ -1524,6 +1540,13 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1524
1540
  TagTable => 'Image::ExifTool::Sony::Tag9050b',
1525
1541
  ByteOrder => 'LittleEndian',
1526
1542
  },
1543
+ },{
1544
+ Name => 'Tag9050c',
1545
+ Condition => '$$self{Model} =~ /^(ILCE-7SM3)/',
1546
+ SubDirectory => {
1547
+ TagTable => 'Image::ExifTool::Sony::Tag9050c',
1548
+ ByteOrder => 'LittleEndian',
1549
+ },
1527
1550
  },{
1528
1551
  Name => 'Sony_0x9050',
1529
1552
  %unknownCipherData,
@@ -1538,7 +1561,8 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1538
1561
  # 0x23 (e) for DSC-RX10/HX60V/HX350/HX400V/WX220/WX350, ILCE-7/7R/5000/6000, ILCA-68/77M2
1539
1562
  # 0x24 (e) for ILCA-99M2,ILCE-5100/6300/6500/7M2/7RM2/7S/7SM2/QX1, DSC-HX80/HX90V/QX30/RX0/RX100M3/RX100M4/RX100M5/RX10M2/RX10M3/RX1RM2/WX500
1540
1563
  # 0x26 (e) for ILCE-6100/6400/6600/7M3/7RM3/9, DSC-RX0M2/RX10M4/RX100M5A/RX100M6/HX99
1541
- # 0x28 (e) for ILCE-7RM4/9M2, DSC-RX100M7
1564
+ # 0x28 (e) for ILCE-7RM4/9M2, DSC-RX100M7, ZV-1
1565
+ # 0x31 (e) for ILCE-7SM3
1542
1566
  # first byte decoded: 40, 204, 202, 27, 58, 62, 48, 215, 28 respectively
1543
1567
  {
1544
1568
  Name => 'Tag9400a',
@@ -1677,7 +1701,8 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1677
1701
  # 13 0 9 2 2 DSC-QX10/QX100/RX100M2
1678
1702
  # 15 0 35 2 2 ILCA-68/77M2, ILCE-5000/5100/6000/7/7R/7S/7M2/QX1, DSC-HX60V/HX350/HX400V/QX30/RX10/RX100M3/WX220/WX350
1679
1703
  # 16 0 85 2 2 DSC-HX80/HX90V/WX500
1680
- # 17 0 232 1 2 DSC-RX0/RX0M2/RX1RM2/RX10M2/RX10M3/RX10M4/RX100M4/RX100M5/RX100M5A/RX100M6/RX100M7/HX99, ILCE-6100/6300/6400/6500/6600/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2, ILCA-99M2
1704
+ # 17 0 232 1 2 DSC-RX0/RX0M2/RX1RM2/RX10M2/RX10M3/RX10M4/RX100M4/RX100M5/RX100M5A/RX100M6/RX100M7/HX99, ILCE-6100/6300/6400/6500/6600/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2, ILCA-99M2, ZV-1
1705
+ # 18 0 20 0 164 ILCE-7SM3
1681
1706
  # other values for Panorama images and several other models
1682
1707
  0x9404 => [{
1683
1708
  Name => 'Tag9404a',
@@ -1711,7 +1736,8 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1711
1736
  # 142 var (0x25 = 37 var enc.) DSC-HX80/HX90V/RX1RM2/RX10M2/RX10M3/RX100M4/WX500, ILCE-6300/7RM2/7SM2
1712
1737
  # 144 var (0xe1 = 225 var enc.) DSC-RX100M5
1713
1738
  # 145 var (0x76 = 118 var enc.) ILCA-99M2, ILCE-6500, DSC-RX0
1714
- # 163 var (0x8b = 139 var enc.) ILCE-6100/6400/6600/7M3/7RM3/7RM4/9/9M2, DSC-RX0M2/RX10M4/RX100M5A/RX100M6/RX100M7/HX99
1739
+ # 163 var (0x8b = 139 var enc.) ILCE-6100/6400/6600/7M3/7RM3/7RM4/9/9M2, DSC-RX0M2/RX10M4/RX100M5A/RX100M6/RX100M7/HX99, ZV-1
1740
+ # July 2020: ILCE-7SM3 doesn't write this tag anymore, but writes 0x9416
1715
1741
  0x9405 => [{
1716
1742
  Name => 'Tag9405a',
1717
1743
  # first byte must be 0x1b or 0x40 or 0x7d
@@ -1798,6 +1824,10 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1798
1824
  %unknownCipherData,
1799
1825
  # 0x02 - int32u?: 1,3,5,7,9 (A77)
1800
1826
  },
1827
+ 0x9416 => { # replaces 0x9405 for the Sony ILCE-7SM3, from July 2020
1828
+ Name => 'Sony_0x9416',
1829
+ SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9416' },
1830
+ },
1801
1831
  0xb000 => { #8
1802
1832
  Name => 'FileFormat',
1803
1833
  Writable => 'int8u',
@@ -1820,6 +1850,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1820
1850
  '3 3 2 0' => 'ARW 2.3.2', #JR (DSC-RX1RM2,ILCE-7SM2 - support for uncompressed 14-bit RAW)
1821
1851
  '3 3 3 0' => 'ARW 2.3.3', #JR (ILCE-9)
1822
1852
  '3 3 5 0' => 'ARW 2.3.5', #JR (DSC-HX99)
1853
+ '4 0 0 0' => 'ARW 4.0', # (ILCE-7SM3)
1823
1854
  # what about cRAW images?
1824
1855
  },
1825
1856
  },
@@ -1913,6 +1944,8 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1913
1944
  376 => 'ILCE-9M2', #JR
1914
1945
  378 => 'ILCE-6600', #IB/JR
1915
1946
  379 => 'ILCE-6100', #IB/JR
1947
+ 380 => 'ZV-1', #JR
1948
+ 383 => 'ILCE-7SM3',
1916
1949
  },
1917
1950
  },
1918
1951
  0xb020 => { #2
@@ -6049,8 +6082,11 @@ my %isoSetting2010 = (
6049
6082
  33 => 16000,
6050
6083
  34 => 20000,
6051
6084
  35 => 25600,
6085
+ 36 => 32000,
6086
+ 37 => 40000,
6052
6087
  38 => 51200,
6053
6088
  39 => 64000,
6089
+ 40 => 80000,
6054
6090
  41 => 102400,
6055
6091
  42 => 128000,
6056
6092
  43 => 160000,
@@ -7725,6 +7761,107 @@ my %isoSetting2010 = (
7725
7761
  },
7726
7762
  );
7727
7763
 
7764
+ %Image::ExifTool::Sony::Tag9050c = ( #JR
7765
+ PROCESS_PROC => \&ProcessEnciphered,
7766
+ WRITE_PROC => \&WriteEnciphered,
7767
+ CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
7768
+ FORMAT => 'int8u',
7769
+ NOTES => q{
7770
+ Valid from July 2020 for ILCE-7SM3.
7771
+ },
7772
+ WRITABLE => 1,
7773
+ FIRST_ENTRY => 0,
7774
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
7775
+ DATAMEMBER => [ 0x0039 ],
7776
+ 0x0026 => {
7777
+ Name => 'Shutter',
7778
+ Format => 'int16u[3]',
7779
+ PrintConv => {
7780
+ '0 0 0' => 'Silent / Electronic (0 0 0)',
7781
+ OTHER => sub {
7782
+ my ($val, $inv) = @_;
7783
+ return $inv ? ($val=~/\((.*?)\)/ ? $1 : undef) : "Mechanical ($val)";
7784
+ },
7785
+ },
7786
+ },
7787
+ 0x0039 => {
7788
+ Name => 'FlashStatus',
7789
+ RawConv => '$$self{FlashFired} = $val',
7790
+ PrintConv => {
7791
+ 0 => 'No Flash present',
7792
+ 2 => 'Flash Inhibited', # seen for ILCE-7/7R continuous, panorama, HDR mode
7793
+ 64 => 'Built-in Flash present',
7794
+ 65 => 'Built-in Flash Fired',
7795
+ 66 => 'Built-in Flash Inhibited', # seen for panorama, HDR, burst mode
7796
+ 128 => 'External Flash present', # seen for NEX-5N/5T
7797
+ 129 => 'External Flash Fired', # seen for SLT-A99V, ILCE-7R, NEX-5N/5R
7798
+ },
7799
+ },
7800
+ 0x003a => {
7801
+ Name => 'ShutterCount',
7802
+ # or "ShutterCount"? : number of shutter actuations, does not increase during Silent Shooting,
7803
+ # at least for ILCE-7RM2
7804
+ Format => 'int32u',
7805
+ Notes => 'total number of image exposures made by the camera',
7806
+ RawConv => '$val & 0x00ffffff',
7807
+ PrintConv => 'sprintf("%6d",$val)',
7808
+ },
7809
+ 0x0046 => { # appr. same value as Exif ExposureTime, but longer in HDR-modes
7810
+ Name => 'SonyExposureTime',
7811
+ Format => 'int16u',
7812
+ ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
7813
+ ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
7814
+ PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
7815
+ PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
7816
+ },
7817
+ 0x0048 => {
7818
+ Name => 'SonyFNumber',
7819
+ Format => 'int16u',
7820
+ ValueConv => '2 ** (($val/256 - 16) / 2)',
7821
+ ValueConvInv => '(log($val)*2/log(2)+16)*256',
7822
+ PrintConv => 'sprintf("%.1f",$val)',
7823
+ PrintConvInv => '$val',
7824
+ },
7825
+ 0x004b => {
7826
+ Name => 'ReleaseMode2',
7827
+ %releaseMode2,
7828
+ },
7829
+ 0x0050 => {
7830
+ Name => 'ShutterCount2',
7831
+ Condition => '(($$self{FlashFired} & 0x01) != 1) and ($$self{Model} =~ /^(ILCE-7SM3)/)',
7832
+ Format => 'int32u',
7833
+ RawConv => '$val & 0x00ffffff',
7834
+ },
7835
+ 0x0066 => { # appr. same value as Exif ExposureTime, but not valid in HDR-modes
7836
+ Name => 'SonyExposureTime',
7837
+ Condition => '$$self{Model} =~ /^(ILCE-7SM3)/',
7838
+ Format => 'int16u',
7839
+ ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
7840
+ ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
7841
+ PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
7842
+ PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
7843
+ },
7844
+ 0x0068 => { # appr. same value as Exif ExposureTime, but not valid in HDR-modes
7845
+ Name => 'SonyFNumber',
7846
+ Condition => '$$self{Model} =~ /^(ILCE-7SM3)/',
7847
+ Format => 'int16u',
7848
+ ValueConv => '2 ** (($val/256 - 16) / 2)',
7849
+ ValueConvInv => '(log($val)*2/log(2)+16)*256',
7850
+ PrintConv => 'sprintf("%.1f",$val)',
7851
+ PrintConvInv => '$val',
7852
+ },
7853
+ 0x006b => {
7854
+ Name => 'ReleaseMode2',
7855
+ Condition => '$$self{Model} =~ /^(ILCE-7SM3)/',
7856
+ %releaseMode2,
7857
+ },
7858
+ 0x0088 => {
7859
+ Name => 'InternalSerialNumber', #(NC)
7860
+ Format => 'int8u[6]',
7861
+ PrintConv => 'unpack "H*", pack "C*", split " ", $val',
7862
+ },
7863
+ );
7864
+
7728
7865
  %Image::ExifTool::Sony::Tag9400a = ( #JR
7729
7866
  PROCESS_PROC => \&ProcessEnciphered,
7730
7867
  WRITE_PROC => \&WriteEnciphered,
@@ -7901,7 +8038,7 @@ my %isoSetting2010 = (
7901
8038
  GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
7902
8039
  0x0009 => { %releaseMode2 },
7903
8040
  0x000a => [{
7904
- Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2)|DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2))\b/',
8041
+ Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2)|DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2)|ZV-1)\b/',
7905
8042
  Name => 'ShotNumberSincePowerUp',
7906
8043
  Format => 'int8u',
7907
8044
  },{
@@ -7981,11 +8118,12 @@ my %isoSetting2010 = (
7981
8118
  FIRST_ENTRY => 0,
7982
8119
  GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
7983
8120
  DATAMEMBER => [ 0 ],
7984
- IS_SUBDIR => [ 0x0498, 0x04a2, 0x059d, 0x0634, 0x0636, 0x064c, 0x0653, 0x0678, 0x06b8, 0x06de, 0x06e7 ],
8121
+ IS_SUBDIR => [ 0x0498, 0x04a1, 0x04a2, 0x059d, 0x0634, 0x0636, 0x064c, 0x0653, 0x0678, 0x06b8, 0x06de, 0x06e7 ],
7985
8122
  0x0000 => { Name => 'Ver9401', Hidden => 1, RawConv => '$$self{Ver9401} = $val; $$self{OPTIONS}{Unknown}<2 ? undef : $val' },
7986
8123
 
7987
8124
  0x0498 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 148', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
7988
- 0x04a2 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(152|154)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
8125
+ 0x04a1 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 160', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
8126
+ 0x04a2 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(152|154|155)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
7989
8127
  0x059d => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(144|146)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
7990
8128
  0x0634 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 68', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
7991
8129
  0x0636 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(73|74)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
@@ -8056,6 +8194,7 @@ my %isoSetting2010 = (
8056
8194
  14 => 'Tracking',
8057
8195
  15 => 'Face Tracking',
8058
8196
  20 => 'Animal Eye Tracking',
8197
+ # 21 => '???', # (ILCE-7SM3)
8059
8198
  255 => 'Manual',
8060
8199
  },
8061
8200
  },
@@ -8327,7 +8466,7 @@ my %isoSetting2010 = (
8327
8466
  # also often deviating results for Sony FE 90mm F2.8 Macro G OSS ...
8328
8467
  Name => 'SonyFNumber',
8329
8468
  Format => 'int16u',
8330
- Condition => '$$self{Model} !~ /^DSC-/',
8469
+ Condition => '$$self{Model} !~ /^(DSC-|ZV-)/',
8331
8470
  ValueConv => '2 ** (($val/256 - 16) / 2)',
8332
8471
  ValueConvInv => '(log($val)*2/log(2)+16)*256',
8333
8472
  PrintConv => 'sprintf("%.1f",$val)',
@@ -8443,7 +8582,7 @@ my %isoSetting2010 = (
8443
8582
  },
8444
8583
  0x0342 => {
8445
8584
  Name => 'LensZoomPosition',
8446
- Condition => '$$self{Model} !~ /^(ILCA-|ILCE-(7RM2|7M3|7RM3|7RM4|7SM2|6100|6300|6400|6500|6600|9|9M2)|DSC-(HX80|HX90V|HX99|RX0|RX10M2|RX10M3|RX10M4|RX100M4|RX100M5|RX100M5A|RX100M6|RX100M7|WX500))/',
8585
+ Condition => '$$self{Model} !~ /^(ILCA-|ILCE-(7RM2|7M3|7RM3|7RM4|7SM2|6100|6300|6400|6500|6600|9|9M2)|DSC-(HX80|HX90V|HX99|RX0|RX10M2|RX10M3|RX10M4|RX100M4|RX100M5|RX100M5A|RX100M6|RX100M7|WX500)|ZV-)/',
8447
8586
  Format => 'int16u',
8448
8587
  PrintConv => 'sprintf("%.0f%%",$val/10.24)',
8449
8588
  PrintConvInv => '$val=~s/ ?%$//; $val * 10.24',
@@ -9243,6 +9382,145 @@ my %isoSetting2010 = (
9243
9382
  0xbc => { Name => 'AFStatus_94_E6_Center_F2-8', %Image::ExifTool::Minolta::afStatusInfo },
9244
9383
  );
9245
9384
 
9385
+ # tag 0x9416 decoding (ref JR)
9386
+ %Image::ExifTool::Sony::Tag9416 = (
9387
+ PROCESS_PROC => \&ProcessEnciphered,
9388
+ WRITE_PROC => \&WriteEnciphered,
9389
+ CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
9390
+ FORMAT => 'int8u',
9391
+ FIRST_ENTRY => 0,
9392
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
9393
+ 0x0000 => { Name => 'Tag9416_0000', PrintConv => 'sprintf("%3d",$val)', RawConv => '$$self{TagVersion} = $val' },
9394
+ 0x0004 => {
9395
+ Name => 'SonyISO',
9396
+ Format => 'int16u',
9397
+ ValueConv => '100 * 2**(16 - $val/256)',
9398
+ ValueConvInv => '256 * (16 - log($val/100)/log(2))',
9399
+ PrintConv => 'sprintf("%.0f",$val)',
9400
+ PrintConvInv => '$val',
9401
+ },
9402
+ 0x0006 => { %gain2010 },
9403
+ 0x000a => { # appr. same value as Exif ExposureTime, but shorter in HDR-modes
9404
+ Name => 'SonyExposureTime2',
9405
+ Format => 'int16u',
9406
+ ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
9407
+ ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
9408
+ PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
9409
+ PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
9410
+ },
9411
+ 0x000c => {
9412
+ Name => 'ExposureTime',
9413
+ Format => 'rational32u',
9414
+ PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"', # (Bulb NC)
9415
+ PrintConvInv => 'lc($val) eq "bulb" ? 0 : $val',
9416
+ },
9417
+ 0x0010 => { # but sometimes deviating results
9418
+ Name => 'SonyFNumber2',
9419
+ Format => 'int16u',
9420
+ ValueConv => '2 ** (($val/256 - 16) / 2)',
9421
+ ValueConvInv => '(log($val)*2/log(2)+16)*256',
9422
+ PrintConv => 'sprintf("%.1f",$val)',
9423
+ PrintConvInv => '$val',
9424
+ },
9425
+ 0x0012 => {
9426
+ Name => 'SonyMaxApertureValue', # (at current focal length)
9427
+ Format => 'int16u',
9428
+ ValueConv => '2 ** (($val/256 - 16) / 2)',
9429
+ ValueConvInv => '(log($val)*2/log(2)+16)*256',
9430
+ PrintConv => 'sprintf("%.1f",$val)',
9431
+ PrintConvInv => '$val',
9432
+ },
9433
+ 0x001d => { %sequenceImageNumber },
9434
+ 0x0035 => {
9435
+ Name => 'ExposureProgram',
9436
+ Priority => 0,
9437
+ SeparateTable => 'ExposureProgram3',
9438
+ PrintConv => \%sonyExposureProgram3,
9439
+ },
9440
+ 0x0048 => {
9441
+ Name => 'LensMount',
9442
+ Condition => '$$self{Model} !~ /^(DSC-)/',
9443
+ PrintConv => {
9444
+ 0 => 'Unknown',
9445
+ 1 => 'A-mount',
9446
+ 2 => 'E-mount',
9447
+ 3 => 'A-mount (3)',
9448
+ },
9449
+ },
9450
+ 0x0049 => {
9451
+ Name => 'LensFormat',
9452
+ Condition => '$$self{Model} !~ /^(DSC-)/',
9453
+ PrintConv => {
9454
+ 0 => 'Unknown',
9455
+ 1 => 'APS-C',
9456
+ 2 => 'Full-frame',
9457
+ },
9458
+ },
9459
+ 0x004a => {
9460
+ Name => 'LensMount',
9461
+ DataMember => 'LensMount',
9462
+ RawConv => '$$self{LensMount} = $val; $$self{Model} =~ /^(DSC-)/ ? undef : $val',
9463
+ PrintConv => {
9464
+ 0 => 'Unknown',
9465
+ 1 => 'A-mount',
9466
+ 2 => 'E-mount',
9467
+ },
9468
+ },
9469
+ 0x004b => {
9470
+ Name => 'LensType2',
9471
+ Condition => '$$self{LensMount} == 2',
9472
+ Format => 'int16u',
9473
+ SeparateTable => 'LensType2',
9474
+ PrintConv => \%sonyLensTypes2,
9475
+ },
9476
+ 0x004d => {
9477
+ Name => 'LensType',
9478
+ Condition => '$$self{LensMount} == 1',
9479
+ Priority => 0, #PH (just to be safe)
9480
+ Format => 'int16u', #PH
9481
+ SeparateTable => 1,
9482
+ ValueConvInv => '($val & 0xff00) == 0x8000 ? 0 : int($val)',
9483
+ PrintConv => \%sonyLensTypes,
9484
+ },
9485
+ 0x004f => {
9486
+ Name => 'DistortionCorrParams',
9487
+ Format => 'int16s[16]',
9488
+ },
9489
+ 0x0071 => {
9490
+ Name => 'FocalLength',
9491
+ Format => 'int16u',
9492
+ ValueConv => '$val / 10',
9493
+ ValueConvInv => '$val * 10',
9494
+ PrintConv => 'sprintf("%.1f mm",$val)',
9495
+ PrintConvInv => '$val =~ s/ ?mm//; $val',
9496
+ },
9497
+ 0x0073 => {
9498
+ Name => 'MinFocalLength',
9499
+ Format => 'int16u',
9500
+ ValueConv => '$val / 10',
9501
+ ValueConvInv => '$val * 10',
9502
+ PrintConv => 'sprintf("%.1f mm",$val)',
9503
+ PrintConvInv => '$val =~ s/ ?mm//; $val',
9504
+ },
9505
+ 0x0075 => { # may give 0 for fixed focal length lenses
9506
+ Name => 'MaxFocalLength',
9507
+ Format => 'int16u',
9508
+ RawConv => '$val || undef',
9509
+ ValueConv => '$val / 10',
9510
+ ValueConvInv => '$val * 10',
9511
+ PrintConv => 'sprintf("%.1f mm",$val)',
9512
+ PrintConvInv => '$val =~ s/ ?mm//; $val',
9513
+ },
9514
+ 0x088f => {
9515
+ Name => 'VignettingCorrParams',
9516
+ Format => 'int16s[16]',
9517
+ },
9518
+ 0x0914 => {
9519
+ Name => 'ChromaticAberrationCorrParams',
9520
+ Format => 'int16s[32]',
9521
+ },
9522
+ );
9523
+
9246
9524
  %Image::ExifTool::Sony::FaceInfo1 = (
9247
9525
  %binaryDataAttrs,
9248
9526
  GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
@@ -9740,12 +10018,88 @@ my %isoSetting2010 = (
9740
10018
  # 0x8100 - 16 bytes starting with 0x060e2b340401
9741
10019
  0x8100 => { Name => 'Sony_rtmd_0x8100', Format => 'int8u', %hidUnk },
9742
10020
  0x8101 => { Name => 'Sony_rtmd_0x8101', Format => 'int8u', %hidUnk }, # seen: 0,1
10021
+ 0x8106 => { Name => 'Sony_rtmd_0x8106', Format => 'int32u', %hidUnk }, # seen: "25 1"
9743
10022
  0x8109 => { Name => 'Sony_rtmd_0x8109', Format => 'int32u', %hidUnk }, # seen: "1 50"
9744
10023
  0x810a => { Name => 'Sony_rtmd_0x810a', Format => 'int16u', %hidUnk }, # seen: 0
9745
10024
  0x810b => { Name => 'Sony_rtmd_0x810b', Format => 'int16u', %hidUnk }, # seen: 100
9746
10025
  0x810c => { Name => 'Sony_rtmd_0x810c', Format => 'int16u', %hidUnk }, # seen: 100
9747
10026
  0x810d => { Name => 'Sony_rtmd_0x810d', Format => 'int8u', %hidUnk }, # seen: 1
10027
+ 0x8115 => { Name => 'Sony_rtmd_0x8115', Format => 'int16u', %hidUnk }, # seen: 100
9748
10028
  # 0x8300 - container for other tags in this format
10029
+ 0x8500 => {
10030
+ Name => 'GPSVersionID',
10031
+ Groups => { 2 => 'Location' },
10032
+ Format => 'int8u',
10033
+ PrintConv => '$val =~ tr/ /./; $val',
10034
+ },
10035
+ 0x8501 => {
10036
+ Name => 'GPSLatitudeRef',
10037
+ Groups => { 2 => 'Location' },
10038
+ Format => 'string',
10039
+ PrintConv => {
10040
+ N => 'North',
10041
+ S => 'South',
10042
+ },
10043
+ },
10044
+ 0x8502 => {
10045
+ Name => 'GPSLatitude',
10046
+ Groups => { 2 => 'Location' },
10047
+ Format => 'rational64u',
10048
+ ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ToDegrees($val)',
10049
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
10050
+ },
10051
+ 0x8503 => {
10052
+ Name => 'GPSLongitudeRef',
10053
+ Groups => { 2 => 'Location' },
10054
+ Format => 'string',
10055
+ PrintConv => {
10056
+ E => 'East',
10057
+ W => 'West',
10058
+ },
10059
+ },
10060
+ 0x8504 => {
10061
+ Name => 'GPSLongitude',
10062
+ Groups => { 2 => 'Location' },
10063
+ Format => 'rational64u',
10064
+ ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ToDegrees($val)',
10065
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
10066
+ },
10067
+ 0x8507 => {
10068
+ Name => 'GPSTimeStamp',
10069
+ Groups => { 2 => 'Time' },
10070
+ Format => 'rational64u',
10071
+ ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ConvertTimeStamp($val)',
10072
+ PrintConv => 'Image::ExifTool::GPS::PrintTimeStamp($val)',
10073
+ },
10074
+ 0x8509 => {
10075
+ Name => 'GPSStatus',
10076
+ Groups => { 2 => 'Location' },
10077
+ Format => 'string',
10078
+ PrintConv => {
10079
+ A => 'Measurement Active',
10080
+ V => 'Measurement Void',
10081
+ },
10082
+ },
10083
+ 0x850a => {
10084
+ Name => 'GPSMeasureMode',
10085
+ Groups => { 2 => 'Location' },
10086
+ Format => 'string',
10087
+ PrintConv => {
10088
+ 2 => '2-Dimensional Measurement',
10089
+ 3 => '3-Dimensional Measurement',
10090
+ },
10091
+ },
10092
+ 0x8512 => {
10093
+ Name => 'GPSMapDatum',
10094
+ Groups => { 2 => 'Location' },
10095
+ Format => 'string',
10096
+ },
10097
+ 0x851d => {
10098
+ Name => 'GPSDateStamp',
10099
+ Groups => { 2 => 'Time' },
10100
+ Format => 'string',
10101
+ ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
10102
+ },
9749
10103
  0xe000 => { Name => 'Sony_rtmd_0xe000', Format => 'int8u', %hidUnk }, # (16 bytes)
9750
10104
  0xe300 => { Name => 'Sony_rtmd_0xe300', Format => 'int8u', %hidUnk }, # seen: 0,1
9751
10105
  0xe301 => { Name => 'Sony_rtmd_0xe301', Format => 'int32u', %hidUnk }, # seen: 100
@@ -9758,6 +10112,8 @@ my %isoSetting2010 = (
9758
10112
  ValueConv => 'my @a=unpack("x1H4H2H2H2H2H2",$val); "$a[0]:$a[1]:$a[2] $a[3]:$a[4]:$a[5]"',
9759
10113
  PrintConv => '$self->ConvertDateTime($val)',
9760
10114
  },
10115
+ # f010 - 2048 bytes
10116
+ # f020 - 543 bytes
9761
10117
  );
9762
10118
 
9763
10119
  # Composite Sony tags
@@ -9792,6 +10148,17 @@ my %isoSetting2010 = (
9792
10148
  },
9793
10149
  PrintConv => '$val eq "inf" ? $val : sprintf("%.2f m",$val)',
9794
10150
  },
10151
+ GPSDateTime => {
10152
+ Description => 'GPS Date/Time',
10153
+ Groups => { 2 => 'Time' },
10154
+ SubDoc => 1, # generate for all sub-documents
10155
+ Require => {
10156
+ 0 => 'Sony:GPSDateStamp',
10157
+ 1 => 'Sony:GPSTimeStamp',
10158
+ },
10159
+ ValueConv => '"$val[0] $val[1]Z"',
10160
+ PrintConv => '$self->ConvertDateTime($val)',
10161
+ },
9795
10162
  );
9796
10163
 
9797
10164
  # add our composite tags