exiftool-vendored.exe 13.0.0 → 13.17.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.
- package/bin/exiftool.exe +0 -0
- package/bin/exiftool_files/exiftool.pl +169 -65
- package/bin/exiftool_files/lib/File/RandomAccess.pm +1 -1
- package/bin/exiftool_files/lib/File/RandomAccess.pod +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/AAC.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/AES.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/AFCP.pm +6 -6
- package/bin/exiftool_files/lib/Image/ExifTool/AIFF.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/APE.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/APP12.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/ASF.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Apple.pm +11 -9
- package/bin/exiftool_files/lib/Image/ExifTool/Audible.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/BMP.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/BPG.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/BZZ.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/BigTIFF.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +46 -26
- package/bin/exiftool_files/lib/Image/ExifTool/CBOR.pm +5 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +68 -28
- package/bin/exiftool_files/lib/Image/ExifTool/CanonCustom.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/CanonRaw.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/CanonVRD.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/CaptureOne.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Casio.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Charset.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/DICOM.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/DJI.pm +196 -30
- package/bin/exiftool_files/lib/Image/ExifTool/DNG.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/DPX.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/DV.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/DarwinCore.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/DjVu.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/EXE.pm +138 -33
- package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +29 -16
- package/bin/exiftool_files/lib/Image/ExifTool/FITS.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/FLAC.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/FLIF.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/FLIR.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Fixup.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Flash.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/FlashPix.pm +17 -21
- package/bin/exiftool_files/lib/Image/ExifTool/Font.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/FotoStation.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/GE.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/GIF.pm +144 -93
- package/bin/exiftool_files/lib/Image/ExifTool/GIMP.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/GM.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/GPS.pm +34 -30
- package/bin/exiftool_files/lib/Image/ExifTool/GeoTiff.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.dat +0 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.pm +19 -9
- package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +46 -12
- package/bin/exiftool_files/lib/Image/ExifTool/GoPro.pm +120 -8
- package/bin/exiftool_files/lib/Image/ExifTool/H264.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/HP.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/HTML.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/HtmlDump.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/ICC_Profile.pm +81 -2
- package/bin/exiftool_files/lib/Image/ExifTool/ICO.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/ID3.pm +8 -8
- package/bin/exiftool_files/lib/Image/ExifTool/IPTC.pm +10 -7
- package/bin/exiftool_files/lib/Image/ExifTool/ISO.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/ITC.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Import.pm +5 -4
- package/bin/exiftool_files/lib/Image/ExifTool/InDesign.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/InfiRay.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/JPEG.pm +38 -5
- package/bin/exiftool_files/lib/Image/ExifTool/JPEGDigest.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/JSON.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/JVC.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +10 -9
- package/bin/exiftool_files/lib/Image/ExifTool/Kodak.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/LIF.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/LNK.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/cs.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/de.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/en_ca.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/en_gb.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/es.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/fi.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/fr.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/it.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/ja.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/ko.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/nl.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/pl.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/ru.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/sk.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/sv.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/tr.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Leaf.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/LigoGPS.pm +409 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Lytro.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/M2TS.pm +57 -18
- package/bin/exiftool_files/lib/Image/ExifTool/MIE.pm +15 -6
- package/bin/exiftool_files/lib/Image/ExifTool/MIEUnits.pod +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/MIFF.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/MISB.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/MNG.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/MOI.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/MPC.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/MPEG.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/MPF.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/MRC.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/MWG.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/MXF.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/MacOS.pm +3 -2
- package/bin/exiftool_files/lib/Image/ExifTool/MakerNotes.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Matroska.pm +22 -6
- package/bin/exiftool_files/lib/Image/ExifTool/Microsoft.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Minolta.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Motorola.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +457 -103
- package/bin/exiftool_files/lib/Image/ExifTool/NikonCapture.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +6 -6
- package/bin/exiftool_files/lib/Image/ExifTool/NikonSettings.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Nintendo.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/OOXML.pm +8 -8
- package/bin/exiftool_files/lib/Image/ExifTool/Ogg.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/OpenEXR.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Opus.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Other.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/PCX.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/PDF.pm +49 -18
- package/bin/exiftool_files/lib/Image/ExifTool/PGF.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/PICT.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/PLIST.pm +4 -4
- package/bin/exiftool_files/lib/Image/ExifTool/PLUS.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +20 -8
- package/bin/exiftool_files/lib/Image/ExifTool/PPM.pm +12 -3
- package/bin/exiftool_files/lib/Image/ExifTool/PSP.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Palm.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Panasonic.pm +27 -3
- package/bin/exiftool_files/lib/Image/ExifTool/PanasonicRaw.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Parrot.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Pentax.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/PhaseOne.pm +4 -4
- package/bin/exiftool_files/lib/Image/ExifTool/PhotoCD.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Photoshop.pm +65 -4
- package/bin/exiftool_files/lib/Image/ExifTool/PostScript.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/PrintIM.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Protobuf.pm +270 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Qualcomm.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +327 -88
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +199 -195
- package/bin/exiftool_files/lib/Image/ExifTool/README +12 -2
- package/bin/exiftool_files/lib/Image/ExifTool/RIFF.pm +21 -6
- package/bin/exiftool_files/lib/Image/ExifTool/RSRC.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/RTF.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Radiance.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Rawzor.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Real.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Reconyx.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Red.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Ricoh.pm +4 -4
- package/bin/exiftool_files/lib/Image/ExifTool/Samsung.pm +6 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Sanyo.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Scalado.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Shift.pl +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Shortcuts.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Sigma.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/SigmaRaw.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +6 -5
- package/bin/exiftool_files/lib/Image/ExifTool/SonyIDC.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Stim.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/TagInfoXML.pm +6 -5
- package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +7028 -6968
- package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +12079 -11630
- package/bin/exiftool_files/lib/Image/ExifTool/Text.pm +4 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Theora.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Torrent.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Trailer.pm +318 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Unknown.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/VCard.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Validate.pm +6 -6
- package/bin/exiftool_files/lib/Image/ExifTool/Vorbis.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/WPG.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/WTV.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/WriteExif.pl +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/WriteIPTC.pl +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/WritePDF.pl +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/WritePNG.pl +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/WritePostScript.pl +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +170 -79
- package/bin/exiftool_files/lib/Image/ExifTool/WriteRIFF.pl +17 -6
- package/bin/exiftool_files/lib/Image/ExifTool/WriteXMP.pl +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +89 -96
- package/bin/exiftool_files/lib/Image/ExifTool/XISF.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +28 -13
- package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +106 -3
- package/bin/exiftool_files/lib/Image/ExifTool/XMPStruct.pl +2 -3
- package/bin/exiftool_files/lib/Image/ExifTool/ZIP.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/ZISRAW.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/iWork.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool.pm +467 -228
- package/bin/exiftool_files/lib/Image/ExifTool.pod +118 -72
- package/bin/exiftool_files/windows_exiftool.txt +96 -51
- package/package.json +8 -8
|
@@ -43,12 +43,12 @@
|
|
|
43
43
|
package Image::ExifTool::QuickTime;
|
|
44
44
|
|
|
45
45
|
use strict;
|
|
46
|
-
use vars qw($VERSION $AUTOLOAD %stringEncoding);
|
|
46
|
+
use vars qw($VERSION $AUTOLOAD %stringEncoding %avType);
|
|
47
47
|
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.12';
|
|
52
52
|
|
|
53
53
|
sub ProcessMOV($$;$);
|
|
54
54
|
sub ProcessKeys($$$);
|
|
@@ -70,7 +70,6 @@ sub Process_gsen($$$);
|
|
|
70
70
|
sub Process_gdat($$$);
|
|
71
71
|
sub Process_nbmt($$$);
|
|
72
72
|
sub ProcessKenwood($$$);
|
|
73
|
-
sub ProcessLIGO_JSON($$$);
|
|
74
73
|
sub ProcessRIFFTrailer($$$);
|
|
75
74
|
sub ProcessTTAD($$$);
|
|
76
75
|
sub ProcessNMEA($$$);
|
|
@@ -252,15 +251,20 @@ my %timeInfo = (
|
|
|
252
251
|
# Note: This value will be in UTC if generated by a system that is aware of the time zone
|
|
253
252
|
# (also note: this code is duplicated for the CreateDate tag)
|
|
254
253
|
RawConv => q{
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
254
|
+
if ($val) {
|
|
255
|
+
my $offset = (66 * 365 + 17) * 24 * 3600;
|
|
256
|
+
if ($val >= $offset or $$self{OPTIONS}{QuickTimeUTC}) {
|
|
257
|
+
$val -= $offset;
|
|
258
|
+
} elsif (not $$self{IsWriting}) {
|
|
259
|
+
$self->Warn('Patched incorrect time zero for QuickTime date/time tag',1);
|
|
260
|
+
}
|
|
261
|
+
} else {
|
|
262
|
+
undef $val if $self->Options('StrictDate');
|
|
259
263
|
}
|
|
260
264
|
return $val;
|
|
261
265
|
},
|
|
262
266
|
RawConvInv => q{
|
|
263
|
-
if ($$self{FileType} eq 'CR3' and not $self->Options('QuickTimeUTC')) {
|
|
267
|
+
if ($val and $$self{FileType} eq 'CR3' and not $self->Options('QuickTimeUTC')) {
|
|
264
268
|
# convert to UTC
|
|
265
269
|
my $offset = (66 * 365 + 17) * 24 * 3600;
|
|
266
270
|
$val = ConvertUnixTime($val - $offset);
|
|
@@ -273,10 +277,14 @@ my %timeInfo = (
|
|
|
273
277
|
ValueConvInv => q{
|
|
274
278
|
$val = GetUnixTime($val, $self->Options("QuickTimeUTC"));
|
|
275
279
|
return undef unless defined $val;
|
|
280
|
+
return $val unless $val;
|
|
276
281
|
return $val + (66 * 365 + 17) * 24 * 3600;
|
|
277
282
|
},
|
|
278
283
|
PrintConv => '$self->ConvertDateTime($val)',
|
|
279
|
-
PrintConvInv =>
|
|
284
|
+
PrintConvInv => q{
|
|
285
|
+
return $val if $val eq '0000:00:00 00:00:00';
|
|
286
|
+
return $self->InverseDateTime($val);
|
|
287
|
+
}
|
|
280
288
|
# (can't put Groups here because they aren't constant!)
|
|
281
289
|
);
|
|
282
290
|
# properties for ISO 8601 format date/time tags
|
|
@@ -350,6 +358,19 @@ my %vendorID = (
|
|
|
350
358
|
5 => 'UTF16',
|
|
351
359
|
);
|
|
352
360
|
|
|
361
|
+
# media types for which we have separate Keys tables (AudioKeys, VideoKeys)
|
|
362
|
+
%avType = (
|
|
363
|
+
soun => 'Audio',
|
|
364
|
+
vide => 'Video',
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
# path to Keys/ItemList/UserData tags stored in tracks
|
|
368
|
+
my %trackPath = (
|
|
369
|
+
'MOV-Movie-Track-Meta-ItemList' => 'Keys',
|
|
370
|
+
'MOV-Movie-Track-UserData-Meta-ItemList' => 'ItemList',
|
|
371
|
+
'MOV-Movie-Track-UserData' => 'UserData',
|
|
372
|
+
);
|
|
373
|
+
|
|
353
374
|
my %graphicsMode = (
|
|
354
375
|
# (ref http://homepage.mac.com/vanhoek/MovieGuts%20docs/64.html)
|
|
355
376
|
0x00 => 'srcCopy',
|
|
@@ -584,7 +605,26 @@ my %userDefined = (
|
|
|
584
605
|
Condition => '$$valPt =~ /^\0[\0-\x04]..[a-zA-Z ]{4}/s',
|
|
585
606
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::SkipInfo' },
|
|
586
607
|
},
|
|
587
|
-
{
|
|
608
|
+
{
|
|
609
|
+
Name => 'LigoGPSInfo',
|
|
610
|
+
Condition => '$$valPt =~ /^LIGOGPSINFO\0/ and $$self{OPTIONS}{ExtractEmbedded}',
|
|
611
|
+
SubDirectory => {
|
|
612
|
+
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
|
613
|
+
ProcessProc => 'Image::ExifTool::LigoGPS::ProcessLigoGPS',
|
|
614
|
+
},
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
Name => 'Skip',
|
|
618
|
+
RawConv => q{
|
|
619
|
+
if ($val =~ /^LIGOGPSINFO\0/) {
|
|
620
|
+
$self->Warn('Use the ExtractEmbedded option to decode timed GPS',3);
|
|
621
|
+
return undef;
|
|
622
|
+
}
|
|
623
|
+
return $val;
|
|
624
|
+
},
|
|
625
|
+
Unknown => 1,
|
|
626
|
+
Binary => 1,
|
|
627
|
+
},
|
|
588
628
|
],
|
|
589
629
|
wide => { Unknown => 1, Binary => 1 },
|
|
590
630
|
ftyp => { #MP4
|
|
@@ -677,7 +717,7 @@ my %userDefined = (
|
|
|
677
717
|
Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/',
|
|
678
718
|
Notes => 'raw 360Fly sensor data without ExtractEmbedded option',
|
|
679
719
|
RawConv => q{
|
|
680
|
-
$self->
|
|
720
|
+
$self->Warn('Use the ExtractEmbedded option to decode timed SensorData',3);
|
|
681
721
|
return \$val;
|
|
682
722
|
},
|
|
683
723
|
},
|
|
@@ -762,11 +802,11 @@ my %userDefined = (
|
|
|
762
802
|
ProcessProc => \&ProcessKenwood,
|
|
763
803
|
},
|
|
764
804
|
},{
|
|
765
|
-
Name => '
|
|
805
|
+
Name => 'LigoJSON',
|
|
766
806
|
Condition => '$$valPt =~ /^LIGOGPSINFO \{/',
|
|
767
807
|
SubDirectory => {
|
|
768
808
|
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
|
769
|
-
ProcessProc =>
|
|
809
|
+
ProcessProc => 'Image::ExifTool::LigoGPS::ProcessLigoJSON',
|
|
770
810
|
},
|
|
771
811
|
},{
|
|
772
812
|
Name => 'FLIRData',
|
|
@@ -902,6 +942,10 @@ my %userDefined = (
|
|
|
902
942
|
},
|
|
903
943
|
# '35AX'? - seen "AT" (Yada RoadCam Pro 4K dashcam)
|
|
904
944
|
cust => 'CustomInfo', # 70mai A810
|
|
945
|
+
SEAL => {
|
|
946
|
+
Name => 'SEAL',
|
|
947
|
+
SubDirectory => { TagTable => 'Image::ExifTool::XMP::SEAL' },
|
|
948
|
+
},
|
|
905
949
|
);
|
|
906
950
|
|
|
907
951
|
# stuff seen in 'skip' atom (70mai Pro Plus+ MP4 videos)
|
|
@@ -1299,7 +1343,7 @@ my %userDefined = (
|
|
|
1299
1343
|
Condition => '$$valPt=~/^\x9b\x63\x0f\x8d\x63\x74\x40\xec\x82\x04\xbc\x5f\xf5\x09\x17\x28/',
|
|
1300
1344
|
Notes => 'Garmin GPS sensor data',
|
|
1301
1345
|
RawConv => q{
|
|
1302
|
-
$self->
|
|
1346
|
+
$self->Warn('Use the ExtractEmbedded option to decode timed Garmin GPS',3);
|
|
1303
1347
|
return \$val;
|
|
1304
1348
|
},
|
|
1305
1349
|
},
|
|
@@ -1399,11 +1443,15 @@ my %userDefined = (
|
|
|
1399
1443
|
Groups => { 2 => 'Time' },
|
|
1400
1444
|
%timeInfo,
|
|
1401
1445
|
RawConv => q{
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
$val
|
|
1405
|
-
|
|
1406
|
-
|
|
1446
|
+
if ($val) {
|
|
1447
|
+
my $offset = (66 * 365 + 17) * 24 * 3600;
|
|
1448
|
+
if ($val >= $offset or $$self{OPTIONS}{QuickTimeUTC}) {
|
|
1449
|
+
$val -= $offset;
|
|
1450
|
+
} elsif (not $$self{IsWriting}) {
|
|
1451
|
+
$self->Warn('Patched incorrect time zero for QuickTime date/time tag',1);
|
|
1452
|
+
}
|
|
1453
|
+
} else {
|
|
1454
|
+
undef $val if $$self{OPTIONS}{StrictDate};
|
|
1407
1455
|
}
|
|
1408
1456
|
return $$self{CreateDate} = $val;
|
|
1409
1457
|
},
|
|
@@ -1501,7 +1549,7 @@ my %userDefined = (
|
|
|
1501
1549
|
# (this tag is readable/writable as a block through the Extra SphericalVideoXML tags)
|
|
1502
1550
|
Condition => '$$valPt=~/^\xff\xcc\x82\x63\xf8\x55\x4a\x93\x88\x14\x58\x7a\x02\x52\x1f\xdd/',
|
|
1503
1551
|
WriteGroup => 'GSpherical', # write only GSpherical XMP tags here
|
|
1504
|
-
|
|
1552
|
+
MediaType => 'vide', # only write in video tracks
|
|
1505
1553
|
SubDirectory => {
|
|
1506
1554
|
TagTable => 'Image::ExifTool::XMP::Main',
|
|
1507
1555
|
Start => 16,
|
|
@@ -2209,8 +2257,8 @@ my %userDefined = (
|
|
|
2209
2257
|
_cx_ => { Name => 'CX', Format => 'rational64s', Unknown => 1 },
|
|
2210
2258
|
_cy_ => { Name => 'CY', Format => 'rational64s', Unknown => 1 },
|
|
2211
2259
|
rads => { Name => 'Rads', Format => 'rational64s', Unknown => 1 },
|
|
2212
|
-
lvlm => { Name => 'LevelMeter', Format => 'rational64s', Unknown => 1 }, # (guess)
|
|
2213
|
-
Lvlm => { Name => 'LevelMeter', Format => 'rational64s', Unknown => 1 }, # (guess)
|
|
2260
|
+
lvlm => { Name => 'LevelMeter', Format => 'rational64s', Unknown => 1 }, # (guess, Kodak proprietary)
|
|
2261
|
+
Lvlm => { Name => 'LevelMeter', Format => 'rational64s', Unknown => 1 }, # (guess, Kodak proprietary)
|
|
2214
2262
|
pose => { Name => 'pose', SubDirectory => { TagTable => 'Image::ExifTool::Kodak::pose' } },
|
|
2215
2263
|
# AMBA => Ambarella AVC atom (unknown data written by Kodak Playsport video cam)
|
|
2216
2264
|
# tmlp - 1 byte: 0 (PixPro SP360/4KVR360)
|
|
@@ -2553,7 +2601,7 @@ my %userDefined = (
|
|
|
2553
2601
|
TTID => { Name => 'TomTomID', ValueConv => 'unpack("x4H*",$val)' },
|
|
2554
2602
|
TTVI => { Name => 'TomTomVI', Format => 'int32u', Unknown => 1 }, # seen: "0 1 61 508 508"
|
|
2555
2603
|
# TTVD seen: "normal 720p 60fps 60fps 16/9 wide 1x"
|
|
2556
|
-
TTVD => { Name => 'TomTomVD', ValueConv => 'my @a = ($val =~ /[\x20-\
|
|
2604
|
+
TTVD => { Name => 'TomTomVD', ValueConv => 'my @a = ($val =~ /[\x20-\x7e]+/g); "@a"', List => 1 },
|
|
2557
2605
|
);
|
|
2558
2606
|
|
|
2559
2607
|
# User-specific media data atoms (ref 11)
|
|
@@ -2809,7 +2857,7 @@ my %userDefined = (
|
|
|
2809
2857
|
},
|
|
2810
2858
|
iinf => [{
|
|
2811
2859
|
Name => 'ItemInformation',
|
|
2812
|
-
Condition => '$$valPt =~ /^\0/', # (check for version 0)
|
|
2860
|
+
Condition => '$$self{LastItemID} = -1; $$valPt =~ /^\0/', # (check for version 0)
|
|
2813
2861
|
SubDirectory => {
|
|
2814
2862
|
TagTable => 'Image::ExifTool::QuickTime::ItemInfo',
|
|
2815
2863
|
Start => 6, # (4-byte version/flags + 2-byte count)
|
|
@@ -2829,10 +2877,18 @@ my %userDefined = (
|
|
|
2829
2877
|
IgnoreProp => { NonRealTimeMeta => 1 }, # ignore container for Sony 'nrtm'
|
|
2830
2878
|
},
|
|
2831
2879
|
},
|
|
2832
|
-
'keys' => {
|
|
2880
|
+
'keys' => [{
|
|
2881
|
+
Name => 'AudioKeys',
|
|
2882
|
+
Condition => '$$self{MediaType} eq "soun"',
|
|
2883
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::AudioKeys' },
|
|
2884
|
+
},{
|
|
2885
|
+
Name => 'VideoKeys',
|
|
2886
|
+
Condition => '$$self{MediaType} eq "vide"',
|
|
2887
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::VideoKeys' },
|
|
2888
|
+
},{
|
|
2833
2889
|
Name => 'Keys',
|
|
2834
2890
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Keys' },
|
|
2835
|
-
},
|
|
2891
|
+
}],
|
|
2836
2892
|
bxml => {
|
|
2837
2893
|
Name => 'BinaryXML',
|
|
2838
2894
|
Flags => ['Binary','Unknown'],
|
|
@@ -2881,6 +2937,17 @@ my %userDefined = (
|
|
|
2881
2937
|
%unknownInfo,
|
|
2882
2938
|
},
|
|
2883
2939
|
],
|
|
2940
|
+
grpl => {
|
|
2941
|
+
Name => 'Unknown_grpl',
|
|
2942
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::grpl' },
|
|
2943
|
+
},
|
|
2944
|
+
);
|
|
2945
|
+
|
|
2946
|
+
# unknown grpl container
|
|
2947
|
+
%Image::ExifTool::QuickTime::grpl = (
|
|
2948
|
+
PROCESS_PROC => \&ProcessMOV,
|
|
2949
|
+
GROUPS => { 2 => 'Video' },
|
|
2950
|
+
# altr - seen "00 00 00 00 00 00 00 41 00 00 00 02 00 00 00 42 00 00 00 2e"
|
|
2884
2951
|
);
|
|
2885
2952
|
|
|
2886
2953
|
# additional metadata container (ref ISO14496-12:2015)
|
|
@@ -3025,6 +3092,7 @@ my %userDefined = (
|
|
|
3025
3092
|
);
|
|
3026
3093
|
|
|
3027
3094
|
# ref https://aomediacodec.github.io/av1-spec/av1-spec.pdf
|
|
3095
|
+
# (NOTE: conversions are the same as Image::ExifTool::ICC_Profile::ColorRep tags)
|
|
3028
3096
|
%Image::ExifTool::QuickTime::ColorRep = (
|
|
3029
3097
|
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
3030
3098
|
GROUPS => { 2 => 'Video' },
|
|
@@ -3097,6 +3165,7 @@ my %userDefined = (
|
|
|
3097
3165
|
10 => {
|
|
3098
3166
|
Name => 'VideoFullRangeFlag',
|
|
3099
3167
|
Mask => 0x80,
|
|
3168
|
+
PrintConv => { 0 => 'Limited', 1 => 'Full' },
|
|
3100
3169
|
},
|
|
3101
3170
|
);
|
|
3102
3171
|
|
|
@@ -3307,7 +3376,13 @@ my %userDefined = (
|
|
|
3307
3376
|
the associations between items in the file. This information is used by
|
|
3308
3377
|
ExifTool, but these entries are not extracted as tags.
|
|
3309
3378
|
},
|
|
3310
|
-
dimg => {
|
|
3379
|
+
dimg => {
|
|
3380
|
+
Name => 'DerivedImageRef',
|
|
3381
|
+
# also parse these for the ID of the primary 'tmap' item
|
|
3382
|
+
# (tone-mapped image in HDRGainMap HEIC by iPhone 15 and 16)
|
|
3383
|
+
RawConv => \&ParseContentDescribes,
|
|
3384
|
+
WriteHook => \&ParseContentDescribes,
|
|
3385
|
+
},
|
|
3311
3386
|
thmb => { Name => 'ThumbnailRef', RawConv => 'undef' },
|
|
3312
3387
|
auxl => { Name => 'AuxiliaryImageRef', RawConv => 'undef' },
|
|
3313
3388
|
cdsc => {
|
|
@@ -3325,7 +3400,8 @@ my %userDefined = (
|
|
|
3325
3400
|
# hvc1 - HEVC image
|
|
3326
3401
|
# lhv1 - L-HEVC image
|
|
3327
3402
|
# infe - ItemInformationEntry
|
|
3328
|
-
# infe types: avc1,hvc1,lhv1,Exif,xml1,iovl(overlay image),grid,mime,hvt1(tile image)
|
|
3403
|
+
# infe types: avc1,hvc1,lhv1,Exif,xml1,iovl(overlay image),grid,mime,tmap,hvt1(tile image)
|
|
3404
|
+
# ('tmap' has something to do with the new gainmap written by iPhone 15 and 16)
|
|
3329
3405
|
infe => {
|
|
3330
3406
|
Name => 'ItemInfoEntry',
|
|
3331
3407
|
RawConv => \&ParseItemInfoEntry,
|
|
@@ -3446,7 +3522,11 @@ my %userDefined = (
|
|
|
3446
3522
|
#
|
|
3447
3523
|
'----' => {
|
|
3448
3524
|
Name => 'iTunesInfo',
|
|
3449
|
-
|
|
3525
|
+
Deletable => 1, # (deletable via 'iTunes' group)
|
|
3526
|
+
SubDirectory => {
|
|
3527
|
+
TagTable => 'Image::ExifTool::QuickTime::iTunesInfo',
|
|
3528
|
+
DirName => 'iTunes', # (necessary for group 'iTunes' delete)
|
|
3529
|
+
},
|
|
3450
3530
|
},
|
|
3451
3531
|
aART => { Name => 'AlbumArtist', Groups => { 2 => 'Author' } },
|
|
3452
3532
|
covr => { Name => 'CoverArt', Groups => { 2 => 'Preview' }, Binary => 1 },
|
|
@@ -3553,7 +3633,7 @@ my %userDefined = (
|
|
|
3553
3633
|
my $id = Image::ExifTool::ID3::GetGenreID($val);
|
|
3554
3634
|
return unless defined $id and $id =~ /^\d+$/;
|
|
3555
3635
|
return $id + 1;
|
|
3556
|
-
},
|
|
3636
|
+
},
|
|
3557
3637
|
},
|
|
3558
3638
|
egid => 'EpisodeGlobalUniqueID', #7
|
|
3559
3639
|
geID => { #10
|
|
@@ -6601,21 +6681,11 @@ my %userDefined = (
|
|
|
6601
6681
|
publisher => { },
|
|
6602
6682
|
software => { },
|
|
6603
6683
|
year => { Groups => { 2 => 'Time' } },
|
|
6604
|
-
'camera.identifier' => 'CameraIdentifier', # (iPhone 4)
|
|
6605
|
-
'camera.framereadouttimeinmicroseconds' => { # (iPhone 4)
|
|
6606
|
-
Name => 'FrameReadoutTime',
|
|
6607
|
-
ValueConv => '$val * 1e-6',
|
|
6608
|
-
ValueConvInv => 'int($val * 1e6 + 0.5)',
|
|
6609
|
-
PrintConv => '$val * 1e6 . " microseconds"',
|
|
6610
|
-
PrintConvInv => '$val =~ s/ .*//; $val * 1e-6',
|
|
6611
|
-
},
|
|
6612
|
-
# 'camera.focal_length.35mm_equivalent' - not top level (written to Keys in video track)
|
|
6613
|
-
# 'camera.lens_model' - not top level (written to Keys in video track)
|
|
6614
6684
|
'location.ISO6709' => {
|
|
6615
6685
|
Name => 'GPSCoordinates',
|
|
6616
6686
|
Groups => { 2 => 'Location' },
|
|
6617
6687
|
Notes => q{
|
|
6618
|
-
Google Photos may ignore this if the
|
|
6688
|
+
Google Photos may ignore this if the coordinates have more than 5 digits
|
|
6619
6689
|
after the decimal
|
|
6620
6690
|
},
|
|
6621
6691
|
ValueConv => \&ConvertISO6709,
|
|
@@ -6671,7 +6741,6 @@ my %userDefined = (
|
|
|
6671
6741
|
#
|
|
6672
6742
|
# the following tags aren't in the com.apple.quicktime namespace:
|
|
6673
6743
|
#
|
|
6674
|
-
'com.apple.photos.captureMode' => 'CaptureMode',
|
|
6675
6744
|
'com.android.version' => 'AndroidVersion',
|
|
6676
6745
|
'com.android.capture.fps' => { Name => 'AndroidCaptureFPS', Writable => 'float' },
|
|
6677
6746
|
'com.android.manufacturer' => 'AndroidMake',
|
|
@@ -6753,6 +6822,7 @@ my %userDefined = (
|
|
|
6753
6822
|
ValueConv => 'unpack("N", $val)',
|
|
6754
6823
|
Writable => 0, # (don't make this writable because it is found in timed metadata)
|
|
6755
6824
|
},
|
|
6825
|
+
'full-frame-rate-playback-intent' => 'FullFrameRatePlaybackIntent', #forum16824
|
|
6756
6826
|
#
|
|
6757
6827
|
# seen in Apple ProRes RAW file
|
|
6758
6828
|
#
|
|
@@ -6770,6 +6840,58 @@ my %userDefined = (
|
|
|
6770
6840
|
# (mdta)com.apple.proapps.image.{TIFF}.Software (eg. "9.0")
|
|
6771
6841
|
);
|
|
6772
6842
|
|
|
6843
|
+
# Keys tags in the audio track (ref PH)
|
|
6844
|
+
%Image::ExifTool::QuickTime::AudioKeys = (
|
|
6845
|
+
PROCESS_PROC => \&ProcessKeys,
|
|
6846
|
+
WRITE_PROC => \&WriteKeys,
|
|
6847
|
+
CHECK_PROC => \&CheckQTValue,
|
|
6848
|
+
WRITABLE => 1,
|
|
6849
|
+
GROUPS => { 1 => 'AudioKeys', 2 => 'Audio' },
|
|
6850
|
+
WRITE_GROUP => 'AudioKeys',
|
|
6851
|
+
LANG_INFO => \&GetLangInfo,
|
|
6852
|
+
NOTES => q{
|
|
6853
|
+
Keys tags written in the audio track by some Apple devices. These tags
|
|
6854
|
+
belong to the ExifTool AudioKeys family 1 gorup.
|
|
6855
|
+
},
|
|
6856
|
+
'player.movie.audio.gain' => 'AudioGain',
|
|
6857
|
+
'player.movie.audio.treble' => 'Treble',
|
|
6858
|
+
'player.movie.audio.bass' => 'Bass',
|
|
6859
|
+
'player.movie.audio.balance' => 'Balance',
|
|
6860
|
+
'player.movie.audio.pitchshift' => 'PitchShift',
|
|
6861
|
+
'player.movie.audio.mute' => {
|
|
6862
|
+
Name => 'Mute',
|
|
6863
|
+
Format => 'int8u',
|
|
6864
|
+
PrintConv => { 0 => 'Off', 1 => 'On' },
|
|
6865
|
+
},
|
|
6866
|
+
);
|
|
6867
|
+
|
|
6868
|
+
# Keys tags in the video track (ref PH)
|
|
6869
|
+
%Image::ExifTool::QuickTime::VideoKeys = (
|
|
6870
|
+
PROCESS_PROC => \&ProcessKeys,
|
|
6871
|
+
WRITE_PROC => \&WriteKeys,
|
|
6872
|
+
CHECK_PROC => \&CheckQTValue,
|
|
6873
|
+
VARS => { LONG_TAGS => 2 },
|
|
6874
|
+
WRITABLE => 1,
|
|
6875
|
+
GROUPS => { 1 => 'VideoKeys', 2 => 'Camera' },
|
|
6876
|
+
WRITE_GROUP => 'VideoKeys',
|
|
6877
|
+
LANG_INFO => \&GetLangInfo,
|
|
6878
|
+
NOTES => q{
|
|
6879
|
+
Keys tags written in the video track. These tags belong to the ExifTool
|
|
6880
|
+
VideoKeys family 1 gorup.
|
|
6881
|
+
},
|
|
6882
|
+
'camera.identifier' => 'CameraIdentifier',
|
|
6883
|
+
'camera.lens_model' => 'LensModel',
|
|
6884
|
+
'camera.focal_length.35mm_equivalent' => 'FocalLengthIn35mmFormat',
|
|
6885
|
+
'camera.framereadouttimeinmicroseconds' => {
|
|
6886
|
+
Name => 'FrameReadoutTime',
|
|
6887
|
+
ValueConv => '$val * 1e-6',
|
|
6888
|
+
ValueConvInv => 'int($val * 1e6 + 0.5)',
|
|
6889
|
+
PrintConv => '$val * 1e6 . " microseconds"',
|
|
6890
|
+
PrintConvInv => '$val =~ s/ .*//; $val * 1e-6',
|
|
6891
|
+
},
|
|
6892
|
+
'com.apple.photos.captureMode' => 'CaptureMode',
|
|
6893
|
+
);
|
|
6894
|
+
|
|
6773
6895
|
# iTunes info ('----') atoms
|
|
6774
6896
|
%Image::ExifTool::QuickTime::iTunesInfo = (
|
|
6775
6897
|
PROCESS_PROC => \&ProcessMOV,
|
|
@@ -7235,7 +7357,7 @@ my %userDefined = (
|
|
|
7235
7357
|
{
|
|
7236
7358
|
Name => 'VideoFrameRate',
|
|
7237
7359
|
Notes => 'average rate calculated from time-to-sample table for video media',
|
|
7238
|
-
Condition => '$$self{
|
|
7360
|
+
Condition => '$$self{MediaType} eq "vide"',
|
|
7239
7361
|
Format => 'undef', # (necessary to prevent decoding as string!)
|
|
7240
7362
|
# (must be RawConv so appropriate MediaTS is used in calculation)
|
|
7241
7363
|
RawConv => 'Image::ExifTool::QuickTime::CalcSampleRate($self, \$val)',
|
|
@@ -7826,7 +7948,6 @@ my %userDefined = (
|
|
|
7826
7948
|
mode => 'ModeFlags', #PH (?) 0x04 is HD flag (https://compilr.com/heksesang/requiem-mac/UnDrm.java)
|
|
7827
7949
|
# sing - seen 4 zeros
|
|
7828
7950
|
# hi32 - seen "00 00 00 04"
|
|
7829
|
-
|
|
7830
7951
|
);
|
|
7831
7952
|
|
|
7832
7953
|
# MP4 hint sample description box (ref 5)
|
|
@@ -8074,6 +8195,7 @@ my %userDefined = (
|
|
|
8074
8195
|
Format => 'undef[4]',
|
|
8075
8196
|
RawConv => q{
|
|
8076
8197
|
$$self{HandlerType} = $val unless $val eq 'alis' or $val eq 'url ';
|
|
8198
|
+
$$self{MediaType} = $val if @{$$self{PATH}} > 1 and $$self{PATH}[-2] eq 'Media';
|
|
8077
8199
|
$$self{HasHandler}{$val} = 1; # remember all our handlers
|
|
8078
8200
|
return $val;
|
|
8079
8201
|
},
|
|
@@ -8658,24 +8780,28 @@ sub UnpackLang($;$)
|
|
|
8658
8780
|
# Get language code string given QuickTime language and country codes
|
|
8659
8781
|
# Inputs: 0) numerical language code, 1) numerical country code, 2) no defaults
|
|
8660
8782
|
# Returns: language code string (ie. "fra-FR") or undef for default language
|
|
8783
|
+
# ex) 0x15c7 0x0000 is 'eng' with no country (ie. returns 'und' unless $noDef)
|
|
8784
|
+
# 0x15c7 0x5553 is 'eng-US'
|
|
8785
|
+
# 0x1a41 0x4652 is 'fra-FR'
|
|
8786
|
+
# 0x55c4 is 'und'
|
|
8661
8787
|
sub GetLangCode($;$$)
|
|
8662
8788
|
{
|
|
8663
8789
|
my ($lang, $ctry, $noDef) = @_;
|
|
8664
8790
|
# ignore country ('ctry') and language lists ('lang') for now
|
|
8665
8791
|
undef $ctry if $ctry and $ctry <= 255;
|
|
8666
8792
|
undef $lang if $lang and $lang <= 255;
|
|
8667
|
-
$
|
|
8793
|
+
my $langCode = UnpackLang($lang, $noDef);
|
|
8668
8794
|
# add country code if specified
|
|
8669
8795
|
if ($ctry) {
|
|
8670
8796
|
$ctry = unpack('a2',pack('n',$ctry)); # unpack as ISO 3166-1
|
|
8671
8797
|
# treat 'ZZ' like a default country (see ref 12)
|
|
8672
8798
|
undef $ctry if $ctry eq 'ZZ';
|
|
8673
8799
|
if ($ctry and $ctry =~ /^[A-Z]{2}$/) {
|
|
8674
|
-
$
|
|
8675
|
-
$
|
|
8800
|
+
$langCode or $langCode = UnpackLang($lang,1) || 'und';
|
|
8801
|
+
$langCode .= "-$ctry";
|
|
8676
8802
|
}
|
|
8677
8803
|
}
|
|
8678
|
-
return $
|
|
8804
|
+
return $langCode;
|
|
8679
8805
|
}
|
|
8680
8806
|
|
|
8681
8807
|
#------------------------------------------------------------------------------
|
|
@@ -8773,6 +8899,7 @@ sub PrintableTagID($;$)
|
|
|
8773
8899
|
# ContentType - mime type of item
|
|
8774
8900
|
# ContentEncoding - item encoding
|
|
8775
8901
|
# URI - URI of a 'uri '-type item
|
|
8902
|
+
# infe - raw data for 'infe' box (when writing only) [retracted]
|
|
8776
8903
|
# ipma:
|
|
8777
8904
|
# Association - list of associated properties in the ipco container
|
|
8778
8905
|
# Essential - list of "essential" flags for the associated properties
|
|
@@ -8923,10 +9050,18 @@ sub ParseItemInfoEntry($$)
|
|
|
8923
9050
|
$$items{$id}{URI} = GetString(\$val, $pos);
|
|
8924
9051
|
}
|
|
8925
9052
|
}
|
|
9053
|
+
#[retracted] # save raw infe box when writing in case we need to sort items later
|
|
9054
|
+
#[retracted] $$items{$id}{infe} = pack('N', length($val)+8) . 'infe' . $val if $$et{IsWriting};
|
|
8926
9055
|
$et->VPrint(1, "$$et{INDENT} Item $id: Type=", $$items{$id}{Type} || '',
|
|
8927
9056
|
' Name=', $$items{$id}{Name} || '',
|
|
8928
9057
|
' ContentType=', $$items{$id}{ContentType} || '',
|
|
9058
|
+
($$et{PrimaryItem} and $$et{PrimaryItem} == $id) ? ' (PrimaryItem)' : '',
|
|
8929
9059
|
"\n") if $verbose > 1;
|
|
9060
|
+
unless ($id > $$et{LastItemID}) {
|
|
9061
|
+
$et->Warn('Item info entries are out of order'); #[retracted] unless $$et{IsWriting};
|
|
9062
|
+
#[retracted] $$et{ItemsNotSorted} = 1; # set flag indicating the items weren't sorted
|
|
9063
|
+
}
|
|
9064
|
+
$$et{LastItemID} = $id;
|
|
8930
9065
|
return undef;
|
|
8931
9066
|
}
|
|
8932
9067
|
|
|
@@ -8947,6 +9082,7 @@ sub ParseItemPropAssoc($$)
|
|
|
8947
9082
|
my $flg = Get32u(\$val, 0);
|
|
8948
9083
|
my $num = Get32u(\$val, 4);
|
|
8949
9084
|
my $pos = 8;
|
|
9085
|
+
my $lastID = -1;
|
|
8950
9086
|
for ($i=0; $i<$num; ++$i) {
|
|
8951
9087
|
if ($ver == 0) {
|
|
8952
9088
|
return undef if $pos + 3 > $len;
|
|
@@ -8979,6 +9115,9 @@ sub ParseItemPropAssoc($$)
|
|
|
8979
9115
|
$$items{$id}{Association} = \@association;
|
|
8980
9116
|
$$items{$id}{Essential} = \@essential;
|
|
8981
9117
|
$et->VPrint(1, "$$et{INDENT} Item $id properties: @association\n") if $verbose > 1;
|
|
9118
|
+
# (according to ISO/IEC 23008-12, these entries must be sorted by item ID)
|
|
9119
|
+
$et->Warn('Item property association entries are out of order') unless $id > $lastID;
|
|
9120
|
+
$lastID = $id;
|
|
8982
9121
|
}
|
|
8983
9122
|
return undef;
|
|
8984
9123
|
}
|
|
@@ -9025,18 +9164,21 @@ sub HandleItemInfo($)
|
|
|
9025
9164
|
}
|
|
9026
9165
|
}
|
|
9027
9166
|
$warn = "Can't currently decode protected $type metadata" if $$item{ProtectionIndex};
|
|
9028
|
-
|
|
9029
|
-
$
|
|
9167
|
+
# Note: In HEIC's, these seem to indicate data in 'idat' instead of 'mdat'
|
|
9168
|
+
my $constMeth = $$item{ConstructionMethod} || 0;
|
|
9169
|
+
$warn = "Can't currently extract $type with construction method $constMeth" if $constMeth > 1;
|
|
9170
|
+
$warn = "No 'idat' for $type object with construction method 1" if $constMeth == 1 and not $$et{MediaDataInfo};
|
|
9171
|
+
$et->Warn($warn) if $warn and $name;
|
|
9030
9172
|
$warn = 'Not this file' if $$item{DataReferenceIndex}; # (can only extract from "this file")
|
|
9031
9173
|
unless (($$item{Extents} and @{$$item{Extents}}) or $warn) {
|
|
9032
9174
|
$warn = "No Extents for $type item";
|
|
9033
|
-
$et->
|
|
9175
|
+
$et->Warn($warn) if $name;
|
|
9034
9176
|
}
|
|
9035
9177
|
if ($warn) {
|
|
9036
9178
|
$et->VPrint(0, "$$et{INDENT} [not extracted] ($warn)\n") if $verbose > 2;
|
|
9037
9179
|
next;
|
|
9038
9180
|
}
|
|
9039
|
-
my $base = $$item{BaseOffset} || 0;
|
|
9181
|
+
my $base = ($$item{BaseOffset} || 0) + ($constMeth ? $$et{MediaDataInfo}[0] : 0);
|
|
9040
9182
|
if ($verbose > 2) {
|
|
9041
9183
|
# do verbose hex dump
|
|
9042
9184
|
my $len = 0;
|
|
@@ -9094,7 +9236,7 @@ sub HandleItemInfo($)
|
|
|
9094
9236
|
$et->VerboseDump(\$buff);
|
|
9095
9237
|
} else {
|
|
9096
9238
|
$warn = "Error inflating $name metadata";
|
|
9097
|
-
$et->
|
|
9239
|
+
$et->Warn($warn);
|
|
9098
9240
|
$et->VPrint(0, "$$et{INDENT} [not extracted] ($warn)\n") if $verbose > 2;
|
|
9099
9241
|
next;
|
|
9100
9242
|
}
|
|
@@ -9175,6 +9317,7 @@ sub HandleItemInfo($)
|
|
|
9175
9317
|
delete $$et{DOC_NUM};
|
|
9176
9318
|
}
|
|
9177
9319
|
delete $$et{ItemInfo};
|
|
9320
|
+
delete $$et{MediaDataInfo};
|
|
9178
9321
|
}
|
|
9179
9322
|
|
|
9180
9323
|
#------------------------------------------------------------------------------
|
|
@@ -9183,7 +9326,7 @@ sub HandleItemInfo($)
|
|
|
9183
9326
|
sub EEWarn($)
|
|
9184
9327
|
{
|
|
9185
9328
|
my $et = shift;
|
|
9186
|
-
$et->
|
|
9329
|
+
$et->Warn('The ExtractEmbedded option may find more tags in the media data',3);
|
|
9187
9330
|
}
|
|
9188
9331
|
|
|
9189
9332
|
#------------------------------------------------------------------------------
|
|
@@ -9476,6 +9619,8 @@ sub ProcessKeys($$$)
|
|
|
9476
9619
|
my $groups = $$tagInfo{Groups};
|
|
9477
9620
|
$$newInfo{Groups} = $groups ? { %$groups } : { };
|
|
9478
9621
|
$$newInfo{Groups}{$_} or $$newInfo{Groups}{$_} = $$tagTablePtr{GROUPS}{$_} foreach 0..2;
|
|
9622
|
+
# set Keys group. This is necessary for logic when reading the associated ItemList entry,
|
|
9623
|
+
# but note that the group name will be overridden by TAG_EXTRA G1 for tags in a track
|
|
9479
9624
|
$$newInfo{Groups}{1} = 'Keys';
|
|
9480
9625
|
} elsif ($tag =~ /^[-\w. ]+$/ or $tag =~ /\w{4}/) {
|
|
9481
9626
|
# create info for tags with reasonable id's
|
|
@@ -9522,6 +9667,43 @@ sub ProcessMetaKeys($$$)
|
|
|
9522
9667
|
return 1;
|
|
9523
9668
|
}
|
|
9524
9669
|
|
|
9670
|
+
#------------------------------------------------------------------------------
|
|
9671
|
+
# Identify trailers at specified offset from end of file
|
|
9672
|
+
# Inputs: 0) RAF reference, 1) Offset from end of file
|
|
9673
|
+
# Returns: Array ref to first trailer in linked list: 0) name of trailer,
|
|
9674
|
+
# 1) absolute offset to start of this trailer, 2) trailer length,
|
|
9675
|
+
# 3) ref to next trailer. Or undef if no trailer found, or error string on error
|
|
9676
|
+
# - file position is returned to its original location
|
|
9677
|
+
sub IdentifyTrailers($)
|
|
9678
|
+
{
|
|
9679
|
+
my $raf = shift;
|
|
9680
|
+
my ($trailer, $nextTrail, $buff, $type, $len);
|
|
9681
|
+
my $pos = $raf->Tell();
|
|
9682
|
+
my $offset = 0; # positive offset back from end of file
|
|
9683
|
+
while ($raf->Seek(-40-$offset, 2) and $raf->Read($buff, 40) == 40) {
|
|
9684
|
+
if (substr($buff, 8) eq '8db42d694ccc418790edff439fe026bf') {
|
|
9685
|
+
($type, $len) = ('Insta360', unpack('V',$buff));
|
|
9686
|
+
} elsif ($buff =~ /\&\&\&\&(.{4})$/) {
|
|
9687
|
+
($type, $len) = ('LigoGPS', Get32u(\$buff, 36));
|
|
9688
|
+
} elsif ($buff =~ /~\0\x04\0zmie~\0\0\x06.{4}([\x10\x18])(\x04)$/s or
|
|
9689
|
+
$buff =~ /~\0\x04\0zmie~\0\0\x0a.{8}([\x10\x18])(\x08)$/s)
|
|
9690
|
+
{
|
|
9691
|
+
my $oldOrder = GetByteOrder();
|
|
9692
|
+
SetByteOrder($1 eq "\x10" ? 'MM' : 'II');
|
|
9693
|
+
$type = 'MIE';
|
|
9694
|
+
$len = ($2 eq "\x04") ? Get32u(\$buff, 34) : Get64u(\$buff, 30);
|
|
9695
|
+
SetByteOrder($oldOrder);
|
|
9696
|
+
} else {
|
|
9697
|
+
last;
|
|
9698
|
+
}
|
|
9699
|
+
$trailer = [ $type , $raf->Tell() - $len, $len, $nextTrail ];
|
|
9700
|
+
$nextTrail = $trailer;
|
|
9701
|
+
$offset += $len;
|
|
9702
|
+
}
|
|
9703
|
+
$raf->Seek($pos,0) or return 'Seek error';
|
|
9704
|
+
return $trailer;
|
|
9705
|
+
}
|
|
9706
|
+
|
|
9525
9707
|
#------------------------------------------------------------------------------
|
|
9526
9708
|
# Process a QuickTime atom
|
|
9527
9709
|
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) optional tag table ref
|
|
@@ -9543,7 +9725,7 @@ sub ProcessMOV($$;$)
|
|
|
9543
9725
|
|
|
9544
9726
|
my $topLevel = not $$et{InQuickTime};
|
|
9545
9727
|
$$et{InQuickTime} = 1;
|
|
9546
|
-
$$et{HandlerType} = $$et{MetaFormat} = ''
|
|
9728
|
+
$$et{HandlerType} = $$et{MetaFormat} = $$et{MediaType} = '' if $topLevel;
|
|
9547
9729
|
|
|
9548
9730
|
unless (defined $$et{KeysCount}) {
|
|
9549
9731
|
$$et{KeysCount} = 0; # initialize ItemList key directory count
|
|
@@ -9569,15 +9751,10 @@ sub ProcessMOV($$;$)
|
|
|
9569
9751
|
}
|
|
9570
9752
|
($size, $tag) = unpack('Na4', $buff);
|
|
9571
9753
|
my $fast = $$et{OPTIONS}{FastScan} || 0;
|
|
9572
|
-
# check for Insta360 trailer
|
|
9754
|
+
# check for Insta360, LIGOGPSINFO or MIE trailer
|
|
9573
9755
|
if ($topLevel and not $fast) {
|
|
9574
|
-
|
|
9575
|
-
|
|
9576
|
-
substr($buff, 8) eq '8db42d694ccc418790edff439fe026bf')
|
|
9577
|
-
{
|
|
9578
|
-
$trailer = [ 'Insta360', $raf->Tell() - unpack('V',$buff) ];
|
|
9579
|
-
}
|
|
9580
|
-
$raf->Seek($pos,0) or return 0;
|
|
9756
|
+
$trailer = IdentifyTrailers($raf);
|
|
9757
|
+
$trailer and not ref $trailer and $et->Warn($trailer), return 0;
|
|
9581
9758
|
}
|
|
9582
9759
|
if ($dataPt) {
|
|
9583
9760
|
$verbose and $et->VerboseDir($$dirInfo{DirName});
|
|
@@ -9670,7 +9847,7 @@ sub ProcessMOV($$;$)
|
|
|
9670
9847
|
$warnStr = 'End of processing at large atom (LargeFileSupport not enabled)';
|
|
9671
9848
|
last;
|
|
9672
9849
|
} elsif ($et->Options('LargeFileSupport') eq '2') {
|
|
9673
|
-
$et->
|
|
9850
|
+
$et->Warn('Processing large atom (LargeFileSupport is 2)');
|
|
9674
9851
|
}
|
|
9675
9852
|
}
|
|
9676
9853
|
$size = $hi * 4294967296 + $lo - 16;
|
|
@@ -9679,29 +9856,32 @@ sub ProcessMOV($$;$)
|
|
|
9679
9856
|
$size -= 8;
|
|
9680
9857
|
}
|
|
9681
9858
|
if ($validate) {
|
|
9859
|
+
$et->Warn("Invalid 'wide' atom size") if $tag eq 'wide' and $size;
|
|
9682
9860
|
$$et{ValidatePath} or $$et{ValidatePath} = { };
|
|
9683
9861
|
my $path = join('-', @{$$et{PATH}}, $tag);
|
|
9684
9862
|
$path =~ s/-Track-/-$$et{SET_GROUP1}-/ if $$et{SET_GROUP1};
|
|
9685
9863
|
if ($$et{ValidatePath}{$path} and not $dupTagOK{$tag} and not $dupDirOK{$dirID}) {
|
|
9686
9864
|
my $i = Get32u(\$tag,0);
|
|
9687
9865
|
my $str = $i < 255 ? "index $i" : "tag '" . PrintableTagID($tag,2) . "'";
|
|
9688
|
-
$et->
|
|
9866
|
+
$et->Warn("Duplicate $str at " . join('-', @{$$et{PATH}}));
|
|
9689
9867
|
$$et{ValidatePath} = { } if $path eq 'MOV-moov'; # avoid warnings for all contained dups
|
|
9690
9868
|
}
|
|
9691
9869
|
$$et{ValidatePath}{$path} = 1;
|
|
9692
9870
|
}
|
|
9693
9871
|
if ($isUserData and $$et{SET_GROUP1}) {
|
|
9694
9872
|
my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9873
|
+
unless ($$tagInfo{SubDirectory}) {
|
|
9874
|
+
# add track name to UserData tags inside tracks
|
|
9875
|
+
$tag = $$et{SET_GROUP1} . $tag;
|
|
9876
|
+
if (not $$tagTablePtr{$tag} and $tagInfo) {
|
|
9877
|
+
my %newInfo = %$tagInfo;
|
|
9878
|
+
foreach ('Name', 'Description') {
|
|
9879
|
+
next unless $$tagInfo{$_};
|
|
9880
|
+
$newInfo{$_} = $$et{SET_GROUP1} . $$tagInfo{$_};
|
|
9881
|
+
$newInfo{$_} =~ s/^(Track\d+)Track/$1/; # remove duplicate "Track" in name
|
|
9882
|
+
}
|
|
9883
|
+
AddTagToTable($tagTablePtr, $tag, \%newInfo);
|
|
9703
9884
|
}
|
|
9704
|
-
AddTagToTable($tagTablePtr, $tag, \%newInfo);
|
|
9705
9885
|
}
|
|
9706
9886
|
}
|
|
9707
9887
|
# set flag to store additional information for ExtractEmbedded option
|
|
@@ -9757,8 +9937,10 @@ sub ProcessMOV($$;$)
|
|
|
9757
9937
|
# save required tag sizes
|
|
9758
9938
|
if ($$tagTablePtr{"$tag-size"}) {
|
|
9759
9939
|
$et->HandleTag($tagTablePtr, "$tag-size", $size);
|
|
9760
|
-
$et->HandleTag($tagTablePtr, "$tag-offset", $raf->Tell()) if $$tagTablePtr{"$tag-offset"};
|
|
9940
|
+
$et->HandleTag($tagTablePtr, "$tag-offset", $raf->Tell()+$dirBase) if $$tagTablePtr{"$tag-offset"};
|
|
9761
9941
|
}
|
|
9942
|
+
# save position/size of 'idat'
|
|
9943
|
+
$$et{MediaDataInfo} = [ $raf->Tell() + $dirBase, $size ] if $tag eq 'idat';
|
|
9762
9944
|
# stop processing at mdat/idat if -fast2 is used
|
|
9763
9945
|
last if $fast > 1 and ($tag eq 'mdat' or ($tag eq 'idat' and $$et{FileType} ne 'HEIC'));
|
|
9764
9946
|
# load values only if associated with a tag (or verbose) and not too big
|
|
@@ -9766,7 +9948,7 @@ sub ProcessMOV($$;$)
|
|
|
9766
9948
|
# check for RIFF trailer (written by Auto-Vox dashcam)
|
|
9767
9949
|
if ($buff =~ /^(gpsa|gps0|gsen|gsea)...\0/s) { # (yet seen only gpsa as first record)
|
|
9768
9950
|
$et->VPrint(0, sprintf("Found RIFF trailer at offset 0x%x",$lastPos));
|
|
9769
|
-
if ($
|
|
9951
|
+
if ($ee) {
|
|
9770
9952
|
$raf->Seek(-8, 1) or last; # seek back to start of trailer
|
|
9771
9953
|
my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
|
9772
9954
|
ProcessRIFFTrailer($et, { RAF => $raf }, $tbl);
|
|
@@ -9916,6 +10098,7 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
|
9916
10098
|
}
|
|
9917
10099
|
}
|
|
9918
10100
|
if ($tagInfo) {
|
|
10101
|
+
my @found;
|
|
9919
10102
|
my $subdir = $$tagInfo{SubDirectory};
|
|
9920
10103
|
if ($subdir) {
|
|
9921
10104
|
my $start = $$subdir{Start} || 0;
|
|
@@ -10034,21 +10217,23 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
|
10034
10217
|
Index => $index,
|
|
10035
10218
|
Extra => sprintf(", Type='${type}', Flags=0x%x%s, Lang=0x%.4x",$flags,$str,$lang),
|
|
10036
10219
|
) if $verbose;
|
|
10037
|
-
|
|
10038
|
-
|
|
10039
|
-
|
|
10040
|
-
|
|
10041
|
-
|
|
10220
|
+
if (defined $value) {
|
|
10221
|
+
# use "Keys" in path instead of ItemList if this was defined by a Keys tag
|
|
10222
|
+
# (the only reason for this is to have "Keys" in the family 5 group name)
|
|
10223
|
+
# Note that the Keys group is specifically set by the ProcessKeys routine,
|
|
10224
|
+
# even though this tag would be in the ItemList table
|
|
10225
|
+
my $isKeys = $$tagInfo{Groups} && $$tagInfo{Groups}{1} && $$tagInfo{Groups}{1} eq 'Keys';
|
|
10226
|
+
$isKeys and $oldDir = $$et{PATH}[-1], $$et{PATH}[-1] = 'Keys';
|
|
10227
|
+
push @found, $et->FoundTag($langInfo, $value);
|
|
10228
|
+
$$et{PATH}[-1] = $oldDir if $isKeys;
|
|
10042
10229
|
}
|
|
10043
|
-
$et->FoundTag($langInfo, $value) if defined $value;
|
|
10044
|
-
$$et{PATH}[-1] = $oldDir if $isKey;
|
|
10045
10230
|
$pos += $len;
|
|
10046
10231
|
}
|
|
10047
10232
|
} elsif ($tag =~ /^\xa9/ or $$tagInfo{IText}) {
|
|
10048
10233
|
# parse international text to extract all languages
|
|
10049
10234
|
my $pos = 0;
|
|
10050
10235
|
if ($$tagInfo{Format}) {
|
|
10051
|
-
$et->FoundTag($tagInfo, ReadValue(\$val, 0, $$tagInfo{Format}, undef, length($val)));
|
|
10236
|
+
push @found, $et->FoundTag($tagInfo, ReadValue(\$val, 0, $$tagInfo{Format}, undef, length($val)));
|
|
10052
10237
|
$pos = $size;
|
|
10053
10238
|
}
|
|
10054
10239
|
for (;;) {
|
|
@@ -10113,7 +10298,7 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
|
10113
10298
|
$str = substr($val, $pos-$n-2, $n) . $str;
|
|
10114
10299
|
}
|
|
10115
10300
|
$langInfo = GetLangInfoQT($et, $tagInfo, $lang) if $lang;
|
|
10116
|
-
$et->FoundTag($langInfo || $tagInfo, $str);
|
|
10301
|
+
push @found, $et->FoundTag($langInfo || $tagInfo, $str);
|
|
10117
10302
|
$pos += $len;
|
|
10118
10303
|
}
|
|
10119
10304
|
} else {
|
|
@@ -10127,6 +10312,7 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
|
10127
10312
|
$$et{BASE} = $dataPos;
|
|
10128
10313
|
}
|
|
10129
10314
|
my $key = $et->FoundTag($tagInfo, $val);
|
|
10315
|
+
push @found, $key;
|
|
10130
10316
|
$$et{BASE} = $oldBase if defined $oldBase;
|
|
10131
10317
|
# decode if necessary (NOTE: must be done after RawConv)
|
|
10132
10318
|
if (defined $key and (not $format or $format =~ /^string/) and
|
|
@@ -10142,6 +10328,14 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
|
10142
10328
|
}
|
|
10143
10329
|
}
|
|
10144
10330
|
}
|
|
10331
|
+
# tweak family 1 group names for Keys/ItemList/UserData tags in a track
|
|
10332
|
+
if ($$et{SET_GROUP1} and ($dirID eq 'ilst' or $dirID eq 'udta') and @found) {
|
|
10333
|
+
my $type = $trackPath{join '-', @{$$et{PATH}}};
|
|
10334
|
+
if ($type) {
|
|
10335
|
+
my $grp = ($avType{$$et{MediaType}} || $$et{SET_GROUP1}) . $type;
|
|
10336
|
+
defined and $et->SetGroup($_, $grp) foreach @found;
|
|
10337
|
+
}
|
|
10338
|
+
}
|
|
10145
10339
|
}
|
|
10146
10340
|
} else {
|
|
10147
10341
|
$et->VerboseInfo($tag, $tagInfo,
|
|
@@ -10154,11 +10348,12 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
|
10154
10348
|
last;
|
|
10155
10349
|
}
|
|
10156
10350
|
}
|
|
10351
|
+
$$et{MediaType} = '' if $tag eq 'trak'; # reset track type at end of track
|
|
10157
10352
|
$dataPos += $size + 8; # point to start of next atom data
|
|
10158
10353
|
last if $dirEnd and $dataPos >= $dirEnd; # (note: ignores last value if 0 bytes)
|
|
10159
10354
|
$lastPos = $raf->Tell() + $dirBase;
|
|
10160
10355
|
if ($trailer and $lastPos >= $$trailer[1]) {
|
|
10161
|
-
$et->Warn(sprintf('%s trailer at offset 0x%x', @$trailer), 1);
|
|
10356
|
+
$et->Warn(sprintf('%s trailer at offset 0x%x (%d bytes)', @$trailer[0..2]), 1);
|
|
10162
10357
|
last;
|
|
10163
10358
|
}
|
|
10164
10359
|
$raf->Read($buff, 8) == 8 or last;
|
|
@@ -10209,7 +10404,33 @@ QTLang: foreach $tag (@{$$et{QTLang}}) {
|
|
|
10209
10404
|
# process item information now that we are done processing its 'meta' container
|
|
10210
10405
|
HandleItemInfo($et) if $topLevel or $dirID eq 'meta';
|
|
10211
10406
|
|
|
10212
|
-
|
|
10407
|
+
# process linked list of trailers
|
|
10408
|
+
for (; $trailer; $trailer=$$trailer[3]) {
|
|
10409
|
+
next if $lastPos > $$trailer[1]; # skip if we have already processed this as an atom
|
|
10410
|
+
last unless $raf->Seek($$trailer[1], 0);
|
|
10411
|
+
if ($$trailer[0] eq 'LigoGPS' and $raf->Read($buff, 8) == 8 and $buff =~ /skip$/) {
|
|
10412
|
+
$ee or $et->Warn('Use the ExtractEmbedded option to decode timed GPS',3), next;
|
|
10413
|
+
my $len = Get32u(\$buff, 0) - 16;
|
|
10414
|
+
if ($len > 0 and $raf->Read($buff, $len) == $len and $buff =~ /^LIGOGPSINFO\0/) {
|
|
10415
|
+
my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
|
10416
|
+
my %dirInfo = ( DataPt => \$buff, DataPos => $$trailer[1] + 8, DirName => 'LigoGPSTrailer' );
|
|
10417
|
+
Image::ExifTool::LigoGPS::ProcessLigoGPS($et, \%dirInfo, $tbl);
|
|
10418
|
+
} else {
|
|
10419
|
+
$et->Warn('Unrecognized data in LigoGPS trailer');
|
|
10420
|
+
}
|
|
10421
|
+
} elsif ($$trailer[0] eq 'Insta360' and $ee) {
|
|
10422
|
+
# process Insta360 trailer if it exists
|
|
10423
|
+
$raf->Seek(0, 2) or $et->Warn('Seek error'), last;
|
|
10424
|
+
my $offset = $raf->Tell() - $$trailer[1] - $$trailer[2];
|
|
10425
|
+
ProcessInsta360($et, { RAF => $raf, DirName => $$trailer[0], Offset => $offset });
|
|
10426
|
+
} elsif ($$trailer[0] eq 'MIE') {
|
|
10427
|
+
require Image::ExifTool::MIE;
|
|
10428
|
+
Image::ExifTool::MIE::ProcessMIE($et, { RAF => $raf, DirName => 'MIE', Trailer => 1 });
|
|
10429
|
+
}
|
|
10430
|
+
}
|
|
10431
|
+
# brute force scan for metadata embedded in media data
|
|
10432
|
+
# (and process Insta360 trailer if it exists)
|
|
10433
|
+
ScanMediaData($et) if $ee and $topLevel;
|
|
10213
10434
|
|
|
10214
10435
|
# restore any changed options
|
|
10215
10436
|
$et->Options($_ => $saveOptions{$_}) foreach keys %saveOptions;
|
|
@@ -10227,6 +10448,24 @@ sub ProcessQTIF($$)
|
|
|
10227
10448
|
return ProcessMOV($et, $dirInfo, $table);
|
|
10228
10449
|
}
|
|
10229
10450
|
|
|
10451
|
+
#==============================================================================
|
|
10452
|
+
# Autoload LigoGPS module if necessary
|
|
10453
|
+
# NOTE: Switches to package LigoGPS!
|
|
10454
|
+
#
|
|
10455
|
+
package Image::ExifTool::LigoGPS;
|
|
10456
|
+
use vars qw($AUTOLOAD);
|
|
10457
|
+
sub AUTOLOAD {
|
|
10458
|
+
require Image::ExifTool::LigoGPS;
|
|
10459
|
+
unless (defined &$AUTOLOAD) {
|
|
10460
|
+
my @caller = caller(0);
|
|
10461
|
+
# reproduce Perl's standard 'undefined subroutine' message:
|
|
10462
|
+
die "Undefined subroutine $AUTOLOAD called at $caller[1] line $caller[2]\n";
|
|
10463
|
+
}
|
|
10464
|
+
no strict 'refs';
|
|
10465
|
+
return &$AUTOLOAD(@_); # call the function
|
|
10466
|
+
}
|
|
10467
|
+
#==============================================================================
|
|
10468
|
+
|
|
10230
10469
|
1; # end
|
|
10231
10470
|
|
|
10232
10471
|
__END__
|
|
@@ -10246,7 +10485,7 @@ information from QuickTime and MP4 video, M4A audio, and HEIC image files.
|
|
|
10246
10485
|
|
|
10247
10486
|
=head1 AUTHOR
|
|
10248
10487
|
|
|
10249
|
-
Copyright 2003-
|
|
10488
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
10250
10489
|
|
|
10251
10490
|
This library is free software; you can redistribute it and/or modify it
|
|
10252
10491
|
under the same terms as Perl itself.
|