exiftool_vendored 13.10.0 → 13.14.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.
- checksums.yaml +4 -4
- data/bin/Changes +82 -19
- data/bin/MANIFEST +6 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +3 -3
- data/bin/arg_files/exif2xmp.args +4 -0
- data/bin/arg_files/xmp2exif.args +2 -1
- data/bin/build_geolocation +1 -1
- data/bin/exiftool +208 -150
- data/bin/lib/File/RandomAccess.pm +1 -1
- data/bin/lib/File/RandomAccess.pod +2 -2
- data/bin/lib/Image/ExifTool/AAC.pm +1 -1
- data/bin/lib/Image/ExifTool/AES.pm +1 -1
- data/bin/lib/Image/ExifTool/AFCP.pm +6 -6
- data/bin/lib/Image/ExifTool/AIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/APE.pm +1 -1
- data/bin/lib/Image/ExifTool/APP12.pm +1 -1
- data/bin/lib/Image/ExifTool/ASF.pm +1 -1
- data/bin/lib/Image/ExifTool/Apple.pm +1 -1
- data/bin/lib/Image/ExifTool/Audible.pm +1 -1
- data/bin/lib/Image/ExifTool/BMP.pm +1 -1
- data/bin/lib/Image/ExifTool/BPG.pm +1 -1
- data/bin/lib/Image/ExifTool/BZZ.pm +1 -1
- data/bin/lib/Image/ExifTool/BigTIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +29 -18
- data/bin/lib/Image/ExifTool/CBOR.pm +1 -1
- data/bin/lib/Image/ExifTool/Canon.pm +8 -4
- data/bin/lib/Image/ExifTool/CanonCustom.pm +1 -1
- data/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/CanonVRD.pm +1 -1
- data/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
- data/bin/lib/Image/ExifTool/Casio.pm +1 -1
- data/bin/lib/Image/ExifTool/Charset.pm +1 -1
- data/bin/lib/Image/ExifTool/DICOM.pm +1 -1
- data/bin/lib/Image/ExifTool/DJI.pm +150 -46
- data/bin/lib/Image/ExifTool/DNG.pm +1 -1
- data/bin/lib/Image/ExifTool/DPX.pm +1 -1
- data/bin/lib/Image/ExifTool/DV.pm +1 -1
- data/bin/lib/Image/ExifTool/DarwinCore.pm +1 -1
- data/bin/lib/Image/ExifTool/DjVu.pm +1 -1
- data/bin/lib/Image/ExifTool/EXE.pm +123 -32
- data/bin/lib/Image/ExifTool/Exif.pm +7 -4
- data/bin/lib/Image/ExifTool/FITS.pm +1 -1
- data/bin/lib/Image/ExifTool/FLAC.pm +1 -1
- data/bin/lib/Image/ExifTool/FLIF.pm +1 -1
- data/bin/lib/Image/ExifTool/FLIR.pm +1 -1
- data/bin/lib/Image/ExifTool/Fixup.pm +1 -1
- data/bin/lib/Image/ExifTool/Flash.pm +1 -1
- data/bin/lib/Image/ExifTool/FlashPix.pm +1 -1
- data/bin/lib/Image/ExifTool/Font.pm +1 -1
- data/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
- data/bin/lib/Image/ExifTool/FujiFilm.pm +1 -1
- data/bin/lib/Image/ExifTool/GE.pm +1 -1
- data/bin/lib/Image/ExifTool/GIF.pm +1 -1
- data/bin/lib/Image/ExifTool/GIMP.pm +1 -1
- data/bin/lib/Image/ExifTool/GM.pm +1 -1
- data/bin/lib/Image/ExifTool/GPS.pm +1 -1
- data/bin/lib/Image/ExifTool/GeoTiff.pm +1 -1
- data/bin/lib/Image/ExifTool/Geolocation.pm +17 -8
- data/bin/lib/Image/ExifTool/Geotag.pm +1 -1
- data/bin/lib/Image/ExifTool/GoPro.pm +1 -1
- data/bin/lib/Image/ExifTool/H264.pm +1 -1
- data/bin/lib/Image/ExifTool/HP.pm +1 -1
- data/bin/lib/Image/ExifTool/HTML.pm +1 -1
- data/bin/lib/Image/ExifTool/HtmlDump.pm +1 -1
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +1 -1
- data/bin/lib/Image/ExifTool/ICO.pm +1 -1
- data/bin/lib/Image/ExifTool/ID3.pm +1 -1
- data/bin/lib/Image/ExifTool/IPTC.pm +8 -5
- data/bin/lib/Image/ExifTool/ISO.pm +1 -1
- data/bin/lib/Image/ExifTool/ITC.pm +1 -1
- data/bin/lib/Image/ExifTool/Import.pm +5 -4
- data/bin/lib/Image/ExifTool/InDesign.pm +1 -1
- data/bin/lib/Image/ExifTool/InfiRay.pm +1 -1
- data/bin/lib/Image/ExifTool/JPEG.pm +6 -2
- data/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
- data/bin/lib/Image/ExifTool/JSON.pm +1 -1
- data/bin/lib/Image/ExifTool/JVC.pm +1 -1
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +1 -1
- data/bin/lib/Image/ExifTool/Kodak.pm +1 -1
- data/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/LIF.pm +1 -1
- data/bin/lib/Image/ExifTool/LNK.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/en_ca.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/en_gb.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/fi.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/fr.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/it.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/ja.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/ko.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/nl.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/pl.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/sk.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/tr.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
- data/bin/lib/Image/ExifTool/Leaf.pm +1 -1
- data/bin/lib/Image/ExifTool/LigoGPS.pm +409 -0
- data/bin/lib/Image/ExifTool/Lytro.pm +1 -1
- data/bin/lib/Image/ExifTool/M2TS.pm +22 -13
- data/bin/lib/Image/ExifTool/MIE.pm +1 -1
- data/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
- data/bin/lib/Image/ExifTool/MIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/MISB.pm +1 -1
- data/bin/lib/Image/ExifTool/MNG.pm +1 -1
- data/bin/lib/Image/ExifTool/MOI.pm +1 -1
- data/bin/lib/Image/ExifTool/MPC.pm +1 -1
- data/bin/lib/Image/ExifTool/MPEG.pm +1 -1
- data/bin/lib/Image/ExifTool/MPF.pm +1 -1
- data/bin/lib/Image/ExifTool/MRC.pm +1 -1
- data/bin/lib/Image/ExifTool/MWG.pm +1 -1
- data/bin/lib/Image/ExifTool/MXF.pm +1 -1
- data/bin/lib/Image/ExifTool/MacOS.pm +1 -1
- data/bin/lib/Image/ExifTool/MakerNotes.pm +1 -1
- data/bin/lib/Image/ExifTool/Matroska.pm +12 -4
- data/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
- data/bin/lib/Image/ExifTool/Minolta.pm +1 -1
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/Motorola.pm +1 -1
- data/bin/lib/Image/ExifTool/Nikon.pm +166 -35
- data/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
- data/bin/lib/Image/ExifTool/NikonCustom.pm +1 -1
- data/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
- data/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
- data/bin/lib/Image/ExifTool/OOXML.pm +1 -1
- data/bin/lib/Image/ExifTool/Ogg.pm +1 -1
- data/bin/lib/Image/ExifTool/Olympus.pm +1 -1
- data/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
- data/bin/lib/Image/ExifTool/Opus.pm +1 -1
- data/bin/lib/Image/ExifTool/Other.pm +1 -1
- data/bin/lib/Image/ExifTool/PCX.pm +1 -1
- data/bin/lib/Image/ExifTool/PDF.pm +1 -1
- data/bin/lib/Image/ExifTool/PGF.pm +1 -1
- data/bin/lib/Image/ExifTool/PICT.pm +1 -1
- data/bin/lib/Image/ExifTool/PLIST.pm +1 -1
- data/bin/lib/Image/ExifTool/PLUS.pm +1 -1
- data/bin/lib/Image/ExifTool/PNG.pm +1 -1
- data/bin/lib/Image/ExifTool/PPM.pm +1 -1
- data/bin/lib/Image/ExifTool/PSP.pm +1 -1
- data/bin/lib/Image/ExifTool/Palm.pm +1 -1
- data/bin/lib/Image/ExifTool/Panasonic.pm +20 -2
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/Parrot.pm +1 -1
- data/bin/lib/Image/ExifTool/Pentax.pm +1 -1
- data/bin/lib/Image/ExifTool/PhaseOne.pm +1 -1
- data/bin/lib/Image/ExifTool/PhotoCD.pm +1 -1
- data/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
- data/bin/lib/Image/ExifTool/Photoshop.pm +1 -1
- data/bin/lib/Image/ExifTool/PostScript.pm +1 -1
- data/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
- data/bin/lib/Image/ExifTool/Protobuf.pm +48 -20
- data/bin/lib/Image/ExifTool/Qualcomm.pm +1 -1
- data/bin/lib/Image/ExifTool/QuickTime.pm +206 -66
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +21 -303
- data/bin/lib/Image/ExifTool/README +4 -0
- data/bin/lib/Image/ExifTool/RIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/RSRC.pm +1 -1
- data/bin/lib/Image/ExifTool/RTF.pm +1 -1
- data/bin/lib/Image/ExifTool/Radiance.pm +1 -1
- data/bin/lib/Image/ExifTool/Rawzor.pm +1 -1
- data/bin/lib/Image/ExifTool/Real.pm +1 -1
- data/bin/lib/Image/ExifTool/Reconyx.pm +1 -1
- data/bin/lib/Image/ExifTool/Red.pm +1 -1
- data/bin/lib/Image/ExifTool/Ricoh.pm +1 -1
- data/bin/lib/Image/ExifTool/Samsung.pm +2 -2
- data/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
- data/bin/lib/Image/ExifTool/Scalado.pm +1 -1
- data/bin/lib/Image/ExifTool/Shift.pl +1 -1
- data/bin/lib/Image/ExifTool/Shortcuts.pm +1 -1
- data/bin/lib/Image/ExifTool/Sigma.pm +1 -1
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/Sony.pm +1 -1
- data/bin/lib/Image/ExifTool/SonyIDC.pm +1 -1
- data/bin/lib/Image/ExifTool/Stim.pm +1 -1
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +2 -2
- data/bin/lib/Image/ExifTool/TagLookup.pm +3449 -3435
- data/bin/lib/Image/ExifTool/TagNames.pod +164 -47
- data/bin/lib/Image/ExifTool/Text.pm +1 -1
- data/bin/lib/Image/ExifTool/Theora.pm +1 -1
- data/bin/lib/Image/ExifTool/Torrent.pm +3 -3
- data/bin/lib/Image/ExifTool/Unknown.pm +1 -1
- data/bin/lib/Image/ExifTool/VCard.pm +1 -1
- data/bin/lib/Image/ExifTool/Validate.pm +1 -1
- data/bin/lib/Image/ExifTool/Vivo.pm +124 -0
- data/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
- data/bin/lib/Image/ExifTool/WPG.pm +1 -1
- data/bin/lib/Image/ExifTool/WTV.pm +1 -1
- data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePDF.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePostScript.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +74 -43
- data/bin/lib/Image/ExifTool/WriteRIFF.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
- data/bin/lib/Image/ExifTool/Writer.pl +21 -16
- data/bin/lib/Image/ExifTool/XISF.pm +1 -1
- data/bin/lib/Image/ExifTool/XMP.pm +1 -1
- data/bin/lib/Image/ExifTool/XMP2.pl +1 -1
- data/bin/lib/Image/ExifTool/XMPStruct.pl +1 -1
- data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
- data/bin/lib/Image/ExifTool/ZISRAW.pm +1 -1
- data/bin/lib/Image/ExifTool/iWork.pm +1 -1
- data/bin/lib/Image/ExifTool.pm +34 -12
- data/bin/lib/Image/ExifTool.pod +57 -46
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +4 -2
@@ -15,6 +15,8 @@ my %movMap = (
|
|
15
15
|
QuickTime => 'ItemList', # (default location for QuickTime tags)
|
16
16
|
ItemList => 'Meta', # MOV-Movie-UserData-Meta-ItemList
|
17
17
|
Keys => 'Movie', # MOV-Movie-Meta-Keys !! (hack due to different Meta location)
|
18
|
+
AudioKeys => 'Track', # MOV-Movie-Track-Meta-Keys !!
|
19
|
+
VideoKeys => 'Track', # MOV-Movie-Track-Meta-Keys !!
|
18
20
|
Meta => 'UserData',
|
19
21
|
XMP => 'UserData', # MOV-Movie-UserData-XMP
|
20
22
|
Microsoft => 'UserData', # MOV-Movie-UserData-Microsoft
|
@@ -29,6 +31,8 @@ my %mp4Map = (
|
|
29
31
|
QuickTime => 'ItemList', # (default location for QuickTime tags)
|
30
32
|
ItemList => 'Meta', # MOV-Movie-UserData-Meta-ItemList
|
31
33
|
Keys => 'Movie', # MOV-Movie-Meta-Keys !! (hack due to different Meta location)
|
34
|
+
AudioKeys => 'Track', # MOV-Movie-Track-Meta-Keys !!
|
35
|
+
VideoKeys => 'Track', # MOV-Movie-Track-Meta-Keys !!
|
32
36
|
Meta => 'UserData',
|
33
37
|
UserData => 'Movie', # MOV-Movie-UserData
|
34
38
|
Microsoft => 'UserData', # MOV-Movie-UserData-Microsoft
|
@@ -383,13 +387,14 @@ sub WriteKeys($$$)
|
|
383
387
|
my $outfile = $$dirInfo{OutFile};
|
384
388
|
my ($tag, %done, %remap, %info, %add, $i);
|
385
389
|
|
390
|
+
my $keysGrp = $avType{$$et{MediaType}} ? "$avType{$$et{MediaType}}Keys" : 'Keys';
|
386
391
|
$dirLen < 8 and $et->Warn('Short Keys box'), $dirLen = 8, $$dataPt = "\0" x 8;
|
387
|
-
if ($$et{DEL_GROUP}{
|
392
|
+
if ($$et{DEL_GROUP}{$keysGrp}) {
|
388
393
|
$dirLen = 8; # delete all existing keys
|
389
394
|
# deleted keys are identified by a zero entry in the Remap lookup
|
390
395
|
my $n = Get32u($dataPt, 4);
|
391
396
|
for ($i=1; $i<=$n; ++$i) { $remap{$i} = 0; }
|
392
|
-
$et->VPrint(0, " [deleting $n
|
397
|
+
$et->VPrint(0, " [deleting $n $keysGrp entr".($n==1 ? 'y' : 'ies')."]\n");
|
393
398
|
++$$et{CHANGED};
|
394
399
|
}
|
395
400
|
my $pos = 8;
|
@@ -425,7 +430,7 @@ sub WriteKeys($$$)
|
|
425
430
|
}
|
426
431
|
unless ($dontDelete) {
|
427
432
|
# delete this key
|
428
|
-
$et->VPrint(1, "$$et{INDENT}\[deleting
|
433
|
+
$et->VPrint(1, "$$et{INDENT}\[deleting $keysGrp entry $index '${tag}']\n");
|
429
434
|
$pos += $len;
|
430
435
|
$remap{$index++} = 0;
|
431
436
|
++$$et{CHANGED};
|
@@ -455,7 +460,7 @@ sub WriteKeys($$$)
|
|
455
460
|
# add new entry to 'keys' data
|
456
461
|
my $val = $id =~ /^com\./ ? $id : "com.apple.quicktime.$id";
|
457
462
|
$newData .= Set32u(8 + length($val)) . 'mdta' . $val;
|
458
|
-
$et->VPrint(1, "$$et{INDENT}\[adding
|
463
|
+
$et->VPrint(1, "$$et{INDENT}\[adding $keysGrp entry $newIndex '${id}']\n");
|
459
464
|
$add{$newIndex++} = $tagInfo;
|
460
465
|
++$$et{CHANGED};
|
461
466
|
}
|
@@ -470,7 +475,7 @@ sub WriteKeys($$$)
|
|
470
475
|
# Info - Keys tag information, based on old index value
|
471
476
|
# Add - Keys items deleted, based on old index value
|
472
477
|
# Num - Number of items in edited Keys box
|
473
|
-
$$et{
|
478
|
+
$$et{$keysGrp} = { Remap => \%remap, Info => \%info, Add => \%add, Num => $num };
|
474
479
|
|
475
480
|
return $newData; # return updated Keys box
|
476
481
|
}
|
@@ -556,6 +561,7 @@ sub WriteItemInfo($$$)
|
|
556
561
|
}
|
557
562
|
}
|
558
563
|
my ($hdr, $subTable, $proc);
|
564
|
+
my $strt = 0;
|
559
565
|
if ($name eq 'EXIF') {
|
560
566
|
if (not length $buff) {
|
561
567
|
# create EXIF from scratch
|
@@ -565,6 +571,7 @@ sub WriteItemInfo($$$)
|
|
565
571
|
$hdr = '';
|
566
572
|
} elsif (length($buff) >= 4 and length($buff) >= 4 + unpack('N',$buff)) {
|
567
573
|
$hdr = substr($buff, 0, 4 + unpack('N',$buff));
|
574
|
+
$strt = length $hdr;
|
568
575
|
} else {
|
569
576
|
$et->Warn('Invalid Exif header');
|
570
577
|
next;
|
@@ -578,8 +585,8 @@ sub WriteItemInfo($$$)
|
|
578
585
|
my %dirInfo = (
|
579
586
|
DataPt => \$buff,
|
580
587
|
DataLen => length $buff,
|
581
|
-
DirStart =>
|
582
|
-
DirLen => length($buff) -
|
588
|
+
DirStart => $strt,
|
589
|
+
DirLen => length($buff) - $strt,
|
583
590
|
);
|
584
591
|
my $changed = $$et{CHANGED};
|
585
592
|
my $newVal = $et->WriteDirectory(\%dirInfo, $subTable, $proc);
|
@@ -881,7 +888,7 @@ sub WriteQuickTime($$$)
|
|
881
888
|
$et or return 1; # allow dummy access to autoload this package
|
882
889
|
my ($mdat, @mdat, @mdatEdit, $edit, $track, $outBuff, $co, $term, $delCount);
|
883
890
|
my (%langTags, $canCreate, $delGrp, %boxPos, %didDir, $writeLast, $err, $atomCount);
|
884
|
-
my ($tag, $lastTag, $lastPos, $errStr, $trailer, $buf2);
|
891
|
+
my ($tag, $lastTag, $lastPos, $errStr, $trailer, $buf2, $keysGrp, $keysPath);
|
885
892
|
my $outfile = $$dirInfo{OutFile} || return 0;
|
886
893
|
my $raf = $$dirInfo{RAF}; # (will be null for lower-level atoms)
|
887
894
|
my $dataPt = $$dirInfo{DataPt}; # (will be null for top-level atoms)
|
@@ -915,15 +922,26 @@ sub WriteQuickTime($$$)
|
|
915
922
|
|
916
923
|
$raf->Seek($dirStart, 1) if $dirStart; # skip header if it exists
|
917
924
|
|
925
|
+
if ($avType{$$et{MediaType}}) {
|
926
|
+
# (note: these won't be correct now if we haven't yet processed the Media box,
|
927
|
+
# but in this case they won't be needed until after we set them properly below)
|
928
|
+
($keysGrp, $keysPath) = ("$avType{$$et{MediaType}}Keys", 'MOV-Movie-Track');
|
929
|
+
} else {
|
930
|
+
($keysGrp, $keysPath) = ('Keys', 'MOV-Movie');
|
931
|
+
}
|
918
932
|
my $curPath = join '-', @{$$et{PATH}};
|
919
933
|
my ($dir, $writePath) = ($dirName, $dirName);
|
920
934
|
$writePath = "$dir-$writePath" while defined($dir = $$et{DirMap}{$dir});
|
921
935
|
# hack to create Keys directories if necessary (its containing Meta is in a different location)
|
922
|
-
if ($$addDirs{Keys} and $curPath =~ /^MOV-Movie(-Meta)?$/) {
|
936
|
+
if (($$addDirs{Keys} and $curPath =~ /^MOV-Movie(-Meta)?$/)) {
|
923
937
|
$createKeys = 1; # create new Keys directories
|
924
|
-
} elsif ($curPath
|
938
|
+
} elsif (($$addDirs{AudioKeys} or $$addDirs{VideoKeys}) and $curPath =~ /^MOV-Movie-Track(-Meta)?$/) {
|
939
|
+
$createKeys = -1; # (must wait until MediaType is known)
|
940
|
+
} elsif (($curPath eq 'MOV-Movie-Meta-ItemList') or
|
941
|
+
($curPath eq 'MOV-Movie-Track-Meta-ItemList' and $avType{$$et{MediaType}}))
|
942
|
+
{
|
925
943
|
$createKeys = 2; # create new Keys tags
|
926
|
-
my $keys = $$et{
|
944
|
+
my $keys = $$et{$keysGrp};
|
927
945
|
if ($keys) {
|
928
946
|
# add new tag entries for existing Keys tags, now that we know their ID's
|
929
947
|
# - first make lookup to convert Keys tagInfo ref to index number
|
@@ -931,7 +949,7 @@ sub WriteQuickTime($$$)
|
|
931
949
|
foreach $index (keys %{$$keys{Info}}) {
|
932
950
|
$keysInfo{$$keys{Info}{$index}} = $index if $$keys{Remap}{$index};
|
933
951
|
}
|
934
|
-
my $keysTable = GetTagTable(
|
952
|
+
my $keysTable = GetTagTable("Image::ExifTool::QuickTime::$keysGrp");
|
935
953
|
my $newKeysTags = $et->GetNewTagInfoHash($keysTable);
|
936
954
|
foreach (keys %$newKeysTags) {
|
937
955
|
my $tagInfo = $$newKeysTags{$_};
|
@@ -960,7 +978,8 @@ sub WriteQuickTime($$$)
|
|
960
978
|
}
|
961
979
|
if ($curPath eq $writePath or $createKeys) {
|
962
980
|
$canCreate = 1;
|
963
|
-
|
981
|
+
# (must check the appropriate Keys delete flag if this is a Keys ItemList)
|
982
|
+
$delGrp = $$et{DEL_GROUP}{$createKeys ? $keysGrp : $dirName};
|
964
983
|
}
|
965
984
|
$atomCount = $$tagTablePtr{VARS}{ATOM_COUNT} if $$tagTablePtr{VARS};
|
966
985
|
|
@@ -1078,12 +1097,12 @@ sub WriteQuickTime($$$)
|
|
1078
1097
|
last;
|
1079
1098
|
}
|
1080
1099
|
}
|
1081
|
-
# save the handler type
|
1082
|
-
if ($tag eq 'hdlr' and length $buff >= 12
|
1083
|
-
|
1084
|
-
|
1100
|
+
# save the handler type of the track media
|
1101
|
+
if ($tag eq 'hdlr' and length $buff >= 12 and
|
1102
|
+
@{$$et{PATH}} and $$et{PATH}[-1] eq 'Media')
|
1103
|
+
{
|
1104
|
+
$$et{MediaType} = substr($buff,8,4);
|
1085
1105
|
}
|
1086
|
-
|
1087
1106
|
# if this atom stores offsets, save its location so we can fix up offsets later
|
1088
1107
|
# (are there any other atoms that may store absolute file offsets?)
|
1089
1108
|
if ($tag =~ /^(stco|co64|iloc|mfra|moof|sidx|saio|gps |CTBO|uuid)$/) {
|
@@ -1128,11 +1147,11 @@ sub WriteQuickTime($$$)
|
|
1128
1147
|
&{$$tagInfo{WriteHook}}($buff,$et) if $tagInfo and $$tagInfo{WriteHook};
|
1129
1148
|
|
1130
1149
|
# allow numerical tag ID's (ItemList entries defined by Keys)
|
1131
|
-
if (not $tagInfo and $dirName eq 'ItemList' and $$et{
|
1150
|
+
if (not $tagInfo and $dirName eq 'ItemList' and $$et{$keysGrp}) {
|
1132
1151
|
$keysIndex = unpack('N', $tag);
|
1133
|
-
my $newIndex = $$et{
|
1152
|
+
my $newIndex = $$et{$keysGrp}{Remap}{$keysIndex};
|
1134
1153
|
if (defined $newIndex) {
|
1135
|
-
$tagInfo = $$et{
|
1154
|
+
$tagInfo = $$et{$keysGrp}{Info}{$keysIndex};
|
1136
1155
|
unless ($newIndex) {
|
1137
1156
|
if ($tagInfo) {
|
1138
1157
|
$et->VPrint(1," - Keys:$$tagInfo{Name}");
|
@@ -1172,7 +1191,7 @@ sub WriteQuickTime($$$)
|
|
1172
1191
|
if ($subdir) { # process atoms in this container from a buffer in memory
|
1173
1192
|
|
1174
1193
|
if ($tag eq 'trak') {
|
1175
|
-
|
1194
|
+
$$et{MediaType} = ''; # init media type for this track
|
1176
1195
|
delete $$et{AssumedDataRef};
|
1177
1196
|
}
|
1178
1197
|
my $subName = $$subdir{DirName} || $$tagInfo{Name};
|
@@ -1241,10 +1260,13 @@ sub WriteQuickTime($$$)
|
|
1241
1260
|
$$et{CHANGED} = $oldChanged;
|
1242
1261
|
undef $newData;
|
1243
1262
|
}
|
1244
|
-
if ($tag eq 'trak'
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1263
|
+
if ($tag eq 'trak') {
|
1264
|
+
$$et{MediaType} = ''; # reset media type at end of track
|
1265
|
+
if ($$et{AssumedDataRef}) {
|
1266
|
+
my $grp = $$et{CUR_WRITE_GROUP} || $dirName;
|
1267
|
+
$et->Error("Can't locate data reference to update offsets for $grp");
|
1268
|
+
delete $$et{AssumedDataRef};
|
1269
|
+
}
|
1248
1270
|
}
|
1249
1271
|
$$et{CUR_WRITE_GROUP} = $oldWriteGroup;
|
1250
1272
|
SetByteOrder('MM');
|
@@ -1540,7 +1562,7 @@ sub WriteQuickTime($$$)
|
|
1540
1562
|
}
|
1541
1563
|
if ($msg) {
|
1542
1564
|
# (allow empty sample description for non-audio/video handler types, eg. 'url ', 'meta')
|
1543
|
-
if ($$et{
|
1565
|
+
if ($$et{MediaType}) {
|
1544
1566
|
my $grp = $$et{CUR_WRITE_GROUP} || $parent;
|
1545
1567
|
$et->Error("$msg for $grp");
|
1546
1568
|
return $rtnErr;
|
@@ -1593,7 +1615,16 @@ sub WriteQuickTime($$$)
|
|
1593
1615
|
}
|
1594
1616
|
$et->VPrint(0, " [deleting $delCount $dirName tag".($delCount==1 ? '' : 's')."]\n") if $delCount;
|
1595
1617
|
|
1596
|
-
|
1618
|
+
# can finally set necessary variables for creating Video/AudioKeys tags
|
1619
|
+
if ($createKeys < 0) {
|
1620
|
+
if ($avType{$$et{MediaType}}) {
|
1621
|
+
$createKeys = 1;
|
1622
|
+
($keysGrp, $keysPath) = ("$avType{$$et{MediaType}}Keys", 'MOV-Movie-Track');
|
1623
|
+
} else {
|
1624
|
+
$canCreate = 0;
|
1625
|
+
}
|
1626
|
+
}
|
1627
|
+
$createKeys &= ~0x01 unless $$addDirs{$keysGrp}; # (Keys may have been written)
|
1597
1628
|
|
1598
1629
|
# add new directories/tags at this level if necessary
|
1599
1630
|
if ($canCreate and (exists $$et{EDIT_DIRS}{$dirName} or $createKeys)) {
|
@@ -1604,13 +1635,13 @@ sub WriteQuickTime($$$)
|
|
1604
1635
|
my ($tag, $index);
|
1605
1636
|
# add Keys tags if necessary
|
1606
1637
|
if ($createKeys) {
|
1607
|
-
if ($curPath eq
|
1638
|
+
if ($curPath eq $keysPath) {
|
1608
1639
|
# add Meta for Keys if necessary
|
1609
1640
|
unless ($didDir{meta}) {
|
1610
1641
|
$$dirs{meta} = $Image::ExifTool::QuickTime::Movie{meta};
|
1611
1642
|
push @addTags, 'meta';
|
1612
1643
|
}
|
1613
|
-
} elsif ($curPath eq
|
1644
|
+
} elsif ($curPath eq "$keysPath-Meta") {
|
1614
1645
|
# special case for Keys Meta -- reset directories and start again
|
1615
1646
|
undef @addTags;
|
1616
1647
|
$dirs = { };
|
@@ -1619,10 +1650,10 @@ sub WriteQuickTime($$$)
|
|
1619
1650
|
$$dirs{$_} = $Image::ExifTool::QuickTime::Meta{$_};
|
1620
1651
|
push @addTags, $_;
|
1621
1652
|
}
|
1622
|
-
} elsif ($curPath eq
|
1623
|
-
foreach $index (sort { $a <=> $b } keys %{$$et{
|
1653
|
+
} elsif ($curPath eq "$keysPath-Meta-ItemList" and $$et{$keysGrp}) {
|
1654
|
+
foreach $index (sort { $a <=> $b } keys %{$$et{$keysGrp}{Add}}) {
|
1624
1655
|
my $id = Set32u($index);
|
1625
|
-
$$newTags{$id} = $$et{
|
1656
|
+
$$newTags{$id} = $$et{$keysGrp}{Add}{$index};
|
1626
1657
|
push @addTags, $id;
|
1627
1658
|
}
|
1628
1659
|
} else {
|
@@ -1634,8 +1665,7 @@ sub WriteQuickTime($$$)
|
|
1634
1665
|
foreach $tag (@addTags) {
|
1635
1666
|
my $tagInfo = $$dirs{$tag} || $$newTags{$tag};
|
1636
1667
|
next if defined $$tagInfo{CanCreate} and not $$tagInfo{CanCreate};
|
1637
|
-
next if defined $$tagInfo{
|
1638
|
-
(not $$et{HandlerType} or $$et{HandlerType} ne $$tagInfo{HandlerType});
|
1668
|
+
next if defined $$tagInfo{MediaType} and $$et{MediaType} ne $$tagInfo{MediaType};
|
1639
1669
|
my $subdir = $$tagInfo{SubDirectory};
|
1640
1670
|
unless ($subdir) {
|
1641
1671
|
my $nvHash = $et->GetNewValueHash($tagInfo);
|
@@ -1697,13 +1727,13 @@ sub WriteQuickTime($$$)
|
|
1697
1727
|
}
|
1698
1728
|
my $subName = $$subdir{DirName} || $$tagInfo{Name};
|
1699
1729
|
# QuickTime hierarchy is complex, so check full directory path before adding
|
1700
|
-
if ($createKeys and $curPath eq
|
1730
|
+
if ($createKeys and $curPath eq $keysPath and $subName eq 'Meta') {
|
1701
1731
|
$et->VPrint(0, " Creating Meta with mdta Handler and Keys\n");
|
1702
1732
|
# init Meta box for Keys tags with mdta Handler and empty Keys+ItemList
|
1703
1733
|
$buf2 = "\0\0\0\x20hdlr\0\0\0\0\0\0\0\0mdta\0\0\0\0\0\0\0\0\0\0\0\0" .
|
1704
1734
|
"\0\0\0\x10keys\0\0\0\0\0\0\0\0" .
|
1705
1735
|
"\0\0\0\x08ilst";
|
1706
|
-
} elsif ($createKeys and $curPath eq
|
1736
|
+
} elsif ($createKeys and $curPath eq "$keysPath-Meta") {
|
1707
1737
|
$buf2 = ($subName eq 'Keys' ? "\0\0\0\0\0\0\0\0" : '');
|
1708
1738
|
} elsif ($subName eq 'Meta' and $$et{OPTIONS}{QuickTimeHandler}) {
|
1709
1739
|
$et->VPrint(0, " Creating Meta with mdir Handler\n");
|
@@ -1752,8 +1782,8 @@ sub WriteQuickTime($$$)
|
|
1752
1782
|
}
|
1753
1783
|
}
|
1754
1784
|
# add only once (must delete _after_ call to WriteDirectory())
|
1755
|
-
# (Keys
|
1756
|
-
delete $$addDirs{$subName} unless $
|
1785
|
+
# (Keys tags are a special case, and are handled separately)
|
1786
|
+
delete $$addDirs{$subName} unless $createKeys;
|
1757
1787
|
}
|
1758
1788
|
}
|
1759
1789
|
# write HEIC metadata after top-level 'meta' box has been processed if editing this information
|
@@ -1779,9 +1809,9 @@ sub WriteQuickTime($$$)
|
|
1779
1809
|
# (could report a file if editing nothing when it contained an empty Meta atom)
|
1780
1810
|
# ++$$et{CHANGED};
|
1781
1811
|
}
|
1782
|
-
if ($curPath eq
|
1783
|
-
delete $$addDirs{
|
1784
|
-
delete $$et{
|
1812
|
+
if ($curPath eq "$keysPath-Meta") {
|
1813
|
+
delete $$addDirs{$keysGrp}; # prevent creation of another Meta for Keys tags
|
1814
|
+
delete $$et{$keysGrp};
|
1785
1815
|
}
|
1786
1816
|
}
|
1787
1817
|
|
@@ -2109,6 +2139,7 @@ sub WriteMOV($$)
|
|
2109
2139
|
$raf->Seek(0,0);
|
2110
2140
|
|
2111
2141
|
# write the file
|
2142
|
+
$$et{MediaType} = '';
|
2112
2143
|
$$dirInfo{Parent} = '';
|
2113
2144
|
$$dirInfo{DirName} = 'MOV';
|
2114
2145
|
$$dirInfo{ChunkOffset} = [ ]; # (just to be safe)
|
@@ -2134,7 +2165,7 @@ QuickTime-based file formats like MOV and MP4.
|
|
2134
2165
|
|
2135
2166
|
=head1 AUTHOR
|
2136
2167
|
|
2137
|
-
Copyright 2003-
|
2168
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
2138
2169
|
|
2139
2170
|
This library is free software; you can redistribute it and/or modify it
|
2140
2171
|
under the same terms as Perl itself.
|
@@ -372,7 +372,7 @@ Currently writes only WebP files.
|
|
372
372
|
|
373
373
|
=head1 AUTHOR
|
374
374
|
|
375
|
-
Copyright 2003-
|
375
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
376
376
|
|
377
377
|
This library is free software; you can redistribute it and/or modify it
|
378
378
|
under the same terms as Perl itself.
|
@@ -1651,7 +1651,7 @@ This file contains routines to write XMP metadata.
|
|
1651
1651
|
|
1652
1652
|
=head1 AUTHOR
|
1653
1653
|
|
1654
|
-
Copyright 2003-
|
1654
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
1655
1655
|
|
1656
1656
|
This library is free software; you can redistribute it and/or modify it
|
1657
1657
|
under the same terms as Perl itself.
|
@@ -138,11 +138,12 @@ my %rawType = (
|
|
138
138
|
# 2) any dependencies must be added to %excludeGroups
|
139
139
|
my @delGroups = qw(
|
140
140
|
Adobe AFCP APP0 APP1 APP2 APP3 APP4 APP5 APP6 APP7 APP8 APP9 APP10 APP11 APP12
|
141
|
-
APP13 APP14 APP15 CanonVRD CIFF Ducky EXIF ExifIFD File FlashPix
|
142
|
-
GlobParamIFD GPS ICC_Profile IFD0 IFD1 Insta360 InteropIFD IPTC
|
143
|
-
Jpeg2000 JUMBF Keys MakerNotes Meta MetaIFD Microsoft MIE MPF
|
144
|
-
NikonCapture PDF PDF-update PhotoMechanic Photoshop PNG
|
145
|
-
QuickTime RMETA RSRC SEAL SubIFD Trailer UserData
|
141
|
+
APP13 APP14 APP15 AudioKeys CanonVRD CIFF Ducky EXIF ExifIFD File FlashPix
|
142
|
+
FotoStation GlobParamIFD GPS ICC_Profile IFD0 IFD1 Insta360 InteropIFD IPTC
|
143
|
+
ItemList JFIF Jpeg2000 JUMBF Keys MakerNotes Meta MetaIFD Microsoft MIE MPF
|
144
|
+
Nextbase NikonApp NikonCapture PDF PDF-update PhotoMechanic Photoshop PNG
|
145
|
+
PNG-pHYs PrintIM QuickTime RMETA RSRC SEAL SubIFD Trailer UserData VideoKeys
|
146
|
+
Vivo XML XML-* XMP XMP-*
|
146
147
|
);
|
147
148
|
# family 2 group names that we can delete
|
148
149
|
my @delGroup2 = qw(
|
@@ -1297,12 +1298,13 @@ sub SetNewValuesFromFile($$;@)
|
|
1297
1298
|
foreach (qw(ByteUnit Charset CharsetEXIF CharsetFileName CharsetID3 CharsetIPTC
|
1298
1299
|
CharsetPhotoshop Composite DateFormat Debug EncodeHangs Escape ExtendedXMP
|
1299
1300
|
ExtractEmbedded FastScan Filter FixBase Geolocation GeolocAltNames
|
1300
|
-
GeolocFeature GeolocMinPop GeolocMaxDist GlobalTimeShift
|
1301
|
-
IgnoreGroups IgnoreMinorErrors IgnoreTags ImageHashType Lang
|
1302
|
-
LargeFileSupport LigoGPSScale ListItem ListSep MDItemTags
|
1303
|
-
NoPDFList NoWarning Password PrintConv QuickTimeUTC
|
1304
|
-
SavePath ScanForXMP StructFormat SystemTags
|
1305
|
-
Validate WindowsLongPath WindowsWideFile
|
1301
|
+
GeolocFeature GeolocMinPop GeolocMaxDist GlobalTimeShift GPSQuadrant
|
1302
|
+
HexTagIDs IgnoreGroups IgnoreMinorErrors IgnoreTags ImageHashType Lang
|
1303
|
+
LargeFileSupport LigoGPSScale ListItem ListSep MDItemTags
|
1304
|
+
MissingTagValue NoPDFList NoWarning Password PrintConv QuickTimeUTC
|
1305
|
+
RequestTags SaveFormat SavePath ScanForXMP StructFormat SystemTags
|
1306
|
+
TimeZone Unknown UserParam Validate WindowsLongPath WindowsWideFile
|
1307
|
+
XAttrTags XMPAutoConv))
|
1306
1308
|
{
|
1307
1309
|
$srcExifTool->Options($_ => $$options{$_});
|
1308
1310
|
}
|
@@ -2822,7 +2824,10 @@ sub GetAllGroups($;$)
|
|
2822
2824
|
|
2823
2825
|
my %allGroups;
|
2824
2826
|
# add family 1 groups not in tables
|
2825
|
-
|
2827
|
+
no warnings; # (avoid "possible attempt to put comments in qw()")
|
2828
|
+
$family == 1 and map { $allGroups{$_} = 1 } qw(Garmin AudioItemList AudioUserData
|
2829
|
+
VideoItemList VideoUserData Track#Keys Track#ItemList Track#UserData);
|
2830
|
+
use warnings;
|
2826
2831
|
# loop through all tag tables and get all group names
|
2827
2832
|
while (@tableNames) {
|
2828
2833
|
my $table = GetTagTable(pop @tableNames);
|
@@ -5228,7 +5233,7 @@ sub Set64u(@)
|
|
5228
5233
|
{
|
5229
5234
|
my $val = $_[0];
|
5230
5235
|
my $hi = int($val / 4294967296);
|
5231
|
-
my $lo = Set32u($val - $hi * 4294967296);
|
5236
|
+
my $lo = Set32u($val - $hi * 4294967296); # NOTE: subject to round-off errors!
|
5232
5237
|
$hi = Set32u($hi);
|
5233
5238
|
$val = GetByteOrder() eq 'MM' ? $hi . $lo : $lo . $hi;
|
5234
5239
|
$_[1] and substr(${$_[1]}, $_[2], length($val)) = $val;
|
@@ -6102,7 +6107,7 @@ sub WriteJPEG($$)
|
|
6102
6107
|
my $tbuf = '';
|
6103
6108
|
$raf->Seek(-length($buff), 1); # seek back to just after EOI
|
6104
6109
|
$$trailInfo{OutFile} = \$tbuf; # rewrite the trailer
|
6105
|
-
$$trailInfo{
|
6110
|
+
$$trailInfo{ScanForTrailer} = 1;# scan if necessary
|
6106
6111
|
$self->ProcessTrailers($trailInfo) or undef $trailInfo;
|
6107
6112
|
}
|
6108
6113
|
if (not $oldOutfile) {
|
@@ -6987,7 +6992,7 @@ sub SetFileTime($$;$$$$)
|
|
6987
6992
|
$mtime = $m unless defined $mtime;
|
6988
6993
|
$success = eval { utime($atime, $mtime, $file) } if defined $atime and defined $mtime;
|
6989
6994
|
}
|
6990
|
-
$self->Warn('Error
|
6995
|
+
$self->Warn('Error updating file time') unless $success;
|
6991
6996
|
return $success;
|
6992
6997
|
}
|
6993
6998
|
$saveFile = $file;
|
@@ -7376,7 +7381,7 @@ used routines.
|
|
7376
7381
|
|
7377
7382
|
=head1 AUTHOR
|
7378
7383
|
|
7379
|
-
Copyright 2003-
|
7384
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
7380
7385
|
|
7381
7386
|
This library is free software; you can redistribute it and/or modify it
|
7382
7387
|
under the same terms as Perl itself.
|
@@ -163,7 +163,7 @@ information from XISF (Extensible Image Serialization Format) images.
|
|
163
163
|
|
164
164
|
=head1 AUTHOR
|
165
165
|
|
166
|
-
Copyright 2003-
|
166
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
167
167
|
|
168
168
|
This library is free software; you can redistribute it and/or modify it
|
169
169
|
under the same terms as Perl itself.
|
@@ -4582,7 +4582,7 @@ information.
|
|
4582
4582
|
|
4583
4583
|
=head1 AUTHOR
|
4584
4584
|
|
4585
|
-
Copyright 2003-
|
4585
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
4586
4586
|
|
4587
4587
|
This library is free software; you can redistribute it and/or modify it
|
4588
4588
|
under the same terms as Perl itself.
|
@@ -2427,7 +2427,7 @@ This file contains definitions for less common XMP namespaces.
|
|
2427
2427
|
|
2428
2428
|
=head1 AUTHOR
|
2429
2429
|
|
2430
|
-
Copyright 2003-
|
2430
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
2431
2431
|
|
2432
2432
|
This library is free software; you can redistribute it and/or modify it
|
2433
2433
|
under the same terms as Perl itself.
|
@@ -944,7 +944,7 @@ information.
|
|
944
944
|
|
945
945
|
=head1 AUTHOR
|
946
946
|
|
947
|
-
Copyright 2003-
|
947
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
948
948
|
|
949
949
|
This library is free software; you can redistribute it and/or modify it
|
950
950
|
under the same terms as Perl itself.
|
@@ -840,7 +840,7 @@ Electronic Publication (EPUB), and Sketch design files (SKETCH).
|
|
840
840
|
|
841
841
|
=head1 AUTHOR
|
842
842
|
|
843
|
-
Copyright 2003-
|
843
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
844
844
|
|
845
845
|
This library is free software; you can redistribute it and/or modify it
|
846
846
|
under the same terms as Perl itself.
|
@@ -220,7 +220,7 @@ metadata from Zeiss Integrated Software RAW (ZISRAW) CZI files.
|
|
220
220
|
|
221
221
|
=head1 AUTHOR
|
222
222
|
|
223
|
-
Copyright 2003-
|
223
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
224
224
|
|
225
225
|
This library is free software; you can redistribute it and/or modify it
|
226
226
|
under the same terms as Perl itself.
|
@@ -215,7 +215,7 @@ information from Apple iWork '09 XML+ZIP files.
|
|
215
215
|
|
216
216
|
=head1 AUTHOR
|
217
217
|
|
218
|
-
Copyright 2003-
|
218
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
219
219
|
|
220
220
|
This library is free software; you can redistribute it and/or modify it
|
221
221
|
under the same terms as Perl itself.
|
data/bin/lib/Image/ExifTool.pm
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
# Revisions: Nov. 12/2003 - P. Harvey Created
|
9
9
|
# (See html/history.html for revision history)
|
10
10
|
#
|
11
|
-
# Legal: Copyright (c) 2003-
|
11
|
+
# Legal: Copyright (c) 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
12
12
|
# This library is free software; you can redistribute it and/or
|
13
13
|
# modify it under the same terms as Perl itself.
|
14
14
|
#------------------------------------------------------------------------------
|
@@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
29
29
|
%jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
|
30
30
|
%static_vars $advFmtSelf);
|
31
31
|
|
32
|
-
$VERSION = '13.
|
32
|
+
$VERSION = '13.14';
|
33
33
|
$RELEASE = '';
|
34
34
|
@ISA = qw(Exporter);
|
35
35
|
%EXPORT_TAGS = (
|
@@ -154,10 +154,10 @@ sub ReadValue($$$;$$$);
|
|
154
154
|
Matroska::StdTag MOI MXF DV Flash Flash::FLV Real::Media Real::Audio
|
155
155
|
Real::Metafile Red RIFF AIFF ASF WTV DICOM FITS XISF MIE JSON HTML XMP::SVG
|
156
156
|
Palm Palm::MOBI Palm::EXTH Torrent EXE EXE::PEVersion EXE::PEString
|
157
|
-
EXE::
|
158
|
-
VCard::VCalendar VCard::VNote RSRC Rawzor ZIP
|
159
|
-
RTF OOXML iWork ISO FLIR::AFF FLIR::FPF MacOS
|
160
|
-
FlashPix::DocTable
|
157
|
+
EXE::DebugRSDS EXE::DebugNB10 EXE::Misc EXE::MachO EXE::PEF EXE::ELF EXE::AR
|
158
|
+
EXE::CHM LNK Font VCard Text VCard::VCalendar VCard::VNote RSRC Rawzor ZIP
|
159
|
+
ZIP::GZIP ZIP::RAR ZIP::RAR5 RTF OOXML iWork ISO FLIR::AFF FLIR::FPF MacOS
|
160
|
+
MacOS::MDItem FlashPix::DocTable
|
161
161
|
);
|
162
162
|
|
163
163
|
# alphabetical list of current Lang modules
|
@@ -1126,6 +1126,7 @@ my @availableOptions = (
|
|
1126
1126
|
[ 'GeoMinSats', undef, 'geotag minimum satellites' ],
|
1127
1127
|
[ 'GeoSpeedRef', undef, 'geotag GPSSpeedRef' ],
|
1128
1128
|
[ 'GlobalTimeShift', undef, 'apply time shift to all extracted date/time values' ],
|
1129
|
+
[ 'GPSQuadrant', undef, 'quadrant for GPS if not otherwise known' ],
|
1129
1130
|
[ 'Group#', undef, 'return tags for specified groups in family #' ],
|
1130
1131
|
[ 'HexTagIDs', 0, 'use hex tag ID\'s in family 7 group names' ],
|
1131
1132
|
[ 'HtmlDump', 0, 'HTML dump (0-3, higher # = bigger limit)' ],
|
@@ -2500,6 +2501,7 @@ sub Options($$;@)
|
|
2500
2501
|
}
|
2501
2502
|
} elsif ($param =~ /^(IgnoreTags|IgnoreGroups)$/) {
|
2502
2503
|
if (defined $newVal) {
|
2504
|
+
ref $newVal eq 'HASH' and $$options{$param} = $newVal, next;
|
2503
2505
|
# parse list from delimited string if necessary
|
2504
2506
|
my @ignoreList = (ref $newVal eq 'ARRAY') ? @$newVal : ($newVal =~ /[-\w?*:#]+/g);
|
2505
2507
|
ExpandShortcuts(\@ignoreList) if $param eq 'IgnoreTags';
|
@@ -6894,6 +6896,8 @@ sub IdentifyTrailer($;$)
|
|
6894
6896
|
$type = 'Insta360';
|
6895
6897
|
} elsif ($buff =~ m(\0{6}/NIKON APP$)) {
|
6896
6898
|
$type = 'NikonApp';
|
6899
|
+
} elsif ($buff =~ /\xff{4}\x1b\*9HWfu\x84\x93\xa2\xb1$/) {
|
6900
|
+
$type = 'Vivo';
|
6897
6901
|
}
|
6898
6902
|
last;
|
6899
6903
|
}
|
@@ -6906,7 +6910,8 @@ sub IdentifyTrailer($;$)
|
|
6906
6910
|
# Inputs: 0) ExifTool object ref, 1) DirInfo ref:
|
6907
6911
|
# - requires RAF and DirName
|
6908
6912
|
# - OutFile is a scalar reference for writing
|
6909
|
-
# - scans from current file position if
|
6913
|
+
# - scans from current file position for each trailer if ScanForTrailer is set
|
6914
|
+
# (current file position is just after JPEG EOF for a JPEG image)
|
6910
6915
|
# Returns: 1 if trailer was processed or couldn't be processed (or written OK)
|
6911
6916
|
# 0 if trailer was recognized but offsets need fixing (or write error)
|
6912
6917
|
# - DirName, DirLen, DataPos, Offset, Fixup and OutFile are updated
|
@@ -6952,7 +6957,7 @@ sub ProcessTrailers($$)
|
|
6952
6957
|
# read or write this trailer
|
6953
6958
|
# (proc takes Offset as positive offset from end of trailer to end of file,
|
6954
6959
|
# and returns DataPos and DirLen, and Fixup if applicable, and updates
|
6955
|
-
# OutFile when writing)
|
6960
|
+
# OutFile when writing. Returns < 0 if we must scan for this trailer)
|
6956
6961
|
no strict 'refs';
|
6957
6962
|
my $result = &$proc($self, $dirInfo);
|
6958
6963
|
use strict 'refs';
|
@@ -7362,7 +7367,7 @@ sub ProcessJPEG($$;$)
|
|
7362
7367
|
# and scan for AFCP if necessary
|
7363
7368
|
my $fromEnd = 0;
|
7364
7369
|
if ($trailInfo) {
|
7365
|
-
$$trailInfo{
|
7370
|
+
$$trailInfo{ScanForTrailer} = 1; # scan now if necessary
|
7366
7371
|
$self->ProcessTrailers($trailInfo);
|
7367
7372
|
# save offset from end of file to start of first trailer
|
7368
7373
|
$fromEnd = $$trailInfo{Offset};
|
@@ -7562,6 +7567,19 @@ sub ProcessJPEG($$;$)
|
|
7562
7567
|
$$self{SkipData} = \@skipData if @skipData;
|
7563
7568
|
# extract the EXIF information (it is in standard TIFF format)
|
7564
7569
|
$self->ProcessTIFF(\%dirInfo) or $self->Warn('Malformed APP1 EXIF segment');
|
7570
|
+
# scan for Vivo HiddenData if necessary
|
7571
|
+
if ($$self{Make} eq 'vivo' and
|
7572
|
+
# (stored as UserComment by some models)
|
7573
|
+
not ($$self{VALUE}{UserComment} and $$self{VALUE}{UserComment} =~ /^filter:/) and
|
7574
|
+
$$dataPt =~ /(filter: .*?; \n)\0/sg)
|
7575
|
+
{
|
7576
|
+
if ($htmlDump) {
|
7577
|
+
my $n = length($1) + 1;
|
7578
|
+
$self->HDump($segPos+pos($$dataPt)-$n, $n, '[Vivo HiddenData]', undef, 0x08);
|
7579
|
+
}
|
7580
|
+
my $tbl = GetTagTable('Image::ExifTool::Vivo::Main');
|
7581
|
+
$self->HandleTag($tbl, HiddenData => $1);
|
7582
|
+
}
|
7565
7583
|
# avoid looking for preview unless necessary because it really slows
|
7566
7584
|
# us down -- only look for it if we found pointer, and preview is
|
7567
7585
|
# outside EXIF, and PreviewImage is specifically requested
|
@@ -8376,7 +8394,11 @@ sub DoProcessTIFF($$;$)
|
|
8376
8394
|
# save a copy of the EXIF data
|
8377
8395
|
my $dirStart = $$dirInfo{DirStart} || 0;
|
8378
8396
|
my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
|
8379
|
-
|
8397
|
+
if ($dirLen > 0 or not $outfile) {
|
8398
|
+
$$self{EXIF_DATA} = substr($$dataPt, $dirStart, $dirLen);
|
8399
|
+
} else {
|
8400
|
+
delete $$self{EXIF_DATA}; # create from scratch;
|
8401
|
+
}
|
8380
8402
|
$self->VerboseDir('TIFF') if $$self{OPTIONS}{Verbose} and length($$self{INDENT}) > 2;
|
8381
8403
|
} elsif ($outfile) {
|
8382
8404
|
delete $$self{EXIF_DATA}; # create from scratch
|
@@ -8535,7 +8557,7 @@ sub DoProcessTIFF($$;$)
|
|
8535
8557
|
if ($raf) {
|
8536
8558
|
my $trailInfo = IdentifyTrailer($raf);
|
8537
8559
|
if ($trailInfo) {
|
8538
|
-
$$trailInfo{
|
8560
|
+
$$trailInfo{ScanForTrailer} = 1; # scan to find AFCP if necessary
|
8539
8561
|
$self->ProcessTrailers($trailInfo);
|
8540
8562
|
}
|
8541
8563
|
# dump any other known trailer (eg. A100 RAW Data)
|
@@ -8640,7 +8662,7 @@ sub DoProcessTIFF($$;$)
|
|
8640
8662
|
last unless $trailInfo;
|
8641
8663
|
my $tbuf = '';
|
8642
8664
|
$$trailInfo{OutFile} = \$tbuf; # rewrite trailer(s)
|
8643
|
-
$$trailInfo{
|
8665
|
+
$$trailInfo{ScanForTrailer} = 1; # scan for AFCP if necessary
|
8644
8666
|
# rewrite all trailers to buffer
|
8645
8667
|
unless ($self->ProcessTrailers($trailInfo)) {
|
8646
8668
|
undef $trailInfo;
|