exiftool_vendored 11.99.0 → 12.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +201 -2
  3. data/bin/MANIFEST +8 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +43 -42
  7. data/bin/exiftool +172 -99
  8. data/bin/lib/Image/ExifTool.pm +170 -117
  9. data/bin/lib/Image/ExifTool.pod +132 -97
  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 +21 -10
  13. data/bin/lib/Image/ExifTool/Canon.pm +202 -13
  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 +22 -3
  17. data/bin/lib/Image/ExifTool/EXE.pm +8 -5
  18. data/bin/lib/Image/ExifTool/Exif.pm +15 -6
  19. data/bin/lib/Image/ExifTool/Font.pm +9 -2
  20. data/bin/lib/Image/ExifTool/GIF.pm +6 -1
  21. data/bin/lib/Image/ExifTool/GeoTiff.pm +2 -0
  22. data/bin/lib/Image/ExifTool/Geotag.pm +2 -2
  23. data/bin/lib/Image/ExifTool/GoPro.pm +48 -22
  24. data/bin/lib/Image/ExifTool/H264.pm +1 -1
  25. data/bin/lib/Image/ExifTool/ID3.pm +86 -12
  26. data/bin/lib/Image/ExifTool/IPTC.pm +1 -0
  27. data/bin/lib/Image/ExifTool/Import.pm +12 -9
  28. data/bin/lib/Image/ExifTool/JSON.pm +27 -4
  29. data/bin/lib/Image/ExifTool/Lang/de.pm +3 -1
  30. data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
  31. data/bin/lib/Image/ExifTool/M2TS.pm +1 -1
  32. data/bin/lib/Image/ExifTool/MPF.pm +2 -2
  33. data/bin/lib/Image/ExifTool/MacOS.pm +154 -38
  34. data/bin/lib/Image/ExifTool/Matroska.pm +3 -1
  35. data/bin/lib/Image/ExifTool/Minolta.pm +7 -2
  36. data/bin/lib/Image/ExifTool/Nikon.pm +143 -17
  37. data/bin/lib/Image/ExifTool/Olympus.pm +40 -17
  38. data/bin/lib/Image/ExifTool/PNG.pm +14 -3
  39. data/bin/lib/Image/ExifTool/PPM.pm +5 -5
  40. data/bin/lib/Image/ExifTool/Panasonic.pm +148 -14
  41. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +34 -0
  42. data/bin/lib/Image/ExifTool/Parrot.pm +2 -1
  43. data/bin/lib/Image/ExifTool/Pentax.pm +11 -3
  44. data/bin/lib/Image/ExifTool/Photoshop.pm +2 -1
  45. data/bin/lib/Image/ExifTool/QuickTime.pm +240 -37
  46. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +419 -60
  47. data/bin/lib/Image/ExifTool/README +25 -21
  48. data/bin/lib/Image/ExifTool/RSRC.pm +17 -11
  49. data/bin/lib/Image/ExifTool/Radiance.pm +7 -2
  50. data/bin/lib/Image/ExifTool/Ricoh.pm +19 -1
  51. data/bin/lib/Image/ExifTool/Shift.pl +1 -0
  52. data/bin/lib/Image/ExifTool/SigmaRaw.pm +40 -33
  53. data/bin/lib/Image/ExifTool/Sony.pm +423 -39
  54. data/bin/lib/Image/ExifTool/Stim.pm +2 -2
  55. data/bin/lib/Image/ExifTool/TagLookup.pm +5798 -5675
  56. data/bin/lib/Image/ExifTool/TagNames.pod +575 -100
  57. data/bin/lib/Image/ExifTool/Validate.pm +4 -4
  58. data/bin/lib/Image/ExifTool/WriteExif.pl +1 -0
  59. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +30 -21
  60. data/bin/lib/Image/ExifTool/Writer.pl +49 -24
  61. data/bin/lib/Image/ExifTool/XMP.pm +99 -17
  62. data/bin/lib/Image/ExifTool/XMP2.pl +1 -0
  63. data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
  64. data/bin/lib/Image/ExifTool/ZISRAW.pm +123 -0
  65. data/bin/perl-Image-ExifTool.spec +42 -41
  66. data/lib/exiftool_vendored/version.rb +1 -1
  67. metadata +9 -8
@@ -512,6 +512,7 @@ my %panasonicWhiteBalance = ( #forum9396
512
512
  # when format is int32u (S models), these values have been observed (ref IB):
513
513
  # 256 - Leica lens
514
514
  # 257 - Lumix lens
515
+ # 258 - ? (seen once)
515
516
  },
516
517
  0x1202 => { #IB
517
518
  Name => 'LensTypeModel',
@@ -531,14 +532,45 @@ my %panasonicWhiteBalance = ( #forum9396
531
532
  PrintConv => '"$val mm"',
532
533
  PrintConvInv => '$val=~s/\s*mm$//;$val',
533
534
  },
535
+ # 0x1300 - incident light value? (ref forum11395)
536
+ 0x1301 => { #forum11395
537
+ Name => 'ApertureValue',
538
+ Writable => 'int16s',
539
+ Priority => 0,
540
+ ValueConv => '2 ** ($val / 512)',
541
+ ValueConvInv => '$val>0 ? 512*log($val)/log(2) : 0',
542
+ PrintConv => 'sprintf("%.1f",$val)',
543
+ PrintConvInv => '$val',
544
+ },
545
+ 0x1302 => { #forum11395
546
+ Name => 'ShutterSpeedValue',
547
+ Writable => 'int16s',
548
+ Priority => 0,
549
+ ValueConv => 'abs($val/256)<100 ? 2**(-$val/256) : 0',
550
+ ValueConvInv => '$val>0 ? -256*log($val)/log(2) : -25600',
551
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
552
+ PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
553
+ },
554
+ 0x1303 => { #forum11395
555
+ Name => 'SensitivityValue',
556
+ Writable => 'int16s',
557
+ ValueConv => '$val / 256',
558
+ ValueConvInv => 'int($val * 256)',
559
+ },
534
560
  0x1305 => { #forum9384
535
561
  Name => 'HighISOMode',
536
562
  Writable => 'int16u',
537
563
  RawConv => '$val || undef',
538
564
  PrintConv => { 1 => 'On', 2 => 'Off' },
539
565
  },
566
+ # 0x1306 EV for some models like the GX8 (forum11395)
540
567
  # 0x140b - scaled overall black level? (ref forum9281)
541
568
  # 0x1411 - scaled black level per channel difference (ref forum9281)
569
+ 0x1412 => { #forum11397
570
+ Name => 'FacesDetected',
571
+ Writable => 'int8u',
572
+ PrintConv => { 0 => 'No', 1 => 'Yes' },
573
+ },
542
574
  # 0x2000 - WB tungsten=3, daylight=4 (ref forum9467)
543
575
  # 0x2009 - scaled black level per channel (ref forum9281)
544
576
  # 0x3000-0x310b - red/blue balances * 1024 (ref forum9467)
@@ -600,6 +632,8 @@ my %panasonicWhiteBalance = ( #forum9396
600
632
  Writable => 'int8u',
601
633
  PrintConv => \%Image::ExifTool::Exif::orientation,
602
634
  },
635
+ # 0x3504 = Tag 0x1301+0x1302-0x1303 (Bv = Av+Tv-Sv) (forum11395)
636
+ # 0x3505 - same as 0x1300 (forum11395)
603
637
  0x3600 => { #forum9396
604
638
  Name => 'WhiteBalanceDetected',
605
639
  Writable => 'int8u',
@@ -13,7 +13,7 @@ package Image::ExifTool::Parrot;
13
13
  use strict;
14
14
  use vars qw($VERSION);
15
15
 
16
- $VERSION = '1.00';
16
+ $VERSION = '1.01';
17
17
 
18
18
  sub Process_mett($$$);
19
19
 
@@ -703,6 +703,7 @@ sub Process_mett($$$)
703
703
  $et->HandleTag($tagTbl, $id, undef,
704
704
  DataPt => $dataPt,
705
705
  DataPos => $dataPos,
706
+ Base => $$dirInfo{Base},
706
707
  Start => $pos,
707
708
  Size => $size,
708
709
  );
@@ -58,7 +58,7 @@ use Image::ExifTool::Exif;
58
58
  use Image::ExifTool::GPS;
59
59
  use Image::ExifTool::HP;
60
60
 
61
- $VERSION = '3.32';
61
+ $VERSION = '3.35';
62
62
 
63
63
  sub CryptShutterCount($$);
64
64
  sub PrintFilter($$$);
@@ -338,6 +338,7 @@ sub DecodeAFPoints($$$$;$);
338
338
  '8 63' => 'HD PENTAX-D FA 15-30mm F2.8 ED SDM WR', #PH
339
339
  '8 64' => 'HD PENTAX-D FA* 50mm F1.4 SDM AW', #27
340
340
  '8 65' => 'HD PENTAX-D FA 70-210mm F4 ED SDM WR', #PH
341
+ '8 66' => 'HD PENTAX-D FA 85mm F1.4 ED SDM AW', #James O'Neill
341
342
  '8 196' => 'HD PENTAX-DA* 11-18mm F2.8 ED DC AW', #29
342
343
  '8 197' => 'HD PENTAX-DA 55-300mm F4.5-6.3 ED PLM WR RE', #29
343
344
  '8 198' => 'smc PENTAX-DA L 18-50mm F4-5.6 DC WR RE', #29
@@ -2893,13 +2894,20 @@ my %binaryDataAttrs = (
2893
2894
  Writable => 'string',
2894
2895
  Notes => 'left blank by some cameras',
2895
2896
  },
2896
- 0x022a => { #PH (K-5)
2897
+ 0x022a => [{ #PH (RICOH models (GR III))
2898
+ Name => 'FilterInfo',
2899
+ Condition => '$$self{Make} =~ /^RICOH/',
2900
+ SubDirectory => {
2901
+ TagTable => 'Image::ExifTool::Pentax::FilterInfo',
2902
+ ByteOrder => 'LittleEndian',
2903
+ },
2904
+ },{ #PH (K-5)
2897
2905
  Name => 'FilterInfo',
2898
2906
  SubDirectory => {
2899
2907
  TagTable => 'Image::ExifTool::Pentax::FilterInfo',
2900
2908
  ByteOrder => 'BigEndian',
2901
2909
  },
2902
- },
2910
+ }],
2903
2911
  0x022b => { #PH (K-5)
2904
2912
  Name => 'LevelInfo',
2905
2913
  SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LevelInfo' },
@@ -28,7 +28,7 @@ use strict;
28
28
  use vars qw($VERSION $AUTOLOAD $iptcDigestInfo);
29
29
  use Image::ExifTool qw(:DataAccess :Utils);
30
30
 
31
- $VERSION = '1.64';
31
+ $VERSION = '1.65';
32
32
 
33
33
  sub ProcessPhotoshop($$$);
34
34
  sub WritePhotoshop($$$);
@@ -982,6 +982,7 @@ sub ProcessPhotoshop($$$)
982
982
  DataPos => $$dirInfo{DataPos},
983
983
  Size => $size,
984
984
  Start => $pos,
985
+ Base => $$dirInfo{Base},
985
986
  Parent => $$dirInfo{DirName},
986
987
  );
987
988
  $size += 1 if $size & 0x01; # size is padded to an even # bytes
@@ -36,6 +36,7 @@
36
36
  # 24) https://github.com/sergiomb2/libmp4v2/wiki/iTunesMetadata
37
37
  # 25) https://cconcolato.github.io/mp4ra/atoms.html
38
38
  # 26) https://github.com/SamsungVR/android_upload_sdk/blob/master/SDKLib/src/main/java/com/samsung/msca/samsungvr/sdk/UserVideo.java
39
+ # 27) https://exiftool.org/forum/index.php?topic=11517.0
39
40
  #------------------------------------------------------------------------------
40
41
 
41
42
  package Image::ExifTool::QuickTime;
@@ -46,7 +47,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
46
47
  use Image::ExifTool::Exif;
47
48
  use Image::ExifTool::GPS;
48
49
 
49
- $VERSION = '2.49';
50
+ $VERSION = '2.55';
50
51
 
51
52
  sub ProcessMOV($$;$);
52
53
  sub ProcessKeys($$$);
@@ -105,7 +106,9 @@ my %mimeLookup = (
105
106
  MQV => 'video/quicktime',
106
107
  HEIC => 'image/heic',
107
108
  HEVC => 'image/heic-sequence',
109
+ HEICS=> 'image/heic-sequence',
108
110
  HEIF => 'image/heif',
111
+ HEIFS=> 'image/heif-sequence',
109
112
  AVIF => 'image/avif', #PH (NC)
110
113
  CRX => 'video/x-canon-crx', # (will get overridden)
111
114
  );
@@ -228,9 +231,10 @@ my %timeInfo = (
228
231
  Writable => 1,
229
232
  Permanent => 1,
230
233
  DelValue => 0,
231
- # Note: This value will be in UTC if generated by a system that is aware of the time zone
232
- ValueConv => 'ConvertUnixTime($val, $self->Options("QuickTimeUTC"))',
233
- ValueConvInv => 'GetUnixTime($val, $self->Options("QuickTimeUTC")) + (66 * 365 + 17) * 24 * 3600',
234
+ # Note: This value will be in UTC if generated by a system that is aware of the time zone (ie. CR3 files)
235
+ RawConvInv => 'GetUnixTime($val, $self->Options("QuickTimeUTC") || $$self{FileType} eq "CR3") + (66 * 365 + 17) * 24 * 3600',
236
+ ValueConv => 'ConvertUnixTime($val, $self->Options("QuickTimeUTC") || $$self{FileType} eq "CR3")',
237
+ ValueConvInv => '$val',
234
238
  PrintConv => '$self->ConvertDateTime($val)',
235
239
  PrintConvInv => '$self->InverseDateTime($val)',
236
240
  # (can't put Groups here because they aren't constant!)
@@ -418,7 +422,8 @@ my %eeBox = (
418
422
  sbtl => { %eeStd },
419
423
  data => { %eeStd },
420
424
  camm => { %eeStd }, # (Insta360)
421
- '' => { 'gps ' => 'moov' }, # (no handler -- in top level 'moov' box)
425
+ ctbx => { %eeStd }, # (GM cars)
426
+ '' => { 'gps ' => 'moov', 'GPS ' => 'main' }, # (no handler -- in top level 'moov' box, and main)
422
427
  );
423
428
 
424
429
  # QuickTime atoms
@@ -555,6 +560,20 @@ my %eeBox = (
555
560
  Start => 16,
556
561
  },
557
562
  },
563
+ { # (ref https://github.com/JamesHeinrich/getID3/blob/master/getid3/module.audio-video.quicktime.php)
564
+ Name => 'SensorData', # sensor data for the 360Fly
565
+ Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/ and $$self{OPTIONS}{ExtractEmbedded}',
566
+ SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Tags360Fly' },
567
+ },
568
+ {
569
+ Name => 'SensorData',
570
+ Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/',
571
+ Notes => 'raw 360Fly sensor data without ExtractEmbedded option',
572
+ RawConv => q{
573
+ $self->WarnOnce('Use the ExtractEmbedded option to decode timed SensorData',3);
574
+ return \$val;
575
+ },
576
+ },
558
577
  { #PH (Canon CR3)
559
578
  Name => 'PreviewImage',
560
579
  Condition => '$$valPt=~/^\xea\xf4\x2b\x5e\x1c\x98\x4b\x88\xb9\xfb\xb7\xdc\x40\x6e\x4d\x16/',
@@ -589,6 +608,11 @@ my %eeBox = (
589
608
  Groups => { 2 => 'Preview' },
590
609
  Binary => 1,
591
610
  },
611
+ 'thm ' => { #PH (70mai A800)
612
+ Name => 'ThumbnailImage',
613
+ Groups => { 2 => 'Preview' },
614
+ Binary => 1,
615
+ },
592
616
  ardt => { #PH
593
617
  Name => 'ARDroneFile',
594
618
  ValueConv => 'length($val) > 4 ? substr($val,4) : $val', # remove length
@@ -667,6 +691,11 @@ my %eeBox = (
667
691
  },
668
692
  # gpsa - seen hex "01 20 00 00" (DuDuBell M1, VSYS M6L)
669
693
  # gsea - 20 bytes hex "05 00's..." (DuDuBell M1) "05 08 02 01 ..." (VSYS M6L)
694
+ 'GPS ' => { # GPS data written by 70mai dashcam (parsed in QuickTimeStream.pl)
695
+ Name => 'GPSDataList2',
696
+ Unknown => 1,
697
+ Binary => 1,
698
+ },
670
699
  );
671
700
 
672
701
  # MPEG-4 'ftyp' atom
@@ -962,7 +991,7 @@ my %eeBox = (
962
991
  %Image::ExifTool::QuickTime::CleanAperture = (
963
992
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
964
993
  GROUPS => { 2 => 'Video' },
965
- FORMAT => 'rational64u',
994
+ FORMAT => 'rational64s',
966
995
  0 => 'CleanApertureWidth',
967
996
  1 => 'CleanApertureHeight',
968
997
  2 => 'CleanApertureOffsetX',
@@ -1307,6 +1336,7 @@ my %eeBox = (
1307
1336
  Format => 'fixed32s[9]',
1308
1337
  Notes => 'writable for the video track via the Composite Rotation tag',
1309
1338
  Writable => 1,
1339
+ Protected => 1,
1310
1340
  Permanent => 1,
1311
1341
  # only set rotation if image size is non-zero
1312
1342
  RawConvInv => \&GetMatrixStructure,
@@ -1371,8 +1401,8 @@ my %eeBox = (
1371
1401
  },
1372
1402
  ValueConvInv => q{
1373
1403
  require Image::ExifTool::XMP;
1374
- $val = Image::ExifTool::XMP::FormatXMPDate($val);
1375
- $val =~ s/([-+]\d{2}):(\d{2})$/$1$2/; # remove time zone colon
1404
+ my $tmp = Image::ExifTool::XMP::FormatXMPDate($val);
1405
+ ($val = $tmp) =~ s/([-+]\d{2}):(\d{2})$/$1$2/ if defined $tmp; # remove time zone colon
1376
1406
  return $val;
1377
1407
  },
1378
1408
  PrintConv => '$self->ConvertDateTime($val)',
@@ -1634,7 +1664,7 @@ my %eeBox = (
1634
1664
  Groups => { 2 => 'Time' },
1635
1665
  Notes => q{
1636
1666
  Apple Photos has been reported to show a crazy date/time for some MP4 files
1637
- containing this tag
1667
+ containing this tag, but perhaps only if it is missing a time zone
1638
1668
  }, #forum10690/11125
1639
1669
  Shift => 'Time',
1640
1670
  ValueConv => q{
@@ -1857,6 +1887,25 @@ my %eeBox = (
1857
1887
  ByteOrder => 'LittleEndian',
1858
1888
  },
1859
1889
  },
1890
+ # ---- Garmin ---- (ref PH)
1891
+ uuid => [{
1892
+ Name => 'GarminSoftware', # (NC)
1893
+ Condition => '$$valPt =~ /^VIRBactioncamera/',
1894
+ RawConv => 'substr($val, 16)',
1895
+ RawConvInv => '"VIRBactioncamera$val"',
1896
+ },{
1897
+ # have seen "28 f3 11 e2 b7 91 4f 6f 94 e2 4f 5d ea cb 3c 01" for RicohThetaZ1 accelerometer RADT data (not yet decoded)
1898
+ Name => 'UUID-Unknown',
1899
+ Writable => 0,
1900
+ %unknownInfo,
1901
+ }],
1902
+ pmcc => {
1903
+ Name => 'GarminSettings',
1904
+ ValueConv => 'substr($val, 4)',
1905
+ ValueConvInv => '"\0\0\0\x01$val"',
1906
+ },
1907
+ # hmtp - "\0\0\0\x01" followed by 408 bytes of zero
1908
+ # vrin - "\0\0\0\x01" followed by 8 bytes of zero
1860
1909
  # ---- GoPro ---- (ref PH)
1861
1910
  GoPr => 'GoProType', # (Hero3+)
1862
1911
  FIRM => { Name => 'FirmwareVersion', Avoid => 1 }, # (Hero4)
@@ -1870,7 +1919,7 @@ my %eeBox = (
1870
1919
  # SETT? 12 bytes (Hero4)
1871
1920
  # MUID? 32 bytes (Hero4, starts with serial number hash)
1872
1921
  # HMMT? 404 bytes (Hero4, all zero)
1873
- # BCID? 26 bytes (Hero5, all zero)
1922
+ # BCID? 26 bytes (Hero5, all zero), 36 bytes GoPro Max
1874
1923
  # GUMI? 16 bytes (Hero5)
1875
1924
  "FOV\0" => 'FieldOfView', #forum8938 (Hero2) seen: "Wide"
1876
1925
  GPMF => {
@@ -2040,6 +2089,63 @@ my %eeBox = (
2040
2089
  ProcessProc => \&Image::ExifTool::ProcessTIFF, # (because ProcessMOV is default)
2041
2090
  },
2042
2091
  },
2092
+ '@mak' => { Name => 'Make', Avoid => 1 },
2093
+ '@mod' => { Name => 'Model', Avoid => 1 },
2094
+ '@swr' => { Name => 'SoftwareVersion', Avoid => 1 },
2095
+ '@day' => {
2096
+ Name => 'ContentCreateDate',
2097
+ Notes => q{
2098
+ some stupid Ricoh programmer used the '@' symbol instead of the copyright
2099
+ symbol in these tag ID's for the Ricoh Theta Z1 and maybe other models
2100
+ },
2101
+ Groups => { 2 => 'Time' },
2102
+ Shift => 'Time',
2103
+ Avoid => 1,
2104
+ # handle values in the form "2010-02-12T13:27:14-0800"
2105
+ ValueConv => q{
2106
+ require Image::ExifTool::XMP;
2107
+ $val = Image::ExifTool::XMP::ConvertXMPDate($val);
2108
+ $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary
2109
+ return $val;
2110
+ },
2111
+ ValueConvInv => q{
2112
+ require Image::ExifTool::XMP;
2113
+ my $tmp = Image::ExifTool::XMP::FormatXMPDate($val);
2114
+ ($val = $tmp) =~ s/([-+]\d{2}):(\d{2})$/$1$2/ if defined $tmp; # remove time zone colon
2115
+ return $val;
2116
+ },
2117
+ PrintConv => '$self->ConvertDateTime($val)',
2118
+ PrintConvInv => '$self->InverseDateTime($val)',
2119
+ },
2120
+ '@xyz' => { #PH (iPhone 3GS)
2121
+ Name => 'GPSCoordinates',
2122
+ Groups => { 2 => 'Location' },
2123
+ Avoid => 1,
2124
+ ValueConv => \&ConvertISO6709,
2125
+ ValueConvInv => \&ConvInvISO6709,
2126
+ PrintConv => \&PrintGPSCoordinates,
2127
+ PrintConvInv => \&PrintInvGPSCoordinates,
2128
+ },
2129
+ # RDT1 - pairs of int32u_BE, starting at byte 8: "458275 471846"
2130
+ # RDT2 - pairs of int32u_BE, starting at byte 8: "472276 468526"
2131
+ # RDT3 - pairs of int32u_BE, starting at byte 8: "876603 482191"
2132
+ # RDT4 - pairs of int32u_BE, starting at byte 8: "1955 484612"
2133
+ # RDT6 - empty
2134
+ # RDT7 - empty
2135
+ # RDT8 - empty
2136
+ # RDT9 - only 16-byte header?
2137
+ # the boxes below all have a similar header (little-endian):
2138
+ # 0 int32u - number of records
2139
+ # 4 ? - "1e 00"
2140
+ # 6 int16u - record length in bytes
2141
+ # 8 ? - "23 01 00 00 00 00 00 00"
2142
+ # 16 - start of records (each record ends in an int64u timestamp in ns)
2143
+ # RDTA - float[4],ts: "-0.31289672 -0.2245330 11.303817 0 775.780"
2144
+ # RDTB - float[4],ts: "-0.04841613 -0.2166595 0.0724792 0 775.780"
2145
+ # RDTC - float[4],ts: "27.60925 -27.10037 -13.27285 0 775.829"
2146
+ # RDTD - int16s[3],ts: "353 -914 16354 0 775.829"
2147
+ # RDTG - ts: "775.825"
2148
+ # RDTI - float[4],ts: "0.00165951 0.005770059 0.06838259 0.1744695 775.862"
2043
2149
  # ---- Samsung ----
2044
2150
  vndr => 'Vendor', #PH (Samsung PL70)
2045
2151
  SDLN => 'PlayMode', #PH (NC, Samsung ST80 "SEQ_PLAY")
@@ -2450,7 +2556,23 @@ my %eeBox = (
2450
2556
  Start => 4,
2451
2557
  },
2452
2558
  },
2453
- # idat
2559
+ idat => {
2560
+ Name => 'MetaImageSize', #PH (NC)
2561
+ Format => 'int16u',
2562
+ # (don't know what the first two numbers are for)
2563
+ PrintConv => '$val =~ s/^(\d+) (\d+) (\d+) (\d+)/${3}x$4/; $val',
2564
+ },
2565
+ uuid => [
2566
+ { #PH (Canon R5/R6 HIF)
2567
+ Name => 'MetaVersion', # (NC)
2568
+ Condition => '$$valPt=~/^\x85\xc0\xb6\x87\x82\x0f\x11\xe0\x81\x11\xf4\xce\x46\x2b\x6a\x48/',
2569
+ RawConv => 'substr($val, 0x14)',
2570
+ },
2571
+ {
2572
+ Name => 'UUID-Unknown',
2573
+ %unknownInfo,
2574
+ },
2575
+ ],
2454
2576
  );
2455
2577
 
2456
2578
  # additional metadata container (ref ISO14496-12:2015)
@@ -2516,6 +2638,7 @@ my %eeBox = (
2516
2638
  Name => 'Rotation',
2517
2639
  Format => 'int8u',
2518
2640
  Writable => 'int8u',
2641
+ Protected => 1,
2519
2642
  ValueConv => '$val * 90',
2520
2643
  ValueConvInv => 'int($val / 90 + 0.5)',
2521
2644
  },
@@ -2547,6 +2670,7 @@ my %eeBox = (
2547
2670
  Name => 'PixelAspectRatio',
2548
2671
  Format => 'int32u',
2549
2672
  Writable => 'int32u',
2673
+ Protected => 1,
2550
2674
  },
2551
2675
  rloc => {
2552
2676
  Name => 'RelativeLocation',
@@ -2555,7 +2679,7 @@ my %eeBox = (
2555
2679
  },
2556
2680
  clap => {
2557
2681
  Name => 'CleanAperture',
2558
- Format => 'rational64u',
2682
+ Format => 'rational64s',
2559
2683
  Notes => '4 numbers: width, height, left and top',
2560
2684
  },
2561
2685
  hvcC => {
@@ -2760,12 +2884,16 @@ my %eeBox = (
2760
2884
  WRITE_PROC => \&WriteQuickTime,
2761
2885
  GROUPS => { 2 => 'Image' },
2762
2886
  # (Note: ExifTool's ItemRefVersion may be used to test the iref version number)
2763
- # dimg - DerivedImage
2764
- # thmb - Thumbnail
2765
- # auxl - AuxiliaryImage
2887
+ NOTES => q{
2888
+ The Item reference entries listed in the table below contain information about
2889
+ the associations between items in the file. This information is used by
2890
+ ExifTool, but these entries are not extracted as tags.
2891
+ },
2892
+ dimg => { Name => 'DerivedImageRef', RawConv => 'undef' },
2893
+ thmb => { Name => 'ThumbnailRef', RawConv => 'undef' },
2894
+ auxl => { Name => 'AuxiliaryImageRef', RawConv => 'undef' },
2766
2895
  cdsc => {
2767
2896
  Name => 'ContentDescribes',
2768
- Notes => 'parsed, but not extracted as a tag',
2769
2897
  RawConv => \&ParseContentDescribes,
2770
2898
  WriteHook => \&ParseContentDescribes,
2771
2899
  },
@@ -2893,10 +3021,25 @@ my %eeBox = (
2893
3021
  "\xa9grp" => 'Grouping',
2894
3022
  "\xa9lyr" => 'Lyrics',
2895
3023
  "\xa9nam" => 'Title',
2896
- # "\xa9st3" ? #10
2897
3024
  "\xa9too" => 'Encoder',
2898
3025
  "\xa9trk" => 'Track',
2899
3026
  "\xa9wrt" => 'Composer',
3027
+ #
3028
+ # the following tags written by AtomicParsley 0.9.6
3029
+ # (ref https://exiftool.org/forum/index.php?topic=11455.0)
3030
+ #
3031
+ "\xa9st3" => 'Subtitle',
3032
+ "\xa9con" => 'Conductor',
3033
+ "\xa9sol" => 'Soloist',
3034
+ "\xa9arg" => 'Arranger',
3035
+ "\xa9ope" => 'OriginalArtist',
3036
+ "\xa9dir" => 'Director',
3037
+ "\xa9ard" => 'ArtDirector',
3038
+ "\xa9sne" => 'SoundEngineer',
3039
+ "\xa9prd" => 'Producer',
3040
+ "\xa9xpd" => 'ExecutiveProducer',
3041
+ sdes => 'StoreDescription',
3042
+ #
2900
3043
  '----' => {
2901
3044
  Name => 'iTunesInfo',
2902
3045
  SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::iTunesInfo' },
@@ -2905,18 +3048,29 @@ my %eeBox = (
2905
3048
  covr => { Name => 'CoverArt', Groups => { 2 => 'Preview' } },
2906
3049
  cpil => { #10
2907
3050
  Name => 'Compilation',
2908
- Format => 'int8u', #23
3051
+ Format => 'int8u', #27 (ref 23 contradicts what AtomicParsley actually writes, which is int8s)
3052
+ Writable => 'int8s',
2909
3053
  PrintConv => { 0 => 'No', 1 => 'Yes' },
2910
3054
  },
2911
3055
  disk => {
2912
3056
  Name => 'DiskNumber',
2913
3057
  Format => 'undef', # (necessary to prevent decoding as string!)
2914
- ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
2915
- ValueConvInv => 'my @a = split / of /, $val; @a==2 ? pack("n3",0,@a) : undef',
3058
+ ValueConv => q{
3059
+ return \$val unless length($val) >= 6;
3060
+ my @a = unpack 'x2nn', $val;
3061
+ return $a[1] ? join(' of ', @a) : $a[0];
3062
+ },
3063
+ ValueConvInv => q{
3064
+ my @a = $val =~ /\d+/g;
3065
+ return undef if @a == 0 or @a > 2;
3066
+ push @a, 0 if @a == 1;
3067
+ return pack('n3', 0, @a);
3068
+ },
2916
3069
  },
2917
3070
  pgap => { #10
2918
3071
  Name => 'PlayGap',
2919
3072
  Format => 'int8u', #23
3073
+ Writable => 'int8s', #27
2920
3074
  PrintConv => {
2921
3075
  0 => 'Insert Gap',
2922
3076
  1 => 'No Gap',
@@ -2924,13 +3078,26 @@ my %eeBox = (
2924
3078
  },
2925
3079
  tmpo => {
2926
3080
  Name => 'BeatsPerMinute',
2927
- Format => 'int16u', # marked as boolean but really int16u in my sample
3081
+ # marked as boolean but really int16u in my sample
3082
+ # (but written as int16s by iTunes and AtomicParsley, ref forum11506)
3083
+ Format => 'int16u',
3084
+ Writable => 'int16s',
2928
3085
  },
2929
3086
  trkn => {
2930
3087
  Name => 'TrackNumber',
2931
3088
  Format => 'undef', # (necessary to prevent decoding as string!)
2932
- ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
2933
- ValueConvInv => 'my @a = split / of /, $val; @a==2 ? pack("n3",0,@a) : undef',
3089
+ ValueConv => q{
3090
+ return \$val unless length($val) >= 6;
3091
+ my @a = unpack 'x2nn', $val;
3092
+ return $a[1] ? join(' of ', @a) : $a[0];
3093
+ },
3094
+ # (see forum11501 for discussion about the format used)
3095
+ ValueConvInv => q{
3096
+ my @a = $val =~ /\d+/g;
3097
+ return undef if @a == 0 or @a > 2;
3098
+ push @a, 0 if @a == 1;
3099
+ return pack('n4', 0, @a, 0);
3100
+ },
2934
3101
  },
2935
3102
  #
2936
3103
  # Note: it is possible that the tags below are not being decoded properly
@@ -2939,6 +3106,7 @@ my %eeBox = (
2939
3106
  akID => { #10
2940
3107
  Name => 'AppleStoreAccountType',
2941
3108
  Format => 'int8u', #24
3109
+ Writable => 'int8s', #27
2942
3110
  PrintConv => {
2943
3111
  0 => 'iTunes',
2944
3112
  1 => 'AOL',
@@ -2949,12 +3117,14 @@ my %eeBox = (
2949
3117
  atID => { #10 (or TV series)
2950
3118
  Name => 'AlbumTitleID',
2951
3119
  Format => 'int32u',
3120
+ Writable => 'int32s', #27
2952
3121
  },
2953
3122
  auth => { Name => 'Author', Groups => { 2 => 'Author' } },
2954
3123
  catg => 'Category', #7
2955
3124
  cnID => { #10
2956
3125
  Name => 'AppleStoreCatalogID',
2957
3126
  Format => 'int32u',
3127
+ Writable => 'int32s', #27
2958
3128
  },
2959
3129
  cprt => { Name => 'Copyright', Groups => { 2 => 'Author' } },
2960
3130
  dscp => { Name => 'Description', Avoid => 1 },
@@ -2962,22 +3132,28 @@ my %eeBox = (
2962
3132
  gnre => { #10
2963
3133
  Name => 'Genre',
2964
3134
  Avoid => 1,
2965
- # (Note: not written as int16u if numerical, although it should be)
3135
+ # (Note: see https://exiftool.org/forum/index.php?topic=11537.0)
3136
+ Format => 'undef',
3137
+ ValueConv => 'unpack("n",$val)',
3138
+ ValueConvInv => '$val =~ /^\d+$/ ? pack("n",$val) : undef',
2966
3139
  PrintConv => q{
2967
3140
  return $val unless $val =~ /^\d+$/;
2968
3141
  require Image::ExifTool::ID3;
2969
3142
  Image::ExifTool::ID3::PrintGenre($val - 1); # note the "- 1"
2970
3143
  },
2971
3144
  PrintConvInv => q{
3145
+ return $val if $val =~ /^[0-9]+$/;
2972
3146
  require Image::ExifTool::ID3;
2973
3147
  my $id = Image::ExifTool::ID3::GetGenreID($val);
2974
- return defined $id ? $id : $val;
2975
- },
3148
+ return unless defined $id and $id =~ /^\d+$/;
3149
+ return $id + 1;
3150
+ },
2976
3151
  },
2977
3152
  egid => 'EpisodeGlobalUniqueID', #7
2978
3153
  geID => { #10
2979
3154
  Name => 'GenreID',
2980
3155
  Format => 'int32u',
3156
+ Writable => 'int32s', #27
2981
3157
  SeparateTable => 1,
2982
3158
  # the following lookup is based on http://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/genres
2983
3159
  # (see scripts/parse_genre to parse genre JSON file from above)
@@ -5630,6 +5806,7 @@ my %eeBox = (
5630
5806
  hdvd => { #10
5631
5807
  Name => 'HDVideo',
5632
5808
  Format => 'int8u', #24
5809
+ Writable => 'int8s', #27
5633
5810
  PrintConv => { 0 => 'No', 1 => 'Yes' },
5634
5811
  },
5635
5812
  keyw => 'Keyword', #7
@@ -5637,18 +5814,21 @@ my %eeBox = (
5637
5814
  pcst => { #7
5638
5815
  Name => 'Podcast',
5639
5816
  Format => 'int8u', #23
5817
+ Writable => 'int8s', #27
5640
5818
  PrintConv => { 0 => 'No', 1 => 'Yes' },
5641
5819
  },
5642
5820
  perf => 'Performer',
5643
5821
  plID => { #10 (or TV season)
5644
5822
  Name => 'PlayListID',
5645
5823
  Format => 'int8u', # actually int64u, but split it up
5824
+ Writable => 'int32s', #27
5646
5825
  },
5647
5826
  purd => 'PurchaseDate', #7
5648
5827
  purl => 'PodcastURL', #7
5649
5828
  rtng => { #10
5650
5829
  Name => 'Rating',
5651
5830
  Format => 'int8u', #23
5831
+ Writable => 'int8s', #27
5652
5832
  PrintConv => {
5653
5833
  0 => 'none',
5654
5834
  1 => 'Explicit',
@@ -5659,6 +5839,7 @@ my %eeBox = (
5659
5839
  sfID => { #10
5660
5840
  Name => 'AppleStoreCountry',
5661
5841
  Format => 'int32u',
5842
+ Writable => 'int32s', #27
5662
5843
  SeparateTable => 1,
5663
5844
  PrintConv => { #21
5664
5845
  143441 => 'United States', # US
@@ -5827,6 +6008,7 @@ my %eeBox = (
5827
6008
  stik => { #10
5828
6009
  Name => 'MediaType',
5829
6010
  Format => 'int8u', #23
6011
+ Writable => 'int8s', #27
5830
6012
  PrintConvColumns => 2,
5831
6013
  PrintConv => { #(http://weblog.xanga.com/gryphondwb/615474010/iphone-ringtones---what-did-itunes-741-really-do.html)
5832
6014
  0 => 'Movie (old)', #forum9059 (was Movie)
@@ -5848,6 +6030,7 @@ my %eeBox = (
5848
6030
  tves => { #7/10
5849
6031
  Name => 'TVEpisode',
5850
6032
  Format => 'int32u',
6033
+ Writable => 'int32s', #27
5851
6034
  },
5852
6035
  tvnn => 'TVNetworkName', #7
5853
6036
  tvsh => 'TVShow', #10
@@ -5858,7 +6041,8 @@ my %eeBox = (
5858
6041
  yrrc => 'Year', #(ffmpeg source)
5859
6042
  itnu => { #PH (iTunes 10.5)
5860
6043
  Name => 'iTunesU',
5861
- Format => 'int8s',
6044
+ Format => 'int8u', #27
6045
+ Writable => 'int8s', #27
5862
6046
  Description => 'iTunes U',
5863
6047
  PrintConv => { 0 => 'No', 1 => 'Yes' },
5864
6048
  },
@@ -5915,15 +6099,18 @@ my %eeBox = (
5915
6099
  "\xa9mvn" => 'MovementName', #PH
5916
6100
  "\xa9mvi" => { #PH
5917
6101
  Name => 'MovementNumber',
5918
- Format => 'int16s',
6102
+ Format => 'int16u', #27
6103
+ Writable => 'int16s', #27
5919
6104
  },
5920
6105
  "\xa9mvc" => { #PH
5921
6106
  Name => 'MovementCount',
5922
- Format => 'int16s',
6107
+ Format => 'int16u', #27
6108
+ Writable => 'int16s', #27
5923
6109
  },
5924
6110
  shwm => { #PH
5925
6111
  Name => 'ShowMovement',
5926
- Format => 'int8s',
6112
+ Format => 'int8u', #27
6113
+ Writable => 'int8s', #27
5927
6114
  PrintConv => { 0 => 'No', 1 => 'Yes' },
5928
6115
  },
5929
6116
  );
@@ -6700,7 +6887,7 @@ my %eeBox = (
6700
6887
  #
6701
6888
  # AudioFormat Offset Child atoms
6702
6889
  # ----------- ------ ----------------
6703
- # mp4a 52 * wave, chan, esds, SA3D(Insta360 spherical video params?)
6890
+ # mp4a 52 * wave, chan, esds, SA3D(Insta360 spherical video params?,also GoPro Max)
6704
6891
  # in24 52 wave, chan
6705
6892
  # "ms\0\x11" 52 wave
6706
6893
  # sowt 52 chan
@@ -6737,6 +6924,7 @@ my %eeBox = (
6737
6924
  # alac - 28 bytes
6738
6925
  # adrm - AAX DRM atom? 148 bytes
6739
6926
  # aabd - AAX unknown 17kB (contains 'aavd' strings)
6927
+ # SA3D - written by Garmin VIRB360
6740
6928
  );
6741
6929
 
6742
6930
  # AMR decode config box (ref 3)
@@ -7223,6 +7411,20 @@ my %eeBox = (
7223
7411
  #
7224
7412
  ftab => { Name => 'FontTable', Format => 'undef', ValueConv => 'substr($val, 5)' },
7225
7413
  name => { Name => 'OtherName', Format => 'undef', ValueConv => 'substr($val, 4)' },
7414
+ # mrlh = GM header?
7415
+ # mrlv = GM data
7416
+ # mrld = GM data (448-byte records):
7417
+ # 0 - int32u count
7418
+ # 4 - int32u ? (related to units) 0=none,1=m/km,2=L,3=kph,4=C,7=deg,8=rpm,9=kPa,10=G,11=V,15=Nm,16=%
7419
+ # 8 - int32u ? (0,1,3,4,5)
7420
+ # 12 - string[64] units
7421
+ # 76 - int32u ? (1,3,7,15)
7422
+ # 80 - int32u 0
7423
+ # 84 - undef[4] ?
7424
+ # 88 - int16u[6] ?
7425
+ # 100 - undef[32] ?
7426
+ # 132 - string[64] measurement name
7427
+ # 196 - string[64] measurement name
7226
7428
  );
7227
7429
 
7228
7430
  # MP4 data information box (ref 5)
@@ -7519,6 +7721,7 @@ my %eeBox = (
7519
7721
  1 => 'QuickTime:HandlerType',
7520
7722
  },
7521
7723
  Writable => 1,
7724
+ Protected => 1,
7522
7725
  WriteAlso => {
7523
7726
  MatrixStructure => 'Image::ExifTool::QuickTime::GetRotationMatrix($val)',
7524
7727
  },
@@ -8353,7 +8556,7 @@ sub EEWarn($)
8353
8556
  #------------------------------------------------------------------------------
8354
8557
  # Get quicktime format from flags word
8355
8558
  # Inputs: 0) quicktime atom flags, 1) data length
8356
- # Returns: Exiftool format string
8559
+ # Returns: ExifTool format string
8357
8560
  sub QuickTimeFormat($$)
8358
8561
  {
8359
8562
  my ($flags, $len) = @_;
@@ -8580,7 +8783,7 @@ sub ProcessKeys($$$)
8580
8783
  my $ns = substr($$dataPt, $pos + 4, 4);
8581
8784
  my $tag = substr($$dataPt, $pos + 8, $len - 8);
8582
8785
  $tag =~ s/\0.*//s; # truncate at null
8583
- $tag =~ s/^com\.apple\.quicktime\.// if $ns eq 'mdta'; # remove apple quicktime domain
8786
+ $tag =~ s/^com\.(apple\.quicktime\.)?// if $ns eq 'mdta'; # remove apple quicktime domain
8584
8787
  $tag = "Tag_$ns" unless $tag;
8585
8788
  # (I have some samples where the tag is a reversed ItemList or UserData tag ID)
8586
8789
  my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
@@ -9091,10 +9294,10 @@ ItemID: foreach $id (keys %$items) {
9091
9294
  }
9092
9295
  }
9093
9296
  if ($ctry or $lang) {
9094
- $lang = GetLangCode($lang, $ctry);
9095
- if ($lang) {
9297
+ my $langCode = GetLangCode($lang, $ctry);
9298
+ if ($langCode) {
9096
9299
  # get tagInfo for other language
9097
- $langInfo = GetLangInfoQT($et, $tagInfo, $lang);
9300
+ $langInfo = GetLangInfoQT($et, $tagInfo, $langCode);
9098
9301
  # save other language tag ID's so we can delete later if necessary
9099
9302
  if ($langInfo) {
9100
9303
  $$tagInfo{OtherLang} or $$tagInfo{OtherLang} = [ ];
@@ -9111,7 +9314,7 @@ ItemID: foreach $id (keys %$items) {
9111
9314
  Size => $len,
9112
9315
  Format => $format,
9113
9316
  Index => $index,
9114
- Extra => sprintf(", Type='${type}', Flags=0x%x%s",$flags,($lang ? ", Lang=$lang" : '')),
9317
+ Extra => sprintf(", Type='${type}', Flags=0x%x, Lang=0x%.4x",$flags,$lang),
9115
9318
  ) if $verbose;
9116
9319
  # use "Keys" in path instead of ItemList if this was defined by a Keys tag
9117
9320
  my $isKey = $$tagInfo{Groups} && $$tagInfo{Groups}{1} && $$tagInfo{Groups}{1} eq 'Keys';