exiftool_vendored 12.50.0 → 12.52.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/Changes +39 -2
- data/bin/MANIFEST +2 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/exiftool +5 -4
- data/bin/lib/Image/ExifTool/Casio.pm +3 -3
- data/bin/lib/Image/ExifTool/FLIR.pm +6 -5
- data/bin/lib/Image/ExifTool/GPS.pm +11 -5
- data/bin/lib/Image/ExifTool/Geotag.pm +12 -4
- data/bin/lib/Image/ExifTool/JPEG.pm +1 -0
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +24 -3
- data/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/fr.pm +6015 -759
- data/bin/lib/Image/ExifTool/Lang/sk.pm +1927 -0
- data/bin/lib/Image/ExifTool/Matroska.pm +261 -45
- data/bin/lib/Image/ExifTool/Nikon.pm +470 -272
- data/bin/lib/Image/ExifTool/NikonCustom.pm +139 -106
- data/bin/lib/Image/ExifTool/Olympus.pm +3 -2
- data/bin/lib/Image/ExifTool/PNG.pm +8 -1
- data/bin/lib/Image/ExifTool/QuickTime.pm +4 -1
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +44 -11
- data/bin/lib/Image/ExifTool/README +2 -1
- data/bin/lib/Image/ExifTool/Sony.pm +4 -4
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +11 -6
- data/bin/lib/Image/ExifTool/TagLookup.pm +4543 -4491
- data/bin/lib/Image/ExifTool/TagNames.pod +227 -37
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +12 -7
- data/bin/lib/Image/ExifTool/WriteXMP.pl +15 -1
- data/bin/lib/Image/ExifTool/Writer.pl +33 -13
- data/bin/lib/Image/ExifTool/ZIP.pm +19 -7
- data/bin/lib/Image/ExifTool.pm +36 -15
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -2
@@ -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.
|
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
|
@@ -58,7 +75,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
58
75
|
#
|
59
76
|
# General
|
60
77
|
#
|
61
|
-
0x3f => { Name => 'CRC-32',
|
78
|
+
0x3f => { Name => 'CRC-32', Format => 'unsigned', Unknown => 1 },
|
62
79
|
0x6c => { Name => 'Void', NoSave => 1, Unknown => 1 },
|
63
80
|
#
|
64
81
|
# Signature
|
@@ -104,18 +121,18 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
104
121
|
Name => 'Info',
|
105
122
|
SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
|
106
123
|
},
|
107
|
-
0x33a4 => { Name => 'SegmentUID',
|
124
|
+
0x33a4 => { Name => 'SegmentUID', %uidInfo, Unknown => 1 },
|
108
125
|
0x3384 => { Name => 'SegmentFileName', Format => 'utf8' },
|
109
|
-
0x1cb923 => { Name => 'PrevUID',
|
126
|
+
0x1cb923 => { Name => 'PrevUID', %uidInfo, Unknown => 1 },
|
110
127
|
0x1c83ab => { Name => 'PrevFileName', Format => 'utf8' },
|
111
|
-
0x1eb923 => { Name => 'NextUID',
|
128
|
+
0x1eb923 => { Name => 'NextUID', %uidInfo, Unknown => 1 },
|
112
129
|
0x1e83bb => { Name => 'NextFileName', Format => 'utf8' },
|
113
130
|
0x0444 => { Name => 'SegmentFamily', Binary => 1, Unknown => 1 },
|
114
131
|
0x2924 => {
|
115
132
|
Name => 'ChapterTranslate',
|
116
133
|
SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
|
117
134
|
},
|
118
|
-
0x29fc => { Name => 'ChapterTranslateEditionUID',
|
135
|
+
0x29fc => { Name => 'ChapterTranslateEditionUID', %uidInfo, Unknown => 1 },
|
119
136
|
0x29bf => {
|
120
137
|
Name => 'ChapterTranslateCodec',
|
121
138
|
Format => 'unsigned',
|
@@ -228,7 +245,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
228
245
|
SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
|
229
246
|
},
|
230
247
|
0x57 => { Name => 'TrackNumber', Format => 'unsigned' },
|
231
|
-
0x33c5 => { Name => 'TrackUID',
|
248
|
+
0x33c5 => { Name => 'TrackUID', %uidInfo },
|
232
249
|
0x03 => {
|
233
250
|
Name => 'TrackType',
|
234
251
|
Format => 'unsigned',
|
@@ -305,7 +322,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
305
322
|
Format => 'utf8',
|
306
323
|
}
|
307
324
|
],
|
308
|
-
0x3446 => { Name => 'TrackAttachmentUID'
|
325
|
+
0x3446 => { Name => 'TrackAttachmentUID',%uidInfo },
|
309
326
|
0x1a9697=>{ Name => 'CodecSettings', Format => 'utf8' },
|
310
327
|
0x1b4040=>{ Name => 'CodecInfoURL', Format => 'string' },
|
311
328
|
0x6b240 =>{ Name => 'CodecDownloadURL', Format => 'string' },
|
@@ -315,7 +332,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
315
332
|
Name => 'TrackTranslate',
|
316
333
|
SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
|
317
334
|
},
|
318
|
-
0x26fc => { Name => 'TrackTranslateEditionUID',
|
335
|
+
0x26fc => { Name => 'TrackTranslateEditionUID', %uidInfo, Unknown => 1 },
|
319
336
|
0x26bf => {
|
320
337
|
Name => 'TrackTranslateCodec',
|
321
338
|
Format => 'unsigned',
|
@@ -362,6 +379,8 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
362
379
|
0 => 'Pixels',
|
363
380
|
1 => 'cm',
|
364
381
|
2 => 'inches',
|
382
|
+
3 => 'Display Aspect Ratio',
|
383
|
+
4 => 'Unknown',
|
365
384
|
},
|
366
385
|
},
|
367
386
|
0x14b3 => {
|
@@ -517,7 +536,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
517
536
|
0x66e => { Name => 'AttachedFileName', Format => 'utf8' },
|
518
537
|
0x660 => { Name => 'AttachedFileMIMEType', Format => 'string' },
|
519
538
|
0x65c => { Name => 'AttachedFileData', Binary => 1 },
|
520
|
-
0x6ae => { Name => 'AttachedFileUID',
|
539
|
+
0x6ae => { Name => 'AttachedFileUID', %uidInfo },
|
521
540
|
0x675 => { Name => 'AttachedFileReferral', Binary => 1, Unknown => 1 },
|
522
541
|
#
|
523
542
|
# Chapters
|
@@ -530,7 +549,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
530
549
|
Name => 'EditionEntry',
|
531
550
|
SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
|
532
551
|
},
|
533
|
-
0x5bc => { Name => 'EditionUID',
|
552
|
+
0x5bc => { Name => 'EditionUID', %uidInfo, Unknown => 1 },
|
534
553
|
0x5bd => { Name => 'EditionFlagHidden', Format => 'unsigned', Unknown => 1 },
|
535
554
|
0x5db => { Name => 'EditionFlagDefault',Format => 'unsigned', Unknown => 1 },
|
536
555
|
0x5dd => { Name => 'EditionFlagOrdered',Format => 'unsigned', Unknown => 1 },
|
@@ -538,7 +557,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
538
557
|
Name => 'ChapterAtom',
|
539
558
|
SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
|
540
559
|
},
|
541
|
-
0x33c4 => { Name => 'ChapterUID',
|
560
|
+
0x33c4 => { Name => 'ChapterUID', %uidInfo, Unknown => 1 },
|
542
561
|
0x11 => {
|
543
562
|
Name => 'ChapterTimeStart',
|
544
563
|
Groups => { 1 => 'Chapter#' },
|
@@ -554,8 +573,8 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
554
573
|
},
|
555
574
|
0x18 => { Name => 'ChapterFlagHidden', Format => 'unsigned', Unknown => 1 },
|
556
575
|
0x598 => { Name => 'ChapterFlagEnabled',Format => 'unsigned', Unknown => 1 },
|
557
|
-
0x2e67=> { Name => 'ChapterSegmentUID',
|
558
|
-
0x2ebc=> { Name => 'ChapterSegmentEditionUID',
|
576
|
+
0x2e67=> { Name => 'ChapterSegmentUID', %uidInfo, Unknown => 1 },
|
577
|
+
0x2ebc=> { Name => 'ChapterSegmentEditionUID', %uidInfo, Unknown => 1 },
|
559
578
|
0x23c3 => {
|
560
579
|
Name => 'ChapterPhysicalEquivalent',
|
561
580
|
Format => 'unsigned',
|
@@ -622,21 +641,24 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
622
641
|
Name => 'Targets',
|
623
642
|
SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
|
624
643
|
},
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
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 },
|
631
651
|
0x27c8 => {
|
632
652
|
Name => 'SimpleTag',
|
633
653
|
SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
|
634
654
|
},
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
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 },
|
640
662
|
#
|
641
663
|
# Spherical Video V2 (untested)
|
642
664
|
#
|
@@ -685,6 +707,172 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' );
|
|
685
707
|
0x7675 => { Name => 'ProjectionPoseRoll', Format => 'float' },
|
686
708
|
);
|
687
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
|
+
|
688
876
|
#------------------------------------------------------------------------------
|
689
877
|
# Get variable-length Matroska integer
|
690
878
|
# Inputs: 0) data buffer, 1) position in data
|
@@ -726,7 +914,7 @@ sub ProcessMKV($$)
|
|
726
914
|
{
|
727
915
|
my ($et, $dirInfo) = @_;
|
728
916
|
my $raf = $$dirInfo{RAF};
|
729
|
-
my ($buff, $buf2, @dirEnd, $trackIndent, %trackTypes);
|
917
|
+
my ($buff, $buf2, @dirEnd, $trackIndent, %trackTypes, $struct);
|
730
918
|
|
731
919
|
$raf->Read($buff, 4) == 4 or return 0;
|
732
920
|
return 0 unless $buff =~ /^\x1a\x45\xdf\xa3/;
|
@@ -751,14 +939,33 @@ sub ProcessMKV($$)
|
|
751
939
|
$$et{TrackTypes} = \%trackTypes; # store Track types reference
|
752
940
|
my $oldIndent = $$et{INDENT};
|
753
941
|
my $chapterNum = 0;
|
942
|
+
my $dirName = 'MKV';
|
754
943
|
|
755
944
|
# loop over all Matroska elements
|
756
945
|
for (;;) {
|
757
|
-
while (@dirEnd
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
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
|
+
}
|
762
969
|
}
|
763
970
|
# read more if we are getting close to the end of our buffer
|
764
971
|
# (24 more bytes should be enough to read this element header)
|
@@ -789,21 +996,27 @@ sub ProcessMKV($$)
|
|
789
996
|
}
|
790
997
|
my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
|
791
998
|
# just fall through into the contained EBML elements
|
792
|
-
if ($tagInfo
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
$
|
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;
|
804
1016
|
}
|
805
|
-
next;
|
806
1017
|
}
|
1018
|
+
} elsif ($verbose) {
|
1019
|
+
$et->VPrint(0,sprintf("$$et{INDENT}- Tag 0x%x (Unknown, %d bytes)\n", $tag, $size));
|
807
1020
|
}
|
808
1021
|
last if $unknownSize;
|
809
1022
|
if ($pos + $size > $dataLen) {
|
@@ -887,8 +1100,9 @@ sub ProcessMKV($$)
|
|
887
1100
|
Start => $pos,
|
888
1101
|
Size => $size,
|
889
1102
|
);
|
890
|
-
if ($$tagInfo{NoSave}) {
|
1103
|
+
if ($$tagInfo{NoSave} or $struct) {
|
891
1104
|
$et->VerboseInfo($tag, $tagInfo, Value => $val, %parms) if $verbose;
|
1105
|
+
$$struct{$$tagInfo{Name}} = $val if $struct;
|
892
1106
|
} else {
|
893
1107
|
$et->HandleTag($tagTablePtr, $tag, $val, %parms);
|
894
1108
|
}
|
@@ -937,6 +1151,8 @@ under the same terms as Perl itself.
|
|
937
1151
|
|
938
1152
|
=item L<http://www.matroska.org/technical/specs/index.html>
|
939
1153
|
|
1154
|
+
=item L<https://www.matroska.org/technical/tagging.html>
|
1155
|
+
|
940
1156
|
=back
|
941
1157
|
|
942
1158
|
=head1 SEE ALSO
|