exiftool_vendored 12.15.0 → 12.22.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.
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) {