exiftool-vendored.pl 13.17.0 → 13.25.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/Changes +102 -7
- package/bin/MANIFEST +14 -0
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +46 -46
- package/bin/config_files/example.config +1 -1
- package/bin/exiftool +211 -121
- package/bin/lib/Image/ExifTool/Apple.pm +12 -2
- package/bin/lib/Image/ExifTool/BuildTagLookup.pm +2 -2
- package/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
- package/bin/lib/Image/ExifTool/DJI.pm +190 -29
- package/bin/lib/Image/ExifTool/DarwinCore.pm +22 -11
- package/bin/lib/Image/ExifTool/EXE.pm +2 -9
- package/bin/lib/Image/ExifTool/GM.pm +1 -1
- package/bin/lib/Image/ExifTool/GPS.pm +3 -3
- package/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- package/bin/lib/Image/ExifTool/GoPro.pm +86 -48
- package/bin/lib/Image/ExifTool/ICO.pm +2 -2
- package/bin/lib/Image/ExifTool/JPEG.pm +5 -1
- package/bin/lib/Image/ExifTool/JSON.pm +5 -1
- package/bin/lib/Image/ExifTool/Kodak.pm +3 -2
- package/bin/lib/Image/ExifTool/Nikon.pm +943 -1237
- package/bin/lib/Image/ExifTool/Olympus.pm +2 -1
- package/bin/lib/Image/ExifTool/PCAP.pm +462 -0
- package/bin/lib/Image/ExifTool/PDF.pm +10 -1
- package/bin/lib/Image/ExifTool/PLIST.pm +92 -29
- package/bin/lib/Image/ExifTool/PNG.pm +7 -1
- package/bin/lib/Image/ExifTool/Photoshop.pm +2 -2
- package/bin/lib/Image/ExifTool/Plot.pm +713 -0
- package/bin/lib/Image/ExifTool/Protobuf.pm +24 -11
- package/bin/lib/Image/ExifTool/Qualcomm.pm +78 -1
- package/bin/lib/Image/ExifTool/QuickTime.pm +347 -318
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +75 -27
- package/bin/lib/Image/ExifTool/Sony.pm +33 -14
- package/bin/lib/Image/ExifTool/TagLookup.pm +5056 -4967
- package/bin/lib/Image/ExifTool/TagNames.pod +443 -334
- package/bin/lib/Image/ExifTool/Trailer.pm +3 -3
- package/bin/lib/Image/ExifTool/Validate.pm +4 -4
- package/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
- package/bin/lib/Image/ExifTool/WriteExif.pl +9 -4
- package/bin/lib/Image/ExifTool/WritePDF.pl +1 -1
- package/bin/lib/Image/ExifTool/WriteQuickTime.pl +58 -5
- package/bin/lib/Image/ExifTool/Writer.pl +14 -13
- package/bin/lib/Image/ExifTool/XMP.pm +34 -6
- package/bin/lib/Image/ExifTool/XMP2.pl +2 -0
- package/bin/lib/Image/ExifTool.pm +63 -29
- package/bin/lib/Image/ExifTool.pod +83 -86
- package/bin/perl-Image-ExifTool.spec +45 -45
- package/bin/windows_exiftool.txt +95 -71
- package/package.json +3 -3
package/bin/exiftool
CHANGED
|
@@ -11,7 +11,9 @@ use strict;
|
|
|
11
11
|
use warnings;
|
|
12
12
|
require 5.004;
|
|
13
13
|
|
|
14
|
-
my $version = '13.
|
|
14
|
+
my $version = '13.25';
|
|
15
|
+
|
|
16
|
+
$^W = 1; # enable global warnings
|
|
15
17
|
|
|
16
18
|
# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
|
|
17
19
|
my $exePath;
|
|
@@ -52,7 +54,7 @@ sub EncodeXML($);
|
|
|
52
54
|
sub FormatXML($$$);
|
|
53
55
|
sub EscapeJSON($;$);
|
|
54
56
|
sub FormatJSON($$$;$);
|
|
55
|
-
sub PrintCSV();
|
|
57
|
+
sub PrintCSV(;$);
|
|
56
58
|
sub AddGroups($$$$);
|
|
57
59
|
sub ConvertBinary($);
|
|
58
60
|
sub IsEqual($$);
|
|
@@ -189,6 +191,7 @@ my $outFormat; # -1=Canon format, 0=same-line, 1=tag names, 2=values only
|
|
|
189
191
|
my $outOpt; # output file or directory name
|
|
190
192
|
my $overwriteOrig; # flag to overwrite original file (1=overwrite, 2=in place)
|
|
191
193
|
my $pause; # pause before returning
|
|
194
|
+
my $plot; # flag for plot output format
|
|
192
195
|
my $preserveTime; # flag to preserve times of updated files (2=preserve FileCreateDate only)
|
|
193
196
|
my $progress; # flag to calculate total files to process (0=calculate but don't display)
|
|
194
197
|
my $progressCount; # count of files processed
|
|
@@ -216,6 +219,7 @@ my $structOpt; # output structured XMP information (JSON and XML output onl
|
|
|
216
219
|
my $tabFormat; # non-zero for tab output format
|
|
217
220
|
my $tagOut; # flag for separate text output file for each tag
|
|
218
221
|
my $textOut; # extension for text output file (or undef for no output)
|
|
222
|
+
my $textOut2; # complete file name for single text output file
|
|
219
223
|
my $textOverwrite; # flag to overwrite existing text output file (2=append, 3=over+append)
|
|
220
224
|
my $tmpFile; # temporary file to delete on exit
|
|
221
225
|
my $tmpText; # temporary text file
|
|
@@ -459,8 +463,8 @@ undef %filterExt;
|
|
|
459
463
|
undef %ignore;
|
|
460
464
|
undef %outComma;
|
|
461
465
|
undef %outTrailer;
|
|
462
|
-
undef %printFmt;
|
|
463
466
|
undef %preserveTime;
|
|
467
|
+
undef %printFmt;
|
|
464
468
|
undef %seqFileDir;
|
|
465
469
|
undef %setTags;
|
|
466
470
|
undef %setTagsList;
|
|
@@ -1176,6 +1180,7 @@ for (;;) {
|
|
|
1176
1180
|
}
|
|
1177
1181
|
/^overwrite_original$/i and $overwriteOrig = 1, next;
|
|
1178
1182
|
/^overwrite_original_in_place$/i and $overwriteOrig = 2, next;
|
|
1183
|
+
/^plot$/i and require Image::ExifTool::Plot and $plot = Image::ExifTool::Plot->new, next;
|
|
1179
1184
|
if (/^p(-?)$/ or /^printformat(-?)$/i) {
|
|
1180
1185
|
my $fmt = shift;
|
|
1181
1186
|
if ($pass) {
|
|
@@ -1391,7 +1396,8 @@ for (;;) {
|
|
|
1391
1396
|
# add geotag/geosync/geolocate commands first
|
|
1392
1397
|
unshift @newValues, pop @newValues;
|
|
1393
1398
|
if (lc $2 eq 'geotag' and (not defined $addGeotime or $addGeotime) and length $val) {
|
|
1394
|
-
$addGeotime = ($1 || '') . 'Geotime<DateTimeOriginal#'
|
|
1399
|
+
$addGeotime = [ ($1 || '') . 'Geotime<DateTimeOriginal#',
|
|
1400
|
+
($1 || '') . 'Geotime<SubSecDateTimeOriginal#' ];
|
|
1395
1401
|
}
|
|
1396
1402
|
}
|
|
1397
1403
|
}
|
|
@@ -1465,15 +1471,10 @@ if (not @files and not $outOpt and not @newValues) {
|
|
|
1465
1471
|
# print help
|
|
1466
1472
|
unless ((@tags and not $outOpt) or @files or @newValues or $geoOnly) {
|
|
1467
1473
|
if ($doGlob and $doGlob == 2) {
|
|
1468
|
-
|
|
1469
|
-
$rtnVal = 1;
|
|
1470
|
-
next;
|
|
1471
|
-
}
|
|
1472
|
-
if ($outOpt) {
|
|
1473
|
-
Warn "Nothing to write\n";
|
|
1474
|
-
$rtnVal = 1;
|
|
1474
|
+
Error "No matching files\n";
|
|
1475
1475
|
next;
|
|
1476
1476
|
}
|
|
1477
|
+
$outOpt and Error("Nothing to write\n"), next;
|
|
1477
1478
|
unless ($helped) {
|
|
1478
1479
|
# catch warnings if we have problems running perldoc
|
|
1479
1480
|
local $SIG{'__WARN__'} = sub { $evalWarning = $_[0] };
|
|
@@ -1498,38 +1499,34 @@ unless ((@tags and not $outOpt) or @files or @newValues or $geoOnly) {
|
|
|
1498
1499
|
if (defined $deleteOrig and (@newValues or @tags)) {
|
|
1499
1500
|
if (not @newValues) {
|
|
1500
1501
|
my $verb = $deleteOrig ? 'deleting' : 'restoring from';
|
|
1501
|
-
|
|
1502
|
+
Error "Can't specify tags when $verb originals\n";
|
|
1502
1503
|
} elsif ($deleteOrig) {
|
|
1503
|
-
|
|
1504
|
-
|
|
1504
|
+
Error "Can't use -delete_original when writing.\n";
|
|
1505
|
+
Error "Maybe you meant -overwrite_original ?\n";
|
|
1505
1506
|
} else {
|
|
1506
|
-
|
|
1507
|
+
Error "It makes no sense to use -restore_original when writing\n";
|
|
1507
1508
|
}
|
|
1508
|
-
$rtnVal = 1;
|
|
1509
1509
|
next;
|
|
1510
1510
|
}
|
|
1511
1511
|
|
|
1512
1512
|
if ($overwriteOrig > 1 and $outOpt) {
|
|
1513
|
-
|
|
1514
|
-
$rtnVal = 1;
|
|
1513
|
+
Error "Can't overwrite in place when -o option is used\n";
|
|
1515
1514
|
next;
|
|
1516
1515
|
}
|
|
1517
1516
|
|
|
1518
|
-
if (($tagOut or defined $diff) and ($csv or $json or %printFmt or $tabFormat or $xml or
|
|
1517
|
+
if (($tagOut or defined $diff) and ($csv or $json or %printFmt or $tabFormat or $xml or $plot or
|
|
1519
1518
|
($verbose and $html)))
|
|
1520
1519
|
{
|
|
1521
1520
|
my $opt = $tagOut ? '-W' : '-diff';
|
|
1522
|
-
|
|
1523
|
-
$rtnVal = 1;
|
|
1521
|
+
Error "Sorry, $opt may not be combined with -csv, -htmlDump, -j, -p, -t or -X\n";
|
|
1524
1522
|
next;
|
|
1525
1523
|
}
|
|
1526
1524
|
|
|
1527
1525
|
if ($csv and $csv eq 'CSV' and not $isWriting) {
|
|
1528
1526
|
$json = 0; # (not compatible)
|
|
1529
1527
|
if ($textOut) {
|
|
1530
|
-
|
|
1531
|
-
$
|
|
1532
|
-
next;
|
|
1528
|
+
$textOut2 = $textOut;
|
|
1529
|
+
undef $textOut;
|
|
1533
1530
|
}
|
|
1534
1531
|
if ($binaryOutput) {
|
|
1535
1532
|
$binaryOutput = 0;
|
|
@@ -1541,6 +1538,32 @@ if ($csv and $csv eq 'CSV' and not $isWriting) {
|
|
|
1541
1538
|
}
|
|
1542
1539
|
require Image::ExifTool::XMP if $setCharset;
|
|
1543
1540
|
}
|
|
1541
|
+
if ($plot and $textOut) {
|
|
1542
|
+
$textOut2 = $textOut;
|
|
1543
|
+
undef $textOut;
|
|
1544
|
+
}
|
|
1545
|
+
if ($textOut2) {
|
|
1546
|
+
if ($textOverwrite > 1) {
|
|
1547
|
+
Error "Can not append to multi-file output format\n";
|
|
1548
|
+
undef $textOut2;
|
|
1549
|
+
next;
|
|
1550
|
+
}
|
|
1551
|
+
if (not $textOverwrite and $mt->Exists($textOut2, 1)) {
|
|
1552
|
+
Error "Output file $textOut2 already exists\n";
|
|
1553
|
+
undef $textOut2;
|
|
1554
|
+
next;
|
|
1555
|
+
}
|
|
1556
|
+
# make sure we can write the output text file before processing all input files
|
|
1557
|
+
CreateDirectory($textOut2); # create directory if necessary
|
|
1558
|
+
if ($mt->Open(\*OUTFILE, $textOut2, '>')) {
|
|
1559
|
+
close(\*OUTFILE);
|
|
1560
|
+
unlink($textOut2); # (this was just a test)
|
|
1561
|
+
} else {
|
|
1562
|
+
Error("Error creating $textOut2\n");
|
|
1563
|
+
undef $textOut2;
|
|
1564
|
+
next;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1544
1567
|
|
|
1545
1568
|
if ($escapeHTML or $json) {
|
|
1546
1569
|
# must be UTF8 for HTML conversion and JSON output
|
|
@@ -1554,7 +1577,7 @@ if ($escapeHTML or $json) {
|
|
|
1554
1577
|
# set sort option
|
|
1555
1578
|
if ($sortOpt) {
|
|
1556
1579
|
# (note that -csv sorts alphabetically by default anyway if more than 1 file)
|
|
1557
|
-
my $sort = ($outFormat > 0 or $xml or $json or $csv) ? 'Tag' : 'Descr';
|
|
1580
|
+
my $sort = ($outFormat > 0 or $xml or $json or $csv or $plot) ? 'Tag' : 'Descr';
|
|
1558
1581
|
$mt->Options(Sort => $sort, Sort2 => $sort);
|
|
1559
1582
|
}
|
|
1560
1583
|
|
|
@@ -1565,7 +1588,11 @@ if ($mt->Options('Struct') and not $structOpt) {
|
|
|
1565
1588
|
}
|
|
1566
1589
|
|
|
1567
1590
|
# set up for RDF/XML, JSON and PHP output formats
|
|
1568
|
-
if ($
|
|
1591
|
+
if ($plot) {
|
|
1592
|
+
undef $joinLists;
|
|
1593
|
+
$mt->Options(List => 1);
|
|
1594
|
+
$plot->Settings($mt->Options('Plot'));
|
|
1595
|
+
} elsif ($xml) {
|
|
1569
1596
|
require Image::ExifTool::XMP; # for EscapeXML()
|
|
1570
1597
|
my $charset = $mt->Options('Charset');
|
|
1571
1598
|
# standard XML encoding names for supported Charset settings
|
|
@@ -1637,11 +1664,10 @@ if (Image::ExifTool::IsPC()) {
|
|
|
1637
1664
|
unless (@files) {
|
|
1638
1665
|
unless ($outOpt) {
|
|
1639
1666
|
if ($doGlob and $doGlob == 2) {
|
|
1640
|
-
|
|
1667
|
+
Error "No matching files\n";
|
|
1641
1668
|
} else {
|
|
1642
|
-
|
|
1669
|
+
Error "No file specified\n";
|
|
1643
1670
|
}
|
|
1644
|
-
$rtnVal = 1;
|
|
1645
1671
|
next;
|
|
1646
1672
|
}
|
|
1647
1673
|
push @files, ''; # create file from nothing
|
|
@@ -1670,8 +1696,9 @@ if (@newValues) {
|
|
|
1670
1696
|
# assume -geotime value if -geotag specified without -geotime
|
|
1671
1697
|
if ($addGeotime) {
|
|
1672
1698
|
AddSetTagsFile($setTagsFile = '@') unless $setTagsFile and $setTagsFile eq '@';
|
|
1673
|
-
push @{$setTags{$setTagsFile}},
|
|
1674
|
-
|
|
1699
|
+
push @{$setTags{$setTagsFile}}, @$addGeotime;
|
|
1700
|
+
my @a = map qq("-$_"), @$addGeotime;
|
|
1701
|
+
$verbose and print $vout 'Arguments ',join(' and ', @a)," are assumed\n";
|
|
1675
1702
|
}
|
|
1676
1703
|
my %setTagsIndex;
|
|
1677
1704
|
# add/delete option lookup
|
|
@@ -1703,8 +1730,7 @@ if (@newValues) {
|
|
|
1703
1730
|
next; # set tags from dynamic file later
|
|
1704
1731
|
}
|
|
1705
1732
|
unless ($mt->Exists($newVal) or $newVal eq '-') {
|
|
1706
|
-
|
|
1707
|
-
$rtnVal = 1;
|
|
1733
|
+
Error "File '${newVal}' does not exist for -tagsFromFile option\n";
|
|
1708
1734
|
next Command;
|
|
1709
1735
|
}
|
|
1710
1736
|
my $setTags = $setTags{$newVal};
|
|
@@ -1768,19 +1794,20 @@ if (@newValues) {
|
|
|
1768
1794
|
}
|
|
1769
1795
|
}
|
|
1770
1796
|
unless ($isWriting or $outOpt or @tags) {
|
|
1771
|
-
|
|
1772
|
-
$rtnVal = 1;
|
|
1797
|
+
Error "Nothing to do.\n";
|
|
1773
1798
|
next;
|
|
1774
1799
|
}
|
|
1775
1800
|
} elsif (grep /^(\*:)?\*$/, @exclude) {
|
|
1776
|
-
|
|
1777
|
-
$rtnVal = 1;
|
|
1801
|
+
Error "All tags excluded -- nothing to do.\n";
|
|
1778
1802
|
next;
|
|
1779
1803
|
}
|
|
1780
1804
|
if ($isWriting) {
|
|
1781
1805
|
if (defined $diff) {
|
|
1782
1806
|
Error "Can't use -diff option when writing tags\n";
|
|
1783
1807
|
next;
|
|
1808
|
+
} elsif ($plot) {
|
|
1809
|
+
Error "Can't use -plot option when writing tags\n";
|
|
1810
|
+
next;
|
|
1784
1811
|
} elsif (@tags and not $outOpt and not $csv) {
|
|
1785
1812
|
my ($tg, $s) = @tags > 1 ? ("$tags[0] ...", 's') : ($tags[0], '');
|
|
1786
1813
|
Warn "Ignored superfluous tag name$s or invalid option$s: -$tg\n";
|
|
@@ -1929,9 +1956,6 @@ ProcessFiles($mt);
|
|
|
1929
1956
|
|
|
1930
1957
|
Error "No file with specified extension\n" if $filtered and not $validFile;
|
|
1931
1958
|
|
|
1932
|
-
# print CSV information if necessary
|
|
1933
|
-
PrintCSV() if $csv and not $isWriting;
|
|
1934
|
-
|
|
1935
1959
|
# print folder/file trailer if necessary
|
|
1936
1960
|
if ($textOut) {
|
|
1937
1961
|
foreach (keys %outTrailer) {
|
|
@@ -1947,6 +1971,37 @@ if ($textOut) {
|
|
|
1947
1971
|
} else {
|
|
1948
1972
|
print $sectTrailer if $sectTrailer;
|
|
1949
1973
|
print $fileTrailer if $fileTrailer and not $fileHeader;
|
|
1974
|
+
# print CSV or SVG output file if necessary
|
|
1975
|
+
my ($fp, $err);
|
|
1976
|
+
if ($textOut2) {
|
|
1977
|
+
if ($mt->Open(\*OUTFILE, $textOut2, '>')) {
|
|
1978
|
+
$fp = \*OUTFILE;
|
|
1979
|
+
} else {
|
|
1980
|
+
Error("Error creating $textOut2\n");
|
|
1981
|
+
$err = 1;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
unless ($err) {
|
|
1985
|
+
PrintCSV($fp) if $csv and not $isWriting;
|
|
1986
|
+
# print SVG plot
|
|
1987
|
+
if ($plot) {
|
|
1988
|
+
$plot->Draw($fp || \*STDOUT);
|
|
1989
|
+
if ($$plot{Error}) {
|
|
1990
|
+
Error("Error: $$plot{Error}\n");
|
|
1991
|
+
$err = 1;
|
|
1992
|
+
} elsif ($$plot{Warn}) {
|
|
1993
|
+
Warn("Warning: $$plot{Warn}\n");
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
if ($fp) {
|
|
1998
|
+
close($fp) or $err = 1;
|
|
1999
|
+
if ($err) {
|
|
2000
|
+
$mt->Unlink($textOut2);
|
|
2001
|
+
} else {
|
|
2002
|
+
$created{$textOut2} = 1;
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
1950
2005
|
}
|
|
1951
2006
|
|
|
1952
2007
|
my $totWr = $countGoodWr + $countBadWr + $countSameWr + $countCopyWr +
|
|
@@ -1991,7 +2046,7 @@ if (defined $deleteOrig) {
|
|
|
1991
2046
|
# print summary
|
|
1992
2047
|
my $tot = $count + $countBad;
|
|
1993
2048
|
if ($countDir or $totWr or $countFailed or $tot > 1 or $textOut or %countLink) {
|
|
1994
|
-
my $o = (($html or $json or $xml or %printFmt or $csv) and not $textOut) ? \*STDERR : $vout;
|
|
2049
|
+
my $o = (($html or $json or $xml or %printFmt or $csv or $plot) and not $textOut) ? \*STDERR : $vout;
|
|
1995
2050
|
printf($o "%5d directories scanned\n", $countDir) if $countDir;
|
|
1996
2051
|
printf($o "%5d directories created\n", $countNewDir) if $countNewDir;
|
|
1997
2052
|
printf($o "%5d files failed condition\n", $countFailed) if $countFailed;
|
|
@@ -2003,7 +2058,7 @@ if (defined $deleteOrig) {
|
|
|
2003
2058
|
printf($o "%5d files weren't created due to errors\n", $countBadCr) if $countBadCr;
|
|
2004
2059
|
printf($o "%5d image files read\n", $count) if ($tot+$countFailed)>1 or ($countDir and not $totWr);
|
|
2005
2060
|
printf($o "%5d files could not be read\n", $countBad) if $countBad;
|
|
2006
|
-
printf($o "%5d output files created\n", scalar(keys %created)) if $textOut;
|
|
2061
|
+
printf($o "%5d output files created\n", scalar(keys %created)) if $textOut or $textOut2;
|
|
2007
2062
|
printf($o "%5d output files appended\n", scalar(keys %appended)) if %appended;
|
|
2008
2063
|
printf($o "%5d hard links created\n", $countLink{Hard} || 0) if $countLink{Hard} or $countLink{BadHard};
|
|
2009
2064
|
printf($o "%5d hard links could not be created\n", $countLink{BadHard}) if $countLink{BadHard};
|
|
@@ -2208,7 +2263,7 @@ sub GetImageInfo($$)
|
|
|
2208
2263
|
|
|
2209
2264
|
my $lineCount = 0;
|
|
2210
2265
|
my ($fp, $outfile, $append);
|
|
2211
|
-
if ($textOut and ($verbose or $et->Options('PrintCSV')) and not ($tagOut or defined $diff)) {
|
|
2266
|
+
if ($textOut and ($verbose or $et->Options('PrintCSV')) and not ($tagOut or defined $diff or $plot)) {
|
|
2212
2267
|
($fp, $outfile, $append) = OpenOutputFile($orig);
|
|
2213
2268
|
$fp or EFile($file), ++$countBad, return;
|
|
2214
2269
|
# delete file if we exit prematurely (unless appending)
|
|
@@ -2248,7 +2303,7 @@ sub GetImageInfo($$)
|
|
|
2248
2303
|
}
|
|
2249
2304
|
# print file/progress message
|
|
2250
2305
|
my $o;
|
|
2251
|
-
unless ($binaryOutput or $textOut or %printFmt or $html > 1 or $csv) {
|
|
2306
|
+
unless ($binaryOutput or $textOut or %printFmt or $html > 1 or $csv or $plot) {
|
|
2252
2307
|
if ($html) {
|
|
2253
2308
|
require Image::ExifTool::HTML;
|
|
2254
2309
|
my $f = Image::ExifTool::HTML::EscapeHTML($file);
|
|
@@ -2351,7 +2406,7 @@ sub GetImageInfo($$)
|
|
|
2351
2406
|
unless (defined $outfile or $tagOut) {
|
|
2352
2407
|
($fp, $outfile, $append) = OpenOutputFile($orig);
|
|
2353
2408
|
$fp or EFile($file), ++$countBad, return;
|
|
2354
|
-
$tmpText = $outfile
|
|
2409
|
+
$tmpText = $outfile if defined $outfile and not $append;
|
|
2355
2410
|
}
|
|
2356
2411
|
|
|
2357
2412
|
# print differences if requested
|
|
@@ -2462,9 +2517,8 @@ T2: foreach $t2 (@tags2) {
|
|
|
2462
2517
|
$done2{$tag2} = 1 if defined $tag2;
|
|
2463
2518
|
}
|
|
2464
2519
|
print $fp "(no metadata differences)\n" unless $wasDiff;
|
|
2465
|
-
undef $tmpText;
|
|
2466
2520
|
if (defined $outfile) {
|
|
2467
|
-
|
|
2521
|
+
$created{$outfile} = 1;
|
|
2468
2522
|
close($fp);
|
|
2469
2523
|
undef $tmpText;
|
|
2470
2524
|
}
|
|
@@ -2539,6 +2593,17 @@ T2: foreach $t2 (@tags2) {
|
|
|
2539
2593
|
delete $printFmt{HEAD} unless defined $outfile; # print header only once per output file
|
|
2540
2594
|
my $errs = $et->GetInfo('Warning', 'Error');
|
|
2541
2595
|
PrintErrors($et, $errs, $file) and EFile($file);
|
|
2596
|
+
} elsif ($plot) {
|
|
2597
|
+
# add points from this file to the plot
|
|
2598
|
+
my $tagExtra = $$et{TAG_EXTRA};
|
|
2599
|
+
my ($tag, %docNum);
|
|
2600
|
+
foreach $tag (keys %$info) {
|
|
2601
|
+
next unless $$tagExtra{$tag} and $$tagExtra{$tag}{G3};
|
|
2602
|
+
$docNum{$tag} = $1 if $$tagExtra{$tag}{G3} =~ /(\d+)/;
|
|
2603
|
+
}
|
|
2604
|
+
$$plot{DocNum} = \%docNum;
|
|
2605
|
+
$$plot{EE} = 1 if $et->Options('ExtractEmbedded');
|
|
2606
|
+
$plot->AddPoints($info, \@foundTags);
|
|
2542
2607
|
} elsif (not $disableOutput) {
|
|
2543
2608
|
my ($tag, $line, %noDups, %csvInfo, $bra, $ket, $sep, $quote);
|
|
2544
2609
|
if ($fp) {
|
|
@@ -3771,8 +3836,10 @@ sub FormatCSV($)
|
|
|
3771
3836
|
|
|
3772
3837
|
#------------------------------------------------------------------------------
|
|
3773
3838
|
# Print accumulated CSV information
|
|
3774
|
-
|
|
3839
|
+
# Inputs: 0) file ref
|
|
3840
|
+
sub PrintCSV(;$)
|
|
3775
3841
|
{
|
|
3842
|
+
my $fp = shift || \*STDOUT;
|
|
3776
3843
|
my ($file, $lcTag, @tags);
|
|
3777
3844
|
|
|
3778
3845
|
@csvTags or @csvTags = sort keys %csvTags;
|
|
@@ -3780,7 +3847,7 @@ sub PrintCSV()
|
|
|
3780
3847
|
foreach $lcTag (@csvTags) {
|
|
3781
3848
|
push @tags, FormatCSV($csvTags{$lcTag}) if $csvTags{$lcTag};
|
|
3782
3849
|
}
|
|
3783
|
-
print join($csvDelim, 'SourceFile', @tags), "\n";
|
|
3850
|
+
print $fp join($csvDelim, 'SourceFile', @tags), "\n";
|
|
3784
3851
|
my $empty = defined($forcePrint) ? $forcePrint : '';
|
|
3785
3852
|
foreach $file (@csvFiles) {
|
|
3786
3853
|
my @vals = (FormatCSV($file)); # start with full file name
|
|
@@ -3791,7 +3858,7 @@ sub PrintCSV()
|
|
|
3791
3858
|
defined $val or push(@vals,$empty), next;
|
|
3792
3859
|
push @vals, FormatCSV($val);
|
|
3793
3860
|
}
|
|
3794
|
-
print join($csvDelim, @vals), "\n";
|
|
3861
|
+
print $fp join($csvDelim, @vals), "\n";
|
|
3795
3862
|
}
|
|
3796
3863
|
}
|
|
3797
3864
|
|
|
@@ -4125,9 +4192,8 @@ sub ProcessFiles($;$)
|
|
|
4125
4192
|
$filtered = 1;
|
|
4126
4193
|
Progress($vout, "-------- $file (wrong extension)") if $verbose;
|
|
4127
4194
|
} else {
|
|
4128
|
-
|
|
4195
|
+
Error "Error: File not found - $file\n";
|
|
4129
4196
|
FileNotFound($file);
|
|
4130
|
-
$rtnVal = 1;
|
|
4131
4197
|
}
|
|
4132
4198
|
} else {
|
|
4133
4199
|
$validFile = 1;
|
|
@@ -4886,7 +4952,7 @@ sub PrintTagList($@)
|
|
|
4886
4952
|
my $msg = shift;
|
|
4887
4953
|
print $msg, ":\n" unless $quiet;
|
|
4888
4954
|
my $tag;
|
|
4889
|
-
if ($outFormat < 0 and $msg =~ /file extensions$/ and @_) {
|
|
4955
|
+
if (($outFormat < 0 or $verbose) and $msg =~ /file extensions$/ and @_) {
|
|
4890
4956
|
foreach $tag (@_) {
|
|
4891
4957
|
printf(" %-11s %s\n", $tag, GetFileType($tag, 1));
|
|
4892
4958
|
}
|
|
@@ -4989,50 +5055,50 @@ supported by ExifTool (r = read, w = write, c = create):
|
|
|
4989
5055
|
|
|
4990
5056
|
File Types
|
|
4991
5057
|
------------+-------------+-------------+-------------+------------
|
|
4992
|
-
360 r/w | DOCX r | ITC r | NUMBERS r |
|
|
4993
|
-
3FR r | DPX r | J2C r | NXD r |
|
|
4994
|
-
3G2 r/w | DR4 r/w/c | JNG r/w | O r |
|
|
4995
|
-
3GP r/w | DSS r | JP2 r/w | ODP r |
|
|
4996
|
-
7Z r | DV r | JPEG r/w | ODS r |
|
|
4997
|
-
A r | DVB r/w | JSON r | ODT r |
|
|
4998
|
-
AA r | DVR-MS r | JXL r/w | OFR r |
|
|
4999
|
-
AAC r | DYLIB r | K25 r | OGG r |
|
|
5000
|
-
AAE r | EIP r | KDC r | OGV r |
|
|
5001
|
-
AAX r/w | EPS r/w | KEY r | ONP r |
|
|
5002
|
-
ACR r | EPUB r | LA r | OPUS r |
|
|
5003
|
-
AFM r | ERF r/w | LFP r | ORF r/w |
|
|
5004
|
-
AI r/w | EXE r | LIF r | ORI r/w |
|
|
5005
|
-
AIFF r | EXIF r/w/c | LNK r | OTF r |
|
|
5006
|
-
APE r | EXR r | LRV r/w | PAC r |
|
|
5007
|
-
ARQ r/w | EXV r/w/c | M2TS r | PAGES r |
|
|
5008
|
-
ARW r/w | F4A/V r/w | M4A/V r/w | PBM r/w |
|
|
5009
|
-
ASF r | FFF r/w | MACOS r |
|
|
5010
|
-
AVI r | FITS r | MAX r |
|
|
5011
|
-
AVIF r/w | FLA r | MEF r/w |
|
|
5012
|
-
AZW r | FLAC r | MIE r/w/c |
|
|
5013
|
-
BMP r | FLIF r/w | MIFF r |
|
|
5014
|
-
BPG r | FLV r | MKA r |
|
|
5015
|
-
BTF r | FPF r | MKS r |
|
|
5016
|
-
C2PA r | FPX r | MKV r |
|
|
5017
|
-
CHM r | GIF r/w | MNG r/w |
|
|
5018
|
-
COS r | GLV r/w | MOBI r |
|
|
5019
|
-
CR2 r/w | GPR r/w | MODD r |
|
|
5020
|
-
CR3 r/w | GZ r | MOI r |
|
|
5021
|
-
CRM r/w | HDP r/w | MOS r/w |
|
|
5022
|
-
CRW r/w | HDR r | MOV r/w |
|
|
5023
|
-
CS1 r/w | HEIC r/w | MP3 r |
|
|
5024
|
-
CSV r | HEIF r/w | MP4 r/w |
|
|
5025
|
-
CUR r | HTML r | MPC r |
|
|
5026
|
-
CZI r | ICC r/w/c | MPG r |
|
|
5027
|
-
DCM r | ICO r | MPO r/w |
|
|
5028
|
-
DCP r/w | ICS r | MQV r/w |
|
|
5029
|
-
DCR r | IDML r | MRC r |
|
|
5030
|
-
DFONT r | IIQ r/w | MRW r/w |
|
|
5031
|
-
DIVX r | IND r/w | MXF r |
|
|
5032
|
-
DJVU r | INSP r/w | NEF r/w |
|
|
5033
|
-
DLL r | INSV r | NKA r |
|
|
5034
|
-
DNG r/w | INX r | NKSC r/w |
|
|
5035
|
-
DOC r | ISO r | NRW r/w |
|
|
5058
|
+
360 r/w | DOCX r | ITC r | NUMBERS r | RAM r
|
|
5059
|
+
3FR r | DPX r | J2C r | NXD r | RAR r
|
|
5060
|
+
3G2 r/w | DR4 r/w/c | JNG r/w | O r | RAW r/w
|
|
5061
|
+
3GP r/w | DSS r | JP2 r/w | ODP r | RIFF r
|
|
5062
|
+
7Z r | DV r | JPEG r/w | ODS r | RSRC r
|
|
5063
|
+
A r | DVB r/w | JSON r | ODT r | RTF r
|
|
5064
|
+
AA r | DVR-MS r | JXL r/w | OFR r | RW2 r/w
|
|
5065
|
+
AAC r | DYLIB r | K25 r | OGG r | RWL r/w
|
|
5066
|
+
AAE r | EIP r | KDC r | OGV r | RWZ r
|
|
5067
|
+
AAX r/w | EPS r/w | KEY r | ONP r | RM r
|
|
5068
|
+
ACR r | EPUB r | LA r | OPUS r | SEQ r
|
|
5069
|
+
AFM r | ERF r/w | LFP r | ORF r/w | SKETCH r
|
|
5070
|
+
AI r/w | EXE r | LIF r | ORI r/w | SO r
|
|
5071
|
+
AIFF r | EXIF r/w/c | LNK r | OTF r | SR2 r/w
|
|
5072
|
+
APE r | EXR r | LRV r/w | PAC r | SRF r
|
|
5073
|
+
ARQ r/w | EXV r/w/c | M2TS r | PAGES r | SRW r/w
|
|
5074
|
+
ARW r/w | F4A/V r/w | M4A/V r/w | PBM r/w | SVG r
|
|
5075
|
+
ASF r | FFF r/w | MACOS r | PCAP r | SWF r
|
|
5076
|
+
AVI r | FITS r | MAX r | PCAPNG r | THM r/w
|
|
5077
|
+
AVIF r/w | FLA r | MEF r/w | PCD r | TIFF r/w
|
|
5078
|
+
AZW r | FLAC r | MIE r/w/c | PCX r | TORRENT r
|
|
5079
|
+
BMP r | FLIF r/w | MIFF r | PDB r | TTC r
|
|
5080
|
+
BPG r | FLV r | MKA r | PDF r/w | TTF r
|
|
5081
|
+
BTF r | FPF r | MKS r | PEF r/w | TXT r
|
|
5082
|
+
C2PA r | FPX r | MKV r | PFA r | VCF r
|
|
5083
|
+
CHM r | GIF r/w | MNG r/w | PFB r | VNT r
|
|
5084
|
+
COS r | GLV r/w | MOBI r | PFM r | VRD r/w/c
|
|
5085
|
+
CR2 r/w | GPR r/w | MODD r | PGF r | VSD r
|
|
5086
|
+
CR3 r/w | GZ r | MOI r | PGM r/w | WAV r
|
|
5087
|
+
CRM r/w | HDP r/w | MOS r/w | PLIST r | WDP r/w
|
|
5088
|
+
CRW r/w | HDR r | MOV r/w | PICT r | WEBP r/w
|
|
5089
|
+
CS1 r/w | HEIC r/w | MP3 r | PMP r | WEBM r
|
|
5090
|
+
CSV r | HEIF r/w | MP4 r/w | PNG r/w | WMA r
|
|
5091
|
+
CUR r | HTML r | MPC r | PPM r/w | WMV r
|
|
5092
|
+
CZI r | ICC r/w/c | MPG r | PPT r | WPG r
|
|
5093
|
+
DCM r | ICO r | MPO r/w | PPTX r | WTV r
|
|
5094
|
+
DCP r/w | ICS r | MQV r/w | PS r/w | WV r
|
|
5095
|
+
DCR r | IDML r | MRC r | PSB r/w | X3F r/w
|
|
5096
|
+
DFONT r | IIQ r/w | MRW r/w | PSD r/w | XCF r
|
|
5097
|
+
DIVX r | IND r/w | MXF r | PSP r | XISF r
|
|
5098
|
+
DJVU r | INSP r/w | NEF r/w | QTIF r/w | XLS r
|
|
5099
|
+
DLL r | INSV r | NKA r | R3D r | XLSX r
|
|
5100
|
+
DNG r/w | INX r | NKSC r/w | RA r | XMP r/w/c
|
|
5101
|
+
DOC r | ISO r | NRW r/w | RAF r/w | ZIP r
|
|
5036
5102
|
|
|
5037
5103
|
Meta Information
|
|
5038
5104
|
----------------------+----------------------+---------------------
|
|
@@ -5100,6 +5166,7 @@ L<Input-output text formatting|/Input-output text formatting>
|
|
|
5100
5166
|
-n (--printConv) No print conversion
|
|
5101
5167
|
-p[-] STR (-printFormat) Print output in specified format
|
|
5102
5168
|
-php Export tags as a PHP Array
|
|
5169
|
+
-plot Output tags as SVG plot file
|
|
5103
5170
|
-s[NUM] (-short) Short output format (-s for tag names)
|
|
5104
5171
|
-S (-veryShort) Very short output format
|
|
5105
5172
|
-sep STR (-separator) Set separator string for list items
|
|
@@ -5678,14 +5745,16 @@ option may be used to split them back into separate items when importing.
|
|
|
5678
5745
|
Special feature: B<-csv>+=I<CSVFILE> may be used to add items to existing
|
|
5679
5746
|
lists. This affects only list-type tags. Also applies to the B<-j> option.
|
|
5680
5747
|
|
|
5681
|
-
Note that this
|
|
5682
|
-
format options because
|
|
5683
|
-
buffered in memory before the output is written. This may
|
|
5684
|
-
excessive memory usage when processing a very large number of
|
|
5685
|
-
single command. Also,
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5748
|
+
Note that this and the B<-plot> options are fundamentally different than all
|
|
5749
|
+
other output format options because they require information from all input
|
|
5750
|
+
files to be buffered in memory before the output is written. This may
|
|
5751
|
+
result in excessive memory usage when processing a very large number of
|
|
5752
|
+
files with a single command. Also, when used with B<-csv>, the B<-w> option
|
|
5753
|
+
changes to specify a complete file name with no filename formatting codes or
|
|
5754
|
+
append mode allowed, and B<-W> may not be used. When processing a large
|
|
5755
|
+
number of files, it is recommended to either use the JSON (B<-j>) or XML
|
|
5756
|
+
(B<-X>) output format, or use B<-p> to generate a fixed-column CSV file
|
|
5757
|
+
instead of using the B<-csv> option.
|
|
5689
5758
|
|
|
5690
5759
|
=item B<-csvDelim> I<STR>
|
|
5691
5760
|
|
|
@@ -5984,7 +6053,7 @@ with this command:
|
|
|
5984
6053
|
|
|
5985
6054
|
produces output like this:
|
|
5986
6055
|
|
|
5987
|
-
-- Generated by ExifTool 13.
|
|
6056
|
+
-- Generated by ExifTool 13.25 --
|
|
5988
6057
|
File: a.jpg - 2003:10:31 15:44:19
|
|
5989
6058
|
(f/5.6, 1/60s, ISO 100)
|
|
5990
6059
|
File: b.jpg - 2006:05:23 11:57:38
|
|
@@ -6033,6 +6102,21 @@ showing how this could be used in a PHP script:
|
|
|
6033
6102
|
print_r($array);
|
|
6034
6103
|
?>
|
|
6035
6104
|
|
|
6105
|
+
=item B<-plot>
|
|
6106
|
+
|
|
6107
|
+
Write output for all specified tags and all input files as a single
|
|
6108
|
+
SVG-formatted plot. When combined with this feature, the B<-w> option
|
|
6109
|
+
argument is a complete file name with no format codes and the append feature
|
|
6110
|
+
may not be used. Each tag specified on the command line represents a
|
|
6111
|
+
dataset in the plot (or more for array values or if the Split plot setting
|
|
6112
|
+
is used). Non-numerical values are ignored. Each input file may contribute
|
|
6113
|
+
multiple points to a dataset if it contains sub-documents and the B<-ee>
|
|
6114
|
+
option is used, or if the tag value is a delimited string of numbers (valid
|
|
6115
|
+
delimiters are: space, comma, semicolon, tab and newline). Line, Scatter
|
|
6116
|
+
and Histogram plot types are available. See the API Plot Option and
|
|
6117
|
+
L<https://exiftool.org/plot.html> for more details and information about the
|
|
6118
|
+
plot settings.
|
|
6119
|
+
|
|
6036
6120
|
=item B<-s>[I<NUM>] (B<-short>)
|
|
6037
6121
|
|
|
6038
6122
|
Short output format. Prints tag names instead of descriptions. Add I<NUM>
|
|
@@ -6170,6 +6254,10 @@ ways to create a single output file from multiple source files:
|
|
|
6170
6254
|
# 3. With the -W option (see the -W option below)
|
|
6171
6255
|
exiftool -W+! out.txt FILE1 FILE2 ...
|
|
6172
6256
|
|
|
6257
|
+
3) The B<-w> option changes when used with a multi-file output format
|
|
6258
|
+
(B<-csv> or B<-plot>). With these, the argument of B<-w> is a complete file
|
|
6259
|
+
name with no formatting codes, and the append feature may not be used.
|
|
6260
|
+
|
|
6173
6261
|
Advanced features:
|
|
6174
6262
|
|
|
6175
6263
|
A substring of the original file name, directory or extension may be taken
|
|
@@ -6458,13 +6546,13 @@ across directory boundaries if multiple input directories are specified.
|
|
|
6458
6546
|
=item B<-i> I<DIR> (B<-ignore>)
|
|
6459
6547
|
|
|
6460
6548
|
Ignore specified directory name. I<DIR> may be either an individual folder
|
|
6461
|
-
name, or a full path. If a full path is specified,
|
|
6462
|
-
Directory tag exactly to be ignored. Use multiple B<-i>
|
|
6463
|
-
more than one directory name. A special I<DIR> value of
|
|
6464
|
-
|
|
6549
|
+
name, or a full path, and is case sensitive. If a full path is specified,
|
|
6550
|
+
it must match the Directory tag exactly to be ignored. Use multiple B<-i>
|
|
6551
|
+
options to ignore more than one directory name. A special I<DIR> value of
|
|
6552
|
+
C<SYMLINKS> may be specified to avoid recursing into directories which are
|
|
6465
6553
|
symbolic links when the B<-r> option is used. As well, a value of C<HIDDEN>
|
|
6466
|
-
|
|
6467
|
-
|
|
6554
|
+
may be used to ignore files with names that start with a "." (ie. hidden
|
|
6555
|
+
files on Unix systems) when scanning a directory.
|
|
6468
6556
|
|
|
6469
6557
|
=item B<-if>[I<NUM>] I<EXPR>
|
|
6470
6558
|
|
|
@@ -6771,12 +6859,12 @@ B<-listw> and B<-listx> options may be followed by an additional argument of
|
|
|
6771
6859
|
the form C<-GROUP:All> to list only tags in a specific group, where C<GROUP>
|
|
6772
6860
|
is one or more family 0-2 group names (excepting EXIF IFD groups) separated
|
|
6773
6861
|
by colons. With B<-listg>, I<NUM> may be given to specify the group family,
|
|
6774
|
-
otherwise family 0 is assumed. The B<-l> option may be combined
|
|
6775
|
-
B<-listf>, B<-listr> or B<-listwf> to add file descriptions to the
|
|
6776
|
-
The B<-lang> option may be combined with B<-listx> to output
|
|
6777
|
-
a single language, and the B<-sort> and/or B<-lang> options
|
|
6778
|
-
with B<-listgeo>. Also, the API GeolocMinPop, GeolocFeature
|
|
6779
|
-
GeolocAltNames options apply to the B<-listgeo> output. Here are some
|
|
6862
|
+
otherwise family 0 is assumed. The B<-l> or B<-v> option may be combined
|
|
6863
|
+
with B<-listf>, B<-listr> or B<-listwf> to add file descriptions to the
|
|
6864
|
+
list. The B<-lang> option may be combined with B<-listx> to output
|
|
6865
|
+
descriptions in a single language, and the B<-sort> and/or B<-lang> options
|
|
6866
|
+
may be combined with B<-listgeo>. Also, the API GeolocMinPop, GeolocFeature
|
|
6867
|
+
and GeolocAltNames options apply to the B<-listgeo> output. Here are some
|
|
6780
6868
|
examples:
|
|
6781
6869
|
|
|
6782
6870
|
-list # list all tag names
|
|
@@ -7808,8 +7896,9 @@ the B<-geotag> option.)
|
|
|
7808
7896
|
|
|
7809
7897
|
Geotag an image (C<a.jpg>) from position information in a GPS track log
|
|
7810
7898
|
(C<track.log>). Since the C<Geotime> tag is not specified, the value of
|
|
7811
|
-
DateTimeOriginal is used for
|
|
7812
|
-
unless
|
|
7899
|
+
SubSecDateTimeOriginal (preferentially) or DateTimeOriginal is used for
|
|
7900
|
+
geotagging. Local system time is assumed unless the time contains a
|
|
7901
|
+
timezone.
|
|
7813
7902
|
|
|
7814
7903
|
=item C<exiftool -geotag track.log -geolocate=geotag a.jpg>
|
|
7815
7904
|
|
|
@@ -7854,7 +7943,8 @@ Delete XMP GPS tags which were added by the geotag feature.
|
|
|
7854
7943
|
|
|
7855
7944
|
=item C<exiftool -xmp:geotag=track.log a.jpg>
|
|
7856
7945
|
|
|
7857
|
-
Geotag an image with XMP tags, using the time from
|
|
7946
|
+
Geotag an image with XMP tags, using the time from SubSecDateTimeOriginal or
|
|
7947
|
+
DateTimeOriginal.
|
|
7858
7948
|
|
|
7859
7949
|
=item C<exiftool -geotag a.log -geotag b.log -r dir>
|
|
7860
7950
|
|
|
@@ -16,7 +16,7 @@ use vars qw($VERSION);
|
|
|
16
16
|
use Image::ExifTool::Exif;
|
|
17
17
|
use Image::ExifTool::PLIST;
|
|
18
18
|
|
|
19
|
-
$VERSION = '1.
|
|
19
|
+
$VERSION = '1.15';
|
|
20
20
|
|
|
21
21
|
sub ConvertPLIST($$);
|
|
22
22
|
|
|
@@ -307,7 +307,17 @@ sub ConvertPLIST($$);
|
|
|
307
307
|
Name => 'Apple_0x004f',
|
|
308
308
|
Unknown => 1,
|
|
309
309
|
ValueConv => \&ConvertPLIST,
|
|
310
|
-
}
|
|
310
|
+
},
|
|
311
|
+
0x0054 => {
|
|
312
|
+
Name => 'Apple_0x0054',
|
|
313
|
+
Unknown => 1,
|
|
314
|
+
ValueConv => \&ConvertPLIST,
|
|
315
|
+
},
|
|
316
|
+
0x005a => {
|
|
317
|
+
Name => 'Apple_0x005a',
|
|
318
|
+
Unknown => 1,
|
|
319
|
+
ValueConv => \&ConvertPLIST,
|
|
320
|
+
},
|
|
311
321
|
);
|
|
312
322
|
|
|
313
323
|
# PLIST-format CMTime structure (ref PH)
|