exiftool_vendored 13.18.0 → 13.21.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.
@@ -43,12 +43,12 @@
43
43
  package Image::ExifTool::QuickTime;
44
44
 
45
45
  use strict;
46
- use vars qw($VERSION $AUTOLOAD %stringEncoding %avType);
46
+ use vars qw($VERSION $AUTOLOAD %stringEncoding %avType %dontInherit %eeBox);
47
47
  use Image::ExifTool qw(:DataAccess :Utils);
48
48
  use Image::ExifTool::Exif;
49
49
  use Image::ExifTool::GPS;
50
50
 
51
- $VERSION = '3.12';
51
+ $VERSION = '3.13';
52
52
 
53
53
  sub ProcessMOV($$;$);
54
54
  sub ProcessKeys($$$);
@@ -487,9 +487,13 @@ my %qtFlags = ( #12
487
487
  );
488
488
 
489
489
  # properties which don't get inherited from the parent
490
- my %dontInherit = (
491
- ispe => 1, # size of parent may be different
492
- hvcC => 1, # (likely redundant)
490
+ # 1 = parent doesn't inherit this property
491
+ # 2 = parent doesn't inherit, but child does
492
+ %dontInherit = (
493
+ ispe => 1, # primary item must have an ispe and pixi, so no need to inherit these
494
+ pixi => 1,
495
+ hvcC => 2, # (hvcC is a property of hvc1 referred to by primary grid)
496
+ colr => 2, # (colr is a property of primary grid or hvc1 referred to by primary)
493
497
  );
494
498
 
495
499
  # tags that may be duplicated and directories that may contain duplicate tags
@@ -509,7 +513,7 @@ my %hashBox = ( vide => { %eeStd }, soun => { %eeStd } );
509
513
  # when the ExtractEmbedded is enabled (currently only the 'gps ' container name is
510
514
  # used, but others have been checked against all available sample files and may be
511
515
  # useful in the future if the names are used for different boxes on other locations)
512
- my %eeBox = (
516
+ %eeBox = (
513
517
  # (note: vide is only processed if specific atoms exist in the VisualSampleDesc)
514
518
  vide => { %eeStd, JPEG => 'stsd' },
515
519
  text => { %eeStd },
@@ -1596,28 +1600,6 @@ my %userDefined = (
1596
1600
  PrintConv => \&PrintGPSCoordinates,
1597
1601
  PrintConvInv => \&PrintInvGPSCoordinates,
1598
1602
  },
1599
- # \xa9 tags written by DJI Phantom 3: (ref PH)
1600
- "\xa9xsp" => 'SpeedX', #PH (guess)
1601
- "\xa9ysp" => 'SpeedY', #PH (guess)
1602
- "\xa9zsp" => 'SpeedZ', #PH (guess)
1603
- "\xa9fpt" => 'Pitch', #PH
1604
- "\xa9fyw" => 'Yaw', #PH
1605
- "\xa9frl" => 'Roll', #PH
1606
- "\xa9gpt" => 'CameraPitch', #PH
1607
- "\xa9gyw" => 'CameraYaw', #PH
1608
- "\xa9grl" => 'CameraRoll', #PH
1609
- "\xa9enc" => 'EncoderID', #PH (forum9271)
1610
- # and the following entries don't have the proper 4-byte header for \xa9 tags:
1611
- "\xa9dji" => { Name => 'UserData_dji', Format => 'undef', Binary => 1, Unknown => 1, Hidden => 1 },
1612
- "\xa9res" => { Name => 'UserData_res', Format => 'undef', Binary => 1, Unknown => 1, Hidden => 1 },
1613
- "\xa9uid" => { Name => 'UserData_uid', Format => 'undef', Binary => 1, Unknown => 1, Hidden => 1 },
1614
- "\xa9mdl" => {
1615
- Name => 'Model',
1616
- Notes => 'non-standard-format DJI tag',
1617
- Format => 'string',
1618
- Avoid => 1,
1619
- },
1620
- # end DJI tags
1621
1603
  name => 'Name',
1622
1604
  WLOC => {
1623
1605
  Name => 'WindowLocation',
@@ -2088,7 +2070,35 @@ my %userDefined = (
2088
2070
  "\xa9TSC" => 'StartTimeScale', # (Hero6)
2089
2071
  "\xa9TSZ" => 'StartTimeSampleSize', # (Hero6)
2090
2072
  "\xa9TIM" => 'StartTimecode', #PH (NC)
2091
- # --- HTC ----
2073
+ # ---- DJI ----
2074
+ # \xa9 tags written by DJI Phantom 3: (ref PH)
2075
+ "\xa9xsp" => 'SpeedX', #PH (guess)
2076
+ "\xa9ysp" => 'SpeedY', #PH (guess)
2077
+ "\xa9zsp" => 'SpeedZ', #PH (guess)
2078
+ "\xa9fpt" => 'Pitch', #PH
2079
+ "\xa9fyw" => 'Yaw', #PH
2080
+ "\xa9frl" => 'Roll', #PH
2081
+ "\xa9gpt" => 'CameraPitch', #PH
2082
+ "\xa9gyw" => 'CameraYaw', #PH
2083
+ "\xa9grl" => 'CameraRoll', #PH
2084
+ "\xa9enc" => 'EncoderID', #PH (forum9271)
2085
+ # and the following entries don't have the proper 4-byte header for \xa9 tags:
2086
+ "\xa9dji" => { Name => 'UserData_dji', Format => 'undef', Binary => 1, Unknown => 1, Hidden => 1 },
2087
+ "\xa9res" => { Name => 'UserData_res', Format => 'undef', Binary => 1, Unknown => 1, Hidden => 1 },
2088
+ "\xa9uid" => { Name => 'UserData_uid', Format => 'undef', Binary => 1, Unknown => 1, Hidden => 1 },
2089
+ "\xa9mdl" => {
2090
+ Name => 'Model',
2091
+ Notes => 'non-standard-format DJI tag',
2092
+ Format => 'string',
2093
+ Avoid => 1,
2094
+ },
2095
+ btec => {
2096
+ Name => 'GlamourSettings',
2097
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::Glamour' },
2098
+ },
2099
+ fsid => 'OriginalFilePath',
2100
+ # dbcm - seen "\0\0\0\x04"
2101
+ # ---- HTC ----
2092
2102
  htcb => {
2093
2103
  Name => 'HTCBinary',
2094
2104
  SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::HTCBinary' },
@@ -2835,7 +2845,8 @@ my %userDefined = (
2835
2845
  ipma => {
2836
2846
  Name => 'ItemPropertyAssociation',
2837
2847
  RawConv => \&ParseItemPropAssoc,
2838
- WriteHook => \&ParseItemPropAssoc,
2848
+ # (comment out because we do this manually _before_ ipco when writing)
2849
+ # WriteHook => \&ParseItemPropAssoc,
2839
2850
  Notes => 'parsed, but not extracted as a tag',
2840
2851
  },
2841
2852
  );
@@ -8076,6 +8087,7 @@ my %userDefined = (
8076
8087
  Name => 'TimeCode',
8077
8088
  SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TimeCode' },
8078
8089
  },
8090
+ # dbgi - used by DJI - seen "\0\0\0\0"
8079
8091
  );
8080
8092
 
8081
8093
  # TimeCode header
@@ -8198,6 +8210,11 @@ my %userDefined = (
8198
8210
  Name => 'HandlerType',
8199
8211
  Format => 'undef[4]',
8200
8212
  RawConv => q{
8213
+ unless ($$self{HasHandler}{$val} or not $Image::ExifTool::QuickTime::eeBox{$val}
8214
+ or $val eq 'vide' or $$self{OPTIONS}{ExtractEmbedded} or $$self{OPTIONS}{Validate})
8215
+ {
8216
+ Image::ExifTool::QuickTime::EEWarn($self);
8217
+ }
8201
8218
  $$self{HandlerType} = $val unless $val eq 'alis' or $val eq 'url ';
8202
8219
  $$self{MediaType} = $val if @{$$self{PATH}} > 1 and $$self{PATH}[-2] eq 'Media';
8203
8220
  $$self{HasHandler}{$val} = 1; # remember all our handlers
@@ -9800,7 +9817,7 @@ sub ProcessMOV($$;$)
9800
9817
  }
9801
9818
  $$raf{NoBuffer} = 1 if $fast; # disable buffering in FastScan mode
9802
9819
 
9803
- my $ee = $$et{OPTIONS}{ExtractEmbedded};
9820
+ my $ee = $$et{OPTIONS}{ExtractEmbedded} || 0;
9804
9821
  my $hash = $$et{ImageDataHash};
9805
9822
  if ($ee or $hash) {
9806
9823
  $unkOpt = $$et{OPTIONS}{Unknown};
@@ -9874,7 +9891,7 @@ sub ProcessMOV($$;$)
9874
9891
  }
9875
9892
  if ($isUserData and $$et{SET_GROUP1}) {
9876
9893
  my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
9877
- unless ($$tagInfo{SubDirectory}) {
9894
+ unless ($tagInfo and $$tagInfo{SubDirectory}) {
9878
9895
  # add track name to UserData tags inside tracks
9879
9896
  $tag = $$et{SET_GROUP1} . $tag;
9880
9897
  if (not $$tagTablePtr{$tag} and $tagInfo) {
@@ -9897,10 +9914,8 @@ sub ProcessMOV($$;$)
9897
9914
  $eeTag = 1;
9898
9915
  $$et{OPTIONS}{Unknown} = 1; # temporarily enable "Unknown" option
9899
9916
  }
9900
- } elsif ($handlerType ne 'vide' and not $$et{OPTIONS}{Validate}) {
9901
- EEWarn($et);
9902
9917
  }
9903
- } elsif ($ee and $ee > 1 and $eeBox2{$handlerType} and $eeBox2{$handlerType}{$tag}) {
9918
+ } elsif ($ee > 1 and $eeBox2{$handlerType} and $eeBox2{$handlerType}{$tag}) {
9904
9919
  $eeTag = 1;
9905
9920
  $$et{OPTIONS}{Unknown} = 1;
9906
9921
  } elsif ($hash and $hashBox{$handlerType} and $hashBox{$handlerType}{$tag}) {
@@ -9982,17 +9997,19 @@ sub ProcessMOV($$;$)
9982
9997
  my $items = $$et{ItemInfo};
9983
9998
  my ($id, $prop, $docNum, $lowest);
9984
9999
  my $primary = $$et{PrimaryItem} || 0;
10000
+ my $pitem = $$items{$primary} || { };
10001
+ $$pitem{RefersTo} or $$pitem{RefersTo} = { };
9985
10002
  ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
9986
10003
  next unless $$items{$id}{Association};
9987
10004
  my $item = $$items{$id};
9988
10005
  foreach $prop (@{$$item{Association}}) {
9989
10006
  next unless $prop == $index;
9990
- if ($id == $primary or (not $dontInherit{$tag} and
9991
- (($$item{RefersTo} and $$item{RefersTo}{$primary}) or
9992
- # hack: assume Item 1 is from the main image (eg. hvc1 data)
9993
- # to hack the case where the primary item (ie. main image)
9994
- # doesn't directly reference this property
9995
- (not $$item{RefersTo} and $id == 1))))
10007
+ my $dont = $dontInherit{$tag} || 0;
10008
+ if ($id == $primary or (not $dont and
10009
+ ($$item{RefersTo} and $$item{RefersTo}{$primary})) or
10010
+ # special case to assume this property belongs to the primary
10011
+ # image if it belongs to an item referred to by the primary
10012
+ ($dont != 1 and $$pitem{RefersTo}{$id}))
9996
10013
  {
9997
10014
  # this is associated with the primary item or an item describing
9998
10015
  # the primary item, so consider this part of the main document
@@ -111,7 +111,7 @@ my %insvLimit = (
111
111
  The tags below are extracted from timed metadata in QuickTime and other
112
112
  formats of video files when the ExtractEmbedded option is used. Although
113
113
  most of these tags are combined into the single table below, ExifTool
114
- currently reads 100 different types of timed GPS metadata from video files.
114
+ currently reads 103 different types of timed GPS metadata from video files.
115
115
  },
116
116
  VARS => { NO_ID => 1 },
117
117
  GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
@@ -1446,7 +1446,6 @@ Sample: for ($i=0; ; ) {
1446
1446
  $$et{ee} = $ee; # need ee information for 'keys'
1447
1447
  $et->HandleTag($tagTbl, $metaFormat, undef,
1448
1448
  DataPt => \$buff,
1449
- DataPos => 0,
1450
1449
  Base => $$start[$i], # (Base must be set for CR3 files)
1451
1450
  TagInfo => $tagInfo,
1452
1451
  );
@@ -1494,7 +1493,6 @@ Sample: for ($i=0; ; ) {
1494
1493
  FoundSomething($et, $tagTbl, $time[$i], $dur[$i]);
1495
1494
  $et->HandleTag($tagTbl, $type, undef,
1496
1495
  DataPt => \$buff,
1497
- DataPos => 0,
1498
1496
  Base => $$start[$i], # (Base must be set for CR3 files)
1499
1497
  TagInfo => $tagInfo,
1500
1498
  );
@@ -1571,6 +1569,7 @@ sub ProcessFreeGPS($$$)
1571
1569
  my $debug = $et->Options('Debug');
1572
1570
  my $oldOrder = GetByteOrder();
1573
1571
  SetByteOrder('II');
1572
+ $$et{FoundEmbedded} = 1;
1574
1573
 
1575
1574
  if (substr($$dataPt,18,8) eq "\xaa\xaa\xf2\xe1\xf0\xee\x54\x54") {
1576
1575
 
@@ -2208,7 +2207,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
2208
2207
  unpack('x48V6a1a1a1x1V4', $$dataPt);
2209
2208
  if (substr($$dataPt, 16, 3) eq 'IQS') {
2210
2209
  $debug and $et->FoundTag(GPSType => 16);
2211
- # Type 3b (ref PH)
2210
+ # IQS variant (ref PH)
2212
2211
  # header looks like this in my sample:
2213
2212
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 4c 00 00 00 [....freeGPS L...]
2214
2213
  # 0010: 49 51 53 5f 41 37 5f 32 30 31 35 30 34 31 37 00 [IQS_A7_20150417.]
@@ -2219,12 +2218,26 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
2219
2218
  $spd = Get32s($dataPt, 0x54) / 100 * $mpsToKph;
2220
2219
  $alt = GetFloat($dataPt, 0x58) / 1000; # (NC)
2221
2220
  } else {
2222
- $debug and $et->FoundTag(GPSType => 17);
2223
2221
  $lat = GetFloat($dataPt, 0x4c);
2224
2222
  $lon = GetFloat($dataPt, 0x50);
2225
2223
  $spd = GetFloat($dataPt, 0x54) * $knotsToKph;
2226
- $trk = GetFloat($dataPt, 0x58);
2227
- # ($trk is not confirmed; may be GPSImageDirection, ref PH)
2224
+ $trk = GetFloat($dataPt, 0x58); # (NC, may be GPSImageDirection)
2225
+ # Rexing V1-4k dashcam scales the lat/lon
2226
+ # (recognize this dashcam by the KodakVersion, "3.01.054" for my sample)
2227
+ # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 4c 00 00 00 [....freeGPS L...]
2228
+ # 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
2229
+ # 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
2230
+ # 0030: 0e 00 00 00 22 00 00 00 28 00 00 00 14 00 00 00 [...."...(.......]
2231
+ # 0040: 02 00 00 00 16 00 00 00 41 4e 57 00 e9 7e 90 43 [........ANW..~.C]
2232
+ # 0050: 48 76 17 45 0c 02 48 42 14 6e 85 43 00 00 00 00 [Hv.E..HB.n.C....]
2233
+ if ($$et{KodakVersion} and $$et{KodakVersion} eq '3.01.054') {
2234
+ $debug and $et->FoundTag(GPSType => '17b');
2235
+ $lat = ($lat - 187.982162849635) / 3;
2236
+ $lon = ($lon - 2199.19873715495) / 2;
2237
+ $ddd = 1;
2238
+ } else {
2239
+ $debug and $et->FoundTag(GPSType => 17);
2240
+ }
2228
2241
  }
2229
2242
  if ($dirLen >= 0xb0) {
2230
2243
  # lat/lon also stored as doubles by Transcend Driver Pro 230 (ref PH)
@@ -3534,50 +3547,85 @@ sub ProcessWolfbox($$$)
3534
3547
  }
3535
3548
 
3536
3549
  #------------------------------------------------------------------------------
3537
- # Scan media data for "freeGPS" metadata if not found already (ref PH)
3550
+ # Scan media data for "freeGPS" and GoPro metadata if not found already (ref PH)
3538
3551
  # Inputs: 0) ExifTool ref
3539
3552
  sub ScanMediaData($)
3540
3553
  {
3541
3554
  my $et = shift;
3542
3555
  my $raf = $$et{RAF} or return;
3543
- my ($tagTbl, $verbose, $buff, $dataLen);
3544
- my ($pos, $buf2) = (0, '');
3556
+ my ($tagTbl, $verbose, $buff, $dataLen, $found);
3545
3557
 
3546
3558
  # don't rescan for freeGPS if we already found embedded metadata
3547
3559
  my $dataPos = $$et{MediaDataOffset};
3548
- if ($dataPos and not $$et{DOC_COUNT}) {
3560
+ return if $$et{FoundEmbedded} or not $dataPos;
3561
+
3562
+ my ($pos, $buf2) = (0, '');
3563
+ my $ee = $et->Options('ExtractEmbedded');
3564
+ if ($ee > 2) { # scan entire file from start of mdat if ExtractEmbedded > 2
3565
+ $raf->Seek(0,2);
3566
+ $dataLen = $raf->Tell() - $$et{MediaDataOffset};
3567
+ } else {
3549
3568
  $dataLen = $$et{MediaDataSize};
3550
- if ($dataLen) {
3551
- if ($raf->Seek($dataPos, 0)) {
3552
- $$et{FreeGPS2} = { }; # initialize variable space for FreeGPS2()
3553
- } else {
3554
- undef $dataLen;
3555
- }
3556
- }
3557
3569
  }
3570
+ return unless $dataLen and $raf->Seek($dataPos);
3558
3571
 
3559
3572
  # loop through 'mdat' media data looking for GPS information
3560
3573
  while ($dataLen) {
3561
- last if $pos + $gpsBlockSize > $dataLen;
3562
- last unless $raf->Read($buff, $gpsBlockSize);
3574
+ my $n = $gpsBlockSize;
3575
+ $n = $dataLen - $pos if $n + $pos > $dataLen;
3576
+ last unless $n > length($buf2) and $raf->Read($buff, $n - length($buf2));
3563
3577
  $buff = $buf2 . $buff if length $buf2;
3564
- last if length $buff < $gpsBlockSize;
3565
- # look for "freeGPS " block
3566
- # (found on an absolute 0x8000-byte boundary in all of my samples,
3578
+ # look for "freeGPS " or GoPro record
3579
+ # (freeGPS found on an absolute 0x8000-byte boundary in all of my samples,
3567
3580
  # but allow for any alignment when searching)
3568
- if ($buff !~ /\0..\0freeGPS /sg) { # (seen ".." = "\0\x80","\x01\0")
3581
+ if ($buff !~ /(\0..\0freeGPS |GP\x06\0\0)/sg) {
3569
3582
  $buf2 = substr($buff,-12);
3570
3583
  $pos += length($buff)-12;
3571
3584
  # in all of my samples the first freeGPS block is within 2 MB of the start
3572
3585
  # of the mdat, so limit the scan to the first 20 MB to be fast and safe
3573
- next if $tagTbl or $pos < 20e6;
3586
+ next if $found or $pos < 20e6 or $ee > 1;
3574
3587
  last;
3575
- } elsif (not $tagTbl) {
3588
+ } elsif ($1 eq "GP\x06\0\0") { # (GoPro GPS record header)
3589
+ # (found in Chigee Aio-5 Lite and some Insta360 videos)
3590
+ my $buffPos = pos($buff);
3591
+ my $filePos = $raf->Tell();
3592
+ my $start = $filePos - length($buff) + $buffPos - length($1);
3593
+ $raf->Seek($start) or last;
3594
+ unless (defined $found) {
3595
+ $et->VPrint(0, "---- Extract Embedded ----\n");
3596
+ $$et{INDENT} .= '| ';
3597
+ $found = 0;
3598
+ }
3599
+ my $maxLen = $dataLen - ($start - $$et{MediaDataOffset});
3600
+ require Image::ExifTool::GoPro;
3601
+ $et->VPrint(0, sprintf("Unreferenced GoPro record at 0x%x\n",$filePos));
3602
+ my $size = Image::ExifTool::GoPro::ProcessGP6($et, { RAF => $raf, DirLen => $maxLen });
3603
+ if ($size) {
3604
+ unless ($found) {
3605
+ # scan entire file if we found a valid GoPro record
3606
+ # (some records may exist in trailer)
3607
+ $raf->Seek(0, 2) and $dataLen = $raf->Tell() - $$et{MediaDataOffset};
3608
+ $found = 2;
3609
+ }
3610
+ $raf->Seek($start + $size) or last;
3611
+ $pos = $start + $size - $$et{MediaDataOffset};
3612
+ $buf2 = '';
3613
+ } else {
3614
+ # (could have been a random match -- continue with search)
3615
+ $raf->Seek($filePos) or last;
3616
+ $buf2 = substr($buff, $buffPos);
3617
+ $pos += $buffPos;
3618
+ }
3619
+ next;
3620
+ }
3621
+ last if length $buff < $gpsBlockSize;
3622
+ if (not $tagTbl) {
3576
3623
  # initialize variables for extracting metadata from this block
3577
3624
  $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
3578
3625
  $verbose = $$et{OPTIONS}{Verbose};
3579
3626
  $et->VPrint(0, "---- Extract Embedded ----\n");
3580
3627
  $$et{INDENT} .= '| ';
3628
+ $found = 1;
3581
3629
  }
3582
3630
  if (pos($buff) > 12) {
3583
3631
  $pos += pos($buff) - 12;
@@ -3604,7 +3652,7 @@ sub ScanMediaData($)
3604
3652
  $pos += $len;
3605
3653
  $buf2 = substr($buff, $len);
3606
3654
  }
3607
- if ($tagTbl) {
3655
+ if ($found) {
3608
3656
  delete $$et{DOC_NUM}; # reset DOC_NUM after extracting embedded metadata
3609
3657
  $et->VPrint(0, "--------------------------\n");
3610
3658
  $$et{INDENT} = substr $$et{INDENT}, 0, -2;
@@ -30,7 +30,7 @@ use strict;
30
30
  use vars qw($VERSION $AUTOLOAD);
31
31
  use Image::ExifTool qw(:DataAccess :Utils);
32
32
 
33
- $VERSION = '1.70';
33
+ $VERSION = '1.71';
34
34
 
35
35
  sub ConvertTimecode($);
36
36
  sub ProcessSGLT($$$);
@@ -1319,9 +1319,9 @@ my %code2charset = (
1319
1319
  Name => 'ImageWidth',
1320
1320
  Format => 'int16u',
1321
1321
  Priority => 0,
1322
- # add " (lossless)" to FileType since image has a VP8L (lossless) chunk
1322
+ # add " Lossless" to FileType since image has a VP8L (lossless) chunk
1323
1323
  RawConv => q{
1324
- $self->OverrideFileType($$self{VALUE}{FileType} . ' (lossless)', undef, 'webp');
1324
+ $self->OverrideFileType($$self{VALUE}{FileType} . ' Lossless', undef, 'webp');
1325
1325
  return $val;
1326
1326
  },
1327
1327
  ValueConv => '($val & 0x3fff) + 1',
@@ -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.71';
37
+ $VERSION = '3.72';
38
38
 
39
39
  sub ProcessSRF($$$);
40
40
  sub ProcessSR2($$$);
@@ -171,6 +171,7 @@ sub PrintInvLensSpec($;$$);
171
171
  32886 => 'Sony FE 300mm F2.8 GM OSS', #JR
172
172
  32887 => 'Sony E PZ 16-50mm F3.5-5.6 OSS II', #JR
173
173
  32888 => 'Sony FE 85mm F1.4 GM II', #JR
174
+ 32889 => 'Sony FE 28-70mm F2 GM',
174
175
 
175
176
  # (comment this out so LensID will report the LensModel, which is more useful)
176
177
  # 32952 => 'Metabones Canon EF Speed Booster Ultra', #JR (corresponds to 184, but 'Advanced' mode, LensMount reported as E-mount)
@@ -1226,6 +1227,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1226
1227
  9 => 'Center (LA-EA4)', # seen for ILCE-7RM2 with LA-EA4
1227
1228
  11 => 'Zone',
1228
1229
  12 => 'Expanded Flexible Spot',
1230
+ 13 => 'Custom AF Area', # NC, new AFArea option for ILCE-9M3, ILCE-1M2
1229
1231
  },
1230
1232
  },{
1231
1233
  Name => 'AFAreaModeSetting',
@@ -1726,7 +1728,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
1726
1728
  },
1727
1729
  },{
1728
1730
  Name => 'Tag9050d',
1729
- Condition => '$$self{Model} =~ /^(ILCE-(6700|7CM2|7CR)|ZV-(E1|E10M2))\b/',
1731
+ Condition => '$$self{Model} =~ /^(ILCE-(6700|7CM2|7CR)|ZV-(E1|E10M2))\b/ or ($$self{Model} =~ /^(ILCE-1M2)/ and $$valPt =~ /^\x00/)',
1730
1732
  SubDirectory => {
1731
1733
  TagTable => 'Image::ExifTool::Sony::Tag9050d',
1732
1734
  ByteOrder => 'LittleEndian',
@@ -8208,14 +8210,17 @@ my %isoSetting2010 = (
8208
8210
  WRITE_PROC => \&WriteEnciphered,
8209
8211
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
8210
8212
  FORMAT => 'int8u',
8211
- NOTES => 'Valid for ILCE-6700/7CM2/7CR/ZV-E1.',
8213
+ NOTES => q{
8214
+ Valid for ILCE-6700/7CM2/7CR/ZV-E1. Also for ILCE-1M2 when using mechanical
8215
+ shutter.
8216
+ },
8212
8217
  WRITABLE => 1,
8213
8218
  FIRST_ENTRY => 0,
8214
8219
  GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
8215
8220
  0x000a => {
8216
8221
  Name => 'ShutterCount',
8217
8222
  # number of mechanical shutter actuations, does not increase during electronic shutter / Silent Shooting
8218
- Condition => '$$self{Model} =~ /^(ILCE-(6700|7CM2|7CR))/',
8223
+ Condition => '$$self{Model} =~ /^(ILCE-(1M2|6700|7CM2|7CR))/',
8219
8224
  Format => 'int32u',
8220
8225
  Notes => 'total number of mechanical shutter actuations',
8221
8226
  RawConv => '$val & 0x00ffffff',
@@ -8451,7 +8456,7 @@ my %isoSetting2010 = (
8451
8456
  200 => 'Continuous - Sweep Panorama',
8452
8457
  },
8453
8458
  },
8454
- 0x001a => { %sequenceFileNumber },
8459
+ 0x001a => { %sequenceFileNumber }, # ILCE-9M3/1M2 have sometimes deviating values.
8455
8460
  0x001e => {
8456
8461
  Name => 'SequenceLength',
8457
8462
  PrintConv => {
@@ -8476,7 +8481,7 @@ my %isoSetting2010 = (
8476
8481
  },
8477
8482
  0x002a => [{
8478
8483
  Name => 'Quality2',
8479
- Condition => '$$self{Model} !~ /^(ILCE-(1|6700|7CM2|7CR|7M4|7RM5|7SM3|9M3)|ILME-(FX3|FX30)|ZV-(E1|E10M2))\b/',
8484
+ Condition => '$$self{Model} !~ /^(ILCE-(1|1M2|6700|7CM2|7CR|7M4|7RM5|7SM3|9M3)|ILME-(FX3|FX30)|ZV-(E1|E10M2))\b/',
8480
8485
  PrintConv => {
8481
8486
  0 => 'JPEG',
8482
8487
  1 => 'RAW',
@@ -8544,7 +8549,7 @@ my %isoSetting2010 = (
8544
8549
  0x0000 => { Name => 'Ver9401', Hidden => 1, RawConv => '$$self{Ver9401} = $val; $$self{OPTIONS}{Unknown}<2 ? undef : $val' },
8545
8550
 
8546
8551
  0x03e2 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 181', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
8547
- 0x03f4 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 185', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
8552
+ 0x03f4 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(185|186)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
8548
8553
  0x044e => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 178', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
8549
8554
  0x0498 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 148', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
8550
8555
  0x049d => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 167 and $$self{Software} !~ /^ILCE-7M4 (v2|v3)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
@@ -8619,6 +8624,7 @@ my %isoSetting2010 = (
8619
8624
  10 => 'Selective (for Miniature effect)', # seen for DSC-HX30V,TX30,WX60,WX100
8620
8625
  11 => 'Zone', #JR (ILCE-7 series)
8621
8626
  12 => 'Expanded Flexible Spot', #JR (HX90V, ILCE-7 series)
8627
+ 13 => 'Custom AF Area', # NC, new AFArea option for ILCE-9M3, ILCE-1M2
8622
8628
  14 => 'Tracking',
8623
8629
  15 => 'Face Tracking',
8624
8630
  20 => 'Animal Eye Tracking',
@@ -10034,7 +10040,7 @@ my %isoSetting2010 = (
10034
10040
  },
10035
10041
  0x089d => { # Note: 32 values for these newer models, and 32 non-zero values present for new lenses like SEL2470GM2 and SEL2070G
10036
10042
  Name => 'VignettingCorrParams',
10037
- Condition => '$$self{Model} =~ /^(ILCE-(6700|7CM2|7CR|7RM5)|ILME-FX30|ZV-(E1|E10M2))\b/',
10043
+ Condition => '$$self{Model} =~ /^(ILCE-(1M2|6700|7CM2|7CR|7RM5)|ILME-FX30|ZV-(E1|E10M2))\b/',
10038
10044
  Format => 'int16s[32]',
10039
10045
  },
10040
10046
  0x08b5 => {
@@ -10055,7 +10061,7 @@ my %isoSetting2010 = (
10055
10061
  },
10056
10062
  0x08e5 => {
10057
10063
  Name => 'APS-CSizeCapture',
10058
- Condition => '$$self{Model} =~ /^(ILCE-(7CM2|7CR|7RM5)|ZV-E1)\b/',
10064
+ Condition => '$$self{Model} =~ /^(ILCE-(1M2|7CM2|7CR|7RM5)|ZV-E1)\b/',
10059
10065
  PrintConv => {
10060
10066
  0 => 'Off',
10061
10067
  1 => 'On',
@@ -10073,7 +10079,7 @@ my %isoSetting2010 = (
10073
10079
  },
10074
10080
  0x0945 => {
10075
10081
  Name => 'ChromaticAberrationCorrParams',
10076
- Condition => '$$self{Model} =~ /^(ILCE-(6700|7CM2|7CR|7RM5)|ILME-FX30|ZV-(E1|E10M2))\b/',
10082
+ Condition => '$$self{Model} =~ /^(ILCE-(1M2|6700|7CM2|7CR|7RM5)|ILME-FX30|ZV-(E1|E10M2))\b/',
10077
10083
  Format => 'int16s[32]',
10078
10084
  },
10079
10085
  );