exiftool_vendored 13.06.0 → 13.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/Changes +55 -4
- data/bin/MANIFEST +1 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/exiftool +29 -15
- data/bin/lib/Image/ExifTool/AIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/APE.pm +1 -1
- data/bin/lib/Image/ExifTool/ASF.pm +1 -1
- data/bin/lib/Image/ExifTool/Apple.pm +9 -7
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +12 -3
- data/bin/lib/Image/ExifTool/Canon.pm +19 -1
- data/bin/lib/Image/ExifTool/DJI.pm +1 -1
- data/bin/lib/Image/ExifTool/Exif.pm +2 -2
- data/bin/lib/Image/ExifTool/FITS.pm +2 -2
- data/bin/lib/Image/ExifTool/FLIF.pm +2 -2
- data/bin/lib/Image/ExifTool/FlashPix.pm +11 -11
- data/bin/lib/Image/ExifTool/Font.pm +1 -1
- data/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- data/bin/lib/Image/ExifTool/HP.pm +1 -1
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +80 -1
- data/bin/lib/Image/ExifTool/ID3.pm +3 -3
- data/bin/lib/Image/ExifTool/IPTC.pm +2 -2
- data/bin/lib/Image/ExifTool/InDesign.pm +1 -1
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +8 -7
- data/bin/lib/Image/ExifTool/M2TS.pm +39 -9
- data/bin/lib/Image/ExifTool/MXF.pm +2 -2
- data/bin/lib/Image/ExifTool/Matroska.pm +1 -1
- data/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
- data/bin/lib/Image/ExifTool/PDF.pm +15 -15
- data/bin/lib/Image/ExifTool/PLIST.pm +3 -3
- data/bin/lib/Image/ExifTool/PNG.pm +6 -5
- data/bin/lib/Image/ExifTool/Panasonic.pm +1 -1
- data/bin/lib/Image/ExifTool/PhaseOne.pm +3 -3
- data/bin/lib/Image/ExifTool/Photoshop.pm +64 -3
- data/bin/lib/Image/ExifTool/Protobuf.pm +4 -4
- data/bin/lib/Image/ExifTool/QuickTime.pm +72 -24
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +336 -91
- data/bin/lib/Image/ExifTool/README +4 -1
- data/bin/lib/Image/ExifTool/RIFF.pm +3 -3
- data/bin/lib/Image/ExifTool/RTF.pm +1 -1
- data/bin/lib/Image/ExifTool/Ricoh.pm +3 -3
- data/bin/lib/Image/ExifTool/Sony.pm +2 -2
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +4 -3
- data/bin/lib/Image/ExifTool/TagLookup.pm +6982 -6970
- data/bin/lib/Image/ExifTool/TagNames.pod +48 -5
- data/bin/lib/Image/ExifTool/VCard.pm +2 -2
- data/bin/lib/Image/ExifTool/Validate.pm +3 -3
- data/bin/lib/Image/ExifTool/WriteExif.pl +2 -2
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +47 -13
- data/bin/lib/Image/ExifTool/WriteXMP.pl +2 -2
- data/bin/lib/Image/ExifTool/Writer.pl +32 -21
- data/bin/lib/Image/ExifTool/XMP.pm +9 -9
- data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
- data/bin/lib/Image/ExifTool.pm +65 -61
- data/bin/lib/Image/ExifTool.pod +41 -35
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
@@ -12,7 +12,7 @@ meta information extracted from or written to a file.
|
|
12
12
|
=head1 TAG TABLES
|
13
13
|
|
14
14
|
The tables listed below give the names of all tags recognized by ExifTool.
|
15
|
-
They contain a total of
|
15
|
+
They contain a total of 28224 tags, with 17515 unique tag names.
|
16
16
|
|
17
17
|
B<Tag ID>, B<Index#> or B<Sequence> is given in the first column of each
|
18
18
|
table. A B<Tag ID> is the computer-readable equivalent of a tag name, and
|
@@ -8643,6 +8643,7 @@ specification.
|
|
8643
8643
|
'cept' ColorEncodingParams no
|
8644
8644
|
'chad' ChromaticAdaptation no
|
8645
8645
|
'chrm' Chromaticity ICC_Profile Chromaticity
|
8646
|
+
'cicp' ColorRepresentation ICC_Profile ColorRep
|
8646
8647
|
'ciis' ColorimetricIntentImageState no
|
8647
8648
|
'clio' ColorantInfoOut no
|
8648
8649
|
'cloo' ColorantOrderOut no
|
@@ -8681,6 +8682,7 @@ specification.
|
|
8681
8682
|
'gdb1' GamutBoundaryDescription1 no
|
8682
8683
|
'gdb2' GamutBoundaryDescription2 no
|
8683
8684
|
'gdb3' GamutBoundaryDescription3 no
|
8685
|
+
'hdgm' HDGainMapInfo no
|
8684
8686
|
'kTRC' GrayTRC no
|
8685
8687
|
'lumi' Luminance no
|
8686
8688
|
'mcta' MultiplexTypeArray no
|
@@ -8762,6 +8764,15 @@ specification.
|
|
8762
8764
|
28 ChromaticityChannel3 no
|
8763
8765
|
36 ChromaticityChannel4 no
|
8764
8766
|
|
8767
|
+
=head3 ICC_Profile ColorRep Tags
|
8768
|
+
|
8769
|
+
Index1 Tag Name Writable
|
8770
|
+
------ -------- --------
|
8771
|
+
8 ColorPrimaries no
|
8772
|
+
9 TransferCharacteristics no
|
8773
|
+
10 MatrixCoefficients no
|
8774
|
+
11 VideoFullRangeFlag no
|
8775
|
+
|
8765
8776
|
=head3 ICC_Profile ColorantTable Tags
|
8766
8777
|
|
8767
8778
|
Index1 Tag Name Writable
|
@@ -8903,7 +8914,7 @@ access to this information.
|
|
8903
8914
|
0x0432 MeasurementScale? no
|
8904
8915
|
0x0433 TimelineInfo? no
|
8905
8916
|
0x0434 SheetDisclosure? no
|
8906
|
-
0x0435 ChannelOptions
|
8917
|
+
0x0435 ChannelOptions Photoshop ChannelOptions
|
8907
8918
|
0x0436 OnionSkins? no
|
8908
8919
|
0x0438 CountInfo? no
|
8909
8920
|
0x043a PrintInfo2? no
|
@@ -8966,6 +8977,17 @@ access to this information.
|
|
8966
8977
|
------ -------- --------
|
8967
8978
|
4 PixelAspectRatio no
|
8968
8979
|
|
8980
|
+
=head3 Photoshop ChannelOptions Tags
|
8981
|
+
|
8982
|
+
These tags relate only to the appearance of a channel.
|
8983
|
+
|
8984
|
+
Index1 Tag Name Writable
|
8985
|
+
------ -------- --------
|
8986
|
+
0 ChannelColorSpace no
|
8987
|
+
2 ChannelColorData no
|
8988
|
+
11 ChannelOpacity no
|
8989
|
+
12 ChannelColorIndicates no
|
8990
|
+
|
8969
8991
|
=head3 Photoshop DocumentData Tags
|
8970
8992
|
|
8971
8993
|
Tag ID Tag Name Writable
|
@@ -9325,6 +9347,7 @@ Unknown only to reduce the volume of the normal output.
|
|
9325
9347
|
CanonCameraInfo1100D Canon CameraInfo600D
|
9326
9348
|
CanonCameraInfo1200D Canon CameraInfo60D
|
9327
9349
|
CanonCameraInfoR6 Canon CameraInfoR6
|
9350
|
+
CanonCameraInfoR6m2 Canon CameraInfoR6m2
|
9328
9351
|
CanonCameraInfoG5XII Canon CameraInfoG5XII
|
9329
9352
|
CanonCameraInfoPowerShot Canon CameraInfoPowerShot
|
9330
9353
|
CanonCameraInfoPowerShot2 Canon CameraInfoPowerShot2
|
@@ -10321,6 +10344,14 @@ CameraInfo tags for the EOS R5 and R6.
|
|
10321
10344
|
------ -------- --------
|
10322
10345
|
2801 ShutterCount int32u
|
10323
10346
|
|
10347
|
+
=head3 Canon CameraInfoR6m2 Tags
|
10348
|
+
|
10349
|
+
CameraInfo tags for the EOS R6 Mark II.
|
10350
|
+
|
10351
|
+
Index1 Tag Name Writable
|
10352
|
+
------ -------- --------
|
10353
|
+
3369 ShutterCount int32u
|
10354
|
+
|
10324
10355
|
=head3 Canon CameraInfoG5XII Tags
|
10325
10356
|
|
10326
10357
|
CameraInfo tags for the PowerShot G5 X Mark II.
|
@@ -29993,13 +30024,14 @@ for the official QuickTime specification.
|
|
29993
30024
|
'sefd' SamsungTrailer Samsung Trailer
|
29994
30025
|
'skip' CanonSkip Canon Skip
|
29995
30026
|
PreviewImage no
|
29996
|
-
SkipInfo
|
30027
|
+
SkipInfo QuickTime Stream
|
30028
|
+
LigoGPSInfo -
|
29997
30029
|
Skip? no
|
29998
30030
|
'thm ' ThumbnailImage no
|
29999
30031
|
'thum' ThumbnailImage no
|
30000
30032
|
'udat' GPSLog no
|
30001
30033
|
'udta' KenwoodData QuickTime Stream
|
30002
|
-
|
30034
|
+
LigoJSON QuickTime Stream
|
30003
30035
|
FLIRData FLIR UserData
|
30004
30036
|
'uuid' XMP XMP
|
30005
30037
|
UUID-PROF QuickTime Profile
|
@@ -30019,7 +30051,7 @@ for the official QuickTime specification.
|
|
30019
30051
|
The tags below are extracted from timed metadata in QuickTime and other
|
30020
30052
|
formats of video files when the ExtractEmbedded option is used. Although
|
30021
30053
|
most of these tags are combined into the single table below, ExifTool
|
30022
|
-
currently reads
|
30054
|
+
currently reads 96 different types of timed GPS metadata from video files.
|
30023
30055
|
|
30024
30056
|
Tag Name Writable
|
30025
30057
|
-------- --------
|
@@ -30071,6 +30103,8 @@ currently reads 85 different formats of timed GPS metadata from video files.
|
|
30071
30103
|
Unknown01? no
|
30072
30104
|
Unknown02? no
|
30073
30105
|
Unknown03? no
|
30106
|
+
Unknown_H? no
|
30107
|
+
Unknown_M? no
|
30074
30108
|
UserLabel no
|
30075
30109
|
VerticalSpeed no
|
30076
30110
|
VideoTimeStamp no
|
@@ -30252,6 +30286,8 @@ changed via the config file.
|
|
30252
30286
|
'director' Director yes
|
30253
30287
|
'displayname' DisplayName yes
|
30254
30288
|
'encoder' Encoder yes
|
30289
|
+
'full-frame-rate-playback-intent'
|
30290
|
+
FullFrameRatePlaybackIntent yes
|
30255
30291
|
'genre' Genre yes
|
30256
30292
|
'information' Information yes
|
30257
30293
|
'keywords' Keywords yes
|
@@ -30384,6 +30420,7 @@ Tags found in Pittasoft Blackvue dashcam "free" data.
|
|
30384
30420
|
'bxml' BinaryXML? no
|
30385
30421
|
'dinf' DataInfo QuickTime DataInfo
|
30386
30422
|
'free' Free? no
|
30423
|
+
'grpl' Unknown_grpl QuickTime grpl
|
30387
30424
|
'hdlr' Handler QuickTime Handler
|
30388
30425
|
'idat' MetaImageSize no
|
30389
30426
|
'iinf' ItemInformation QuickTime ItemInfo
|
@@ -30418,6 +30455,12 @@ MP4 data reference box.
|
|
30418
30455
|
'url ' URL no
|
30419
30456
|
'urn ' URN no
|
30420
30457
|
|
30458
|
+
=head3 QuickTime grpl Tags
|
30459
|
+
|
30460
|
+
Tag ID Tag Name Writable
|
30461
|
+
------ -------- --------
|
30462
|
+
[no tags known]
|
30463
|
+
|
30421
30464
|
=head3 QuickTime Handler Tags
|
30422
30465
|
|
30423
30466
|
Index1 Tag Name Writable
|
@@ -325,7 +325,7 @@ sub ProcessVCard($$)
|
|
325
325
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT}; # read next card as a new document
|
326
326
|
}
|
327
327
|
unless ($val =~ s/^([-A-Za-z0-9.]+)//) {
|
328
|
-
$et->
|
328
|
+
$et->Warn("Unrecognized line in $lbl file");
|
329
329
|
next;
|
330
330
|
}
|
331
331
|
my $tag = $1;
|
@@ -379,7 +379,7 @@ sub ProcessVCard($$)
|
|
379
379
|
$param{$p} = '';
|
380
380
|
}
|
381
381
|
}
|
382
|
-
$val =~ s/^:// or $et->
|
382
|
+
$val =~ s/^:// or $et->Warn("Invalid line in $lbl file"), next;
|
383
383
|
# add 'Type' parameter to id and name if it exists
|
384
384
|
$param{Type} and $tag .= $param{Type}, $name .= $param{Type};
|
385
385
|
# convert base64-encoded data
|
@@ -421,7 +421,7 @@ sub ValidateExif($$$$$$$$)
|
|
421
421
|
{
|
422
422
|
my ($et, $tagTablePtr, $tag, $tagInfo, $lastTag, $ifd, $count, $formatStr) = @_;
|
423
423
|
|
424
|
-
$et->
|
424
|
+
$et->Warn("Entries in $ifd are out of order") if $tag <= $lastTag;
|
425
425
|
|
426
426
|
# (get tagInfo for unknown tags if Unknown option not used)
|
427
427
|
if (not defined $tagInfo and $$tagTablePtr{$tag} and ref $$tagTablePtr{$tag} eq 'HASH') {
|
@@ -532,8 +532,8 @@ sub ValidateOffsetInfo($$$;$)
|
|
532
532
|
while (@offsets) {
|
533
533
|
my $start = pop @offsets;
|
534
534
|
my $end = $start + pop @sizes;
|
535
|
-
$et->
|
536
|
-
$et->
|
535
|
+
$et->Warn("$dirName:$$offsets[0]{Name} is zero", $minor) if $start == 0;
|
536
|
+
$et->Warn("$dirName:$$sizes[0]{Name} is zero", $minor) if $start == $end;
|
537
537
|
next unless $end > $fileSize;
|
538
538
|
if ($start >= $fileSize) {
|
539
539
|
if ($start == 0xffffffff) {
|
@@ -387,8 +387,8 @@ sub ValidateImageData($$$;$)
|
|
387
387
|
}
|
388
388
|
push @bitsPerSample, $bitsPerSample[0] while @bitsPerSample < $samplesPerPix;
|
389
389
|
foreach (@bitsPerSample) {
|
390
|
-
$et->
|
391
|
-
$et->
|
390
|
+
$et->Warn("$dirName BitsPerSample values are different", $minor) if $_ ne $bitsPerSample[0];
|
391
|
+
$et->Warn("Invalid $dirName BitsPerSample value", $minor) if $_ < 1 or $_ > 32;
|
392
392
|
}
|
393
393
|
}
|
394
394
|
my $bitsPerPixel = 0;
|
@@ -339,7 +339,7 @@ sub FormatQTValue($$;$$)
|
|
339
339
|
$flags = 0x01; # UTF8
|
340
340
|
$$valPt = $et->Encode($$valPt, 'UTF8');
|
341
341
|
}
|
342
|
-
defined $$valPt or $et->
|
342
|
+
defined $$valPt or $et->Warn("Error converting value for $$tagInfo{Name}");
|
343
343
|
return $flags;
|
344
344
|
}
|
345
345
|
|
@@ -482,23 +482,26 @@ sub WriteKeys($$$)
|
|
482
482
|
sub WriteItemInfo($$$)
|
483
483
|
{
|
484
484
|
my ($et, $dirInfo, $outfile) = @_;
|
485
|
-
my $boxPos = $$dirInfo{BoxPos};
|
485
|
+
my $boxPos = $$dirInfo{BoxPos}; # hash of [position,length,irefVer(iref only)] for box in $outfile
|
486
486
|
my $raf = $$et{RAF};
|
487
487
|
my $items = $$et{ItemInfo};
|
488
|
-
my (%did, @mdatEdit, $name);
|
488
|
+
my (%did, @mdatEdit, $name, $tmap);
|
489
489
|
|
490
490
|
return () unless $items and $raf;
|
491
491
|
|
492
492
|
# extract information from EXIF/XMP metadata items
|
493
493
|
my $primary = $$et{PrimaryItem};
|
494
494
|
my $curPos = $raf->Tell();
|
495
|
+
my $lastID = 0;
|
495
496
|
my $id;
|
496
497
|
foreach $id (sort { $a <=> $b } keys %$items) {
|
498
|
+
$lastID = $id;
|
497
499
|
$primary = $id unless defined $primary; # assume primary is lowest-number item if pitm missing
|
498
500
|
my $item = $$items{$id};
|
499
501
|
# only edit primary EXIF/XMP metadata
|
500
502
|
next unless $$item{RefersTo} and $$item{RefersTo}{$primary};
|
501
503
|
my $type = $$item{ContentType} || $$item{Type} || next;
|
504
|
+
$tmap = $id if $type eq 'tmap'; # save ID of primary 'tmap' item (tone-mapped image)
|
502
505
|
# get ExifTool name for this item
|
503
506
|
$name = { Exif => 'EXIF', 'application/rdf+xml' => 'XMP' }->{$type};
|
504
507
|
next unless $name; # only care about EXIF and XMP
|
@@ -548,7 +551,7 @@ sub WriteItemInfo($$$)
|
|
548
551
|
$buff = $v2;
|
549
552
|
$wasDeflated = 1;
|
550
553
|
} else {
|
551
|
-
$et->
|
554
|
+
$et->Warn("Error inflating $name metadata");
|
552
555
|
next;
|
553
556
|
}
|
554
557
|
}
|
@@ -683,7 +686,7 @@ sub WriteItemInfo($$$)
|
|
683
686
|
# write compressed XMP if Compress option is set
|
684
687
|
if ($et->Options('Compress') and length $newVal) {
|
685
688
|
if (not eval { require Compress::Zlib }) {
|
686
|
-
$et->
|
689
|
+
$et->Warn('Install Compress::Zlib to write compressed metadata');
|
687
690
|
} else {
|
688
691
|
my $deflate = Compress::Zlib::deflateInit();
|
689
692
|
if ($deflate) {
|
@@ -700,8 +703,10 @@ sub WriteItemInfo($$$)
|
|
700
703
|
$type = "Exif\0";
|
701
704
|
$mime = '';
|
702
705
|
}
|
703
|
-
my $id =
|
704
|
-
|
706
|
+
my $id = ++$lastID; # use next highest available ID (so ID's in iinf are in order)
|
707
|
+
#[retracted] # create new item information hash to save infe box in case we need it for sorting
|
708
|
+
#[retracted] my $item = $$items{$id} = { };
|
709
|
+
# add new infe entry to iinf box
|
705
710
|
my $n = length($type) + length($mime) + length($enc) + 16;
|
706
711
|
if ($id < 0x10000) {
|
707
712
|
$add{iinf} .= pack('Na4CCCCnn', $n, 'infe', 2, 0, 0, 1, $id, 0) . $type . $mime . $enc;
|
@@ -709,11 +714,14 @@ sub WriteItemInfo($$$)
|
|
709
714
|
$n += 2;
|
710
715
|
$add{iinf} .= pack('Na4CCCCNn', $n, 'infe', 3, 0, 0, 1, $id, 0) . $type . $mime . $enc;
|
711
716
|
}
|
712
|
-
# add
|
717
|
+
#[retracted] $add{iinf} .= $$item{infe};
|
718
|
+
# add new cdsc to iref (also refer to primary 'tmap' if it exists)
|
713
719
|
if ($irefVer) {
|
714
|
-
$
|
720
|
+
my ($fmt, $siz, $num) = defined $tmap ? ('N', 22, 2) : ('', 18, 1);
|
721
|
+
$add{iref} .= pack('Na4NnN'.$fmt, $siz, 'cdsc', $id, $num, $primary, $tmap);
|
715
722
|
} else {
|
716
|
-
$
|
723
|
+
my ($fmt, $siz, $num) = defined $tmap ? ('n', 16, 2) : ('', 14, 1);
|
724
|
+
$add{iref} .= pack('Na4nnn'.$fmt, $siz, 'cdsc', $id, $num, $primary, $tmap);
|
717
725
|
}
|
718
726
|
# add new entry to iloc table (see ISO14496-12:2015 pg.79)
|
719
727
|
my $ilocVer = Get8u($outfile, $$boxPos{iloc}[0] + 8);
|
@@ -778,8 +786,9 @@ sub WriteItemInfo($$$)
|
|
778
786
|
my $added = 0;
|
779
787
|
my $tag;
|
780
788
|
foreach $tag (sort { $$boxPos{$a}[0] <=> $$boxPos{$b}[0] } keys %$boxPos) {
|
789
|
+
$$boxPos{$tag}[0] += $added;
|
781
790
|
next unless $add{$tag};
|
782
|
-
my $pos = $$boxPos{$tag}[0]
|
791
|
+
my $pos = $$boxPos{$tag}[0];
|
783
792
|
unless ($$boxPos{$tag}[1]) {
|
784
793
|
$tag eq 'iref' or $et->Error('Internal error adding iref box'), last;
|
785
794
|
# create new iref box
|
@@ -826,9 +835,34 @@ sub WriteItemInfo($$$)
|
|
826
835
|
}
|
827
836
|
# add new entries to this box (or add pitm after hdlr)
|
828
837
|
substr($$outfile, $pos + $$boxPos{$tag}[1], 0) = $add{$tag};
|
838
|
+
$$boxPos{$tag}[1] += length $add{$tag};
|
829
839
|
$added += length $add{$tag}; # positions are shifted by length of new entries
|
830
840
|
}
|
831
841
|
}
|
842
|
+
#[This sorting idea was retracted because just sorting 'iinf' wasn't sufficient to
|
843
|
+
# repair the problem where an out-of-order ID was added -- Apple Preview still
|
844
|
+
# ignores the gain-map image. It looks like either or both 'iref' and 'iloc' must
|
845
|
+
# also be sorted by ID, although the spec doesn't mention this]
|
846
|
+
#[retracted] # sort infe entries in iinf box if necessary
|
847
|
+
#[retracted] if ($$et{ItemsNotSorted}) {
|
848
|
+
#[retracted] if ($$boxPos{iinf}) {
|
849
|
+
#[retracted] my $iinfVer = Get8u($outfile, $$boxPos{iinf}[0] + 8);
|
850
|
+
#[retracted] my $off = $iinfVer == 0 ? 14 : 16; # offset to first infe item
|
851
|
+
#[retracted] my $sorted = ''; # sorted iinf payload
|
852
|
+
#[retracted] $sorted .= $$items{$_}{infe} || '' foreach sort { $a <=> $b } keys %$items;
|
853
|
+
#[retracted] if (length $sorted == $$boxPos{iinf}[1]-$off) {
|
854
|
+
#[retracted] # replace with sorted infe entries
|
855
|
+
#[retracted] substr($$outfile, $$boxPos{iinf}[0] + $off, length $sorted) = $sorted;
|
856
|
+
#[retracted] $et->Warn('Item info entries are out of order. Fixed.');
|
857
|
+
#[retracted] ++$$et{CHANGED};
|
858
|
+
#[retracted] } else {
|
859
|
+
#[retracted] $et->Warn('Error sorting item info entries');
|
860
|
+
#[retracted] }
|
861
|
+
#[retracted] } else {
|
862
|
+
#[retracted] $et->Warn('Item info entries are out of order');
|
863
|
+
#[retracted] }
|
864
|
+
#[retracted] delete $$et{ItemsNotSorted};
|
865
|
+
#[retracted] }
|
832
866
|
delete $$et{ItemInfo};
|
833
867
|
return @mdatEdit ? \@mdatEdit : undef;
|
834
868
|
}
|
@@ -973,7 +1007,7 @@ sub WriteQuickTime($$$)
|
|
973
1007
|
$et->Error('End of processing at large atom (LargeFileSupport not enabled)');
|
974
1008
|
last;
|
975
1009
|
} elsif ($et->Options('LargeFileSupport') eq '2') {
|
976
|
-
$et->
|
1010
|
+
$et->Warn('Processing large atom (LargeFileSupport is 2)');
|
977
1011
|
}
|
978
1012
|
}
|
979
1013
|
$size = $hi * 4294967296 + $lo - 16;
|
@@ -1129,7 +1163,7 @@ sub WriteQuickTime($$$)
|
|
1129
1163
|
next;
|
1130
1164
|
}
|
1131
1165
|
}
|
1132
|
-
undef $tagInfo if $tagInfo and $$tagInfo{
|
1166
|
+
undef $tagInfo if $tagInfo and $$tagInfo{AddedUnknown};
|
1133
1167
|
|
1134
1168
|
if ($tagInfo and (not defined $$tagInfo{Writable} or $$tagInfo{Writable})) {
|
1135
1169
|
my $subdir = $$tagInfo{SubDirectory};
|
@@ -112,7 +112,7 @@ sub ValidateProperty($$;$)
|
|
112
112
|
my $valLang = $$et{XmpValidateLangAlt} || ($$et{XmpValidateLangAlt} = { });
|
113
113
|
$$valLang{$langPath} or $$valLang{$langPath} = { };
|
114
114
|
if ($$valLang{$langPath}{$lang}) {
|
115
|
-
$et->
|
115
|
+
$et->Warn("Duplicate language ($lang) in lang-alt list: $langPath");
|
116
116
|
} else {
|
117
117
|
$$valLang{$langPath}{$lang} = 1;
|
118
118
|
}
|
@@ -984,7 +984,7 @@ sub WriteXMP($$;$)
|
|
984
984
|
(not @fixInfo or $fixInfo[0] ne $info);
|
985
985
|
pop @props;
|
986
986
|
}
|
987
|
-
$et->
|
987
|
+
$et->Warn("Error finding parent structure for $$tagInfo{Name}") unless @fixInfo;
|
988
988
|
}
|
989
989
|
# fix property path for this tag (last in the @fixInfo list)
|
990
990
|
push @fixInfo, $tagInfo unless @fixInfo and $isStruct;
|
@@ -1299,10 +1299,10 @@ sub SetNewValuesFromFile($$;@)
|
|
1299
1299
|
ExtractEmbedded FastScan Filter FixBase Geolocation GeolocAltNames
|
1300
1300
|
GeolocFeature GeolocMinPop GeolocMaxDist GlobalTimeShift HexTagIDs
|
1301
1301
|
IgnoreGroups IgnoreMinorErrors IgnoreTags ImageHashType Lang
|
1302
|
-
LargeFileSupport ListItem ListSep MDItemTags MissingTagValue
|
1303
|
-
NoWarning Password PrintConv QuickTimeUTC RequestTags SaveFormat
|
1304
|
-
ScanForXMP StructFormat SystemTags TimeZone Unknown UserParam
|
1305
|
-
WindowsLongPath WindowsWideFile XAttrTags XMPAutoConv))
|
1302
|
+
LargeFileSupport LigoGPSScale ListItem ListSep MDItemTags MissingTagValue
|
1303
|
+
NoPDFList NoWarning Password PrintConv QuickTimeUTC RequestTags SaveFormat
|
1304
|
+
SavePath ScanForXMP StructFormat SystemTags TimeZone Unknown UserParam
|
1305
|
+
Validate WindowsLongPath WindowsWideFile XAttrTags XMPAutoConv))
|
1306
1306
|
{
|
1307
1307
|
$srcExifTool->Options($_ => $$options{$_});
|
1308
1308
|
}
|
@@ -1749,7 +1749,7 @@ GNV_TagInfo: foreach $tagInfo (@tagInfoList) {
|
|
1749
1749
|
my $err = &$checkProc($self, $tagInfo, \$val);
|
1750
1750
|
if ($err or not defined $val) {
|
1751
1751
|
$err or $err = 'Error generating raw value';
|
1752
|
-
$self->
|
1752
|
+
$self->Warn("$err for $$tagInfo{Name}");
|
1753
1753
|
@$vals = ();
|
1754
1754
|
last;
|
1755
1755
|
}
|
@@ -1769,7 +1769,7 @@ GNV_TagInfo: foreach $tagInfo (@tagInfoList) {
|
|
1769
1769
|
# an empty warning ("\n") ignores tag with no error
|
1770
1770
|
if ($evalWarning ne "\n") {
|
1771
1771
|
my $err = CleanWarning() . " in $$tagInfo{Name} (RawConvInv)";
|
1772
|
-
$self->
|
1772
|
+
$self->Warn($err);
|
1773
1773
|
}
|
1774
1774
|
@$vals = ();
|
1775
1775
|
last;
|
@@ -1953,8 +1953,8 @@ sub SetFileModifyDate($$;$$$)
|
|
1953
1953
|
}
|
1954
1954
|
my ($aTime, $mTime, $cTime);
|
1955
1955
|
if ($tag eq 'FileCreateDate') {
|
1956
|
-
eval { require Win32::API } or $self->
|
1957
|
-
eval { require Win32API::File } or $self->
|
1956
|
+
eval { require Win32::API } or $self->Warn("Install Win32::API to set $tag"), return -1;
|
1957
|
+
eval { require Win32API::File } or $self->Warn("Install Win32API::File to set $tag"), return -1;
|
1958
1958
|
$cTime = $val;
|
1959
1959
|
} else {
|
1960
1960
|
$aTime = $mTime = $val;
|
@@ -2151,7 +2151,7 @@ sub SetSystemTags($$)
|
|
2151
2151
|
$self->VerboseValue('+ FilePermissions', $perm);
|
2152
2152
|
$result = 1;
|
2153
2153
|
} else {
|
2154
|
-
$self->
|
2154
|
+
$self->Warn('Error setting FilePermissions');
|
2155
2155
|
$result = -1;
|
2156
2156
|
}
|
2157
2157
|
}
|
@@ -2165,7 +2165,7 @@ sub SetSystemTags($$)
|
|
2165
2165
|
$self->VerboseValue('+ FileGroupID', $gid) if $gid >= 0;
|
2166
2166
|
$result = 1;
|
2167
2167
|
} else {
|
2168
|
-
$self->
|
2168
|
+
$self->Warn('Error setting FileGroup/UserID');
|
2169
2169
|
$result = -1 unless $result;
|
2170
2170
|
}
|
2171
2171
|
}
|
@@ -2181,7 +2181,7 @@ sub SetSystemTags($$)
|
|
2181
2181
|
$result = $res if $res == 1 or not $result;
|
2182
2182
|
last;
|
2183
2183
|
} elsif ($tag ne 'FileCreateDate') {
|
2184
|
-
$self->
|
2184
|
+
$self->Warn('Can only set MDItem tags on MacOS');
|
2185
2185
|
last;
|
2186
2186
|
}
|
2187
2187
|
}
|
@@ -4266,7 +4266,7 @@ sub WriteDirectory($$$;$)
|
|
4266
4266
|
# allow MakerNotes to be deleted from ExifIFD of CR3 file
|
4267
4267
|
not ($self->IsRawType() == 2 and $parent eq 'ExifIFD'))
|
4268
4268
|
{
|
4269
|
-
$self->
|
4269
|
+
$self->Warn("Can't delete $1 from $$self{FileType}",1);
|
4270
4270
|
undef $grp1;
|
4271
4271
|
} elsif (not $blockExifTypes{$$self{FILE_TYPE}}) {
|
4272
4272
|
# restrict delete logic to prevent entire tiff image from being killed
|
@@ -4993,7 +4993,7 @@ my $strptimeLib; # strptime library name if available
|
|
4993
4993
|
sub InverseDateTime($$;$$)
|
4994
4994
|
{
|
4995
4995
|
my ($self, $val, $tzFlag, $dateOnly) = @_;
|
4996
|
-
my ($rtnVal, $tz);
|
4996
|
+
my ($rtnVal, $tz, $fs);
|
4997
4997
|
my $fmt = $$self{OPTIONS}{DateFormat};
|
4998
4998
|
# strip off timezone first if it exists
|
4999
4999
|
if (not $fmt and $val =~ s/([-+])(\d{1,2}):?(\d{2})\s*(DST)?$//i) {
|
@@ -5019,8 +5019,17 @@ sub InverseDateTime($$;$$)
|
|
5019
5019
|
$strptimeLib = '';
|
5020
5020
|
}
|
5021
5021
|
}
|
5022
|
-
# handle
|
5023
|
-
|
5022
|
+
# handle fractional seconds (%f) and time zone (%z)
|
5023
|
+
($fs, $tz) = ('', '');
|
5024
|
+
if ($fmt =~ /%(f|:?z)/) {
|
5025
|
+
if ($fmt =~ s/(.*[^%])%f/$1/) {
|
5026
|
+
$fs = $2 if $val =~ s/(.*)(\.\d+)/$1/; # (take last .### as fractional seconds)
|
5027
|
+
}
|
5028
|
+
if ($fmt =~ s/(.*[^%])%(:?)z/$1/) {
|
5029
|
+
my $colon = $2;
|
5030
|
+
$tz = "$2:$3" if $val =~ s/(.*)([-+]\d{2})$colon(\d{2})/$1/;
|
5031
|
+
}
|
5032
|
+
}
|
5024
5033
|
my ($lib, $wrn, @a);
|
5025
5034
|
TryLib: for ($lib=$strptimeLib; ; $lib='') {
|
5026
5035
|
# handle %s format ourself (not supported in Fedora, see forum15032)
|
@@ -5065,7 +5074,7 @@ TryLib: for ($lib=$strptimeLib; ; $lib='') {
|
|
5065
5074
|
$a[$i] = "0$a[$i]"; # pad to 2 digits if necessary
|
5066
5075
|
}
|
5067
5076
|
}
|
5068
|
-
$val = join(':', @a[5,4,3]) . ' ' . join(':', @a[2,1,0]) . $fs;
|
5077
|
+
$val = join(':', @a[5,4,3]) . ' ' . join(':', @a[2,1,0]) . $fs . $tz;
|
5069
5078
|
last;
|
5070
5079
|
}
|
5071
5080
|
}
|
@@ -5077,7 +5086,9 @@ TryLib: for ($lib=$strptimeLib; ; $lib='') {
|
|
5077
5086
|
my $ss = $a[4]; # get SS
|
5078
5087
|
push @a, '00' while @a < 5; # add MM, SS if not given
|
5079
5088
|
# get sub-seconds if they exist (must be after SS, and have leading ".")
|
5080
|
-
|
5089
|
+
unless ($fmt) {
|
5090
|
+
$fs = (@a > 5 and $val =~ /(\.\d+)\s*$/) ? $1 : '';
|
5091
|
+
}
|
5081
5092
|
# add/remove timezone if necessary
|
5082
5093
|
if ($tzFlag) {
|
5083
5094
|
if (not $tz) {
|
@@ -6430,7 +6441,7 @@ sub WriteJPEG($$)
|
|
6430
6441
|
# warn of subsequent XMP blocks specifying a different
|
6431
6442
|
# HasExtendedXMP (have never seen this)
|
6432
6443
|
if ($goodGuid and $goodGuid ne $2) {
|
6433
|
-
$self->
|
6444
|
+
$self->Warn('Multiple XMP segments specifying different extended XMP GUID');
|
6434
6445
|
}
|
6435
6446
|
$goodGuid = $2; # GUID for the standard extended XMP
|
6436
6447
|
}
|
@@ -6578,7 +6589,7 @@ sub WriteJPEG($$)
|
|
6578
6589
|
undef $$segDataPt;
|
6579
6590
|
next Marker;
|
6580
6591
|
} elsif (defined $chunkNum) {
|
6581
|
-
$self->
|
6592
|
+
$self->Warn('Invalid or extraneous ICC_Profile chunk(s)');
|
6582
6593
|
# fall through to preserve this extra profile...
|
6583
6594
|
}
|
6584
6595
|
} elsif ($$segDataPt =~ /^FPXR\0/) {
|
@@ -6985,9 +6996,9 @@ sub SetFileTime($$;$$$$)
|
|
6985
6996
|
# on Windows, try to work around incorrect file times when daylight saving time is in effect
|
6986
6997
|
if ($^O eq 'MSWin32') {
|
6987
6998
|
if (not eval { require Win32::API }) {
|
6988
|
-
$self->
|
6999
|
+
$self->Warn('Install Win32::API for proper handling of Windows file times');
|
6989
7000
|
} elsif (not eval { require Win32API::File }) {
|
6990
|
-
$self->
|
7001
|
+
$self->Warn('Install Win32API::File for proper handling of Windows file times');
|
6991
7002
|
} else {
|
6992
7003
|
# get Win32 handle, needed for SetFileTime
|
6993
7004
|
my $win32Handle = eval { Win32API::File::GetOsFHandle($file) };
|
@@ -2849,7 +2849,7 @@ sub FullEscapeXML($)
|
|
2849
2849
|
$str =~ s/\\/\/sg; # escape backslashes too
|
2850
2850
|
# then use C-escape sequences for invalid characters
|
2851
2851
|
if ($str =~ /[\0-\x1f]/ or Image::ExifTool::IsUTF8(\$str) < 0) {
|
2852
|
-
$str =~ s/([\0-\x1f\
|
2852
|
+
$str =~ s/([\0-\x1f\x7f-\xff])/sprintf("\\x%.2x",ord $1)/sge;
|
2853
2853
|
}
|
2854
2854
|
return $str;
|
2855
2855
|
}
|
@@ -3630,9 +3630,9 @@ NoLoop:
|
|
3630
3630
|
}
|
3631
3631
|
if ($$et{XmpValidate} and $fmt and $fmt eq 'boolean' and $val!~/^True|False$/) {
|
3632
3632
|
if ($val =~ /^true|false$/) {
|
3633
|
-
$et->
|
3633
|
+
$et->Warn("Boolean value for XMP-$ns:$$tagInfo{Name} should be capitalized",1);
|
3634
3634
|
} else {
|
3635
|
-
$et->
|
3635
|
+
$et->Warn(qq(Boolean value for XMP-$ns:$$tagInfo{Name} should be "True" or "False"),1);
|
3636
3636
|
}
|
3637
3637
|
}
|
3638
3638
|
# protect against large binary data in unknown tags
|
@@ -3823,7 +3823,7 @@ sub ParseXMPElement($$$;$$$$)
|
|
3823
3823
|
$stdNS = $uri2ns{$try};
|
3824
3824
|
if ($stdNS) {
|
3825
3825
|
$val = $try;
|
3826
|
-
$et->
|
3826
|
+
$et->Warn("Fixed incorrect URI for xmlns:$ns", 1);
|
3827
3827
|
} elsif ($val =~ m(^http://ns.nikon.com/BASIC_PARAM)) {
|
3828
3828
|
$et->OverrideFileType('NXD','application/x-nikon-nxd');
|
3829
3829
|
} else {
|
@@ -3904,9 +3904,9 @@ sub ParseXMPElement($$$;$$$$)
|
|
3904
3904
|
if ($nItems == 1000) {
|
3905
3905
|
my ($tg,$ns) = GetXMPTagID($propList);
|
3906
3906
|
if ($isWriting) {
|
3907
|
-
$et->
|
3907
|
+
$et->Warn("Excessive number of items for $ns:$tg. Processing may be slow", 1);
|
3908
3908
|
} elsif (not $$et{OPTIONS}{IgnoreMinorErrors}) {
|
3909
|
-
$et->
|
3909
|
+
$et->Warn("Extracted only 1000 $ns:$tg items. Ignore minor errors to extract all", 2);
|
3910
3910
|
last;
|
3911
3911
|
}
|
3912
3912
|
}
|
@@ -4006,12 +4006,12 @@ sub ParseXMPElement($$$;$$$$)
|
|
4006
4006
|
} elsif ($$et{XmpAbout} ne $attrs{$shortName}) {
|
4007
4007
|
if ($isWriting) {
|
4008
4008
|
my $str = "Different 'rdf:about' attributes not handled";
|
4009
|
-
unless ($$et{
|
4009
|
+
unless ($$et{WAS_WARNED}{$str}) {
|
4010
4010
|
$et->Error($str, 1);
|
4011
|
-
$$et{
|
4011
|
+
$$et{WAS_WARNED}{$str} = 1;
|
4012
4012
|
}
|
4013
4013
|
} elsif ($$et{XmpValidate}) {
|
4014
|
-
$et->
|
4014
|
+
$et->Warn("Different 'rdf:about' attributes");
|
4015
4015
|
}
|
4016
4016
|
}
|
4017
4017
|
}
|
@@ -330,7 +330,7 @@ sub ProcessRAR($$)
|
|
330
330
|
$et->Warn('Large block encountered. Aborting.');
|
331
331
|
last;
|
332
332
|
} elsif ($et->Options('LargeFileSupport') eq '2') {
|
333
|
-
$et->
|
333
|
+
$et->Warn('Processing large block (LargeFileSupport is 2)');
|
334
334
|
}
|
335
335
|
}
|
336
336
|
# process the block
|