exiftool_vendored 11.94.0 → 12.06.0

Sign up to get free protection for your applications and to get access to all the features.

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