exiftool_vendored 13.06.0 → 13.10.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 +55 -4
- data/bin/MANIFEST +1 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/exiftool +29 -15
- data/bin/lib/Image/ExifTool/AIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/APE.pm +1 -1
- data/bin/lib/Image/ExifTool/ASF.pm +1 -1
- data/bin/lib/Image/ExifTool/Apple.pm +9 -7
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +12 -3
- data/bin/lib/Image/ExifTool/Canon.pm +19 -1
- data/bin/lib/Image/ExifTool/DJI.pm +1 -1
- data/bin/lib/Image/ExifTool/Exif.pm +2 -2
- data/bin/lib/Image/ExifTool/FITS.pm +2 -2
- data/bin/lib/Image/ExifTool/FLIF.pm +2 -2
- data/bin/lib/Image/ExifTool/FlashPix.pm +11 -11
- data/bin/lib/Image/ExifTool/Font.pm +1 -1
- data/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- data/bin/lib/Image/ExifTool/HP.pm +1 -1
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +80 -1
- data/bin/lib/Image/ExifTool/ID3.pm +3 -3
- data/bin/lib/Image/ExifTool/IPTC.pm +2 -2
- data/bin/lib/Image/ExifTool/InDesign.pm +1 -1
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +8 -7
- data/bin/lib/Image/ExifTool/M2TS.pm +39 -9
- data/bin/lib/Image/ExifTool/MXF.pm +2 -2
- data/bin/lib/Image/ExifTool/Matroska.pm +1 -1
- data/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
- data/bin/lib/Image/ExifTool/PDF.pm +15 -15
- data/bin/lib/Image/ExifTool/PLIST.pm +3 -3
- data/bin/lib/Image/ExifTool/PNG.pm +6 -5
- data/bin/lib/Image/ExifTool/Panasonic.pm +1 -1
- data/bin/lib/Image/ExifTool/PhaseOne.pm +3 -3
- data/bin/lib/Image/ExifTool/Photoshop.pm +64 -3
- data/bin/lib/Image/ExifTool/Protobuf.pm +4 -4
- data/bin/lib/Image/ExifTool/QuickTime.pm +72 -24
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +336 -91
- data/bin/lib/Image/ExifTool/README +4 -1
- data/bin/lib/Image/ExifTool/RIFF.pm +3 -3
- data/bin/lib/Image/ExifTool/RTF.pm +1 -1
- data/bin/lib/Image/ExifTool/Ricoh.pm +3 -3
- data/bin/lib/Image/ExifTool/Sony.pm +2 -2
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +4 -3
- data/bin/lib/Image/ExifTool/TagLookup.pm +6982 -6970
- data/bin/lib/Image/ExifTool/TagNames.pod +48 -5
- data/bin/lib/Image/ExifTool/VCard.pm +2 -2
- data/bin/lib/Image/ExifTool/Validate.pm +3 -3
- data/bin/lib/Image/ExifTool/WriteExif.pl +2 -2
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +47 -13
- data/bin/lib/Image/ExifTool/WriteXMP.pl +2 -2
- data/bin/lib/Image/ExifTool/Writer.pl +32 -21
- data/bin/lib/Image/ExifTool/XMP.pm +9 -9
- data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
- data/bin/lib/Image/ExifTool.pm +65 -61
- data/bin/lib/Image/ExifTool.pod +41 -35
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
@@ -28,11 +28,12 @@ use strict;
|
|
28
28
|
use vars qw($VERSION $AUTOLOAD $iptcDigestInfo %printFlags);
|
29
29
|
use Image::ExifTool qw(:DataAccess :Utils);
|
30
30
|
|
31
|
-
$VERSION = '1.
|
31
|
+
$VERSION = '1.72';
|
32
32
|
|
33
33
|
sub ProcessPhotoshop($$$);
|
34
34
|
sub WritePhotoshop($$$);
|
35
35
|
sub ProcessLayers($$$);
|
36
|
+
sub ProcessChannelOptions($$$);
|
36
37
|
|
37
38
|
# PrintFlags bit definitions (ref forum13785)
|
38
39
|
%printFlags = (
|
@@ -322,7 +323,13 @@ my %unicodeString = (
|
|
322
323
|
0x0432 => { Unknown => 1, Name => 'MeasurementScale' }, #7
|
323
324
|
0x0433 => { Unknown => 1, Name => 'TimelineInfo' }, #7
|
324
325
|
0x0434 => { Unknown => 1, Name => 'SheetDisclosure' }, #7
|
325
|
-
0x0435 => {
|
326
|
+
0x0435 => {
|
327
|
+
Name => 'ChannelOptions', #7/forum16762
|
328
|
+
SubDirectory => {
|
329
|
+
TagTable => 'Image::ExifTool::Photoshop::ChannelOptions',
|
330
|
+
Start => 4,
|
331
|
+
},
|
332
|
+
},
|
326
333
|
0x0436 => { Unknown => 1, Name => 'OnionSkins' }, #7
|
327
334
|
0x0438 => { Unknown => 1, Name => 'CountInfo' }, #7
|
328
335
|
0x043a => { Unknown => 1, Name => 'PrintInfo2' }, #7
|
@@ -350,6 +357,41 @@ my %unicodeString = (
|
|
350
357
|
0x2710 => { Unknown => 1, Name => 'PrintFlagsInfo' },
|
351
358
|
);
|
352
359
|
|
360
|
+
# Photoshop channel options (ref forum16762)
|
361
|
+
%Image::ExifTool::Photoshop::ChannelOptions = (
|
362
|
+
PROCESS_PROC => \&ProcessChannelOptions,
|
363
|
+
VARS => { IS_BINARY => 1 },
|
364
|
+
GROUPS => { 2 => 'Image' },
|
365
|
+
NOTES => 'These tags relate only to the appearance of a channel.',
|
366
|
+
0 => {
|
367
|
+
Name => 'ChannelColorSpace',
|
368
|
+
Format => 'int16u',
|
369
|
+
PrintConv => {
|
370
|
+
0 => 'RGB',
|
371
|
+
1 => 'HSB',
|
372
|
+
2 => 'CMYK',
|
373
|
+
7 => 'Lab',
|
374
|
+
8 => 'Grayscale',
|
375
|
+
},
|
376
|
+
},
|
377
|
+
2 => {
|
378
|
+
Name => 'ChannelColorData',
|
379
|
+
Format => 'int16u[4]',
|
380
|
+
},
|
381
|
+
11 => {
|
382
|
+
Name => 'ChannelOpacity',
|
383
|
+
PrintConv => '"$val%"',
|
384
|
+
},
|
385
|
+
12 => {
|
386
|
+
Name => 'ChannelColorIndicates',
|
387
|
+
PrintConv => {
|
388
|
+
0 => 'Selected Areas',
|
389
|
+
1 => 'Masked Areas',
|
390
|
+
2 => 'Spot Color',
|
391
|
+
},
|
392
|
+
},
|
393
|
+
);
|
394
|
+
|
353
395
|
# Photoshop JPEG quality record (ref 2)
|
354
396
|
%Image::ExifTool::Photoshop::JPEG_Quality = (
|
355
397
|
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
@@ -755,6 +797,25 @@ sub ProcessLayersAndMask($$$)
|
|
755
797
|
return $raf->Seek($end, 0) ? 1 : 0;
|
756
798
|
}
|
757
799
|
|
800
|
+
#------------------------------------------------------------------------------
|
801
|
+
# Process Photoshop channel options (ref forum16762)
|
802
|
+
# Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
|
803
|
+
# Returns: 1 on success
|
804
|
+
sub ProcessChannelOptions($$$)
|
805
|
+
{
|
806
|
+
my ($et, $dirInfo, $tagTablePtr) = @_;
|
807
|
+
my $end = $$dirInfo{DirStart} + $$dirInfo{DirLen};
|
808
|
+
$$dirInfo{DirLen} = 13;
|
809
|
+
my $i;
|
810
|
+
for ($i=0; $$dirInfo{DirStart} + 13 <= $end; ++$i) {
|
811
|
+
$$et{SET_GROUP1} = "Channel$i";
|
812
|
+
$et->ProcessBinaryData($dirInfo, $tagTablePtr);
|
813
|
+
$$dirInfo{DirStart} += 13;
|
814
|
+
}
|
815
|
+
delete $$et{SET_GROUP1};
|
816
|
+
return 1;
|
817
|
+
}
|
818
|
+
|
758
819
|
#------------------------------------------------------------------------------
|
759
820
|
# Process Photoshop layers (beginning with layer count)
|
760
821
|
# Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
|
@@ -1050,7 +1111,7 @@ sub ProcessPhotoshop($$$)
|
|
1050
1111
|
if ($$et{VALUE}{IPTCDigest} and $$et{VALUE}{CurrentIPTCDigest} and
|
1051
1112
|
$$et{VALUE}{IPTCDigest} ne $$et{VALUE}{CurrentIPTCDigest})
|
1052
1113
|
{
|
1053
|
-
$et->
|
1114
|
+
$et->Warn('IPTCDigest is not current. XMP may be out of sync');
|
1054
1115
|
}
|
1055
1116
|
delete $$et{LOW_PRIORITY_DIR}{'*'};
|
1056
1117
|
return $success;
|
@@ -127,7 +127,7 @@ sub ProcessProtobuf($$$;$)
|
|
127
127
|
my $pos = $$dirInfo{Pos};
|
128
128
|
last if $pos >= length $$dataPt;
|
129
129
|
my ($buff, $id, $type) = ReadRecord($dirInfo);
|
130
|
-
defined $buff or $et->
|
130
|
+
defined $buff or $et->Warn('Protobuf format error'), last;
|
131
131
|
if ($type == 2 and $buff =~ /\.proto$/) {
|
132
132
|
# save protocol name separately for directory type
|
133
133
|
$$et{ProtocolName}{$dirName} = substr($buff, 0, -6);
|
@@ -145,7 +145,7 @@ sub ProcessProtobuf($$$;$)
|
|
145
145
|
if ($type == 2 and $$tagInfo{Unknown}) {
|
146
146
|
if ($$tagInfo{IsProtobuf}) {
|
147
147
|
$$tagInfo{IsProtobuf} = 0 unless IsProtobuf(\$buff);
|
148
|
-
} elsif (not defined $$tagInfo{IsProtobuf} and $buff =~ /[^\x20-\
|
148
|
+
} elsif (not defined $$tagInfo{IsProtobuf} and $buff =~ /[^\x20-\x7e]/ and
|
149
149
|
IsProtobuf(\$buff))
|
150
150
|
{
|
151
151
|
$$tagInfo{IsProtobuf} = 1;
|
@@ -175,7 +175,7 @@ sub ProcessProtobuf($$$;$)
|
|
175
175
|
my %subdir = ( DataPt => \$buff, Base => $addr, DirName => $dirName );
|
176
176
|
ProcessProtobuf($et, \%subdir, $tagTbl, "$prefix$id-");
|
177
177
|
next;
|
178
|
-
} elsif ($buff !~ /[^\x20-\
|
178
|
+
} elsif ($buff !~ /[^\x20-\x7e]/) {
|
179
179
|
$val = $buff; # assume this is an ASCII string
|
180
180
|
} elsif (length($buff) % 4) {
|
181
181
|
$val = '0x' . unpack('H*', $buff);
|
@@ -201,7 +201,7 @@ sub ProcessProtobuf($$$;$)
|
|
201
201
|
);
|
202
202
|
}
|
203
203
|
# warn if we didn't finish exactly at the end of the buffer
|
204
|
-
$et->
|
204
|
+
$et->Warn('Truncated protobuf data') unless $prefix or $$dirInfo{Pos} == length $$dataPt;
|
205
205
|
return 1;
|
206
206
|
}
|
207
207
|
|
@@ -48,7 +48,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
48
48
|
use Image::ExifTool::Exif;
|
49
49
|
use Image::ExifTool::GPS;
|
50
50
|
|
51
|
-
$VERSION = '3.
|
51
|
+
$VERSION = '3.07';
|
52
52
|
|
53
53
|
sub ProcessMOV($$;$);
|
54
54
|
sub ProcessKeys($$$);
|
@@ -69,8 +69,9 @@ sub Process_gps0($$$);
|
|
69
69
|
sub Process_gsen($$$);
|
70
70
|
sub Process_gdat($$$);
|
71
71
|
sub Process_nbmt($$$);
|
72
|
+
sub ProcessLigoGPS($$$;$);
|
73
|
+
sub ProcessLigoJSON($$$);
|
72
74
|
sub ProcessKenwood($$$);
|
73
|
-
sub ProcessLIGO_JSON($$$);
|
74
75
|
sub ProcessRIFFTrailer($$$);
|
75
76
|
sub ProcessTTAD($$$);
|
76
77
|
sub ProcessNMEA($$$);
|
@@ -255,7 +256,7 @@ my %timeInfo = (
|
|
255
256
|
my $offset = (66 * 365 + 17) * 24 * 3600;
|
256
257
|
return $val - $offset if $val >= $offset or $$self{OPTIONS}{QuickTimeUTC};
|
257
258
|
if ($val and not $$self{IsWriting}) {
|
258
|
-
$self->
|
259
|
+
$self->Warn('Patched incorrect time zero for QuickTime date/time tag',1);
|
259
260
|
}
|
260
261
|
return $val;
|
261
262
|
},
|
@@ -584,6 +585,14 @@ my %userDefined = (
|
|
584
585
|
Condition => '$$valPt =~ /^\0[\0-\x04]..[a-zA-Z ]{4}/s',
|
585
586
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::SkipInfo' },
|
586
587
|
},
|
588
|
+
{
|
589
|
+
Name => 'LigoGPSInfo',
|
590
|
+
Condition => '$$valPt =~ /^LIGOGPSINFO\0/',
|
591
|
+
SubDirectory => {
|
592
|
+
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
593
|
+
ProcessProc => \&ProcessLigoGPS,
|
594
|
+
},
|
595
|
+
},
|
587
596
|
{ Name => 'Skip', Unknown => 1, Binary => 1 },
|
588
597
|
],
|
589
598
|
wide => { Unknown => 1, Binary => 1 },
|
@@ -677,7 +686,7 @@ my %userDefined = (
|
|
677
686
|
Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/',
|
678
687
|
Notes => 'raw 360Fly sensor data without ExtractEmbedded option',
|
679
688
|
RawConv => q{
|
680
|
-
$self->
|
689
|
+
$self->Warn('Use the ExtractEmbedded option to decode timed SensorData',3);
|
681
690
|
return \$val;
|
682
691
|
},
|
683
692
|
},
|
@@ -762,11 +771,11 @@ my %userDefined = (
|
|
762
771
|
ProcessProc => \&ProcessKenwood,
|
763
772
|
},
|
764
773
|
},{
|
765
|
-
Name => '
|
774
|
+
Name => 'LigoJSON',
|
766
775
|
Condition => '$$valPt =~ /^LIGOGPSINFO \{/',
|
767
776
|
SubDirectory => {
|
768
777
|
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
769
|
-
ProcessProc => \&
|
778
|
+
ProcessProc => \&ProcessLigoJSON,
|
770
779
|
},
|
771
780
|
},{
|
772
781
|
Name => 'FLIRData',
|
@@ -1303,7 +1312,7 @@ my %userDefined = (
|
|
1303
1312
|
Condition => '$$valPt=~/^\x9b\x63\x0f\x8d\x63\x74\x40\xec\x82\x04\xbc\x5f\xf5\x09\x17\x28/',
|
1304
1313
|
Notes => 'Garmin GPS sensor data',
|
1305
1314
|
RawConv => q{
|
1306
|
-
$self->
|
1315
|
+
$self->Warn('Use the ExtractEmbedded option to decode timed Garmin GPS',3);
|
1307
1316
|
return \$val;
|
1308
1317
|
},
|
1309
1318
|
},
|
@@ -1407,7 +1416,7 @@ my %userDefined = (
|
|
1407
1416
|
if ($val >= $offset or $$self{OPTIONS}{QuickTimeUTC}) {
|
1408
1417
|
$val -= $offset;
|
1409
1418
|
} elsif ($val and not $$self{IsWriting}) {
|
1410
|
-
$self->
|
1419
|
+
$self->Warn('Patched incorrect time zero for QuickTime date/time tag',1);
|
1411
1420
|
}
|
1412
1421
|
return $$self{CreateDate} = $val;
|
1413
1422
|
},
|
@@ -2213,8 +2222,8 @@ my %userDefined = (
|
|
2213
2222
|
_cx_ => { Name => 'CX', Format => 'rational64s', Unknown => 1 },
|
2214
2223
|
_cy_ => { Name => 'CY', Format => 'rational64s', Unknown => 1 },
|
2215
2224
|
rads => { Name => 'Rads', Format => 'rational64s', Unknown => 1 },
|
2216
|
-
lvlm => { Name => 'LevelMeter', Format => 'rational64s', Unknown => 1 }, # (guess)
|
2217
|
-
Lvlm => { Name => 'LevelMeter', Format => 'rational64s', Unknown => 1 }, # (guess)
|
2225
|
+
lvlm => { Name => 'LevelMeter', Format => 'rational64s', Unknown => 1 }, # (guess, Kodak proprietary)
|
2226
|
+
Lvlm => { Name => 'LevelMeter', Format => 'rational64s', Unknown => 1 }, # (guess, Kodak proprietary)
|
2218
2227
|
pose => { Name => 'pose', SubDirectory => { TagTable => 'Image::ExifTool::Kodak::pose' } },
|
2219
2228
|
# AMBA => Ambarella AVC atom (unknown data written by Kodak Playsport video cam)
|
2220
2229
|
# tmlp - 1 byte: 0 (PixPro SP360/4KVR360)
|
@@ -2557,7 +2566,7 @@ my %userDefined = (
|
|
2557
2566
|
TTID => { Name => 'TomTomID', ValueConv => 'unpack("x4H*",$val)' },
|
2558
2567
|
TTVI => { Name => 'TomTomVI', Format => 'int32u', Unknown => 1 }, # seen: "0 1 61 508 508"
|
2559
2568
|
# TTVD seen: "normal 720p 60fps 60fps 16/9 wide 1x"
|
2560
|
-
TTVD => { Name => 'TomTomVD', ValueConv => 'my @a = ($val =~ /[\x20-\
|
2569
|
+
TTVD => { Name => 'TomTomVD', ValueConv => 'my @a = ($val =~ /[\x20-\x7e]+/g); "@a"', List => 1 },
|
2561
2570
|
);
|
2562
2571
|
|
2563
2572
|
# User-specific media data atoms (ref 11)
|
@@ -2813,7 +2822,7 @@ my %userDefined = (
|
|
2813
2822
|
},
|
2814
2823
|
iinf => [{
|
2815
2824
|
Name => 'ItemInformation',
|
2816
|
-
Condition => '$$valPt =~ /^\0/', # (check for version 0)
|
2825
|
+
Condition => '$$self{LastItemID} = -1; $$valPt =~ /^\0/', # (check for version 0)
|
2817
2826
|
SubDirectory => {
|
2818
2827
|
TagTable => 'Image::ExifTool::QuickTime::ItemInfo',
|
2819
2828
|
Start => 6, # (4-byte version/flags + 2-byte count)
|
@@ -2885,6 +2894,17 @@ my %userDefined = (
|
|
2885
2894
|
%unknownInfo,
|
2886
2895
|
},
|
2887
2896
|
],
|
2897
|
+
grpl => {
|
2898
|
+
Name => 'Unknown_grpl',
|
2899
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::grpl' },
|
2900
|
+
},
|
2901
|
+
);
|
2902
|
+
|
2903
|
+
# unknown grpl container
|
2904
|
+
%Image::ExifTool::QuickTime::grpl = (
|
2905
|
+
PROCESS_PROC => \&ProcessMOV,
|
2906
|
+
GROUPS => { 2 => 'Video' },
|
2907
|
+
# altr - seen "00 00 00 00 00 00 00 41 00 00 00 02 00 00 00 42 00 00 00 2e"
|
2888
2908
|
);
|
2889
2909
|
|
2890
2910
|
# additional metadata container (ref ISO14496-12:2015)
|
@@ -3029,6 +3049,7 @@ my %userDefined = (
|
|
3029
3049
|
);
|
3030
3050
|
|
3031
3051
|
# ref https://aomediacodec.github.io/av1-spec/av1-spec.pdf
|
3052
|
+
# (NOTE: conversions are the same as Image::ExifTool::ICC_Profile::ColorRep tags)
|
3032
3053
|
%Image::ExifTool::QuickTime::ColorRep = (
|
3033
3054
|
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
3034
3055
|
GROUPS => { 2 => 'Video' },
|
@@ -3312,7 +3333,13 @@ my %userDefined = (
|
|
3312
3333
|
the associations between items in the file. This information is used by
|
3313
3334
|
ExifTool, but these entries are not extracted as tags.
|
3314
3335
|
},
|
3315
|
-
dimg => {
|
3336
|
+
dimg => {
|
3337
|
+
Name => 'DerivedImageRef',
|
3338
|
+
# also parse these for the ID of the primary 'tmap' item
|
3339
|
+
# (tone-mapped image in HDRGainMap HEIC by iPhone 15 and 16)
|
3340
|
+
RawConv => \&ParseContentDescribes,
|
3341
|
+
WriteHook => \&ParseContentDescribes,
|
3342
|
+
},
|
3316
3343
|
thmb => { Name => 'ThumbnailRef', RawConv => 'undef' },
|
3317
3344
|
auxl => { Name => 'AuxiliaryImageRef', RawConv => 'undef' },
|
3318
3345
|
cdsc => {
|
@@ -3330,7 +3357,8 @@ my %userDefined = (
|
|
3330
3357
|
# hvc1 - HEVC image
|
3331
3358
|
# lhv1 - L-HEVC image
|
3332
3359
|
# infe - ItemInformationEntry
|
3333
|
-
# infe types: avc1,hvc1,lhv1,Exif,xml1,iovl(overlay image),grid,mime,hvt1(tile image)
|
3360
|
+
# infe types: avc1,hvc1,lhv1,Exif,xml1,iovl(overlay image),grid,mime,tmap,hvt1(tile image)
|
3361
|
+
# ('tmap' has something to do with the new gainmap written by iPhone 15 and 16)
|
3334
3362
|
infe => {
|
3335
3363
|
Name => 'ItemInfoEntry',
|
3336
3364
|
RawConv => \&ParseItemInfoEntry,
|
@@ -6560,7 +6588,7 @@ my %userDefined = (
|
|
6560
6588
|
PROCESS_PROC => \&ProcessKeys,
|
6561
6589
|
WRITE_PROC => \&WriteKeys,
|
6562
6590
|
CHECK_PROC => \&CheckQTValue,
|
6563
|
-
VARS => { LONG_TAGS =>
|
6591
|
+
VARS => { LONG_TAGS => 9 },
|
6564
6592
|
WRITABLE => 1,
|
6565
6593
|
# (not PREFERRED when writing)
|
6566
6594
|
GROUPS => { 1 => 'Keys' },
|
@@ -6758,6 +6786,7 @@ my %userDefined = (
|
|
6758
6786
|
ValueConv => 'unpack("N", $val)',
|
6759
6787
|
Writable => 0, # (don't make this writable because it is found in timed metadata)
|
6760
6788
|
},
|
6789
|
+
'full-frame-rate-playback-intent' => 'FullFrameRatePlaybackIntent', #forum16824
|
6761
6790
|
#
|
6762
6791
|
# seen in Apple ProRes RAW file
|
6763
6792
|
#
|
@@ -8778,6 +8807,7 @@ sub PrintableTagID($;$)
|
|
8778
8807
|
# ContentType - mime type of item
|
8779
8808
|
# ContentEncoding - item encoding
|
8780
8809
|
# URI - URI of a 'uri '-type item
|
8810
|
+
# infe - raw data for 'infe' box (when writing only) [retracted]
|
8781
8811
|
# ipma:
|
8782
8812
|
# Association - list of associated properties in the ipco container
|
8783
8813
|
# Essential - list of "essential" flags for the associated properties
|
@@ -8928,10 +8958,18 @@ sub ParseItemInfoEntry($$)
|
|
8928
8958
|
$$items{$id}{URI} = GetString(\$val, $pos);
|
8929
8959
|
}
|
8930
8960
|
}
|
8961
|
+
#[retracted] # save raw infe box when writing in case we need to sort items later
|
8962
|
+
#[retracted] $$items{$id}{infe} = pack('N', length($val)+8) . 'infe' . $val if $$et{IsWriting};
|
8931
8963
|
$et->VPrint(1, "$$et{INDENT} Item $id: Type=", $$items{$id}{Type} || '',
|
8932
8964
|
' Name=', $$items{$id}{Name} || '',
|
8933
8965
|
' ContentType=', $$items{$id}{ContentType} || '',
|
8966
|
+
($$et{PrimaryItem} and $$et{PrimaryItem} == $id) ? ' (PrimaryItem)' : '',
|
8934
8967
|
"\n") if $verbose > 1;
|
8968
|
+
unless ($id > $$et{LastItemID}) {
|
8969
|
+
$et->Warn('Item info entries are out of order'); #[retracted] unless $$et{IsWriting};
|
8970
|
+
#[retracted] $$et{ItemsNotSorted} = 1; # set flag indicating the items weren't sorted
|
8971
|
+
}
|
8972
|
+
$$et{LastItemID} = $id;
|
8935
8973
|
return undef;
|
8936
8974
|
}
|
8937
8975
|
|
@@ -8952,6 +8990,7 @@ sub ParseItemPropAssoc($$)
|
|
8952
8990
|
my $flg = Get32u(\$val, 0);
|
8953
8991
|
my $num = Get32u(\$val, 4);
|
8954
8992
|
my $pos = 8;
|
8993
|
+
my $lastID = -1;
|
8955
8994
|
for ($i=0; $i<$num; ++$i) {
|
8956
8995
|
if ($ver == 0) {
|
8957
8996
|
return undef if $pos + 3 > $len;
|
@@ -8984,6 +9023,9 @@ sub ParseItemPropAssoc($$)
|
|
8984
9023
|
$$items{$id}{Association} = \@association;
|
8985
9024
|
$$items{$id}{Essential} = \@essential;
|
8986
9025
|
$et->VPrint(1, "$$et{INDENT} Item $id properties: @association\n") if $verbose > 1;
|
9026
|
+
# (according to ISO/IEC 23008-12, these entries must be sorted by item ID)
|
9027
|
+
$et->Warn('Item property association entries are out of order') unless $id > $lastID;
|
9028
|
+
$lastID = $id;
|
8987
9029
|
}
|
8988
9030
|
return undef;
|
8989
9031
|
}
|
@@ -9030,18 +9072,21 @@ sub HandleItemInfo($)
|
|
9030
9072
|
}
|
9031
9073
|
}
|
9032
9074
|
$warn = "Can't currently decode protected $type metadata" if $$item{ProtectionIndex};
|
9033
|
-
|
9034
|
-
$
|
9075
|
+
# Note: In HEIC's, these seem to indicate data in 'idat' instead of 'mdat'
|
9076
|
+
my $constMeth = $$item{ConstructionMethod} || 0;
|
9077
|
+
$warn = "Can't currently extract $type with construction method $constMeth" if $constMeth > 1;
|
9078
|
+
$warn = "No 'idat' for $type object with construction method 1" if $constMeth == 1 and not $$et{MediaDataInfo};
|
9079
|
+
$et->Warn($warn) if $warn and $name;
|
9035
9080
|
$warn = 'Not this file' if $$item{DataReferenceIndex}; # (can only extract from "this file")
|
9036
9081
|
unless (($$item{Extents} and @{$$item{Extents}}) or $warn) {
|
9037
9082
|
$warn = "No Extents for $type item";
|
9038
|
-
$et->
|
9083
|
+
$et->Warn($warn) if $name;
|
9039
9084
|
}
|
9040
9085
|
if ($warn) {
|
9041
9086
|
$et->VPrint(0, "$$et{INDENT} [not extracted] ($warn)\n") if $verbose > 2;
|
9042
9087
|
next;
|
9043
9088
|
}
|
9044
|
-
my $base = $$item{BaseOffset} || 0;
|
9089
|
+
my $base = ($$item{BaseOffset} || 0) + ($constMeth ? $$et{MediaDataInfo}[0] : 0);
|
9045
9090
|
if ($verbose > 2) {
|
9046
9091
|
# do verbose hex dump
|
9047
9092
|
my $len = 0;
|
@@ -9099,7 +9144,7 @@ sub HandleItemInfo($)
|
|
9099
9144
|
$et->VerboseDump(\$buff);
|
9100
9145
|
} else {
|
9101
9146
|
$warn = "Error inflating $name metadata";
|
9102
|
-
$et->
|
9147
|
+
$et->Warn($warn);
|
9103
9148
|
$et->VPrint(0, "$$et{INDENT} [not extracted] ($warn)\n") if $verbose > 2;
|
9104
9149
|
next;
|
9105
9150
|
}
|
@@ -9180,6 +9225,7 @@ sub HandleItemInfo($)
|
|
9180
9225
|
delete $$et{DOC_NUM};
|
9181
9226
|
}
|
9182
9227
|
delete $$et{ItemInfo};
|
9228
|
+
delete $$et{MediaDataInfo};
|
9183
9229
|
}
|
9184
9230
|
|
9185
9231
|
#------------------------------------------------------------------------------
|
@@ -9188,7 +9234,7 @@ sub HandleItemInfo($)
|
|
9188
9234
|
sub EEWarn($)
|
9189
9235
|
{
|
9190
9236
|
my $et = shift;
|
9191
|
-
$et->
|
9237
|
+
$et->Warn('The ExtractEmbedded option may find more tags in the media data',3);
|
9192
9238
|
}
|
9193
9239
|
|
9194
9240
|
#------------------------------------------------------------------------------
|
@@ -9675,7 +9721,7 @@ sub ProcessMOV($$;$)
|
|
9675
9721
|
$warnStr = 'End of processing at large atom (LargeFileSupport not enabled)';
|
9676
9722
|
last;
|
9677
9723
|
} elsif ($et->Options('LargeFileSupport') eq '2') {
|
9678
|
-
$et->
|
9724
|
+
$et->Warn('Processing large atom (LargeFileSupport is 2)');
|
9679
9725
|
}
|
9680
9726
|
}
|
9681
9727
|
$size = $hi * 4294967296 + $lo - 16;
|
@@ -9690,7 +9736,7 @@ sub ProcessMOV($$;$)
|
|
9690
9736
|
if ($$et{ValidatePath}{$path} and not $dupTagOK{$tag} and not $dupDirOK{$dirID}) {
|
9691
9737
|
my $i = Get32u(\$tag,0);
|
9692
9738
|
my $str = $i < 255 ? "index $i" : "tag '" . PrintableTagID($tag,2) . "'";
|
9693
|
-
$et->
|
9739
|
+
$et->Warn("Duplicate $str at " . join('-', @{$$et{PATH}}));
|
9694
9740
|
$$et{ValidatePath} = { } if $path eq 'MOV-moov'; # avoid warnings for all contained dups
|
9695
9741
|
}
|
9696
9742
|
$$et{ValidatePath}{$path} = 1;
|
@@ -9762,8 +9808,10 @@ sub ProcessMOV($$;$)
|
|
9762
9808
|
# save required tag sizes
|
9763
9809
|
if ($$tagTablePtr{"$tag-size"}) {
|
9764
9810
|
$et->HandleTag($tagTablePtr, "$tag-size", $size);
|
9765
|
-
$et->HandleTag($tagTablePtr, "$tag-offset", $raf->Tell()) if $$tagTablePtr{"$tag-offset"};
|
9811
|
+
$et->HandleTag($tagTablePtr, "$tag-offset", $raf->Tell()+$dirBase) if $$tagTablePtr{"$tag-offset"};
|
9766
9812
|
}
|
9813
|
+
# save position/size of 'idat'
|
9814
|
+
$$et{MediaDataInfo} = [ $raf->Tell() + $dirBase, $size ] if $tag eq 'idat';
|
9767
9815
|
# stop processing at mdat/idat if -fast2 is used
|
9768
9816
|
last if $fast > 1 and ($tag eq 'mdat' or ($tag eq 'idat' and $$et{FileType} ne 'HEIC'));
|
9769
9817
|
# load values only if associated with a tag (or verbose) and not too big
|