exiftool_vendored 12.73.0 → 12.75.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 +41 -2
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +46 -45
- data/bin/exiftool +97 -83
- data/bin/lib/File/RandomAccess.pm +31 -5
- data/bin/lib/File/RandomAccess.pod +4 -4
- data/bin/lib/Image/ExifTool/7Z.pm +3 -3
- data/bin/lib/Image/ExifTool/AFCP.pm +2 -2
- data/bin/lib/Image/ExifTool/BZZ.pm +2 -2
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +7 -7
- data/bin/lib/Image/ExifTool/Canon.pm +6 -5
- data/bin/lib/Image/ExifTool/CanonVRD.pm +2 -2
- data/bin/lib/Image/ExifTool/DICOM.pm +2 -2
- data/bin/lib/Image/ExifTool/DNG.pm +4 -4
- data/bin/lib/Image/ExifTool/Exif.pm +3 -2
- data/bin/lib/Image/ExifTool/FLIR.pm +2 -2
- data/bin/lib/Image/ExifTool/Fixup.pm +3 -3
- data/bin/lib/Image/ExifTool/FlashPix.pm +3 -3
- data/bin/lib/Image/ExifTool/FujiFilm.pm +8 -3
- data/bin/lib/Image/ExifTool/Geotag.pm +3 -3
- data/bin/lib/Image/ExifTool/HtmlDump.pm +2 -2
- data/bin/lib/Image/ExifTool/ID3.pm +2 -2
- data/bin/lib/Image/ExifTool/Import.pm +5 -5
- data/bin/lib/Image/ExifTool/JSON.pm +2 -2
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +51 -12
- data/bin/lib/Image/ExifTool/MIE.pm +3 -3
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -2
- data/bin/lib/Image/ExifTool/Nikon.pm +3 -1
- data/bin/lib/Image/ExifTool/NikonCustom.pm +3 -3
- data/bin/lib/Image/ExifTool/Ogg.pm +2 -2
- data/bin/lib/Image/ExifTool/PDF.pm +54 -4
- data/bin/lib/Image/ExifTool/PLIST.pm +3 -3
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +3 -3
- data/bin/lib/Image/ExifTool/PhaseOne.pm +2 -2
- data/bin/lib/Image/ExifTool/Photoshop.pm +3 -3
- data/bin/lib/Image/ExifTool/PostScript.pm +2 -2
- data/bin/lib/Image/ExifTool/QuickTime.pm +41 -107
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +8 -6
- data/bin/lib/Image/ExifTool/RSRC.pm +2 -2
- data/bin/lib/Image/ExifTool/Samsung.pm +4 -4
- data/bin/lib/Image/ExifTool/Shift.pl +1 -2
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +3 -3
- data/bin/lib/Image/ExifTool/Sony.pm +3 -3
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +2 -2
- data/bin/lib/Image/ExifTool/TagLookup.pm +8 -5
- data/bin/lib/Image/ExifTool/TagNames.pod +36 -5
- data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteExif.pl +26 -23
- data/bin/lib/Image/ExifTool/WritePDF.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteXMP.pl +4 -2
- data/bin/lib/Image/ExifTool/Writer.pl +68 -44
- data/bin/lib/Image/ExifTool/XMP.pm +2 -1
- data/bin/lib/Image/ExifTool/XMP2.pl +9 -0
- data/bin/lib/Image/ExifTool/ZIP.pm +6 -6
- data/bin/lib/Image/ExifTool.pm +42 -26
- data/bin/lib/Image/ExifTool.pod +76 -71
- data/bin/perl-Image-ExifTool.spec +45 -44
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
@@ -171,9 +171,9 @@ sub RebuildMakerNotes($$$)
|
|
171
171
|
my $saveOrder = GetByteOrder();
|
172
172
|
my $loc = Image::ExifTool::MakerNotes::LocateIFD($et,\%subdirInfo);
|
173
173
|
if (defined $loc) {
|
174
|
-
my $makerFixup = $subdirInfo{Fixup} =
|
174
|
+
my $makerFixup = $subdirInfo{Fixup} = Image::ExifTool::Fixup->new;
|
175
175
|
# create new exiftool object to rewrite the directory without changing it
|
176
|
-
my $newTool =
|
176
|
+
my $newTool = Image::ExifTool->new;
|
177
177
|
$newTool->Options(
|
178
178
|
IgnoreMinorErrors => $$et{OPTIONS}{IgnoreMinorErrors},
|
179
179
|
FixBase => $$et{OPTIONS}{FixBase},
|
@@ -565,7 +565,7 @@ sub WriteExif($$$)
|
|
565
565
|
my $firstBase = $base;
|
566
566
|
my $raf = $$dirInfo{RAF};
|
567
567
|
my $dirName = $$dirInfo{DirName} || 'unknown';
|
568
|
-
my $fixup = $$dirInfo{Fixup} ||
|
568
|
+
my $fixup = $$dirInfo{Fixup} || Image::ExifTool::Fixup->new;
|
569
569
|
my $imageDataFlag = $$dirInfo{ImageData} || '';
|
570
570
|
my $verbose = $et->Options('Verbose');
|
571
571
|
my $out = $et->Options('TextOut');
|
@@ -745,7 +745,7 @@ sub WriteExif($$$)
|
|
745
745
|
my $valBuff = ''; # buffer for value data
|
746
746
|
my @valFixups; # list of fixups for offsets in valBuff
|
747
747
|
# fixup for offsets in dirBuff
|
748
|
-
my $dirFixup =
|
748
|
+
my $dirFixup = Image::ExifTool::Fixup->new;
|
749
749
|
my $entryBasedFixup;
|
750
750
|
my $lastTagID = -1;
|
751
751
|
my ($oldInfo, $oldFormat, $oldFormName, $oldCount, $oldSize, $oldValue, $oldImageData);
|
@@ -896,7 +896,7 @@ Entry: for (;;) {
|
|
896
896
|
TagInfo => $oldInfo || $tmpInfo,
|
897
897
|
Offset => $base + $valuePtr + $dataPos,
|
898
898
|
Size => $oldSize,
|
899
|
-
Fixup =>
|
899
|
+
Fixup => Image::ExifTool::Fixup->new,
|
900
900
|
},
|
901
901
|
$invalidPreview = 2;
|
902
902
|
# remove SubDirectory to prevent processing (for now)
|
@@ -1348,7 +1348,7 @@ NoOverwrite: next if $isNew > 0;
|
|
1348
1348
|
# create empty source directory
|
1349
1349
|
my %sourceDir = (
|
1350
1350
|
Parent => $dirName,
|
1351
|
-
Fixup =>
|
1351
|
+
Fixup => Image::ExifTool::Fixup->new,
|
1352
1352
|
);
|
1353
1353
|
$sourceDir{DirName} = $$newInfo{Groups}{1} if $$newInfo{SubIFD};
|
1354
1354
|
$newValue = $et->WriteDirectory(\%sourceDir, $subTable);
|
@@ -1509,7 +1509,7 @@ NoOverwrite: next if $isNew > 0;
|
|
1509
1509
|
}
|
1510
1510
|
if (defined $loc) {
|
1511
1511
|
# we need fixup data for this subdirectory
|
1512
|
-
$subdirInfo{Fixup} =
|
1512
|
+
$subdirInfo{Fixup} = Image::ExifTool::Fixup->new;
|
1513
1513
|
# rewrite maker notes
|
1514
1514
|
my $changed = $$et{CHANGED};
|
1515
1515
|
$subdir = $et->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
|
@@ -1673,7 +1673,7 @@ NoOverwrite: next if $isNew > 0;
|
|
1673
1673
|
Name => $$newInfo{Name},
|
1674
1674
|
TagInfo => $newInfo,
|
1675
1675
|
Parent => $dirName,
|
1676
|
-
Fixup =>
|
1676
|
+
Fixup => Image::ExifTool::Fixup->new,
|
1677
1677
|
RAF => $raf,
|
1678
1678
|
Subdir => $subdir,
|
1679
1679
|
# set ImageData only for 1st level SubIFD's
|
@@ -1782,7 +1782,7 @@ NoOverwrite: next if $isNew > 0;
|
|
1782
1782
|
#### eval Base ($start,$base)
|
1783
1783
|
$subdirBase += eval $$subdir{Base};
|
1784
1784
|
}
|
1785
|
-
my $subFixup =
|
1785
|
+
my $subFixup = Image::ExifTool::Fixup->new;
|
1786
1786
|
my %subdirInfo = (
|
1787
1787
|
Base => $subdirBase,
|
1788
1788
|
DataPt => $valueDataPt,
|
@@ -1995,7 +1995,7 @@ NoOverwrite: next if $isNew > 0;
|
|
1995
1995
|
# hold onto the PreviewImage until we can determine if it fits
|
1996
1996
|
$$et{PREVIEW_INFO} or $$et{PREVIEW_INFO} = {
|
1997
1997
|
Data => $$newValuePt,
|
1998
|
-
Fixup =>
|
1998
|
+
Fixup => Image::ExifTool::Fixup->new,
|
1999
1999
|
};
|
2000
2000
|
$$et{PREVIEW_INFO}{ChangeBase} = 1 if $$newInfo{ChangeBase};
|
2001
2001
|
if ($$newInfo{IsOffset} and $$newInfo{IsOffset} eq '2') {
|
@@ -2017,7 +2017,7 @@ NoOverwrite: next if $isNew > 0;
|
|
2017
2017
|
$valBuff .= $$newValuePt; # add value data to buffer
|
2018
2018
|
# must save a fixup pointer for every pointer in the directory
|
2019
2019
|
if ($entryBased) {
|
2020
|
-
$entryBasedFixup or $entryBasedFixup =
|
2020
|
+
$entryBasedFixup or $entryBasedFixup = Image::ExifTool::Fixup->new;
|
2021
2021
|
$entryBasedFixup->AddFixup(length($dirBuff) + 8, $dataTag);
|
2022
2022
|
} else {
|
2023
2023
|
$dirFixup->AddFixup(length($dirBuff) + 8, $dataTag);
|
@@ -2277,14 +2277,17 @@ NoOverwrite: next if $isNew > 0;
|
|
2277
2277
|
$$offsetInfo{0x117} and $$offsetInfo{0x145} and
|
2278
2278
|
$$offsetInfo{0x111}[2]==1) # (must be a single strip or the tile offsets could get out of sync)
|
2279
2279
|
{
|
2280
|
-
#
|
2281
|
-
|
2282
|
-
|
2283
|
-
|
2284
|
-
|
2285
|
-
|
2286
|
-
|
2287
|
-
|
2280
|
+
# check the start offsets to see if they are the same
|
2281
|
+
if ($$offsetInfo{0x111}[3] == $$offsetInfo{0x144}[3]) {
|
2282
|
+
# some Sony ARW images contain double-referenced raw data stored as both strips
|
2283
|
+
# and tiles. Copy the data using only the strip tags, but store the TileOffets
|
2284
|
+
# information for updating later (see PanasonicRaw:PatchRawDataOffset for a
|
2285
|
+
# description of offsetInfo elements)
|
2286
|
+
$$offsetInfo{0x111}[5] = $$offsetInfo{0x144}; # hack to save TileOffsets
|
2287
|
+
# delete tile information from offsetInfo because we will copy as strips
|
2288
|
+
delete $$offsetInfo{0x144};
|
2289
|
+
delete $$offsetInfo{0x145};
|
2290
|
+
}
|
2288
2291
|
} else {
|
2289
2292
|
$et->Error("TIFF $dirName contains both strip and tile data");
|
2290
2293
|
}
|
@@ -2451,7 +2454,7 @@ NoOverwrite: next if $isNew > 0;
|
|
2451
2454
|
$newOffset += $blockSize; # data comes after other deferred data
|
2452
2455
|
# create fixup for SubIFD ImageData
|
2453
2456
|
if ($imageDataFlag eq 'SubIFD' and not $subIfdDataFixup) {
|
2454
|
-
$subIfdDataFixup =
|
2457
|
+
$subIfdDataFixup = Image::ExifTool::Fixup->new;
|
2455
2458
|
$imageData[-1][4] = $subIfdDataFixup;
|
2456
2459
|
}
|
2457
2460
|
$size += $pad; # account for pad byte if necessary
|
@@ -2522,7 +2525,7 @@ NoOverwrite: next if $isNew > 0;
|
|
2522
2525
|
# hold onto the PreviewImage until we can determine if it fits
|
2523
2526
|
$$et{PREVIEW_INFO} or $$et{PREVIEW_INFO} = {
|
2524
2527
|
Data => $buff,
|
2525
|
-
Fixup =>
|
2528
|
+
Fixup => Image::ExifTool::Fixup->new,
|
2526
2529
|
};
|
2527
2530
|
if ($$tagInfo{IsOffset} and $$tagInfo{IsOffset} eq '2') {
|
2528
2531
|
$$et{PREVIEW_INFO}{NoBaseShift} = 1;
|
@@ -2603,7 +2606,7 @@ NoOverwrite: next if $isNew > 0;
|
|
2603
2606
|
$fixup->AddFixup($entry + 8);
|
2604
2607
|
# create special fixup for SubIFD data
|
2605
2608
|
if ($imageDataFlag eq 'SubIFD') {
|
2606
|
-
my $subIfdDataFixup =
|
2609
|
+
my $subIfdDataFixup = Image::ExifTool::Fixup->new;
|
2607
2610
|
$subIfdDataFixup->AddFixup($entry + 8);
|
2608
2611
|
# save fixup in imageData list
|
2609
2612
|
$$blockInfo[4] = $subIfdDataFixup;
|
@@ -2668,7 +2671,7 @@ NoOverwrite: next if $isNew > 0;
|
|
2668
2671
|
} else {
|
2669
2672
|
# Doesn't fit, or we still don't know, so save fixup information
|
2670
2673
|
# and put the preview at the end of the file
|
2671
|
-
$$previewInfo{Fixup} or $$previewInfo{Fixup} =
|
2674
|
+
$$previewInfo{Fixup} or $$previewInfo{Fixup} = Image::ExifTool::Fixup->new;
|
2672
2675
|
$$previewInfo{Fixup}->AddFixup($fixup);
|
2673
2676
|
}
|
2674
2677
|
} elsif (defined $newData and $deleteAll) {
|
@@ -290,7 +290,7 @@ sub WritePDF($$)
|
|
290
290
|
$raf->Seek($pos, 0);
|
291
291
|
|
292
292
|
# create a new ExifTool object and use it to read PDF and XMP information
|
293
|
-
my $newTool =
|
293
|
+
my $newTool = Image::ExifTool->new;
|
294
294
|
$newTool->Options(List => 1);
|
295
295
|
$newTool->Options(Password => $et->Options('Password'));
|
296
296
|
$newTool->Options(NoPDFList => $et->Options('NoPDFList'));
|
@@ -1083,6 +1083,8 @@ sub WriteXMP($$;$)
|
|
1083
1083
|
# delete all structure (or pseudo-structure) elements
|
1084
1084
|
require 'Image/ExifTool/XMPStruct.pl';
|
1085
1085
|
($deleted, $added, $existed) = DeleteStruct($et, \%capture, \$path, $nvHash, \$changed);
|
1086
|
+
# don't add if it didn't exist and not IsCreating and Avoid
|
1087
|
+
undef $added if not $existed and not $$nvHash{IsCreating} and $$tagInfo{Avoid};
|
1086
1088
|
next unless $deleted or $added or $et->IsOverwriting($nvHash);
|
1087
1089
|
next if $existed and $$nvHash{CreateOnly};
|
1088
1090
|
} elsif ($cap) {
|
@@ -1262,8 +1264,8 @@ sub WriteXMP($$;$)
|
|
1262
1264
|
# check to see if we want to create this tag
|
1263
1265
|
# (create non-avoided tags in XMP data files by default)
|
1264
1266
|
my $isCreating = ($$nvHash{IsCreating} or (($isStruct or
|
1265
|
-
($preferred and not $$
|
1266
|
-
|
1267
|
+
($preferred and not defined $$nvHash{Shift})) and
|
1268
|
+
not $$tagInfo{Avoid} and not $$nvHash{EditOnly}));
|
1267
1269
|
|
1268
1270
|
# don't add new values unless...
|
1269
1271
|
# ...tag existed before and was deleted, or we added it to a list
|
@@ -26,6 +26,7 @@ sub RemoveNewValuesForGroup($$);
|
|
26
26
|
sub GetWriteGroup1($$);
|
27
27
|
sub Sanitize($$);
|
28
28
|
sub ConvInv($$$$$;$$);
|
29
|
+
sub PushValue($$$;$);
|
29
30
|
|
30
31
|
my $loadedAllTables; # flag indicating we loaded all tables
|
31
32
|
my $advFmtSelf; # ExifTool object during evaluation of advanced formatting expr
|
@@ -1260,7 +1261,7 @@ sub SetNewValuesFromFile($$;@)
|
|
1260
1261
|
}
|
1261
1262
|
# expand shortcuts
|
1262
1263
|
@setTags and ExpandShortcuts(\@setTags);
|
1263
|
-
my $srcExifTool =
|
1264
|
+
my $srcExifTool = Image::ExifTool->new;
|
1264
1265
|
# set flag to indicate we are being called from inside SetNewValuesFromFile()
|
1265
1266
|
$$srcExifTool{TAGS_FROM_FILE} = 1;
|
1266
1267
|
# synchronize and increment the file sequence number
|
@@ -1582,7 +1583,7 @@ SET: foreach $set (@setList) {
|
|
1582
1583
|
my $opts = $$set[3];
|
1583
1584
|
# handle expressions
|
1584
1585
|
if ($$opts{EXPR}) {
|
1585
|
-
my $val = $srcExifTool->InsertTagValues(
|
1586
|
+
my $val = $srcExifTool->InsertTagValues($$set[1], \@tags, 'Error');
|
1586
1587
|
my $err = $$srcExifTool{VALUE}{Error};
|
1587
1588
|
if ($err) {
|
1588
1589
|
# pass on any error as a warning unless it is suppressed
|
@@ -2432,7 +2433,7 @@ sub WriteInfo($$;$$)
|
|
2432
2433
|
#
|
2433
2434
|
until ($$self{VALUE}{Error}) {
|
2434
2435
|
# create random access file object (disable seek test in case of straight copy)
|
2435
|
-
$raf or $raf =
|
2436
|
+
$raf or $raf = File::RandomAccess->new($inRef, 1);
|
2436
2437
|
$raf->BinMode();
|
2437
2438
|
if ($numNew == $numPseudo) {
|
2438
2439
|
$rtnVal = 1;
|
@@ -2703,7 +2704,7 @@ sub GetAllTags(;$)
|
|
2703
2704
|
my (%allTags, @groups);
|
2704
2705
|
@groups = split ':', $group if $group;
|
2705
2706
|
|
2706
|
-
my $et =
|
2707
|
+
my $et = Image::ExifTool->new;
|
2707
2708
|
LoadAllTables(); # first load all our tables
|
2708
2709
|
my @tableNames = keys %allTables;
|
2709
2710
|
|
@@ -2748,7 +2749,7 @@ sub GetWritableTags(;$)
|
|
2748
2749
|
my (%writableTags, @groups);
|
2749
2750
|
@groups = split ':', $group if $group;
|
2750
2751
|
|
2751
|
-
my $et =
|
2752
|
+
my $et = Image::ExifTool->new;
|
2752
2753
|
LoadAllTables();
|
2753
2754
|
my @tableNames = keys %allTables;
|
2754
2755
|
|
@@ -3124,11 +3125,37 @@ Conv: for (;;) {
|
|
3124
3125
|
return($val, $err);
|
3125
3126
|
}
|
3126
3127
|
|
3128
|
+
#------------------------------------------------------------------------------
|
3129
|
+
# Dereference value and push onto list
|
3130
|
+
# Inputs: 0) ExifTool ref, 1) value, 2) list ref, 3) flag to push MissingTagValue for undef value
|
3131
|
+
sub PushValue($$$;$)
|
3132
|
+
{
|
3133
|
+
local $_;
|
3134
|
+
my ($self, $val, $list, $missing) = @_;
|
3135
|
+
if (ref $val eq 'ARRAY' and ref $$val[0] ne 'HASH') {
|
3136
|
+
$self->PushValue($_, $list, $missing) foreach @$val;
|
3137
|
+
} elsif (ref $val eq 'SCALAR') {
|
3138
|
+
if ($$self{OPTIONS}{Binary} or $$val =~ /^Binary data/) {
|
3139
|
+
push @$list, $$val;
|
3140
|
+
} else {
|
3141
|
+
push @$list, 'Binary data ' . length($$val) . ' bytes';
|
3142
|
+
}
|
3143
|
+
} elsif (ref $val eq 'HASH' or ref $val eq 'ARRAY') {
|
3144
|
+
require 'Image/ExifTool/XMPStruct.pl';
|
3145
|
+
push @$list, Image::ExifTool::XMP::SerializeStruct($self, $val);
|
3146
|
+
} elsif (not defined $val) {
|
3147
|
+
my $mval = $$self{OPTIONS}{MissingTagValue};
|
3148
|
+
push @$list, $mval if $missing and defined $mval;
|
3149
|
+
} else {
|
3150
|
+
push @$list, $val;
|
3151
|
+
}
|
3152
|
+
}
|
3153
|
+
|
3127
3154
|
#------------------------------------------------------------------------------
|
3128
3155
|
# Convert tag names to values or variables in a string
|
3129
3156
|
# (eg. '${EXIF:ISO}x $$' --> '100x $' without hash ref, or "$info{'EXIF:ISO'}x $" with)
|
3130
|
-
# Inputs: 0) ExifTool object ref, 1)
|
3131
|
-
# 2)
|
3157
|
+
# Inputs: 0) ExifTool object ref, 1) string with embedded tag names,
|
3158
|
+
# 2) reference to list of found tags or undef to use FOUND_TAGS, 3) Options:
|
3132
3159
|
# undef - set missing tags to ''
|
3133
3160
|
# 'Error' - issue minor error on missing tag (and return undef)
|
3134
3161
|
# 'Warn' - issue minor warning on missing tag (and return undef)
|
@@ -3145,20 +3172,22 @@ Conv: for (;;) {
|
|
3145
3172
|
# - advanced feature allows Perl expressions inside braces (eg. '${model;tr/ //d}')
|
3146
3173
|
# - an error/warning in an advanced expression ("${TAG;EXPR}") generates an error
|
3147
3174
|
# if option set to 'Error', or a warning otherwise
|
3148
|
-
sub InsertTagValues(
|
3175
|
+
sub InsertTagValues($$;$$$$)
|
3149
3176
|
{
|
3150
3177
|
local $_;
|
3151
|
-
my ($self, $
|
3178
|
+
my ($self, $line, $foundTags, $opt, $docGrp, $cache) = @_;
|
3152
3179
|
my $rtnStr = '';
|
3153
3180
|
my ($docNum, $tag);
|
3181
|
+
|
3154
3182
|
if ($docGrp) {
|
3155
3183
|
$docNum = $docGrp =~ /(\d+)$/ ? $1 : 0;
|
3156
3184
|
} else {
|
3157
3185
|
undef $cache; # no cache if no document groups
|
3158
3186
|
}
|
3187
|
+
$foundTags or $foundTags = $$self{FOUND_TAGS} || [];
|
3159
3188
|
while ($line =~ s/(.*?)\$(\{\s*)?([-\w]*\w|\$|\/)//s) {
|
3160
3189
|
my ($pre, $bra, $var) = ($1, $2, $3);
|
3161
|
-
my (@tags, $
|
3190
|
+
my (@tags, $tg, $val, @val, $type, $expr, $didExpr, $level, $asList);
|
3162
3191
|
# "$$" represents a "$" symbol, and "$/" is a newline
|
3163
3192
|
if ($var eq '$' or $var eq '/') {
|
3164
3193
|
$line =~ s/^\s*\}// if $bra;
|
@@ -3261,15 +3290,24 @@ sub InsertTagValues($$$;$$$)
|
|
3261
3290
|
} elsif (defined $$et{OPTIONS}{UserParam}{$lcTag}) {
|
3262
3291
|
$val = $$et{OPTIONS}{UserParam}{$lcTag};
|
3263
3292
|
} elsif ($tag =~ /(.*):(.+)/) {
|
3264
|
-
my $group;
|
3293
|
+
my ($group, @matches);
|
3265
3294
|
($group, $tag) = ($1, $2);
|
3266
|
-
|
3267
|
-
|
3268
|
-
|
3269
|
-
|
3295
|
+
# join values of all matching tags if "All" group is used
|
3296
|
+
# (and remove "All" from group prefix)
|
3297
|
+
if ($group =~ s/(^|:)(all|\*)(:|$)/$1 and $3/ei) {
|
3298
|
+
if (lc $tag eq 'all') {
|
3299
|
+
@matches = $group ? $et->GroupMatches($group, $fileTags) : @$fileTags;
|
3300
|
+
} else {
|
3301
|
+
@matches = grep /^$tag(\s|$)/i, @$fileTags;
|
3302
|
+
@matches = $et->GroupMatches($group, \@matches) if $group;
|
3303
|
+
}
|
3304
|
+
$self->PushValue(scalar $et->GetValue($_, $type), \@val) foreach @matches;
|
3305
|
+
} elsif (lc $tag eq 'all') {
|
3306
|
+
# return "1" if any tag from the specified group exists
|
3307
|
+
$val = $et->GroupMatches($group, $fileTags) ? 1 : 0;
|
3270
3308
|
} else {
|
3271
3309
|
# find the specified tag
|
3272
|
-
|
3310
|
+
@matches = grep /^$tag(\s|$)/i, @$fileTags;
|
3273
3311
|
@matches = $et->GroupMatches($group, \@matches);
|
3274
3312
|
foreach $tg (@matches) {
|
3275
3313
|
if (defined $val and $tg =~ / \((\d+)\)$/) {
|
@@ -3298,31 +3336,15 @@ sub InsertTagValues($$$;$$$)
|
|
3298
3336
|
}
|
3299
3337
|
}
|
3300
3338
|
$self->Options(ListJoin => $oldListJoin) if $asList;
|
3301
|
-
|
3302
|
-
push @val, @$val;
|
3303
|
-
undef $val;
|
3304
|
-
last unless @tags;
|
3305
|
-
} elsif (ref $val eq 'SCALAR') {
|
3306
|
-
if ($$self{OPTIONS}{Binary} or $$val =~ /^Binary data/) {
|
3307
|
-
$val = $$val;
|
3308
|
-
} else {
|
3309
|
-
$val = 'Binary data ' . length($$val) . ' bytes';
|
3310
|
-
}
|
3311
|
-
} elsif (ref $val eq 'HASH') {
|
3312
|
-
require 'Image/ExifTool/XMPStruct.pl';
|
3313
|
-
$val = Image::ExifTool::XMP::SerializeStruct($self, $val);
|
3314
|
-
} elsif (not defined $val) {
|
3315
|
-
$val = $$self{OPTIONS}{MissingTagValue} if $asList;
|
3316
|
-
}
|
3317
|
-
last unless @tags;
|
3318
|
-
push @val, $val if defined $val;
|
3339
|
+
$self->PushValue($val, \@val, $asList);
|
3319
3340
|
undef $val;
|
3341
|
+
last unless @tags;
|
3320
3342
|
}
|
3321
3343
|
if (@val) {
|
3322
|
-
|
3344
|
+
$self->PushValue($val, \@val) if defined $val;
|
3323
3345
|
$val = join $$self{OPTIONS}{ListSep}, @val;
|
3324
|
-
}
|
3325
|
-
|
3346
|
+
} elsif (defined $val) {
|
3347
|
+
$self->PushValue($val, \@val); # (so the eval has access to @val if required)
|
3326
3348
|
}
|
3327
3349
|
# evaluate advanced formatting expression if given (eg. "${TAG;EXPR}")
|
3328
3350
|
if (defined $expr and defined $val) {
|
@@ -3331,7 +3353,7 @@ sub InsertTagValues($$$;$$$)
|
|
3331
3353
|
$advFmtSelf = $self;
|
3332
3354
|
if ($asList) {
|
3333
3355
|
foreach (@val) {
|
3334
|
-
#### eval advanced formatting expression ($_, $self, @val, $advFmtSelf)
|
3356
|
+
#### eval advanced formatting expression ($_, $self, @val, $tag, $advFmtSelf)
|
3335
3357
|
eval $expr;
|
3336
3358
|
$@ and $evalWarning = $@;
|
3337
3359
|
}
|
@@ -3340,7 +3362,7 @@ sub InsertTagValues($$$;$$$)
|
|
3340
3362
|
$val = @val ? join $$self{OPTIONS}{ListSep}, @val : undef;
|
3341
3363
|
} else {
|
3342
3364
|
$_ = $val;
|
3343
|
-
#### eval advanced formatting expression ($_, $self, @val, $advFmtSelf)
|
3365
|
+
#### eval advanced formatting expression ($_, $self, @val, $tag, $advFmtSelf)
|
3344
3366
|
eval $expr;
|
3345
3367
|
$@ and $evalWarning = $@;
|
3346
3368
|
$val = ref $_ eq 'ARRAY' ? join($$self{OPTIONS}{ListSep}, @$_): $_;
|
@@ -3395,6 +3417,7 @@ sub InsertTagValues($$$;$$$)
|
|
3395
3417
|
#------------------------------------------------------------------------------
|
3396
3418
|
# Reformat date/time value in $_ based on specified format string
|
3397
3419
|
# Inputs: 0) date/time format string
|
3420
|
+
# Returns: Reformatted date/time string
|
3398
3421
|
sub DateFmt($)
|
3399
3422
|
{
|
3400
3423
|
my $et = bless { OPTIONS => { DateFormat => shift, StrictDate => 1 } };
|
@@ -3406,6 +3429,7 @@ sub DateFmt($)
|
|
3406
3429
|
$_ = $et->ConvertDateTime($_);
|
3407
3430
|
defined $_ or warn "Error converting date/time\n";
|
3408
3431
|
$$advFmtSelf{GLOBAL_TIME_OFFSET} = $$et{GLOBAL_TIME_OFFSET} if $shift;
|
3432
|
+
return $_;
|
3409
3433
|
}
|
3410
3434
|
|
3411
3435
|
#------------------------------------------------------------------------------
|
@@ -3515,7 +3539,7 @@ sub CreateDirectory($$)
|
|
3515
3539
|
}
|
3516
3540
|
unless ($k32CreateDir) {
|
3517
3541
|
return -1 if defined $k32CreateDir;
|
3518
|
-
$k32CreateDir =
|
3542
|
+
$k32CreateDir = Win32::API->new('KERNEL32', 'CreateDirectoryW', 'PP', 'I');
|
3519
3543
|
unless ($k32CreateDir) {
|
3520
3544
|
$self->Warn('Error calling Win32::API::CreateDirectoryW');
|
3521
3545
|
$k32CreateDir = 0;
|
@@ -6233,7 +6257,7 @@ sub WriteJPEG($$)
|
|
6233
6257
|
last unless $$editDirs{CIFF};
|
6234
6258
|
my $newData = '';
|
6235
6259
|
my %dirInfo = (
|
6236
|
-
RAF =>
|
6260
|
+
RAF => File::RandomAccess->new($segDataPt),
|
6237
6261
|
OutFile => \$newData,
|
6238
6262
|
);
|
6239
6263
|
require Image::ExifTool::CanonRaw;
|
@@ -6952,7 +6976,7 @@ sub SetFileTime($$;$$$$)
|
|
6952
6976
|
}
|
6953
6977
|
unless ($k32SetFileTime) {
|
6954
6978
|
return 0 if defined $k32SetFileTime;
|
6955
|
-
$k32SetFileTime =
|
6979
|
+
$k32SetFileTime = Win32::API->new('KERNEL32', 'SetFileTime', 'NPPP', 'I');
|
6956
6980
|
unless ($k32SetFileTime) {
|
6957
6981
|
$self->Warn('Error calling Win32::API::SetFileTime');
|
6958
6982
|
$k32SetFileTime = 0;
|
@@ -7196,7 +7220,7 @@ sub WriteBinaryData($$$)
|
|
7196
7220
|
$$self{HiddenData} = {
|
7197
7221
|
Offset => $offset,
|
7198
7222
|
Size => $size,
|
7199
|
-
Fixup =>
|
7223
|
+
Fixup => Image::ExifTool::Fixup->new,
|
7200
7224
|
Base => $$dirInfo{Base},
|
7201
7225
|
};
|
7202
7226
|
next;
|
@@ -7205,7 +7229,7 @@ sub WriteBinaryData($$$)
|
|
7205
7229
|
next unless $$tagInfo{DataTag} eq 'PreviewImage' and $$self{FILE_TYPE} eq 'JPEG';
|
7206
7230
|
my $previewInfo = $$self{PREVIEW_INFO};
|
7207
7231
|
$previewInfo or $previewInfo = $$self{PREVIEW_INFO} = {
|
7208
|
-
Fixup =>
|
7232
|
+
Fixup => Image::ExifTool::Fixup->new,
|
7209
7233
|
};
|
7210
7234
|
# set flag indicating we are using short pointers
|
7211
7235
|
$$previewInfo{IsShort} = 1 unless $format eq 'int32u';
|
@@ -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.63';
|
54
54
|
@ISA = qw(Exporter);
|
55
55
|
@EXPORT_OK = qw(EscapeXML UnescapeXML);
|
56
56
|
|
@@ -3644,6 +3644,7 @@ NoLoop:
|
|
3644
3644
|
IgnoreProp => $$subdir{IgnoreProp}, # (allow XML to ignore specified properties)
|
3645
3645
|
IsExtended => 1, # (hack to avoid Duplicate warning for embedded XMP)
|
3646
3646
|
NoStruct => 1, # (don't try to build structures since this isn't true XMP)
|
3647
|
+
NoBlockSave => 1,# (don't save as a block because we already did this)
|
3647
3648
|
);
|
3648
3649
|
my $oldOrder = GetByteOrder();
|
3649
3650
|
SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder};
|
@@ -2191,6 +2191,15 @@ my %sSubVersion = (
|
|
2191
2191
|
GROUPS => { 0 => 'SVG', 2 => 'Unknown' },
|
2192
2192
|
LANG_INFO => \&GetLangInfo,
|
2193
2193
|
NAMESPACE => undef, # variable namespace
|
2194
|
+
'c2pa:manifest' => {
|
2195
|
+
Name => 'JUMBF',
|
2196
|
+
Groups => { 0 => 'JUMBF' },
|
2197
|
+
RawConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
|
2198
|
+
SubDirectory => {
|
2199
|
+
TagTable => 'Image::ExifTool::Jpeg2000::Main',
|
2200
|
+
ByteOrder => 'BigEndian',
|
2201
|
+
},
|
2202
|
+
},
|
2194
2203
|
);
|
2195
2204
|
|
2196
2205
|
#------------------------------------------------------------------------------
|
@@ -20,7 +20,7 @@ use strict;
|
|
20
20
|
use vars qw($VERSION $warnString);
|
21
21
|
use Image::ExifTool qw(:DataAccess :Utils);
|
22
22
|
|
23
|
-
$VERSION = '1.
|
23
|
+
$VERSION = '1.31';
|
24
24
|
|
25
25
|
sub WarnProc($) { $warnString = $_[0]; }
|
26
26
|
|
@@ -367,7 +367,7 @@ sub ProcessRAR($$)
|
|
367
367
|
# read the header and create new RAF object for reading it
|
368
368
|
my $header;
|
369
369
|
$raf->Read($header, $headSize) == $headSize or last;
|
370
|
-
my $rafHdr =
|
370
|
+
my $rafHdr = File::RandomAccess->new(\$header);
|
371
371
|
my $headType = ReadULEB($rafHdr); # get header type
|
372
372
|
|
373
373
|
if ($headType == 4) { # encryption block
|
@@ -550,14 +550,14 @@ sub ProcessZIP($$)
|
|
550
550
|
} elsif (eval { require IO::String }) {
|
551
551
|
# read the whole file into memory (what else can I do?)
|
552
552
|
$raf->Slurp();
|
553
|
-
$fh =
|
553
|
+
$fh = IO::String->new(${$raf->{BUFF_PT}});
|
554
554
|
} else {
|
555
555
|
my $type = $raf->{FILE_PT} ? 'pipe or socket' : 'scalar reference';
|
556
556
|
$et->Warn("Install IO::String to decode compressed ZIP information from a $type");
|
557
557
|
last;
|
558
558
|
}
|
559
559
|
$et->VPrint(1, " --- using Archive::Zip ---\n");
|
560
|
-
$zip =
|
560
|
+
$zip = Archive::Zip->new;
|
561
561
|
# catch all warnings! (Archive::Zip is bad for this)
|
562
562
|
local $SIG{'__WARN__'} = \&WarnProc;
|
563
563
|
my $status = $zip->readFromFileHandle($fh);
|
@@ -568,8 +568,8 @@ sub ProcessZIP($$)
|
|
568
568
|
# a failed test with Perl 5.6.2 GNU/Linux 2.6.32-5-686 i686-linux-64int-ld
|
569
569
|
$raf->Seek(0,0);
|
570
570
|
$raf->Slurp();
|
571
|
-
$fh =
|
572
|
-
$zip =
|
571
|
+
$fh = IO::String->new(${$raf->{BUFF_PT}});
|
572
|
+
$zip = Archive::Zip->new;
|
573
573
|
$status = $zip->readFromFileHandle($fh);
|
574
574
|
}
|
575
575
|
if ($status) {
|