exiftool_vendored 12.42.0 → 12.52.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +226 -6
  3. data/bin/MANIFEST +14 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +45 -44
  7. data/bin/config_files/acdsee.config +2 -1
  8. data/bin/config_files/frameCount.config +56 -0
  9. data/bin/config_files/tiff_version.config +1 -1
  10. data/bin/exiftool +116 -97
  11. data/bin/fmt_files/gpx.fmt +3 -0
  12. data/bin/fmt_files/gpx_wpt.fmt +3 -0
  13. data/bin/lib/Image/ExifTool/Apple.pm +16 -3
  14. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +23 -12
  15. data/bin/lib/Image/ExifTool/Canon.pm +66 -37
  16. data/bin/lib/Image/ExifTool/CanonRaw.pm +8 -1
  17. data/bin/lib/Image/ExifTool/CanonVRD.pm +7 -8
  18. data/bin/lib/Image/ExifTool/Casio.pm +3 -3
  19. data/bin/lib/Image/ExifTool/DJI.pm +2 -1
  20. data/bin/lib/Image/ExifTool/DarwinCore.pm +13 -1
  21. data/bin/lib/Image/ExifTool/EXE.pm +9 -1
  22. data/bin/lib/Image/ExifTool/Exif.pm +17 -12
  23. data/bin/lib/Image/ExifTool/FLAC.pm +17 -3
  24. data/bin/lib/Image/ExifTool/FLIR.pm +9 -7
  25. data/bin/lib/Image/ExifTool/FlashPix.pm +26 -3
  26. data/bin/lib/Image/ExifTool/FujiFilm.pm +51 -4
  27. data/bin/lib/Image/ExifTool/GPS.pm +31 -5
  28. data/bin/lib/Image/ExifTool/Geotag.pm +36 -8
  29. data/bin/lib/Image/ExifTool/ICC_Profile.pm +3 -2
  30. data/bin/lib/Image/ExifTool/ICO.pm +143 -0
  31. data/bin/lib/Image/ExifTool/ID3.pm +6 -6
  32. data/bin/lib/Image/ExifTool/IPTC.pm +5 -1
  33. data/bin/lib/Image/ExifTool/JPEG.pm +1 -0
  34. data/bin/lib/Image/ExifTool/Jpeg2000.pm +24 -3
  35. data/bin/lib/Image/ExifTool/LNK.pm +5 -2
  36. data/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
  37. data/bin/lib/Image/ExifTool/Lang/fr.pm +6015 -759
  38. data/bin/lib/Image/ExifTool/Lang/sk.pm +1927 -0
  39. data/bin/lib/Image/ExifTool/M2TS.pm +98 -8
  40. data/bin/lib/Image/ExifTool/MIE.pm +9 -3
  41. data/bin/lib/Image/ExifTool/MISB.pm +494 -0
  42. data/bin/lib/Image/ExifTool/MakerNotes.pm +3 -1
  43. data/bin/lib/Image/ExifTool/Matroska.pm +272 -48
  44. data/bin/lib/Image/ExifTool/Motorola.pm +8 -2
  45. data/bin/lib/Image/ExifTool/Nikon.pm +746 -382
  46. data/bin/lib/Image/ExifTool/NikonCustom.pm +139 -106
  47. data/bin/lib/Image/ExifTool/NikonSettings.pm +5 -3
  48. data/bin/lib/Image/ExifTool/Olympus.pm +6 -4
  49. data/bin/lib/Image/ExifTool/PNG.pm +8 -1
  50. data/bin/lib/Image/ExifTool/Panasonic.pm +21 -4
  51. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +25 -5
  52. data/bin/lib/Image/ExifTool/Parrot.pm +96 -2
  53. data/bin/lib/Image/ExifTool/Pentax.pm +7 -2
  54. data/bin/lib/Image/ExifTool/Photoshop.pm +29 -3
  55. data/bin/lib/Image/ExifTool/QuickTime.pm +166 -13
  56. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +161 -22
  57. data/bin/lib/Image/ExifTool/README +15 -4
  58. data/bin/lib/Image/ExifTool/RIFF.pm +106 -9
  59. data/bin/lib/Image/ExifTool/Samsung.pm +2 -2
  60. data/bin/lib/Image/ExifTool/Sigma.pm +27 -1
  61. data/bin/lib/Image/ExifTool/SigmaRaw.pm +37 -13
  62. data/bin/lib/Image/ExifTool/Sony.pm +75 -47
  63. data/bin/lib/Image/ExifTool/TagInfoXML.pm +13 -6
  64. data/bin/lib/Image/ExifTool/TagLookup.pm +4791 -4519
  65. data/bin/lib/Image/ExifTool/TagNames.pod +2056 -1446
  66. data/bin/lib/Image/ExifTool/Text.pm +3 -4
  67. data/bin/lib/Image/ExifTool/Torrent.pm +2 -3
  68. data/bin/lib/Image/ExifTool/Validate.pm +3 -3
  69. data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +7 -0
  70. data/bin/lib/Image/ExifTool/WriteExif.pl +100 -23
  71. data/bin/lib/Image/ExifTool/WriteIPTC.pl +2 -6
  72. data/bin/lib/Image/ExifTool/WritePhotoshop.pl +5 -5
  73. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +12 -7
  74. data/bin/lib/Image/ExifTool/WriteRIFF.pl +359 -0
  75. data/bin/lib/Image/ExifTool/WriteXMP.pl +15 -1
  76. data/bin/lib/Image/ExifTool/Writer.pl +46 -18
  77. data/bin/lib/Image/ExifTool/XMP.pm +78 -59
  78. data/bin/lib/Image/ExifTool/XMP2.pl +19 -4
  79. data/bin/lib/Image/ExifTool/ZIP.pm +19 -7
  80. data/bin/lib/Image/ExifTool.pm +146 -38
  81. data/bin/lib/Image/ExifTool.pod +83 -69
  82. data/bin/perl-Image-ExifTool.spec +43 -43
  83. data/lib/exiftool_vendored/version.rb +1 -1
  84. metadata +10 -4
@@ -6,6 +6,7 @@
6
6
  # Revisions: 05/26/2010 - P. Harvey Created
7
7
  #
8
8
  # References: 1) http://www.matroska.org/technical/specs/index.html
9
+ # 2) https://www.matroska.org/technical/tagging.html
9
10
  #------------------------------------------------------------------------------
10
11
 
11
12
  package Image::ExifTool::Matroska;
@@ -14,10 +15,26 @@ use strict;
14
15
  use vars qw($VERSION);
15
16
  use Image::ExifTool qw(:DataAccess :Utils);
16
17
 
17
- $VERSION = '1.11';
18
+ $VERSION = '1.13';
19
+
20
+ sub HandleStruct($$;$$$$);
18
21
 
19
22
  my %noYes = ( 0 => 'No', 1 => 'Yes' );
20
23
 
24
+ my %dateInfo = (
25
+ Groups => { 2 => 'Time' },
26
+ # the spec says to use "-" as a date separator, but my only sample uses ":", so
27
+ # convert to ":" if necessary, and avoid translating all "-" in case someone wants
28
+ # to include a negative time zone (although the spec doesn't mention time zones)
29
+ ValueConv => '$val =~ s/^(\d{4})-(\d{2})-/$1:$2:/; $val',
30
+ PrintConv => '$self->ConvertDateTime($val)',
31
+ );
32
+
33
+ my %uidInfo = (
34
+ Format => 'string',
35
+ ValueConv => 'unpack("H*",$val)'
36
+ );
37
+
21
38
  # Matroska tags
22
39
  # Note: The tag ID's in the Matroska documentation include the length designation
23
40
  # (the upper bits), which is not included in the tag ID's below
@@ -27,8 +44,10 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
27
44
  NOTES => q{
28
45
  The following tags are extracted from Matroska multimedia container files.
29
46
  This container format is used by file types such as MKA, MKV, MKS and WEBM.
30
- For speed, ExifTool extracts tags only up to the first Cluster unless the
31
- L<Verbose|../ExifTool.html#Verbose> (-v) or L<Unknown|../ExifTool.html#Unknown> = 2 (-U) option is used. See
47
+ For speed, by default ExifTool extracts tags only up to the first Cluster.
48
+ However, the L<Verbose|../ExifTool.html#Verbose> (-v) and L<Unknown|../ExifTool.html#Unknown> = 2 (-U) options force processing of
49
+ Cluster data, and the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> (-ee) option skips over Clusters to
50
+ read subsequent tags. See
32
51
  L<http://www.matroska.org/technical/specs/index.html> for the official
33
52
  Matroska specification.
34
53
  },
@@ -56,7 +75,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
56
75
  #
57
76
  # General
58
77
  #
59
- 0x3f => { Name => 'CRC-32', Binary => 1, Unknown => 1 },
78
+ 0x3f => { Name => 'CRC-32', Format => 'unsigned', Unknown => 1 },
60
79
  0x6c => { Name => 'Void', NoSave => 1, Unknown => 1 },
61
80
  #
62
81
  # Signature
@@ -102,18 +121,18 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
102
121
  Name => 'Info',
103
122
  SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
104
123
  },
105
- 0x33a4 => { Name => 'SegmentUID', Binary => 1, Unknown => 1 },
124
+ 0x33a4 => { Name => 'SegmentUID', %uidInfo, Unknown => 1 },
106
125
  0x3384 => { Name => 'SegmentFileName', Format => 'utf8' },
107
- 0x1cb923 => { Name => 'PrevUID', Binary => 1, Unknown => 1 },
126
+ 0x1cb923 => { Name => 'PrevUID', %uidInfo, Unknown => 1 },
108
127
  0x1c83ab => { Name => 'PrevFileName', Format => 'utf8' },
109
- 0x1eb923 => { Name => 'NextUID', Binary => 1, Unknown => 1 },
128
+ 0x1eb923 => { Name => 'NextUID', %uidInfo, Unknown => 1 },
110
129
  0x1e83bb => { Name => 'NextFileName', Format => 'utf8' },
111
130
  0x0444 => { Name => 'SegmentFamily', Binary => 1, Unknown => 1 },
112
131
  0x2924 => {
113
132
  Name => 'ChapterTranslate',
114
133
  SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
115
134
  },
116
- 0x29fc => { Name => 'ChapterTranslateEditionUID',Format => 'unsigned', Unknown => 1 },
135
+ 0x29fc => { Name => 'ChapterTranslateEditionUID', %uidInfo, Unknown => 1 },
117
136
  0x29bf => {
118
137
  Name => 'ChapterTranslateCodec',
119
138
  Format => 'unsigned',
@@ -226,7 +245,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
226
245
  SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
227
246
  },
228
247
  0x57 => { Name => 'TrackNumber', Format => 'unsigned' },
229
- 0x33c5 => { Name => 'TrackUID', Format => 'unsigned', Unknown => 1 },
248
+ 0x33c5 => { Name => 'TrackUID', %uidInfo },
230
249
  0x03 => {
231
250
  Name => 'TrackType',
232
251
  Format => 'unsigned',
@@ -269,10 +288,11 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
269
288
  }
270
289
  ],
271
290
  0x3314f => { Name => 'TrackTimecodeScale',Format => 'float' },
272
- 0x137f => { Name => 'TrackOffset', Format => 'signed', Unknown => 1 },
291
+ 0x137f => { Name => 'TrackOffset', Format => 'signed', Unknown => 1 },
273
292
  0x15ee => { Name => 'MaxBlockAdditionID',Format => 'unsigned', Unknown => 1 },
274
- 0x136e => { Name => 'TrackName', Format => 'utf8' },
275
- 0x2b59c => { Name => 'TrackLanguage', Format => 'string' },
293
+ 0x136e => { Name => 'TrackName', Format => 'utf8' },
294
+ 0x2b59c => { Name => 'TrackLanguage', Format => 'string' },
295
+ 0x2b59d => { Name => 'TrackLanguageIETF', Format => 'string' },
276
296
  0x06 => [
277
297
  {
278
298
  Name => 'VideoCodecID',
@@ -302,7 +322,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
302
322
  Format => 'utf8',
303
323
  }
304
324
  ],
305
- 0x3446 => { Name => 'TrackAttachmentUID',Format => 'unsigned' },
325
+ 0x3446 => { Name => 'TrackAttachmentUID',%uidInfo },
306
326
  0x1a9697=>{ Name => 'CodecSettings', Format => 'utf8' },
307
327
  0x1b4040=>{ Name => 'CodecInfoURL', Format => 'string' },
308
328
  0x6b240 =>{ Name => 'CodecDownloadURL', Format => 'string' },
@@ -312,7 +332,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
312
332
  Name => 'TrackTranslate',
313
333
  SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
314
334
  },
315
- 0x26fc => { Name => 'TrackTranslateEditionUID',Format => 'unsigned', Unknown => 1 },
335
+ 0x26fc => { Name => 'TrackTranslateEditionUID', %uidInfo, Unknown => 1 },
316
336
  0x26bf => {
317
337
  Name => 'TrackTranslateCodec',
318
338
  Format => 'unsigned',
@@ -359,6 +379,8 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
359
379
  0 => 'Pixels',
360
380
  1 => 'cm',
361
381
  2 => 'inches',
382
+ 3 => 'Display Aspect Ratio',
383
+ 4 => 'Unknown',
362
384
  },
363
385
  },
364
386
  0x14b3 => {
@@ -514,7 +536,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
514
536
  0x66e => { Name => 'AttachedFileName', Format => 'utf8' },
515
537
  0x660 => { Name => 'AttachedFileMIMEType', Format => 'string' },
516
538
  0x65c => { Name => 'AttachedFileData', Binary => 1 },
517
- 0x6ae => { Name => 'AttachedFileUID', Format => 'unsigned' },
539
+ 0x6ae => { Name => 'AttachedFileUID', %uidInfo },
518
540
  0x675 => { Name => 'AttachedFileReferral', Binary => 1, Unknown => 1 },
519
541
  #
520
542
  # Chapters
@@ -527,7 +549,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
527
549
  Name => 'EditionEntry',
528
550
  SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
529
551
  },
530
- 0x5bc => { Name => 'EditionUID', Format => 'unsigned', Unknown => 1 },
552
+ 0x5bc => { Name => 'EditionUID', %uidInfo, Unknown => 1 },
531
553
  0x5bd => { Name => 'EditionFlagHidden', Format => 'unsigned', Unknown => 1 },
532
554
  0x5db => { Name => 'EditionFlagDefault',Format => 'unsigned', Unknown => 1 },
533
555
  0x5dd => { Name => 'EditionFlagOrdered',Format => 'unsigned', Unknown => 1 },
@@ -535,7 +557,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
535
557
  Name => 'ChapterAtom',
536
558
  SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
537
559
  },
538
- 0x33c4 => { Name => 'ChapterUID', Format => 'unsigned', Unknown => 1 },
560
+ 0x33c4 => { Name => 'ChapterUID', %uidInfo, Unknown => 1 },
539
561
  0x11 => {
540
562
  Name => 'ChapterTimeStart',
541
563
  Groups => { 1 => 'Chapter#' },
@@ -551,8 +573,8 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
551
573
  },
552
574
  0x18 => { Name => 'ChapterFlagHidden', Format => 'unsigned', Unknown => 1 },
553
575
  0x598 => { Name => 'ChapterFlagEnabled',Format => 'unsigned', Unknown => 1 },
554
- 0x2e67=> { Name => 'ChapterSegmentUID', Binary => 1, Unknown => 1 },
555
- 0x2ebc=> { Name => 'ChapterSegmentEditionUID', Binary => 1, Unknown => 1 },
576
+ 0x2e67=> { Name => 'ChapterSegmentUID', %uidInfo, Unknown => 1 },
577
+ 0x2ebc=> { Name => 'ChapterSegmentEditionUID', %uidInfo, Unknown => 1 },
556
578
  0x23c3 => {
557
579
  Name => 'ChapterPhysicalEquivalent',
558
580
  Format => 'unsigned',
@@ -619,21 +641,24 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
619
641
  Name => 'Targets',
620
642
  SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
621
643
  },
622
- 0x28ca => { Name => 'TargetTypeValue', Format => 'unsigned' },
623
- 0x23ca => { Name => 'TargetType', Format => 'string' },
624
- 0x23c5 => { Name => 'TagTrackUID', Format => 'unsigned', Unknown => 1 },
625
- 0x23c9 => { Name => 'TagEditionUID', Format => 'unsigned', Unknown => 1 },
626
- 0x23c4 => { Name => 'TagChapterUID', Format => 'unsigned', Unknown => 1 },
627
- 0x23c6 => { Name => 'TagAttachmentUID', Format => 'unsigned', Unknown => 1 },
644
+ # Targets elements
645
+ 0x28ca => { Name => 'TargetTypeValue', Format => 'unsigned' },
646
+ 0x23ca => { Name => 'TargetType', Format => 'string' },
647
+ 0x23c5 => { Name => 'TagTrackUID', %uidInfo },
648
+ 0x23c9 => { Name => 'TagEditionUID', %uidInfo },
649
+ 0x23c4 => { Name => 'TagChapterUID', %uidInfo },
650
+ 0x23c6 => { Name => 'TagAttachmentUID', %uidInfo },
628
651
  0x27c8 => {
629
652
  Name => 'SimpleTag',
630
653
  SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
631
654
  },
632
- 0x5a3 => { Name => 'TagName', Format => 'utf8' },
633
- 0x47a => { Name => 'TagLanguage', Format => 'string' },
634
- 0x484 => { Name => 'TagDefault', Format => 'unsigned', PrintConv => \%noYes },
635
- 0x487 => { Name => 'TagString', Format => 'utf8' },
636
- 0x485 => { Name => 'TagBinary', Binary => 1 },
655
+ # SimpleTag elements
656
+ 0x5a3 => { Name => 'TagName', Format => 'utf8' },
657
+ 0x47a => { Name => 'TagLanguage', Format => 'string' },
658
+ 0x47a => { Name => 'TagLanguageBCP47', Format => 'string' },
659
+ 0x484 => { Name => 'TagDefault', Format => 'unsigned', PrintConv => \%noYes },
660
+ 0x487 => { Name => 'TagString', Format => 'utf8' },
661
+ 0x485 => { Name => 'TagBinary', Binary => 1 },
637
662
  #
638
663
  # Spherical Video V2 (untested)
639
664
  #
@@ -682,6 +707,172 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
682
707
  0x7675 => { Name => 'ProjectionPoseRoll', Format => 'float' },
683
708
  );
684
709
 
710
+ # standardized tag names (ref 2)
711
+ %Image::ExifTool::Matroska::Tags = (
712
+ GROUPS => { 2 => 'Video' },
713
+ VARS => { LONG_TAGS => 1 },
714
+ NOTES => q{
715
+ Standardized Matroska tags (see
716
+ L<https://www.matroska.org/technical/tagging.html>).
717
+ },
718
+ ORIGINAL => 'Original', # struct
719
+ SAMPLE => 'Sample', # struct
720
+ COUNTRY => 'Country', # struct (should deal with this properly!)
721
+ TOTAL_PARTS => 'TotalParts',
722
+ PART_NUMBER => 'PartNumber',
723
+ PART_OFFSET => 'PartOffset',
724
+ TITLE => 'Title',
725
+ SUBTITLE => 'Subtitle',
726
+ URL => 'URL', # nested
727
+ SORT_WITH => 'SortWith', # nested
728
+ INSTRUMENTS => 'Instruments', # nested
729
+ EMAIL => 'Email', # nested
730
+ ADDRESS => 'Address', # nested
731
+ FAX => 'FAX', # nested
732
+ PHONE => 'Phone', # nested
733
+ ARTIST => 'Artist',
734
+ LEAD_PERFORMER => 'LeadPerformer',
735
+ ACCOMPANIMENT => 'Accompaniment',
736
+ COMPOSER => 'Composer',
737
+ ARRANGER => 'Arranger',
738
+ LYRICS => 'Lyrics',
739
+ LYRICIST => 'Lyricist',
740
+ CONDUCTOR => 'Conductor',
741
+ DIRECTOR => 'Director',
742
+ ASSISTANT_DIRECTOR => 'AssistantDirector',
743
+ DIRECTOR_OF_PHOTOGRAPHY => 'DirectorOfPhotography',
744
+ SOUND_ENGINEER => 'SoundEngineer',
745
+ ART_DIRECTOR => 'ArtDirector',
746
+ PRODUCTION_DESIGNER => 'ProductionDesigner',
747
+ CHOREGRAPHER => 'Choregrapher',
748
+ COSTUME_DESIGNER => 'CostumeDesigner',
749
+ ACTOR => 'Actor',
750
+ CHARACTER => 'Character',
751
+ WRITTEN_BY => 'WrittenBy',
752
+ SCREENPLAY_BY => 'ScreenplayBy',
753
+ EDITED_BY => 'EditedBy',
754
+ PRODUCER => 'Producer',
755
+ COPRODUCER => 'Coproducer',
756
+ EXECUTIVE_PRODUCER => 'ExecutiveProducer',
757
+ DISTRIBUTED_BY => 'DistributedBy',
758
+ MASTERED_BY => 'MasteredBy',
759
+ ENCODED_BY => 'EncodedBy',
760
+ MIXED_BY => 'MixedBy',
761
+ REMIXED_BY => 'RemixedBy',
762
+ PRODUCTION_STUDIO => 'ProductionStudio',
763
+ THANKS_TO => 'ThanksTo',
764
+ PUBLISHER => 'Publisher',
765
+ LABEL => 'Label',
766
+ GENRE => 'Genre',
767
+ MOOD => 'Mood',
768
+ ORIGINAL_MEDIA_TYPE => 'OriginalMediaType',
769
+ CONTENT_TYPE => 'ContentType',
770
+ SUBJECT => 'Subject',
771
+ DESCRIPTION => 'Description',
772
+ KEYWORDS => 'Keywords',
773
+ SUMMARY => 'Summary',
774
+ SYNOPSIS => 'Synopsis',
775
+ INITIAL_KEY => 'InitialKey',
776
+ PERIOD => 'Period',
777
+ LAW_RATING => 'LawRating',
778
+ DATE_RELEASED => { Name => 'DateReleased', %dateInfo },
779
+ DATE_RECORDED => { Name => 'DateTimeOriginal', %dateInfo, Description => 'Date/Time Original' },
780
+ DATE_ENCODED => { Name => 'DateEncoded', %dateInfo },
781
+ DATE_TAGGED => { Name => 'DateTagged', %dateInfo },
782
+ DATE_DIGITIZED => { Name => 'CreateDate', %dateInfo },
783
+ DATE_WRITTEN => { Name => 'DateWritten', %dateInfo },
784
+ DATE_PURCHASED => { Name => 'DatePurchased', %dateInfo },
785
+ RECORDING_LOCATION => 'RecordingLocation',
786
+ COMPOSITION_LOCATION => 'CompositionLocation',
787
+ COMPOSER_NATIONALITY => 'ComposerNationality',
788
+ COMMENT => 'Comment',
789
+ PLAY_COUNTER => 'PlayCounter',
790
+ RATING => 'Rating',
791
+ ENCODER => 'Encoder',
792
+ ENCODER_SETTINGS => 'EncoderSettings',
793
+ BPS => 'BPS',
794
+ FPS => 'FPS',
795
+ BPM => 'BPM',
796
+ MEASURE => 'Measure',
797
+ TUNING => 'Tuning',
798
+ REPLAYGAIN_GAIN => 'ReplaygainGain',
799
+ REPLAYGAIN_PEAK => 'ReplaygainPeak',
800
+ ISRC => 'ISRC',
801
+ MCDI => 'MCDI',
802
+ ISBN => 'ISBN',
803
+ BARCODE => 'Barcode',
804
+ CATALOG_NUMBER => 'CatalogNumber',
805
+ LABEL_CODE => 'LabelCode',
806
+ LCCN => 'Lccn',
807
+ IMDB => 'IMDB',
808
+ TMDB => 'TMDB',
809
+ TVDB => 'TVDB',
810
+ PURCHASE_ITEM => 'PurchaseItem',
811
+ PURCHASE_INFO => 'PurchaseInfo',
812
+ PURCHASE_OWNER => 'PurchaseOwner',
813
+ PURCHASE_PRICE => 'PurchasePrice',
814
+ PURCHASE_CURRENCY => 'PurchaseCurrency',
815
+ COPYRIGHT => 'Copyright',
816
+ PRODUCTION_COPYRIGHT => 'ProductionCopyright',
817
+ LICENSE => 'License',
818
+ TERMS_OF_USE => 'TermsOfUse',
819
+ );
820
+
821
+ #------------------------------------------------------------------------------
822
+ # Handle MKV SimpleTag structure
823
+ # Inputs: 0) ExifTool ref, 1) structure ref, 2) parent tag ID, 3) parent tag Name,
824
+ # 4) language code, 5) country code
825
+ sub HandleStruct($$;$$$$)
826
+ {
827
+ local $_;
828
+ my ($et, $struct, $pid, $pname, $lang, $ctry) = @_;
829
+ my $tagTbl = GetTagTable('Image::ExifTool::Matroska::Tags');
830
+ my $tag = $$struct{TagName};
831
+ my $tagInfo = $$tagTbl{$tag};
832
+ # create tag if necessary
833
+ unless (ref $tagInfo eq 'HASH') {
834
+ my $name = ucfirst lc $tag;
835
+ $name =~ tr/0-9a-zA-Z_//dc;
836
+ $name =~ s/_([a-z])/\U$1/g;
837
+ $name = "Tag_$name" if length $name < 2;
838
+ $tagInfo = AddTagToTable($tagTbl, $tag, { Name => $name });
839
+ }
840
+ my ($id, $nm);
841
+ if ($pid) {
842
+ $id = "$pid/$tag";
843
+ $nm = "$pname/$$tagInfo{Name}";
844
+ unless ($$tagTbl{$id}) {
845
+ my %copy = %$tagInfo;
846
+ $copy{Name} = $nm;
847
+ $tagInfo = AddTagToTable($tagTbl, $id, \%copy);
848
+ }
849
+ } else {
850
+ ($id, $nm) = ($tag, $$tagInfo{Name});
851
+ }
852
+ if (defined $$struct{TagString} or defined $$struct{TagBinary}) {
853
+ my $val = defined $$struct{TagString} ? $$struct{TagString} : \$$struct{TagBinary};
854
+ $lang = $$struct{TagLanguageBCP47} || $$struct{TagLanguage} || $lang;
855
+ # (Note: not currently handling TagDefault attribute)
856
+ my $code = $lang;
857
+ $code = $lang ? "${lang}-${ctry}" : "eng-${ctry}" if $ctry; # ('eng' is default lang)
858
+ if ($code) {
859
+ $tagInfo = Image::ExifTool::GetLangInfo($tagInfo, $code);
860
+ $et->HandleTag($tagTbl, $$tagInfo{TagID}, $val);
861
+ } else {
862
+ $et->HandleTag($tagTbl, $id, $val);
863
+ }
864
+ # COUNTRY is handled as an attribute for contained tags
865
+ if ($tag eq 'COUNTRY') {
866
+ $ctry = $val;
867
+ ($id, $nm) = ($pid, $pname);
868
+ }
869
+ }
870
+ if ($$struct{struct}) {
871
+ # step into each contained structure
872
+ HandleStruct($et, $_, $id, $nm, $lang, $ctry) foreach @{$$struct{struct}};
873
+ }
874
+ }
875
+
685
876
  #------------------------------------------------------------------------------
686
877
  # Get variable-length Matroska integer
687
878
  # Inputs: 0) data buffer, 1) position in data
@@ -723,7 +914,7 @@ sub ProcessMKV($$)
723
914
  {
724
915
  my ($et, $dirInfo) = @_;
725
916
  my $raf = $$dirInfo{RAF};
726
- my ($buff, $buf2, @dirEnd, $trackIndent, %trackTypes);
917
+ my ($buff, $buf2, @dirEnd, $trackIndent, %trackTypes, $struct);
727
918
 
728
919
  $raf->Read($buff, 4) == 4 or return 0;
729
920
  return 0 unless $buff =~ /^\x1a\x45\xdf\xa3/;
@@ -743,18 +934,38 @@ sub ProcessMKV($$)
743
934
 
744
935
  # set flag to process entire file (otherwise we stop at the first Cluster)
745
936
  my $verbose = $et->Options('Verbose');
746
- my $processAll = ($verbose or $et->Options('Unknown') > 1);
937
+ my $processAll = ($verbose or $et->Options('Unknown') > 1) ? 2 : 0;
938
+ ++$processAll if $et->Options('ExtractEmbedded');
747
939
  $$et{TrackTypes} = \%trackTypes; # store Track types reference
748
940
  my $oldIndent = $$et{INDENT};
749
941
  my $chapterNum = 0;
942
+ my $dirName = 'MKV';
750
943
 
751
944
  # loop over all Matroska elements
752
945
  for (;;) {
753
- while (@dirEnd and $pos + $dataPos >= $dirEnd[-1][0]) {
754
- pop @dirEnd;
755
- # use INDENT to decide whether or not we are done this Track element
756
- delete $$et{SET_GROUP1} if $trackIndent and $trackIndent eq $$et{INDENT};
757
- $$et{INDENT} = substr($$et{INDENT}, 0, -2);
946
+ while (@dirEnd) {
947
+ if ($pos + $dataPos >= $dirEnd[-1][0]) {
948
+ pop @dirEnd;
949
+ if ($struct) {
950
+ if (@dirEnd and $dirEnd[-1][2]) {
951
+ # save this nested structure
952
+ $dirEnd[-1][2]{struct} or $dirEnd[-1][2]{struct} = [ ];
953
+ push @{$dirEnd[-1][2]{struct}}, $struct;
954
+ $struct = $dirEnd[-1][2];
955
+ } else {
956
+ # handle completed structures now
957
+ HandleStruct($et, $struct);
958
+ undef $struct;
959
+ }
960
+ }
961
+ $dirName = @dirEnd ? $dirEnd[-1][1] : 'MKV';
962
+ # use INDENT to decide whether or not we are done this Track element
963
+ delete $$et{SET_GROUP1} if $trackIndent and $trackIndent eq $$et{INDENT};
964
+ $$et{INDENT} = substr($$et{INDENT}, 0, -2);
965
+ } else {
966
+ $dirName = $dirEnd[-1][1];
967
+ last;
968
+ }
758
969
  }
759
970
  # read more if we are getting close to the end of our buffer
760
971
  # (24 more bytes should be enough to read this element header)
@@ -785,17 +996,27 @@ sub ProcessMKV($$)
785
996
  }
786
997
  my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
787
998
  # just fall through into the contained EBML elements
788
- if ($tagInfo and $$tagInfo{SubDirectory}) {
789
- # stop processing at first cluster unless we are in verbose mode
790
- last if $$tagInfo{Name} eq 'Cluster' and not $processAll;
791
- $$et{INDENT} .= '| ';
792
- $et->VerboseDir($$tagTablePtr{$tag}{Name}, undef, $size);
793
- push @dirEnd, [ $pos + $dataPos + $size, $$tagInfo{Name} ];
794
- if ($$tagInfo{Name} eq 'ChapterAtom') {
795
- $$et{SET_GROUP1} = 'Chapter' . (++$chapterNum);
796
- $trackIndent = $$et{INDENT};
999
+ if ($tagInfo) {
1000
+ if ($$tagInfo{SubDirectory}) {
1001
+ # stop processing at first cluster unless we are using -v -U or -ee
1002
+ if ($$tagInfo{Name} eq 'Cluster' and $processAll < 2) {
1003
+ last unless $processAll;
1004
+ undef $tagInfo; # just skip the Cluster when -ee is used
1005
+ } else {
1006
+ $$et{INDENT} .= '| ';
1007
+ $et->VerboseDir($$tagTablePtr{$tag}{Name}, undef, $size);
1008
+ $dirName = $$tagInfo{Name};
1009
+ push @dirEnd, [ $pos + $dataPos + $size, $dirName, $struct ];
1010
+ $struct = { } if $dirName eq 'SimpleTag'; # keep track of SimpleTag elements
1011
+ if ($$tagInfo{Name} eq 'ChapterAtom') {
1012
+ $$et{SET_GROUP1} = 'Chapter' . (++$chapterNum);
1013
+ $trackIndent = $$et{INDENT};
1014
+ }
1015
+ next;
1016
+ }
797
1017
  }
798
- next;
1018
+ } elsif ($verbose) {
1019
+ $et->VPrint(0,sprintf("$$et{INDENT}- Tag 0x%x (Unknown, %d bytes)\n", $tag, $size));
799
1020
  }
800
1021
  last if $unknownSize;
801
1022
  if ($pos + $size > $dataLen) {
@@ -879,8 +1100,9 @@ sub ProcessMKV($$)
879
1100
  Start => $pos,
880
1101
  Size => $size,
881
1102
  );
882
- if ($$tagInfo{NoSave}) {
1103
+ if ($$tagInfo{NoSave} or $struct) {
883
1104
  $et->VerboseInfo($tag, $tagInfo, Value => $val, %parms) if $verbose;
1105
+ $$struct{$$tagInfo{Name}} = $val if $struct;
884
1106
  } else {
885
1107
  $et->HandleTag($tagTablePtr, $tag, $val, %parms);
886
1108
  }
@@ -929,6 +1151,8 @@ under the same terms as Perl itself.
929
1151
 
930
1152
  =item L<http://www.matroska.org/technical/specs/index.html>
931
1153
 
1154
+ =item L<https://www.matroska.org/technical/tagging.html>
1155
+
932
1156
  =back
933
1157
 
934
1158
  =head1 SEE ALSO
@@ -14,7 +14,7 @@ use strict;
14
14
  use vars qw($VERSION);
15
15
  use Image::ExifTool::Exif;
16
16
 
17
- $VERSION = '1.01';
17
+ $VERSION = '1.02';
18
18
 
19
19
  # Motorola makernotes tags (ref PH)
20
20
  %Image::ExifTool::Motorola::Main = (
@@ -54,7 +54,12 @@ $VERSION = '1.01';
54
54
  # 0x6400 - string: 'AUTO','ON','OFF'
55
55
  # 0x6401 - string: 'HDR'
56
56
  # 0x6410 - string: 'NO','YES'
57
- # 0x6420 - int32s: 0 (only exists in HDR images?)
57
+ # 0x6420 - int32s for some models: 0 (only exists in HDR images?)
58
+ 0x6420 => { #forum13731
59
+ Condition => '$format eq "string"',
60
+ Name => 'CustomRendered',
61
+ Writable => 'string',
62
+ },
58
63
  # 0x6430 - float
59
64
  # 0x6431 - int8u: 0,1
60
65
  # 0x6432 - int8u: 0,79,100
@@ -89,6 +94,7 @@ $VERSION = '1.01';
89
94
  # 0x64c2,0x64c3 - int32s
90
95
  # 0x64c4 - int32s
91
96
  # 0x64c5 - int32u
97
+ 0x64d0 => { Name => 'DriveMode', Writable => 'string' }, #forum13731
92
98
  # 0x6500 - int8u: 1
93
99
  # 0x6501 - string: 'Luma-Chroma Plane','Chroma only' or int8u: 0
94
100
  # 0x6502 - string: 'Luma-Chroma Plane','Chroma only','' or int8u: 1,255