exiftool_vendored 12.15.0 → 12.22.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +96 -2
  3. data/bin/MANIFEST +1 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +2 -2
  7. data/bin/config_files/example.config +1 -8
  8. data/bin/exiftool +104 -59
  9. data/bin/fmt_files/gpx.fmt +1 -1
  10. data/bin/fmt_files/gpx_wpt.fmt +1 -1
  11. data/bin/fmt_files/kml.fmt +1 -1
  12. data/bin/fmt_files/kml_track.fmt +1 -1
  13. data/bin/lib/Image/ExifTool.pm +74 -24
  14. data/bin/lib/Image/ExifTool.pod +34 -24
  15. data/bin/lib/Image/ExifTool/Apple.pm +3 -2
  16. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +24 -13
  17. data/bin/lib/Image/ExifTool/Canon.pm +26 -2
  18. data/bin/lib/Image/ExifTool/CanonCustom.pm +19 -1
  19. data/bin/lib/Image/ExifTool/DJI.pm +6 -6
  20. data/bin/lib/Image/ExifTool/DPX.pm +3 -3
  21. data/bin/lib/Image/ExifTool/Exif.pm +35 -16
  22. data/bin/lib/Image/ExifTool/FITS.pm +13 -2
  23. data/bin/lib/Image/ExifTool/FujiFilm.pm +2 -1
  24. data/bin/lib/Image/ExifTool/GPS.pm +24 -13
  25. data/bin/lib/Image/ExifTool/H264.pm +20 -5
  26. data/bin/lib/Image/ExifTool/ICC_Profile.pm +2 -2
  27. data/bin/lib/Image/ExifTool/M2TS.pm +40 -4
  28. data/bin/lib/Image/ExifTool/MIE.pm +2 -2
  29. data/bin/lib/Image/ExifTool/Microsoft.pm +296 -82
  30. data/bin/lib/Image/ExifTool/Nikon.pm +5 -5
  31. data/bin/lib/Image/ExifTool/NikonSettings.pm +16 -16
  32. data/bin/lib/Image/ExifTool/Olympus.pm +2 -2
  33. data/bin/lib/Image/ExifTool/QuickTime.pm +58 -30
  34. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +27 -8
  35. data/bin/lib/Image/ExifTool/README +5 -4
  36. data/bin/lib/Image/ExifTool/RIFF.pm +2 -2
  37. data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -0
  38. data/bin/lib/Image/ExifTool/Sony.pm +63 -29
  39. data/bin/lib/Image/ExifTool/TagInfoXML.pm +1 -0
  40. data/bin/lib/Image/ExifTool/TagLookup.pm +4032 -3981
  41. data/bin/lib/Image/ExifTool/TagNames.pod +261 -104
  42. data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
  43. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +7 -5
  44. data/bin/lib/Image/ExifTool/WriteXMP.pl +9 -6
  45. data/bin/lib/Image/ExifTool/Writer.pl +49 -14
  46. data/bin/lib/Image/ExifTool/XMP.pm +31 -5
  47. data/bin/perl-Image-ExifTool.spec +1 -1
  48. data/lib/exiftool_vendored/version.rb +1 -1
  49. metadata +48 -6
@@ -62,7 +62,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
62
62
  use Image::ExifTool::Exif;
63
63
  use Image::ExifTool::GPS;
64
64
 
65
- $VERSION = '3.91';
65
+ $VERSION = '3.94';
66
66
 
67
67
  sub LensIDConv($$$);
68
68
  sub ProcessNikonAVI($$$);
@@ -640,6 +640,7 @@ sub GetAFPointGrid($$;$);
640
640
  '24 44 60 98 34 3C 1A 02' => 'Tokina AT-X 840 AF-II (AF 80-400mm f/4.5-5.6)',
641
641
  '00 44 60 98 34 3C 00 02' => 'Tokina AT-X 840 D (AF 80-400mm f/4.5-5.6)',
642
642
  '14 48 68 8E 30 30 0B 00' => 'Tokina AT-X 340 AF (AF 100-300mm f/4)',
643
+ '8C 48 29 3C 24 24 86 06' => 'Tokina opera 16-28mm F2.8 FF', #30
643
644
  #
644
645
  '06 3F 68 68 2C 2C 06 00' => 'Cosina AF 100mm F3.5 Macro',
645
646
  '07 36 3D 5F 2C 3C 03 00' => 'Cosina AF Zoom 28-80mm F3.5-5.6 MC Macro',
@@ -1520,7 +1521,7 @@ my %binaryDataAttrs = (
1520
1521
  7 => 'Fired, External', #14
1521
1522
  8 => 'Fired, Commander Mode',
1522
1523
  9 => 'Fired, TTL Mode',
1523
- 18 => 'Fired, Sync Mode', #G.F. (movie LED light)
1524
+ 18 => 'LED Light', #G.F. (movie LED light)
1524
1525
  },
1525
1526
  },
1526
1527
  0x0088 => [
@@ -9184,6 +9185,7 @@ my %nikonFocalConversions = (
9184
9185
  7 => 'Fired, External', #14
9185
9186
  8 => 'Fired, Commander Mode',
9186
9187
  9 => 'Fired, TTL Mode',
9188
+ 18 => 'LED Light', #G.F. (movie LED light)
9187
9189
  },
9188
9190
  },
9189
9191
  0x2000098 => [
@@ -9944,12 +9946,10 @@ sub PrescanExif($$$)
9944
9946
  $dataLen = length $data;
9945
9947
  $dirStart = 0;
9946
9948
  }
9947
- # loop through necessary IFD entries
9948
- my ($lastTag) = sort { $b <=> $a } keys %$tagHash; # (reverse sort)
9949
+ # loop through Nikon MakerNote IFD entries
9949
9950
  for ($index=0; $index<$numEntries; ++$index) {
9950
9951
  my $entry = $dirStart + 2 + 12 * $index;
9951
9952
  my $tagID = Get16u($dataPt, $entry);
9952
- last if $tagID > $lastTag; # (assuming tags are in order)
9953
9953
  next unless exists $$tagHash{$tagID}; # only extract required tags
9954
9954
  my $format = Get16u($dataPt, $entry+2);
9955
9955
  next if $format < 1 or $format > 13;
@@ -17,7 +17,7 @@ use strict;
17
17
  use vars qw($VERSION);
18
18
  use Image::ExifTool qw(:DataAccess :Utils);
19
19
 
20
- $VERSION = '1.00';
20
+ $VERSION = '1.02';
21
21
 
22
22
  sub ProcessNikonSettings($$$);
23
23
 
@@ -911,14 +911,14 @@ my %infoD6 = (
911
911
  },
912
912
  0x05a => [{ # CSf6-b-1 and CSf6-b-2 (D6), CSf5-b-1 and CSf5-b-2 (Z7_2), (continued from above)
913
913
  Name => 'CmdDialsChangeMainSub',
914
- Condition => '$$self{CmdDialsChangeMainSubExposure} == 1',
914
+ Condition => '$$self{CmdDialsChangeMainSubExposure} and $$self{CmdDialsChangeMainSubExposure} == 1',
915
915
  PrintConv => {
916
916
  1 => 'Autofocus On, Exposure On',
917
917
  2 => 'Autofocus Off, Exposure On',
918
918
  },
919
919
  },{
920
920
  Name => 'CmdDialsChangeMainSub',
921
- Condition => '$$self{CmdDialsChangeMainSubExposure} == 2',
921
+ Condition => '$$self{CmdDialsChangeMainSubExposure} and $$self{CmdDialsChangeMainSubExposure} == 2',
922
922
  PrintConv => {
923
923
  1 => 'Autofocus On, Exposure On (Mode A)',
924
924
  2 => 'Autofocus Off, Exposure On (Mode A)',
@@ -1014,7 +1014,7 @@ my %infoD6 = (
1014
1014
  }],
1015
1015
  0x08b => [{ # CSf6-a-1 and CSf6-a-2 (D6), CSf5-a-1 and CSf5-a-2 (Z7_2), (continued from above)
1016
1016
  Name => 'CmdDialsReverseRotation',
1017
- Condition => '$$self{CmdDialsReverseRotExposureComp} == 1',
1017
+ Condition => '$$self{CmdDialsReverseRotExposureComp} and $$self{CmdDialsReverseRotExposureComp} == 1',
1018
1018
  PrintConv => {
1019
1019
  1 => 'No',
1020
1020
  2 => 'Shutter Speed & Aperture',
@@ -1283,7 +1283,7 @@ my %infoD6 = (
1283
1283
  PrintConv => {
1284
1284
  1 => 'Enable',
1285
1285
  2 => 'Enable (Standby Timer Active)',
1286
- 3 => 'Diaable',
1286
+ 3 => 'Disable',
1287
1287
  },
1288
1288
  },
1289
1289
  0x0ab => { # CSf11 (D6)
@@ -1313,7 +1313,7 @@ my %infoD6 = (
1313
1313
  1 => 'Power Aperture (Open)',
1314
1314
  2 => 'Exposure Compensation',
1315
1315
  3 => 'Subject Tracking',
1316
- 4 => 'LiveView Info Display On/Off)',
1316
+ 4 => 'LiveView Info Display On/Off',
1317
1317
  5 => 'Grid Display',
1318
1318
  6 => 'Zoom (Low)',
1319
1319
  7 => 'Zoom (1:1)',
@@ -1357,7 +1357,7 @@ my %infoD6 = (
1357
1357
  1 => 'Power Aperture (Close)',
1358
1358
  2 => 'Exposure Compensation',
1359
1359
  3 => 'Subject Tracking',
1360
- 4 => 'LiveView Info Display On/Off)',
1360
+ 4 => 'LiveView Info Display On/Off',
1361
1361
  5 => 'Grid Display',
1362
1362
  6 => 'Zoom (Low)',
1363
1363
  7 => 'Zoom (1:1)',
@@ -1545,10 +1545,10 @@ my %infoD6 = (
1545
1545
  12 => 'None',
1546
1546
  },
1547
1547
  },
1548
- 0x0fb => { Name => 'SecondarySlotFunction', PrintConv => \%tagSecondarySlotFunction }, # tag name selected to maintain compatibility with older cameras # (Z7_2)
1549
- 0x0fb => { Name => 'SecondarySlotFunction', PrintConv => \%tagSecondarySlotFunction }, # (D6)
1550
- 0x0fc => { Name => 'SilentPhotography', PrintConv => \%onOff }, # (D6,Z7_2) # tag is associated with Silent LiveView Photography (as distinguisehed from Silent Interval or Silent Focus Shift)
1551
- 0x0fd => { Name => 'ExtendedShuttterSpeeds', PrintConv => \%onOff }, # CSd7 (D6), CSd6 (Z7_2)
1548
+ 0x0fb => { Name => 'SecondarySlotFunction', PrintConv => \%tagSecondarySlotFunction }, # tag name selected to maintain compatibility with older cameras # (Z7_2)
1549
+ 0x0fb => { Name => 'SecondarySlotFunction', PrintConv => \%tagSecondarySlotFunction }, # (D6)
1550
+ 0x0fc => { Name => 'SilentPhotography', PrintConv => \%onOff }, # (D6,Z7_2) # tag is associated with Silent LiveView Photography (as distinguisehed from Silent Interval or Silent Focus Shift)
1551
+ 0x0fd => { Name => 'ExtendedShutterSpeeds', PrintConv => \%onOff }, # CSd7 (D6), CSd6 (Z7_2)
1552
1552
  0x109 => { # (D6,Z7_2)
1553
1553
  Name => 'BracketSet',
1554
1554
  RawConv => '$$self{BracketSet} = $val',
@@ -1578,7 +1578,7 @@ my %infoD6 = (
1578
1578
  },
1579
1579
  },{
1580
1580
  Name => 'BracketProgram',
1581
- Condition => '$$self{BracketSet} == 4',
1581
+ Condition => '$$self{BracketSet} and $$self{BracketSet} == 4',
1582
1582
  Notes => 'White Balance Bracketing',
1583
1583
  RawConv => '$$self{BracketProgram} = $val',
1584
1584
  PrintConv => {
@@ -1595,7 +1595,7 @@ my %infoD6 = (
1595
1595
  },
1596
1596
  },{
1597
1597
  Name => 'BracketProgram',
1598
- Condition => '$$self{BracketSet} == 5',
1598
+ Condition => '$$self{BracketSet} and $$self{BracketSet} == 5',
1599
1599
  Notes => 'Active-D Bracketing',
1600
1600
  RawConv => '$$self{BracketProgram} = $val',
1601
1601
  Mask => 0x0f,
@@ -1802,9 +1802,9 @@ my %infoD6 = (
1802
1802
  },
1803
1803
  },
1804
1804
  0x139 => { Name => 'PlaybackFlickUp', RawConv => '$$self{PlaybackFlickUp} = $val', PrintConv => \%flickUpDownD6 }, # CSf12-1-a # (D6)
1805
- 0x13a => { Name => 'PlaybackFlickUpRating', Condition => '$$self{PlaybackFlickUp} == 1', Notes => 'Meaningful only when PlaybackFlickUp is Rating', PrintConv => \%flickUpDownRatingD6 }, # CSf12-1-b # (D6)
1805
+ 0x13a => { Name => 'PlaybackFlickUpRating', Condition => '$$self{PlaybackFlickUp} and $$self{PlaybackFlickUp} == 1', Notes => 'Meaningful only when PlaybackFlickUp is Rating', PrintConv => \%flickUpDownRatingD6 }, # CSf12-1-b # (D6)
1806
1806
  0x13b => { Name => 'PlaybackFlickDown', RawConv => '$$self{PlaybackFlickDown} = $val', PrintConv => \%flickUpDownD6 }, # CSf12-2-a # (D6)
1807
- 0x13c => { Name => 'PlaybackFlickDownRating', Condition => '$$self{PlaybackFlickDown} == 1', Notes => 'Meaningful only when PlaybackFlickDown is Rating', PrintConv => \%flickUpDownRatingD6 }, # CSf12-2-b # (D6)
1807
+ 0x13c => { Name => 'PlaybackFlickDownRating', Condition => '$$self{PlaybackFlickDown} and $$self{PlaybackFlickDown} == 1', Notes => 'Meaningful only when PlaybackFlickDown is Rating', PrintConv => \%flickUpDownRatingD6 }, # CSf12-2-b # (D6)
1808
1808
  0x13d => { # CSg2-d (D6)
1809
1809
  Name => 'MovieFunc3Button',
1810
1810
  PrintConv => {
@@ -1875,7 +1875,7 @@ my %infoD6 = (
1875
1875
  0x164 => { # CSg7-a (Z7_2)
1876
1876
  Name => 'VerticalMovieFuncButton',
1877
1877
  PrintConv => {
1878
- 1 => 'LiveView Info Display On/Off)',
1878
+ 1 => 'LiveView Info Display On/Off',
1879
1879
  2 => 'Record Movies',
1880
1880
  3 => 'Exposure Compensation',
1881
1881
  4 => 'ISO',
@@ -40,7 +40,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
40
40
  use Image::ExifTool::Exif;
41
41
  use Image::ExifTool::APP12;
42
42
 
43
- $VERSION = '2.70';
43
+ $VERSION = '2.71';
44
44
 
45
45
  sub PrintLensInfo($$$);
46
46
 
@@ -3952,7 +3952,7 @@ my %indexInfo = (
3952
3952
  1 => 'LensTypeModel',
3953
3953
  },
3954
3954
  Notes => 'based on tags found in some Panasonic RW2 images',
3955
- SeparateTable => 'LensType',
3955
+ SeparateTable => 'Olympus LensType',
3956
3956
  ValueConv => '"$val[0] $val[1]"',
3957
3957
  PrintConv => \%olympusLensTypes,
3958
3958
  },
@@ -47,7 +47,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
47
47
  use Image::ExifTool::Exif;
48
48
  use Image::ExifTool::GPS;
49
49
 
50
- $VERSION = '2.56';
50
+ $VERSION = '2.61';
51
51
 
52
52
  sub ProcessMOV($$;$);
53
53
  sub ProcessKeys($$$);
@@ -243,7 +243,11 @@ my %timeInfo = (
243
243
  },
244
244
  # (all CR3 files store UTC times - PH)
245
245
  ValueConv => 'ConvertUnixTime($val, $self->Options("QuickTimeUTC") || $$self{FileType} eq "CR3")',
246
- ValueConvInv => 'GetUnixTime($val, $self->Options("QuickTimeUTC")) + (66 * 365 + 17) * 24 * 3600',
246
+ ValueConvInv => q{
247
+ $val = GetUnixTime($val, $self->Options("QuickTimeUTC"));
248
+ return undef unless defined $val;
249
+ return $val + (66 * 365 + 17) * 24 * 3600;
250
+ },
247
251
  PrintConv => '$self->ConvertDateTime($val)',
248
252
  PrintConvInv => '$self->InverseDateTime($val)',
249
253
  # (can't put Groups here because they aren't constant!)
@@ -258,11 +262,15 @@ my %unknownInfo = (
258
262
  Unknown => 1,
259
263
  ValueConv => '$val =~ /^([\x20-\x7e]*)\0*$/ ? $1 : \$val',
260
264
  );
265
+
266
+ # multi-language text with 6-byte header
267
+ my %langText = ( IText => 6 );
268
+
261
269
  # parsing for most of the 3gp udta language text boxes
262
- my %langText = (
270
+ my %langText3gp = (
263
271
  Notes => 'used in 3gp videos',
264
- IText => 6,
265
272
  Avoid => 1,
273
+ IText => 6,
266
274
  );
267
275
 
268
276
  # 4-character Vendor ID codes (ref PH)
@@ -424,7 +432,6 @@ my %eeBox = (
424
432
  # (note: vide is only processed if specific atoms exist in the VideoSampleDesc)
425
433
  vide => { %eeStd,
426
434
  JPEG => 'stsd',
427
- # avcC => 'stsd', # (uncomment to parse H264 stream)
428
435
  },
429
436
  text => { %eeStd },
430
437
  meta => { %eeStd },
@@ -434,6 +441,10 @@ my %eeBox = (
434
441
  ctbx => { %eeStd }, # (GM cars)
435
442
  '' => { 'gps ' => 'moov', 'GPS ' => 'main' }, # (no handler -- in top level 'moov' box, and main)
436
443
  );
444
+ # boxes to save when ExtractEmbedded is set to 2 or higher
445
+ my %eeBox2 = (
446
+ vide => { avcC => 'stsd' }, # (parses H264 video stream)
447
+ );
437
448
 
438
449
  # QuickTime atoms
439
450
  %Image::ExifTool::QuickTime::Main = (
@@ -1542,15 +1553,15 @@ my %eeBox = (
1542
1553
  # the following are 3gp tags, references:
1543
1554
  # http://atomicparsley.sourceforge.net
1544
1555
  # http://www.3gpp.org/ftp/tsg_sa/WG4_CODEC/TSGS4_25/Docs/
1545
- # (note that all %langText tags are Avoid => 1)
1546
- cprt => { Name => 'Copyright', %langText, Groups => { 2 => 'Author' } },
1547
- auth => { Name => 'Author', %langText, Groups => { 2 => 'Author' } },
1548
- titl => { Name => 'Title', %langText },
1549
- dscp => { Name => 'Description',%langText },
1550
- perf => { Name => 'Performer', %langText },
1551
- gnre => { Name => 'Genre', %langText },
1552
- albm => { Name => 'Album', %langText },
1553
- coll => { Name => 'CollectionName', %langText }, #17
1556
+ # (note that all %langText3gp tags are Avoid => 1)
1557
+ cprt => { Name => 'Copyright', %langText3gp, Groups => { 2 => 'Author' } },
1558
+ auth => { Name => 'Author', %langText3gp, Groups => { 2 => 'Author' } },
1559
+ titl => { Name => 'Title', %langText3gp },
1560
+ dscp => { Name => 'Description',%langText3gp },
1561
+ perf => { Name => 'Performer', %langText3gp },
1562
+ gnre => { Name => 'Genre', %langText3gp },
1563
+ albm => { Name => 'Album', %langText3gp },
1564
+ coll => { Name => 'CollectionName', %langText3gp }, #17
1554
1565
  rtng => {
1555
1566
  Name => 'Rating',
1556
1567
  # (4-byte flags, 4-char entity, 4-char criteria, 2-byte lang, string)
@@ -1581,8 +1592,11 @@ my %eeBox = (
1581
1592
  },
1582
1593
  kywd => {
1583
1594
  Name => 'Keywords',
1584
- # (4 byte flags, 2-byte lang, 1-byte count, count x pascal strings)
1595
+ # (4 byte flags, 2-byte lang, 1-byte count, count x pascal strings, ref 17)
1596
+ # (but I have also seen a simple string written by iPhone)
1585
1597
  RawConv => q{
1598
+ my $sep = $self->Options('ListSep');
1599
+ return join($sep, split /\0+/, $val) unless $val =~ /^\0/; # (iPhone)
1586
1600
  return '<err>' unless length $val >= 7;
1587
1601
  my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 4));
1588
1602
  $lang = $lang ? "($lang) " : '';
@@ -1598,7 +1612,6 @@ my %eeBox = (
1598
1612
  push @vals, $v;
1599
1613
  $pos += $len;
1600
1614
  }
1601
- my $sep = $self->Options('ListSep');
1602
1615
  return $lang . join($sep, @vals);
1603
1616
  },
1604
1617
  },
@@ -1985,7 +1998,11 @@ my %eeBox = (
1985
1998
  # ---- Microsoft ----
1986
1999
  Xtra => { #PH (microsoft)
1987
2000
  Name => 'MicrosoftXtra',
1988
- SubDirectory => { TagTable => 'Image::ExifTool::Microsoft::Xtra' },
2001
+ WriteGroup => 'Microsoft',
2002
+ SubDirectory => {
2003
+ DirName => 'Microsoft',
2004
+ TagTable => 'Image::ExifTool::Microsoft::Xtra',
2005
+ },
1989
2006
  },
1990
2007
  # ---- Minolta ----
1991
2008
  MMA0 => { #PH (DiMage 7Hi)
@@ -2034,7 +2051,7 @@ my %eeBox = (
2034
2051
  SubDirectory => { TagTable => 'Image::ExifTool::Olympus::thmb' },
2035
2052
  },{ #17 (format is in bytes 3-7)
2036
2053
  Name => 'ThumbnailImage',
2037
- Condition => '$$valPt =~ /^.{8}\xff\xd8\xff\xdb/s',
2054
+ Condition => '$$valPt =~ /^.{8}\xff\xd8\xff[\xdb\xe0]/s',
2038
2055
  Groups => { 2 => 'Preview' },
2039
2056
  RawConv => 'substr($val, 8)',
2040
2057
  Binary => 1,
@@ -2991,9 +3008,9 @@ my %eeBox = (
2991
3008
  3-character ISO 639-2 language code and an optional ISO 3166-1 alpha 2
2992
3009
  country code to the tag name (eg. "ItemList:Title-fra" or
2993
3010
  "ItemList::Title-fra-FR"). When creating a new Meta box to contain the
2994
- ItemList directory, by default ExifTool does not specify a
2995
- L<Handler|Image::ExifTool::TagNames/QuickTime Handler Tags>, but the
2996
- API L<QuickTimeHandler|../ExifTool.html#QuickTimeHandler> option may be used to include an 'mdir' Handler box.
3011
+ ItemList directory, by default ExifTool adds an 'mdir' (Metadata) Handler
3012
+ box because Apple software may ignore ItemList tags otherwise, but the API
3013
+ L<QuickTimeHandler|../ExifTool.html#QuickTimeHandler> option may be set to 0 to avoid this.
2997
3014
  },
2998
3015
  # in this table, binary 1 and 2-byte "data"-type tags are interpreted as
2999
3016
  # int8u and int16u. Multi-byte binary "data" tags are extracted as binary data.
@@ -6154,13 +6171,12 @@ my %eeBox = (
6154
6171
  PROCESS_PROC => \&ProcessKeys,
6155
6172
  WRITE_PROC => \&WriteKeys,
6156
6173
  CHECK_PROC => \&CheckQTValue,
6157
- VARS => { LONG_TAGS => 3 },
6174
+ VARS => { LONG_TAGS => 7 },
6158
6175
  WRITABLE => 1,
6159
6176
  # (not PREFERRED when writing)
6160
6177
  GROUPS => { 1 => 'Keys' },
6161
6178
  WRITE_GROUP => 'Keys',
6162
6179
  LANG_INFO => \&GetLangInfo,
6163
- FORMAT => 'string',
6164
6180
  NOTES => q{
6165
6181
  This directory contains a list of key names which are used to decode tags
6166
6182
  written by the "mdta" handler. Also in this table are a few tags found in
@@ -6262,6 +6278,11 @@ my %eeBox = (
6262
6278
  PrintConv => '$self->ConvertDateTime($val)',
6263
6279
  PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
6264
6280
  },
6281
+ 'location.accuracy.horizontal' => { Name => 'LocationAccuracyHorizontal' },
6282
+ 'live-photo.auto' => { Name => 'LivePhotoAuto', Writable => 'int8u' },
6283
+ 'live-photo.vitality-score' => { Name => 'LivePhotoVitalityScore', Writable => 'float' },
6284
+ 'live-photo.vitality-scoring-version' => { Name => 'LivePhotoVitalityScoringVersion', Writable => 'int64s' },
6285
+ 'apple.photos.variation-identifier' => { Name => 'ApplePhotosVariationIdentifier', Writable => 'int64s' },
6265
6286
  'direction.facing' => { Name => 'CameraDirection', Groups => { 2 => 'Location' } },
6266
6287
  'direction.motion' => { Name => 'CameraMotion', Groups => { 2 => 'Location' } },
6267
6288
  'location.body' => { Name => 'LocationBody', Groups => { 2 => 'Location' } },
@@ -6297,11 +6318,15 @@ my %eeBox = (
6297
6318
  # com.divergentmedia.clipwrap.manufacturer ('Sony')
6298
6319
  # com.divergentmedia.clipwrap.originalDateTime ('2013/2/6 10:30:40+0200')
6299
6320
  #
6300
- # seen in timed metadata (mebx), and added dynamically to the table
6301
- # via SaveMetaKeys(). NOTE: these tags are not writable!
6321
+ # seen in timed metadata (mebx), and added dynamically to the table via SaveMetaKeys()
6322
+ # NOTE: these tags are not writable! (timed metadata cannot yet be written)
6302
6323
  #
6303
6324
  # (mdta)com.apple.quicktime.video-orientation (dtyp=66, int16s)
6304
- 'video-orientation' => { Name => 'VideoOrientation', Writable => 0 },
6325
+ 'video-orientation' => {
6326
+ Name => 'VideoOrientation',
6327
+ Writable => 0,
6328
+ PrintConv => \%Image::ExifTool::Exif::orientation, #PH (NC)
6329
+ },
6305
6330
  # (mdta)com.apple.quicktime.live-photo-info (dtyp=com.apple.quicktime.com.apple.quicktime.live-photo-info)
6306
6331
  'live-photo-info' => {
6307
6332
  Name => 'LivePhotoInfo',
@@ -8571,7 +8596,7 @@ sub QuickTimeFormat($$)
8571
8596
  my ($flags, $len) = @_;
8572
8597
  my $format;
8573
8598
  if ($flags == 0x15 or $flags == 0x16) {
8574
- $format = { 1=>'int8', 2=>'int16', 4=>'int32' }->{$len};
8599
+ $format = { 1=>'int8', 2=>'int16', 4=>'int32', 8=>'int64' }->{$len};
8575
8600
  $format .= $flags == 0x15 ? 's' : 'u' if $format;
8576
8601
  } elsif ($flags == 0x17) {
8577
8602
  $format = 'float';
@@ -8884,7 +8909,7 @@ sub ProcessMOV($$;$)
8884
8909
  my $dirID = $$dirInfo{DirID} || '';
8885
8910
  my $charsetQuickTime = $et->Options('CharsetQuickTime');
8886
8911
  my ($buff, $tag, $size, $track, $isUserData, %triplet, $doDefaultLang, $index);
8887
- my ($dirEnd, $ee, $unkOpt, %saveOptions, $atomCount);
8912
+ my ($dirEnd, $unkOpt, %saveOptions, $atomCount);
8888
8913
 
8889
8914
  my $topLevel = not $$et{InQuickTime};
8890
8915
  $$et{InQuickTime} = 1;
@@ -8948,8 +8973,8 @@ sub ProcessMOV($$;$)
8948
8973
  }
8949
8974
  $$raf{NoBuffer} = 1 if $et->Options('FastScan'); # disable buffering in FastScan mode
8950
8975
 
8951
- if ($$et{OPTIONS}{ExtractEmbedded}) {
8952
- $ee = 1;
8976
+ my $ee = $$et{OPTIONS}{ExtractEmbedded};
8977
+ if ($ee) {
8953
8978
  $unkOpt = $$et{OPTIONS}{Unknown};
8954
8979
  require 'Image/ExifTool/QuickTimeStream.pl';
8955
8980
  }
@@ -9032,6 +9057,9 @@ sub ProcessMOV($$;$)
9032
9057
  } elsif ($handlerType ne 'vide' and not $$et{OPTIONS}{Validate}) {
9033
9058
  EEWarn($et);
9034
9059
  }
9060
+ } elsif ($ee and $ee > 1 and $eeBox2{$handlerType} and $eeBox2{$handlerType}{$tag}) {
9061
+ $eeTag = 1;
9062
+ $$et{OPTIONS}{Unknown} = 1;
9035
9063
  }
9036
9064
  my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
9037
9065
 
@@ -65,8 +65,9 @@ my @dateMax = ( 24, 59, 59, 2200, 12, 31 );
65
65
  my $gpsBlockSize = 0x8000;
66
66
 
67
67
  # conversion factors
68
- my $knotsToKph = 1.852; # knots --> km/h
69
- my $mpsToKph = 3.6; # m/s --> km/h
68
+ my $knotsToKph = 1.852; # knots --> km/h
69
+ my $mpsToKph = 3.6; # m/s --> km/h
70
+ my $mphToKph = 1.60934; # mph --> km/h
70
71
 
71
72
  # handler types to process based on MetaFormat/OtherFormat
72
73
  my %processByMetaFormat = (
@@ -96,7 +97,7 @@ my %insvLimit = (
96
97
  NOTES => q{
97
98
  Timed metadata extracted from QuickTime media data and some AVI videos when
98
99
  the ExtractEmbedded option is used. Although most of these tags are
99
- combined into the single table below, ExifTool currently reads 49 different
100
+ combined into the single table below, ExifTool currently reads 51 different
100
101
  formats of timed GPS metadata from video files.
101
102
  },
102
103
  VARS => { NO_ID => 1 },
@@ -531,7 +532,10 @@ my %insvLimit = (
531
532
  PROCESS_PROC => \&Process_tx3g,
532
533
  GROUPS => { 2 => 'Location' },
533
534
  FIRST_ENTRY => 0,
534
- NOTES => 'Tags extracted from the tx3g sbtl timed metadata of Yuneec drones.',
535
+ NOTES => q{
536
+ Tags extracted from the tx3g sbtl timed metadata of Yuneec drones, and
537
+ subtitle text in some other videos.
538
+ },
535
539
  Lat => {
536
540
  Name => 'GPSLatitude',
537
541
  RawConv => '$$self{FoundGPSLatitude} = 1; $val',
@@ -552,6 +556,11 @@ my %insvLimit = (
552
556
  GimYaw => 'GimbalYaw',
553
557
  GimPitch => 'GimbalPitch',
554
558
  GimRoll => 'GimbalRoll',
559
+ DateTime => { # for date/time-format subtitle text
560
+ Groups => { 2 => 'Time' },
561
+ PrintConv => '$self->ConvertDateTime($val)',
562
+ },
563
+ Text => { Groups => { 2 => 'Other' } },
555
564
  );
556
565
 
557
566
  %Image::ExifTool::QuickTime::INSV_MakerNotes = (
@@ -1195,6 +1204,10 @@ sub ProcessSamples($)
1195
1204
  $pos += $hdrLen + $len;
1196
1205
  last if $pos + $hdrLen >= length($buff);
1197
1206
  }
1207
+ if ($$et{GotNAL06}) {
1208
+ my $eeOpt = $et->Options('ExtractEmbedded');
1209
+ last unless $eeOpt and $eeOpt > 2;
1210
+ }
1198
1211
  next;
1199
1212
  }
1200
1213
  if ($verbose > 1) {
@@ -1237,8 +1250,8 @@ sub ProcessSamples($)
1237
1250
  next if length($buff) < 20 + $n;
1238
1251
  $et->HandleTag($tagTbl, GPSLatitude => Get32s(\$buff, 12+$n) * 180/0x80000000);
1239
1252
  $et->HandleTag($tagTbl, GPSLongitude => Get32s(\$buff, 16+$n) * 180/0x80000000);
1240
- $et->HandleTag($tagTbl, GPSSpeed => Get16u(\$buff, 8+$n));
1241
- $et->HandleTag($tagTbl, GPSSpeedRef => 'M');
1253
+ $et->HandleTag($tagTbl, GPSSpeed => Get16u(\$buff, 8+$n) * $mphToKph);
1254
+ $et->HandleTag($tagTbl, GPSSpeedRef => 'K');
1242
1255
  SetGPSDateTime($et, $tagTbl, $time[$i]);
1243
1256
  next; # all done (don't store/process as text)
1244
1257
  }
@@ -1981,7 +1994,13 @@ sub Process_tx3g($$$)
1981
1994
  my $dataPt = $$dirInfo{DataPt};
1982
1995
  return 0 if length $$dataPt < 2;
1983
1996
  pos($$dataPt) = 2; # skip 2-byte length word
1984
- $et->HandleTag($tagTablePtr, $1, $2) while $$dataPt =~ /(\w+):([^:]*[^:\s])(\s|$)/sg;
1997
+ $et->VerboseDir('tx3g', undef, length($$dataPt)-2);
1998
+ $et->HandleTag($tagTablePtr, 'Text', substr($$dataPt, 2));
1999
+ if ($$dataPt =~ /^..\w{3} (\d{4})-(\d{2})-(\d{2}) (\d{2}:\d{2}:\d{2}) ?([-+])(\d{2}):?(\d{2})$/s) {
2000
+ $et->HandleTag($tagTablePtr, 'DateTime', "$1:$2:$3 $4$5$6:$7");
2001
+ } else {
2002
+ $et->HandleTag($tagTablePtr, $1, $2) while $$dataPt =~ /(\w+):([^:]*[^:\s])(\s|$)/sg;
2003
+ }
1985
2004
  return 1;
1986
2005
  }
1987
2006
 
@@ -2513,7 +2532,7 @@ sub ProcessInsta360($;$)
2513
2532
  $et->HandleTag($tagTbl, GPSTrack => $a[9]);
2514
2533
  $et->HandleTag($tagTbl, GPSTrackRef => 'T');
2515
2534
  $et->HandleTag($tagTbl, GPSAltitude => $a[10]);
2516
- $et->HandleTag($tagTbl, Unknown02 => "@a[1,2]") if $unknown;
2535
+ $et->HandleTag($tagTbl, Unknown02 => "@a[1,2]") if $unknown; # millisecond counter (https://exiftool.org/forum/index.php?topic=9884.msg65143#msg65143)
2517
2536
  }
2518
2537
  }
2519
2538
  } elsif ($id == 0x101) {