exiftool-vendored.exe 12.97.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/exiftool_files/exiftool.pl +221 -41
- package/bin/exiftool_files/lib/File/RandomAccess.pm +5 -2
- package/bin/exiftool_files/lib/Image/ExifTool/APP12.pm +3 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +2 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.dat +0 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +4 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Import.pm +7 -3
- package/bin/exiftool_files/lib/Image/ExifTool/InDesign.pm +4 -3
- package/bin/exiftool_files/lib/Image/ExifTool/JSON.pm +3 -4
- package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +2 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Lytro.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/M2TS.pm +10 -2
- package/bin/exiftool_files/lib/Image/ExifTool/PhaseOne.pm +2 -1
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +17 -6
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +88 -9
- package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +6 -1
- package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +14 -9
- package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +40 -23
- package/bin/exiftool_files/lib/Image/ExifTool/WritePDF.pl +47 -21
- package/bin/exiftool_files/lib/Image/ExifTool/WriteXMP.pl +16 -4
- package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +16 -6
- package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +19 -4
- package/bin/exiftool_files/lib/Image/ExifTool/XMPStruct.pl +15 -7
- package/bin/exiftool_files/lib/Image/ExifTool.pm +37 -12
- package/bin/exiftool_files/lib/Image/ExifTool.pod +31 -8
- package/bin/exiftool_files/readme_windows.txt +8 -13
- package/bin/exiftool_files/windows_exiftool.txt +32 -10
- package/package.json +7 -7
|
@@ -184,11 +184,19 @@ sub GetFreeEntries($)
|
|
|
184
184
|
{
|
|
185
185
|
my $dict = shift;
|
|
186
186
|
my %xrefFree;
|
|
187
|
-
#
|
|
188
|
-
# so we can simplify things for now and only support this type of entry
|
|
187
|
+
# we write xref stream entries in 'CNn' or 'CNNn' format (with 8-byte 'NN' offset),
|
|
189
188
|
my $w = $$dict{W};
|
|
190
|
-
if (ref $w eq 'ARRAY'
|
|
191
|
-
my $
|
|
189
|
+
if (ref $w eq 'ARRAY') {
|
|
190
|
+
my $bytes = "@$w";
|
|
191
|
+
my $fmt;
|
|
192
|
+
if ($bytes eq '1 4 2') {
|
|
193
|
+
$fmt = 'CNn';
|
|
194
|
+
} elsif ($bytes eq '1 8 2') {
|
|
195
|
+
$fmt = 'CNNn';
|
|
196
|
+
} else {
|
|
197
|
+
return \%xrefFree;
|
|
198
|
+
}
|
|
199
|
+
my $size = $$dict{_entry_size}; # this will be 7 for 'CNn' or 11 for 'CNNn'
|
|
192
200
|
my $index = $$dict{Index};
|
|
193
201
|
my $len = length $$dict{_stream};
|
|
194
202
|
# scan the table for free objects
|
|
@@ -200,7 +208,12 @@ sub GetFreeEntries($)
|
|
|
200
208
|
my $count = $$index[$i*2+1];
|
|
201
209
|
for ($j=0; $j<$count; ++$j) {
|
|
202
210
|
last if $pos + $size > $len;
|
|
203
|
-
my @t = unpack("x$pos
|
|
211
|
+
my @t = unpack("x$pos $fmt", $$dict{_stream});
|
|
212
|
+
if (@t == 4) {
|
|
213
|
+
$t[1] = $t[1] * 4294967296 + $t[2];
|
|
214
|
+
$t[2] = $t[3];
|
|
215
|
+
@t = 3;
|
|
216
|
+
}
|
|
204
217
|
# add entry if object was free
|
|
205
218
|
$xrefFree{$start+$j} = [ $t[1], $t[2], 'f' ] if $t[0] == 0;
|
|
206
219
|
$pos += $size; # step to next entry
|
|
@@ -657,24 +670,37 @@ sub WritePDF($$)
|
|
|
657
670
|
$newXRef{$nextObject++} = [ Tell($outfile) - $$et{PDFBase} + length($/), 0, 'n' ];
|
|
658
671
|
$$mainDict{Size} = $nextObject;
|
|
659
672
|
# create xref stream and Index entry
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
my
|
|
666
|
-
|
|
667
|
-
$
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
$
|
|
671
|
-
|
|
673
|
+
my $bits = 4;
|
|
674
|
+
Restart: for (;;) {
|
|
675
|
+
$$mainDict{W} = [ 1, $bits, 2 ]; # int8u, int32u/int64u, int16u ('CNn' or 'CNNn')
|
|
676
|
+
$$mainDict{Index} = [ ];
|
|
677
|
+
$$mainDict{_stream} = '';
|
|
678
|
+
my @ids = sort { $a <=> $b } keys %newXRef;
|
|
679
|
+
while (@ids) {
|
|
680
|
+
my $startID = $ids[0];
|
|
681
|
+
for (;;) {
|
|
682
|
+
$id = shift @ids;
|
|
683
|
+
my ($pos, $gen, $type) = @{$newXRef{$id}};
|
|
684
|
+
if ($pos > 0xffffffff) {
|
|
685
|
+
if ($bits == 4) {
|
|
686
|
+
# switch to 64-bit integer offsets
|
|
687
|
+
$bits = 8;
|
|
688
|
+
next Restart;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
if ($bits == 4) {
|
|
692
|
+
$$mainDict{_stream} .= pack('CNn', $type eq 'f' ? 0 : 1, $pos, $gen);
|
|
693
|
+
} else {
|
|
694
|
+
my $hi = int($pos / 4294967296);
|
|
695
|
+
my $lo = $pos - $hi * 4294967296;
|
|
696
|
+
$$mainDict{_stream} .= pack('CNNn', $type eq 'f' ? 0 : 1, $hi, $lo, $gen);
|
|
697
|
+
}
|
|
698
|
+
last if not @ids or $ids[0] != $id + 1;
|
|
672
699
|
}
|
|
673
|
-
|
|
674
|
-
|
|
700
|
+
# add Index entries for this section of the xref stream
|
|
701
|
+
push @{$$mainDict{Index}}, $startID, $id - $startID + 1;
|
|
675
702
|
}
|
|
676
|
-
|
|
677
|
-
push @{$$mainDict{Index}}, $startID, $id - $startID + 1;
|
|
703
|
+
last;
|
|
678
704
|
}
|
|
679
705
|
# write the xref stream object
|
|
680
706
|
$keyExt = "$id 0 obj"; # (set anyway, but xref stream should NOT be encrypted)
|
|
@@ -925,19 +925,31 @@ sub WriteXMP($$;$)
|
|
|
925
925
|
# get hash of all information we want to change
|
|
926
926
|
# (sorted by tag name so alternate languages come last, but with structures
|
|
927
927
|
# first so flattened tags may be used to override individual structure elements)
|
|
928
|
-
my (@tagInfoList, $delLangPath, %delLangPaths, %delAllLang, $firstNewPath);
|
|
928
|
+
my (@tagInfoList, @structList, $delLangPath, %delLangPaths, %delAllLang, $firstNewPath, @langTags);
|
|
929
929
|
my $writeGroup = $$dirInfo{WriteGroup};
|
|
930
930
|
foreach $tagInfo (sort ByTagName $et->GetNewTagInfoList()) {
|
|
931
931
|
next unless $et->GetGroup($tagInfo, 0) eq 'XMP';
|
|
932
932
|
next if $$tagInfo{Name} eq 'XMP'; # (ignore full XMP block if we didn't write it already)
|
|
933
933
|
next if $writeGroup and $writeGroup ne $$et{NEW_VALUE}{$tagInfo}{WriteGroup};
|
|
934
|
-
if ($$tagInfo{
|
|
935
|
-
|
|
934
|
+
if ($$tagInfo{LangCode}) {
|
|
935
|
+
push @langTags, $tagInfo
|
|
936
|
+
} elsif ($$tagInfo{Struct}) {
|
|
937
|
+
push @structList, $tagInfo;
|
|
936
938
|
} else {
|
|
937
939
|
push @tagInfoList, $tagInfo;
|
|
938
940
|
}
|
|
939
941
|
}
|
|
940
|
-
|
|
942
|
+
if (@langTags) {
|
|
943
|
+
# keep original order in which lang-alt entries were added
|
|
944
|
+
foreach $tagInfo (sort { $$et{NEW_VALUE}{$a}{Order} <=> $$et{NEW_VALUE}{$b}{Order} } @langTags) {
|
|
945
|
+
if ($$tagInfo{Struct}) {
|
|
946
|
+
push @structList, $tagInfo;
|
|
947
|
+
} else {
|
|
948
|
+
push @tagInfoList, $tagInfo;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
foreach $tagInfo (@structList, @tagInfoList) {
|
|
941
953
|
my @delPaths; # list of deleted paths
|
|
942
954
|
my $tag = $$tagInfo{TagID};
|
|
943
955
|
my $path = GetPropertyPath($tagInfo);
|
|
@@ -295,10 +295,11 @@ my %ignorePrintConv = map { $_ => 1 } qw(OTHER BITMASK Notes);
|
|
|
295
295
|
# CreateGroups - hash of all family 0 group names where tag may be created
|
|
296
296
|
# WriteGroup - group name where information is being written (correct case)
|
|
297
297
|
# WantGroup - group name as specified in call to function (case insensitive)
|
|
298
|
-
# Next - pointer to next new value hash (if more than one)
|
|
298
|
+
# Next - pointer to next new value hash (if more than one for this tag)
|
|
299
299
|
# NoReplace - set if value was created with Replace=0
|
|
300
300
|
# AddBefore - number of list items added by a subsequent Replace=0 call
|
|
301
|
-
# IsNVH -
|
|
301
|
+
# IsNVH - flag indicating this is a new value hash
|
|
302
|
+
# Order - counter to indicate the order that new value hashes were created
|
|
302
303
|
# Shift - shift value
|
|
303
304
|
# Save - counter used by SaveNewValues()/RestoreNewValues()
|
|
304
305
|
# MAKER_NOTE_FIXUP - pointer to fixup if necessary for a maker note value
|
|
@@ -317,7 +318,7 @@ sub SetNewValue($;$$%)
|
|
|
317
318
|
|
|
318
319
|
unless (defined $tag) {
|
|
319
320
|
delete $$self{NEW_VALUE};
|
|
320
|
-
$$self{SAVE_COUNT} = 0;
|
|
321
|
+
$$self{SAVE_COUNT} = $$self{NV_COUNT} = 0;
|
|
321
322
|
$$self{DEL_GROUP} = { };
|
|
322
323
|
return 1;
|
|
323
324
|
}
|
|
@@ -1389,8 +1390,16 @@ sub SetNewValuesFromFile($$;@)
|
|
|
1389
1390
|
return $info if $$info{Error} and $$info{Error} eq 'Error opening file';
|
|
1390
1391
|
delete $$srcExifTool{VALUE}{Error}; # delete so we can check this later
|
|
1391
1392
|
|
|
1392
|
-
# sort tags in
|
|
1393
|
-
my @tags
|
|
1393
|
+
# sort tags in file order with priority tags last
|
|
1394
|
+
my (@tags, @prio);
|
|
1395
|
+
foreach (sort { $$srcExifTool{FILE_ORDER}{$a} <=> $$srcExifTool{FILE_ORDER}{$b} } keys %$info) {
|
|
1396
|
+
if (/ /) {
|
|
1397
|
+
push @tags, $_;
|
|
1398
|
+
} else {
|
|
1399
|
+
push @prio, $_;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
push @tags, @prio;
|
|
1394
1403
|
#
|
|
1395
1404
|
# simply transfer all tags from source image if no tags specified
|
|
1396
1405
|
#
|
|
@@ -3896,6 +3905,7 @@ sub GetNewValueHash($$;$$$$)
|
|
|
3896
3905
|
TagInfo => $tagInfo,
|
|
3897
3906
|
WriteGroup => $writeGroup,
|
|
3898
3907
|
IsNVH => 1, # set flag so we can recognize a new value hash
|
|
3908
|
+
Order => $$self{NV_COUNT}++,
|
|
3899
3909
|
};
|
|
3900
3910
|
# add entry to our NEW_VALUE hash
|
|
3901
3911
|
if ($$self{NEW_VALUE}{$tagInfo}) {
|
|
@@ -4023,7 +4033,7 @@ sub RemoveNewValuesForGroup($$)
|
|
|
4023
4033
|
#------------------------------------------------------------------------------
|
|
4024
4034
|
# Get list of tagInfo hashes for all new data
|
|
4025
4035
|
# Inputs: 0) ExifTool object reference, 1) optional tag table pointer
|
|
4026
|
-
# Returns: list of tagInfo hashes
|
|
4036
|
+
# Returns: list of tagInfo hashes in no particular order
|
|
4027
4037
|
sub GetNewTagInfoList($;$)
|
|
4028
4038
|
{
|
|
4029
4039
|
my ($self, $tagTablePtr) = @_;
|
|
@@ -50,7 +50,7 @@ use Image::ExifTool::Exif;
|
|
|
50
50
|
use Image::ExifTool::GPS;
|
|
51
51
|
require Exporter;
|
|
52
52
|
|
|
53
|
-
$VERSION = '3.
|
|
53
|
+
$VERSION = '3.67';
|
|
54
54
|
@ISA = qw(Exporter);
|
|
55
55
|
@EXPORT_OK = qw(EscapeXML UnescapeXML);
|
|
56
56
|
|
|
@@ -2016,6 +2016,7 @@ my %sPantryItem = (
|
|
|
2016
2016
|
Writable => 'integer',
|
|
2017
2017
|
List => 'Seq',
|
|
2018
2018
|
AutoSplit => 1,
|
|
2019
|
+
Notes => 'deprecated',
|
|
2019
2020
|
},
|
|
2020
2021
|
OECF => {
|
|
2021
2022
|
Name => 'Opto-ElectricConvFactor',
|
|
@@ -2267,7 +2268,7 @@ my %sPantryItem = (
|
|
|
2267
2268
|
3 => 'Distant',
|
|
2268
2269
|
},
|
|
2269
2270
|
},
|
|
2270
|
-
ImageUniqueID => { },
|
|
2271
|
+
ImageUniqueID => { Avoid => 1, Notes => 'moved to exifEX namespace in 2024 spec' },
|
|
2271
2272
|
GPSVersionID => { Groups => { 2 => 'Location' } },
|
|
2272
2273
|
GPSLatitude => { Groups => { 2 => 'Location' }, %latConv },
|
|
2273
2274
|
GPSLongitude => { Groups => { 2 => 'Location' }, %longConv },
|
|
@@ -2509,6 +2510,15 @@ my %sPantryItem = (
|
|
|
2509
2510
|
Values => { List => 'Seq', Writable => 'rational' },
|
|
2510
2511
|
},
|
|
2511
2512
|
},
|
|
2513
|
+
# new in Exif 3.0
|
|
2514
|
+
ImageUniqueID => { },
|
|
2515
|
+
ImageTitle => { },
|
|
2516
|
+
ImageEditor => { },
|
|
2517
|
+
Photographer => { Groups => { 2 => 'Author' } },
|
|
2518
|
+
CameraFirmware => { Groups => { 2 => 'Camera' } },
|
|
2519
|
+
RAWDevelopingSoftware => { },
|
|
2520
|
+
ImageEditingSoftware => { },
|
|
2521
|
+
MetadataEditingSoftware => { },
|
|
2512
2522
|
);
|
|
2513
2523
|
|
|
2514
2524
|
# Auxiliary namespace properties (aux) - not fully documented (ref PH)
|
|
@@ -3777,8 +3787,13 @@ sub ParseXMPElement($$$;$$$$)
|
|
|
3777
3787
|
|
|
3778
3788
|
# extract property attributes
|
|
3779
3789
|
my ($parseResource, %attrs, @attrs);
|
|
3780
|
-
|
|
3781
|
-
|
|
3790
|
+
# this hangs Perl (v5.18.4) for a specific capture string [patched in ExifTool 12.98]
|
|
3791
|
+
# while ($attrs =~ m/(\S+?)\s*=\s*(['"])(.*?)\2/sg) {
|
|
3792
|
+
while ($attrs =~ /(\S+?)\s*=\s*(['"])/g) {
|
|
3793
|
+
my ($attr, $quote) = ($1, $2);
|
|
3794
|
+
my $p0 = pos($attrs);
|
|
3795
|
+
last unless $attrs =~ /$quote/g;
|
|
3796
|
+
my $val = substr($attrs, $p0, pos($attrs)-$p0-1);
|
|
3782
3797
|
# handle namespace prefixes (defined by xmlns:PREFIX, or used with PREFIX:tag)
|
|
3783
3798
|
if ($attr =~ /(.*?):/) {
|
|
3784
3799
|
if ($1 eq 'xmlns') {
|
|
@@ -39,8 +39,7 @@ sub SerializeStruct($$;$)
|
|
|
39
39
|
|
|
40
40
|
if (ref $obj eq 'HASH') {
|
|
41
41
|
# support hashes with ordered keys
|
|
42
|
-
|
|
43
|
-
foreach $key (@keys) {
|
|
42
|
+
foreach $key (Image::ExifTool::OrderedKeys($obj)) {
|
|
44
43
|
my $hdr = $sfmt ? EscapeJSON($key) . ':' : $key . '=';
|
|
45
44
|
push @vals, $hdr . SerializeStruct($et, $$obj{$key}, '}');
|
|
46
45
|
}
|
|
@@ -218,7 +217,7 @@ sub DumpStruct($;$)
|
|
|
218
217
|
$indent or $indent = '';
|
|
219
218
|
if (ref $obj eq 'HASH') {
|
|
220
219
|
print "{\n";
|
|
221
|
-
foreach (
|
|
220
|
+
foreach (Image::ExifTool::OrderedKeys($obj)) {
|
|
222
221
|
print "$indent $_ = ";
|
|
223
222
|
DumpStruct($$obj{$_}, "$indent ");
|
|
224
223
|
}
|
|
@@ -253,8 +252,10 @@ sub CheckStruct($$$)
|
|
|
253
252
|
ref $struct eq 'HASH' or return wantarray ? (undef, "Expecting $strName structure") : undef;
|
|
254
253
|
|
|
255
254
|
my ($key, $err, $warn, %copy, $rtnVal, $val);
|
|
255
|
+
# copy the ordered keys if they exist
|
|
256
|
+
$copy{_ordered_keys_} = [ ] if $$struct{_ordered_keys_};
|
|
256
257
|
Key:
|
|
257
|
-
foreach $key (
|
|
258
|
+
foreach $key (Image::ExifTool::OrderedKeys($struct)) {
|
|
258
259
|
my $tag = $key;
|
|
259
260
|
# allow trailing '#' to disable print conversion on a per-field basis
|
|
260
261
|
my ($type, $fieldInfo);
|
|
@@ -377,6 +378,7 @@ Key:
|
|
|
377
378
|
$copy{$tag} = \@copy;
|
|
378
379
|
} elsif ($$fieldInfo{Struct}) {
|
|
379
380
|
$warn = "Improperly formed structure in $strName $tag";
|
|
381
|
+
next;
|
|
380
382
|
} else {
|
|
381
383
|
$et->Sanitize(\$$struct{$key});
|
|
382
384
|
($val,$err) = $et->ConvInv($$struct{$key},$fieldInfo,$tag,$strName,$type,'');
|
|
@@ -387,6 +389,7 @@ Key:
|
|
|
387
389
|
# turn this into a list if necessary
|
|
388
390
|
$copy{$tag} = $$fieldInfo{List} ? [ $val ] : $val;
|
|
389
391
|
}
|
|
392
|
+
push @{$copy{_ordered_keys_}}, $tag if $copy{_ordered_keys_}; # save ordered keys
|
|
390
393
|
}
|
|
391
394
|
if (%copy or not $warn) {
|
|
392
395
|
$rtnVal = \%copy;
|
|
@@ -562,7 +565,7 @@ sub AddNewStruct($$$$$$)
|
|
|
562
565
|
# after all valid structure fields, which is necessary when serializing the XMP later)
|
|
563
566
|
%$struct or $$struct{'~dummy~'} = '';
|
|
564
567
|
|
|
565
|
-
foreach $tag (
|
|
568
|
+
foreach $tag (Image::ExifTool::OrderedKeys($struct)) {
|
|
566
569
|
my $fieldInfo = $$strTable{$tag};
|
|
567
570
|
unless ($fieldInfo) {
|
|
568
571
|
next unless $tag eq '~dummy~'; # check for dummy field
|
|
@@ -652,7 +655,8 @@ sub ConvertStruct($$$$;$)
|
|
|
652
655
|
my (%struct, $key);
|
|
653
656
|
my $table = $$tagInfo{Table};
|
|
654
657
|
$parentID = $$tagInfo{TagID} unless $parentID;
|
|
655
|
-
|
|
658
|
+
$struct{_ordered_keys_} = [ ] if $$value{_ordered_keys_};
|
|
659
|
+
foreach $key (Image::ExifTool::OrderedKeys($value)) {
|
|
656
660
|
my $tagID = $parentID . ucfirst($key);
|
|
657
661
|
my $flatInfo = $$table{$tagID};
|
|
658
662
|
unless ($flatInfo) {
|
|
@@ -669,7 +673,11 @@ sub ConvertStruct($$$$;$)
|
|
|
669
673
|
} else {
|
|
670
674
|
$v = $et->GetValue($flatInfo, $type, $v);
|
|
671
675
|
}
|
|
672
|
-
|
|
676
|
+
if (defined $v) {
|
|
677
|
+
$struct{$key} = $v; # save the converted value
|
|
678
|
+
# maintain ordered keys if necessary
|
|
679
|
+
push @{$struct{_ordered_keys_}}, $key if $struct{_ordered_keys_};
|
|
680
|
+
}
|
|
673
681
|
}
|
|
674
682
|
return \%struct;
|
|
675
683
|
} elsif (ref $value eq 'ARRAY') {
|
|
@@ -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 = '
|
|
32
|
+
$VERSION = '13.00';
|
|
33
33
|
$RELEASE = '';
|
|
34
34
|
@ISA = qw(Exporter);
|
|
35
35
|
%EXPORT_TAGS = (
|
|
@@ -37,7 +37,7 @@ $RELEASE = '';
|
|
|
37
37
|
Public => [qw(
|
|
38
38
|
ImageInfo AvailableOptions GetTagName GetShortcuts GetAllTags
|
|
39
39
|
GetWritableTags GetAllGroups GetDeleteGroups GetFileType CanWrite
|
|
40
|
-
CanCreate AddUserDefinedTags
|
|
40
|
+
CanCreate AddUserDefinedTags OrderedKeys
|
|
41
41
|
)],
|
|
42
42
|
# exports not part of the public API, but used by ExifTool modules:
|
|
43
43
|
DataAccess => [qw(
|
|
@@ -740,7 +740,7 @@ my %fileDescription = (
|
|
|
740
740
|
OGV => 'video/ogg',
|
|
741
741
|
ONP => 'application/on1',
|
|
742
742
|
ORF => 'image/x-olympus-orf',
|
|
743
|
-
OTF => 'application/
|
|
743
|
+
OTF => 'application/font-otf',
|
|
744
744
|
PAGES=> 'application/x-iwork-pages-sffpages',
|
|
745
745
|
PBM => 'image/x-portable-bitmap',
|
|
746
746
|
PCD => 'image/x-photo-cd',
|
|
@@ -798,8 +798,8 @@ my %fileDescription = (
|
|
|
798
798
|
THMX => 'application/vnd.ms-officetheme',
|
|
799
799
|
TIFF => 'image/tiff',
|
|
800
800
|
Torrent => 'application/x-bittorrent',
|
|
801
|
-
TTC => 'application/
|
|
802
|
-
TTF => 'application/
|
|
801
|
+
TTC => 'application/font-ttf',
|
|
802
|
+
TTF => 'application/font-ttf',
|
|
803
803
|
TXT => 'text/plain',
|
|
804
804
|
VCard=> 'text/vcard',
|
|
805
805
|
VRD => 'application/octet-stream', #PH (NC)
|
|
@@ -1466,12 +1466,12 @@ my %systemTagsNotes = (
|
|
|
1466
1466
|
PrintConv => sub {
|
|
1467
1467
|
my ($mask, $val) = (0400, oct(shift));
|
|
1468
1468
|
my %types = (
|
|
1469
|
-
0010000 => 'p',
|
|
1470
|
-
0020000 => 'c',
|
|
1471
|
-
0040000 => 'd',
|
|
1472
|
-
0060000 => 'b',
|
|
1473
|
-
0120000 => 'l',
|
|
1474
|
-
0140000 => 's',
|
|
1469
|
+
0010000 => 'p', # FIFO
|
|
1470
|
+
0020000 => 'c', # character special file
|
|
1471
|
+
0040000 => 'd', # directory
|
|
1472
|
+
0060000 => 'b', # block special file
|
|
1473
|
+
0120000 => 'l', # sym link
|
|
1474
|
+
0140000 => 's', # socket link
|
|
1475
1475
|
);
|
|
1476
1476
|
my $str = $types{$val & 0170000} || '-';
|
|
1477
1477
|
while ($mask) {
|
|
@@ -2292,6 +2292,7 @@ sub new
|
|
|
2292
2292
|
$$self{PATH} = [ ]; # (this too)
|
|
2293
2293
|
$$self{DEL_GROUP} = { }; # lookup for groups to delete when writing
|
|
2294
2294
|
$$self{SAVE_COUNT} = 0; # count calls to SaveNewValues()
|
|
2295
|
+
$$self{NV_COUNT} = 0; # count of NEW_VALUE entries
|
|
2295
2296
|
$$self{FILE_SEQUENCE} = 0; # sequence number for files when reading
|
|
2296
2297
|
$$self{FILES_WRITTEN} = 0; # count of files successfully written
|
|
2297
2298
|
$$self{INDENT2} = ''; # indentation of verbose messages from SetNewValue
|
|
@@ -2517,6 +2518,8 @@ sub Options($$;@)
|
|
|
2517
2518
|
# set Compact and XMPShorthand options, preserving backward compatibility
|
|
2518
2519
|
my ($p, %compact);
|
|
2519
2520
|
foreach $p ('Compact','XMPShorthand') {
|
|
2521
|
+
# (allow setting from a HASH (undocumented)
|
|
2522
|
+
ref $newVal eq 'HASH' and %compact = %{$newVal}, next;
|
|
2520
2523
|
my $val = $param eq $p ? $newVal : $$options{Compact}{$p};
|
|
2521
2524
|
if (defined $val) {
|
|
2522
2525
|
my @v = ($val =~ /\w+/g);
|
|
@@ -4195,6 +4198,16 @@ sub CanCreate($)
|
|
|
4195
4198
|
return 0;
|
|
4196
4199
|
}
|
|
4197
4200
|
|
|
4201
|
+
#------------------------------------------------------------------------------
|
|
4202
|
+
# Return list of ordered keys if available, otherwise just sort alphabetically
|
|
4203
|
+
# Inputs: 0) hash ref
|
|
4204
|
+
# Returns: List of ordered/sorted keys
|
|
4205
|
+
sub OrderedKeys($)
|
|
4206
|
+
{
|
|
4207
|
+
my $hash = shift;
|
|
4208
|
+
return $$hash{_ordered_keys_} ? @{$$hash{_ordered_keys_}} : sort keys %$hash;
|
|
4209
|
+
}
|
|
4210
|
+
|
|
4198
4211
|
#==============================================================================
|
|
4199
4212
|
# Functions below this are not part of the public API
|
|
4200
4213
|
|
|
@@ -7290,7 +7303,10 @@ sub ProcessJPEG($$;$)
|
|
|
7290
7303
|
last; # all done parsing file
|
|
7291
7304
|
} elsif (defined $markerLenBytes{$marker}) {
|
|
7292
7305
|
# handle other stand-alone markers and segments we skipped over
|
|
7293
|
-
$verbose and $marker
|
|
7306
|
+
if ($verbose and $marker) {
|
|
7307
|
+
next if $verbose < 4 and ($marker & 0xf8) == 0xd0;
|
|
7308
|
+
print $out "${indent}JPEG $markerName\n";
|
|
7309
|
+
}
|
|
7294
7310
|
next;
|
|
7295
7311
|
} elsif ($marker == 0xdb and length($$segDataPt) and # DQT
|
|
7296
7312
|
# save the DQT data only if JPEGDigest has been requested
|
|
@@ -7901,8 +7917,17 @@ sub ProcessJPEG($$;$)
|
|
|
7901
7917
|
my $seq = Get32u($segDataPt, 4);
|
|
7902
7918
|
my $len = Get32u($segDataPt, 8);
|
|
7903
7919
|
my $type = substr($$segDataPt, 12, 4);
|
|
7920
|
+
# a Microsoft bug writes $len and $type incorrectly as little-endian
|
|
7921
|
+
if ($type eq 'bmuj') {
|
|
7922
|
+
$self->WarnOnce('Wrong byte order in C2PA APP11 JUMBF header');
|
|
7923
|
+
$type = 'jumb';
|
|
7924
|
+
$len = unpack('x8V', $$segDataPt);
|
|
7925
|
+
# fix the header
|
|
7926
|
+
substr($$segDataPt, 8, 8) = Set32u($len) . $type;
|
|
7927
|
+
}
|
|
7904
7928
|
my $hdrLen;
|
|
7905
7929
|
if ($len == 1 and length($$segDataPt) >= 24) {
|
|
7930
|
+
# (haven't seen this with the Microsoft bug)
|
|
7906
7931
|
$len = Get64u($$segDataPt, 16);
|
|
7907
7932
|
$hdrLen = 16;
|
|
7908
7933
|
} else {
|
|
@@ -332,13 +332,14 @@ L</ImageInfo>:
|
|
|
332
332
|
|
|
333
333
|
Values of the returned hash are usually simple scalars, but a scalar
|
|
334
334
|
reference is used to indicate binary data and an array reference may be used
|
|
335
|
-
to indicate a list. Also, a hash reference may be returned if the
|
|
336
|
-
option is used
|
|
337
|
-
|
|
338
|
-
enabled
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
335
|
+
to indicate a list. Also, a hash reference may be returned if the
|
|
336
|
+
L</Struct> option is used (see the L</OrderedKeys> option to obtain the hash
|
|
337
|
+
keys). Lists of values are joined by commas into a single string only if
|
|
338
|
+
the PrintConv option is enabled and the ListJoin option is enabled (which
|
|
339
|
+
are the defaults). Note that binary values are not necessarily extracted
|
|
340
|
+
unless specifically requested, or the Binary option is enabled and the tag
|
|
341
|
+
is not specifically excluded. If not extracted the value is a reference to
|
|
342
|
+
a string of the form "Binary data ##### bytes".
|
|
342
343
|
|
|
343
344
|
The code below gives an example of how to handle these return values, as
|
|
344
345
|
well as illustrating the use of other ExifTool functions:
|
|
@@ -1089,7 +1090,9 @@ values in standard format).
|
|
|
1089
1090
|
|
|
1090
1091
|
Flag to return XMP structures as hash references instead of flattening into
|
|
1091
1092
|
individual tags. Has no effect when writing since both flattened and
|
|
1092
|
-
structured tags may always be written.
|
|
1093
|
+
structured tags may always be written. A special "_ordered_keys_" element
|
|
1094
|
+
containing a list of ordered keys may exist if the structure elements are
|
|
1095
|
+
ordered (see the L<OrderedKeys> method). Possible values are:
|
|
1093
1096
|
|
|
1094
1097
|
undef - (default) Same as 0 for reading, 2 for copying
|
|
1095
1098
|
0 - Read/copy flattened tags
|
|
@@ -2749,6 +2752,26 @@ details on the elements of the tag information hash.
|
|
|
2749
2752
|
|
|
2750
2753
|
=back
|
|
2751
2754
|
|
|
2755
|
+
=head2 OrderedKeys [static]
|
|
2756
|
+
|
|
2757
|
+
Return a list of ordered keys from a tag value that is a HASH reference
|
|
2758
|
+
when the Struct option is used.
|
|
2759
|
+
|
|
2760
|
+
use Image::ExifTool ':Public';
|
|
2761
|
+
my @keys = OrderedKeys($structRef);
|
|
2762
|
+
|
|
2763
|
+
=over 4
|
|
2764
|
+
|
|
2765
|
+
=item Inputs:
|
|
2766
|
+
|
|
2767
|
+
0) Structure HASH reference
|
|
2768
|
+
|
|
2769
|
+
=item Return Value:
|
|
2770
|
+
|
|
2771
|
+
List of ordered keys, or sorted alphabetically if not ordered.
|
|
2772
|
+
|
|
2773
|
+
=back
|
|
2774
|
+
|
|
2752
2775
|
=head1 CHARACTER ENCODINGS
|
|
2753
2776
|
|
|
2754
2777
|
Certain meta information formats allow coded character sets other than plain
|
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
This
|
|
1
|
+
This readme is for the Windows ExifTool package by Oliver Betz.
|
|
2
|
+
|
|
3
|
+
This package is intended to avoid problems of the PAR packed original ExifTool for Windows.
|
|
2
4
|
|
|
3
5
|
It consists of:
|
|
4
6
|
|
|
5
7
|
* ExifTool by Phil Harvey https://exiftool.org/ resp. https://github.com/exiftool/exiftool
|
|
6
|
-
* Strawberry Perl
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
Please note that there can be up to three exiftool scripts in the "exiftool_files" directory:
|
|
10
|
-
* exiftool.pl - only this one is called by the launcher
|
|
11
|
-
* exiftool - this is from the original ExifTool distribution
|
|
12
|
-
* windows_exiftool - this is from the original ExifTool distribution
|
|
8
|
+
* Strawberry Perl https://strawberryperl.com/
|
|
9
|
+
* Tiny launcher by Oliver Betz https://oliverbetz.de/pages/Artikel/ExifTool-for-Windows
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
See https://exiftool.org/ and https://strawberryperl.com/ for the license of ExifTool and Strawberry Perl.
|
|
12
|
+
The launcher is licensed under the https://creativecommons.org/publicdomain/zero/1.0/legalcode CC0 license
|
|
16
13
|
|
|
17
14
|
I make no warranties about the package, and disclaim liability for all uses of the package, to the fullest extent permitted by applicable law.
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Oliver Betz
|
|
16
|
+
Oliver Betz
|
|
@@ -222,6 +222,7 @@ OPTIONS
|
|
|
222
222
|
|
|
223
223
|
Special features
|
|
224
224
|
|
|
225
|
+
-diff FILE2 Compare metadata with another file
|
|
225
226
|
-geotag TRKFILE Geotag images from specified GPS log
|
|
226
227
|
-globalTimeShift SHIFT Shift all formatted date/time values
|
|
227
228
|
-use MODULE Add features from plug-in module
|
|
@@ -311,8 +312,8 @@ OPTIONS
|
|
|
311
312
|
Write a new value for the specified tag (eg. "-comment=wow"), or
|
|
312
313
|
delete the tag if no *VALUE* is given (eg. "-comment="). "+=" and
|
|
313
314
|
"-=" are used to add or remove existing entries from a list, or to
|
|
314
|
-
shift date/time values (see Image::ExifTool::Shift.pl and
|
|
315
|
-
below for more details). "+=" may also be used to increment
|
|
315
|
+
shift date/time values (see Image::ExifTool::Shift.pl and notes 6
|
|
316
|
+
and 7 below for more details). "+=" may also be used to increment
|
|
316
317
|
numerical values (or decrement if *VALUE* is negative), and "-="
|
|
317
318
|
may be used to conditionally delete or replace a tag (see "WRITING
|
|
318
319
|
EXAMPLES" for examples). "^=" is used to write an empty string
|
|
@@ -398,6 +399,10 @@ OPTIONS
|
|
|
398
399
|
copy it to another tag in the same operation, use the
|
|
399
400
|
-globalTimeShift option.
|
|
400
401
|
|
|
402
|
+
7) The "+=" operator may not be used to shift a List-type date/time
|
|
403
|
+
tag (eg. XMP-dc:Date) because "+=" is used to add elements to the
|
|
404
|
+
list. Instead, the -globalTimeShift option should be used.
|
|
405
|
+
|
|
401
406
|
Special feature: Integer values may be specified in hexadecimal
|
|
402
407
|
with a leading "0x", and simple rational values may be specified as
|
|
403
408
|
fractions.
|
|
@@ -1034,7 +1039,7 @@ OPTIONS
|
|
|
1034
1039
|
|
|
1035
1040
|
produces output like this:
|
|
1036
1041
|
|
|
1037
|
-
-- Generated by ExifTool
|
|
1042
|
+
-- Generated by ExifTool 13.00 --
|
|
1038
1043
|
File: a.jpg - 2003:10:31 15:44:19
|
|
1039
1044
|
(f/5.6, 1/60s, ISO 100)
|
|
1040
1045
|
File: b.jpg - 2006:05:23 11:57:38
|
|
@@ -1584,10 +1589,10 @@ OPTIONS
|
|
|
1584
1589
|
the corresponding family 8 group name is specified for the tag. See
|
|
1585
1590
|
the -fileNUM option details for more information.
|
|
1586
1591
|
|
|
1587
|
-
5) The -a option
|
|
1588
|
-
and the values of duplicate tags are accessible
|
|
1589
|
-
a group name (such as a family 4
|
|
1590
|
-
$Copy2:TAG, etc).
|
|
1592
|
+
5) The -a (Duplicates) option is implied when -if is used without a
|
|
1593
|
+
fast *NUM*, and the values of duplicate tags are accessible by
|
|
1594
|
+
specifying a group name in the expression (such as a family 4
|
|
1595
|
+
instance number, eg. $Copy1:TAG, $Copy2:TAG, etc).
|
|
1591
1596
|
|
|
1592
1597
|
6) A special "OK" UserParam is available to test the success of the
|
|
1593
1598
|
previous command when -execute was used, and may be used like any
|
|
@@ -1849,9 +1854,9 @@ OPTIONS
|
|
|
1849
1854
|
The flags are formatted as a comma-separated list of the following
|
|
1850
1855
|
possible values: Avoid, Binary, List, Mandatory, Permanent,
|
|
1851
1856
|
Protected, Unknown and Unsafe (see the Tag Name documentation). For
|
|
1852
|
-
XMP List tags, the list type (Alt, Bag or Seq) is
|
|
1853
|
-
|
|
1854
|
-
|
|
1857
|
+
XMP List tags, the list type (Alt, Bag or Seq) is also given, and
|
|
1858
|
+
flattened structure tags are indicated by a Flattened flag with
|
|
1859
|
+
'struct' giving the ID of the parent structure.
|
|
1855
1860
|
|
|
1856
1861
|
Note that none of the -list options require an input *FILE*.
|
|
1857
1862
|
|
|
@@ -1864,6 +1869,23 @@ OPTIONS
|
|
|
1864
1869
|
as file names, even if they begin with a dash ("-").
|
|
1865
1870
|
|
|
1866
1871
|
Special features
|
|
1872
|
+
-diff *FILE2*
|
|
1873
|
+
Compare metadata in *FILE* with *FILE2*. The *FILE2* name may
|
|
1874
|
+
include filename formatting codes (see the -w option). All
|
|
1875
|
+
extracted tags from the files are compared, but the extracted tags
|
|
1876
|
+
may be controlled by adding -TAG or --TAG options. For example,
|
|
1877
|
+
below is a command to compare all the same-named files in two
|
|
1878
|
+
different directories, ignoring the System tags:
|
|
1879
|
+
|
|
1880
|
+
exiftool DIR1 -diff DIR2/%f.%e --system:all
|
|
1881
|
+
|
|
1882
|
+
The -g and -G options may be used to organize the output by the
|
|
1883
|
+
specified family of groups, with -G1 being the default. The -a
|
|
1884
|
+
option is implied. Adding -v includes a count of the number of tags
|
|
1885
|
+
that are the same in each group. The following text formatting
|
|
1886
|
+
options are valid when -diff is used: -c, -charset, -d, -E, -ec,
|
|
1887
|
+
-ex, -L, -lang, -n, -s, -sep, -struct and -w.
|
|
1888
|
+
|
|
1867
1889
|
-geotag *TRKFILE*
|
|
1868
1890
|
Geotag images from the specified GPS track log file. Using the
|
|
1869
1891
|
-geotag option is equivalent to writing a value to the "Geotag"
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "exiftool-vendored.exe",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "13.0.0",
|
|
4
4
|
"description": "Vendored win32 ExifTool for Node.js",
|
|
5
5
|
"main": "./index.js",
|
|
6
|
-
"homepage": "https://github.com/
|
|
6
|
+
"homepage": "https://github.com/photostructure/exiftool-vendored.exe#readme",
|
|
7
7
|
"bugs": {
|
|
8
|
-
"url": "https://github.com/
|
|
8
|
+
"url": "https://github.com/photostructure/exiftool-vendored.js/issues"
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
|
-
"url": "
|
|
12
|
+
"url": "git+ssh://git@github.com/photostructure/exiftool-vendored.exe.git"
|
|
13
13
|
},
|
|
14
14
|
"os": [
|
|
15
15
|
"win32"
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"axios": "^1.7.7",
|
|
46
|
-
"mocha": "^10.
|
|
47
|
-
"npm-check-updates": "^17.1.
|
|
46
|
+
"mocha": "^10.8.0",
|
|
47
|
+
"npm-check-updates": "^17.1.9",
|
|
48
48
|
"prettier": "^3.3.3",
|
|
49
|
-
"release-it": "^17.
|
|
49
|
+
"release-it": "^17.10.0",
|
|
50
50
|
"unzipper": "^0.12.3",
|
|
51
51
|
"xml2js": "^0.6.2"
|
|
52
52
|
}
|