exiftool_vendored 12.58.0 → 12.60.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 +45 -3
- data/bin/MANIFEST +4 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/config_files/example.config +1 -0
- data/bin/exiftool +81 -54
- data/bin/lib/Image/ExifTool/CanonRaw.pm +5 -1
- data/bin/lib/Image/ExifTool/DJI.pm +2 -2
- data/bin/lib/Image/ExifTool/Exif.pm +53 -14
- data/bin/lib/Image/ExifTool/FlashPix.pm +27 -9
- data/bin/lib/Image/ExifTool/FujiFilm.pm +6 -3
- data/bin/lib/Image/ExifTool/Geotag.pm +30 -7
- data/bin/lib/Image/ExifTool/LIF.pm +10 -2
- data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -1
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -1
- data/bin/lib/Image/ExifTool/Nikon.pm +6 -5
- data/bin/lib/Image/ExifTool/Olympus.pm +87 -7
- data/bin/lib/Image/ExifTool/PNG.pm +10 -2
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
- data/bin/lib/Image/ExifTool/PhaseOne.pm +14 -1
- data/bin/lib/Image/ExifTool/QuickTime.pm +21 -6
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +37 -5
- data/bin/lib/Image/ExifTool/RIFF.pm +32 -11
- data/bin/lib/Image/ExifTool/Ricoh.pm +2 -1
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +9 -3
- data/bin/lib/Image/ExifTool/Sony.pm +2 -1
- data/bin/lib/Image/ExifTool/TagLookup.pm +2254 -2246
- data/bin/lib/Image/ExifTool/TagNames.pod +45 -25
- data/bin/lib/Image/ExifTool/WriteExif.pl +13 -13
- data/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
- data/bin/lib/Image/ExifTool/Writer.pl +111 -19
- data/bin/lib/Image/ExifTool/XMP.pm +18 -3
- data/bin/lib/Image/ExifTool/XMP2.pl +2 -1
- data/bin/lib/Image/ExifTool.pm +109 -17
- data/bin/lib/Image/ExifTool.pod +40 -5
- 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 26393 tags, with 16860 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
|
@@ -498,6 +498,9 @@ for the official EXIF 2.32 specification.
|
|
498
498
|
0x7035 ChromaticAberrationCorrParams SubIFD int16s[33]!
|
499
499
|
0x7036 DistortionCorrection SubIFD int16s!
|
500
500
|
0x7037 DistortionCorrParams SubIFD int16s[17]!
|
501
|
+
0x7038 SonyRawImageSize SubIFD int32u[2]!
|
502
|
+
0x7310 BlackLevel SubIFD int16u[4]!
|
503
|
+
0x7313 WB_RGGBLevels SubIFD int16s[4]!
|
501
504
|
0x74c7 SonyCropTopLeft SubIFD int32u[2]!
|
502
505
|
0x74c8 SonyCropSize SubIFD int32u[2]!
|
503
506
|
0x800d ImageID - no
|
@@ -1287,6 +1290,7 @@ L<http://www.adobe.com/devnet/xmp/> for the official XMP specification.
|
|
1287
1290
|
digiKam XMP digiKam
|
1288
1291
|
drone-dji DJI XMP
|
1289
1292
|
dwc DarwinCore
|
1293
|
+
et XMP ExifTool
|
1290
1294
|
exif XMP exif
|
1291
1295
|
exifEX XMP exifEX
|
1292
1296
|
expressionmedia XMP ExpressionMedia
|
@@ -4034,6 +4038,14 @@ These tags belong to the ExifTool XMP-digiKam family 1 group.
|
|
4034
4038
|
PickLabel string
|
4035
4039
|
TagsList string+
|
4036
4040
|
|
4041
|
+
=head3 XMP ExifTool Tags
|
4042
|
+
|
4043
|
+
These tags belong to the ExifTool XMP-et family 1 group.
|
4044
|
+
|
4045
|
+
Tag Name Writable
|
4046
|
+
-------- --------
|
4047
|
+
OriginalImageMD5 string
|
4048
|
+
|
4037
4049
|
=head3 XMP exif Tags
|
4038
4050
|
|
4039
4051
|
EXIF namespace for EXIF tags. See
|
@@ -5307,7 +5319,8 @@ These tags belong to the ExifTool XMP-pmi family 1 group.
|
|
5307
5319
|
=head3 XMP prism Tags
|
5308
5320
|
|
5309
5321
|
Publishing Requirements for Industry Standard Metadata 3.0 namespace
|
5310
|
-
tags. (see
|
5322
|
+
tags. (see
|
5323
|
+
L<https://www.w3.org/Submission/2020/SUBM-prism-20200910/prism-basic.html/>)
|
5311
5324
|
|
5312
5325
|
These tags belong to the ExifTool XMP-prism family 1 group.
|
5313
5326
|
|
@@ -17329,6 +17342,8 @@ any information found here will be extracted, even if the tag is not listed.
|
|
17329
17342
|
0x0304 FocusStepNear int16u
|
17330
17343
|
0x0305 FocusDistance rational64u
|
17331
17344
|
0x0308 AFPoint int16u
|
17345
|
+
0x031b AFPointDetails no
|
17346
|
+
AFPointDetails int16u
|
17332
17347
|
0x0328 AFInfo Olympus AFInfo
|
17333
17348
|
0x1201 ExternalFlash int16u[2]
|
17334
17349
|
0x1203 ExternalFlashGuideNumber? rational64s
|
@@ -21862,7 +21877,10 @@ These tags are found in IFD0 of Panasonic/Leica RAW, RW2 and RWL images.
|
|
21862
21877
|
0x011c Gamma int16u
|
21863
21878
|
0x0120 CameraIFD PanasonicRaw CameraIFD
|
21864
21879
|
0x0121 Multishot int32u
|
21880
|
+
0x0127 JpgFromRaw2 no
|
21881
|
+
0x013b Artist string
|
21865
21882
|
0x02bc ApplicationNotes XMP
|
21883
|
+
0x8298 Copyright string
|
21866
21884
|
0x83bb IPTC-NAA IPTC
|
21867
21885
|
0x8769 ExifOffset EXIF
|
21868
21886
|
0x8825 GPSInfo GPS
|
@@ -22143,30 +22161,32 @@ Note that Microsoft is not consistent with the time zone used for some
|
|
22143
22161
|
date/time tags, and it may be either UTC or local time depending on the
|
22144
22162
|
software used to create the file.
|
22145
22163
|
|
22146
|
-
Tag ID
|
22147
|
-
------
|
22148
|
-
"\x01CompObj"
|
22149
|
-
"\x05Audio Info"
|
22150
|
-
"\x05Data Object"
|
22164
|
+
Tag ID Tag Name Writable
|
22165
|
+
------ -------- --------
|
22166
|
+
"\x01CompObj" CompObj FlashPix CompObj
|
22167
|
+
"\x05Audio Info" AudioInfo FlashPix AudioInfo
|
22168
|
+
"\x05Data Object" DataObject FlashPix DataObject
|
22151
22169
|
"\x05DocumentSummaryInformation" DocumentInfo FlashPix DocumentInfo
|
22152
|
-
"\x05Extension List"
|
22153
|
-
"\x05Global Info"
|
22154
|
-
"\x05Image Contents"
|
22155
|
-
"\x05Image Info"
|
22156
|
-
"\x05Operation"
|
22157
|
-
"\x05Screen Nail"
|
22158
|
-
"\x05SummaryInformation"
|
22159
|
-
"\x05Transform"
|
22160
|
-
'Audio Stream'
|
22161
|
-
'BasicFileInfo'
|
22162
|
-
'Contents'
|
22163
|
-
'Current User'
|
22164
|
-
'ICC Profile 0001'
|
22165
|
-
'IeImg'
|
22166
|
-
'
|
22167
|
-
'
|
22168
|
-
'
|
22169
|
-
'
|
22170
|
+
"\x05Extension List" Extensions FlashPix Extensions
|
22171
|
+
"\x05Global Info" GlobalInfo FlashPix GlobalInfo
|
22172
|
+
"\x05Image Contents" Image FlashPix Image
|
22173
|
+
"\x05Image Info" ImageInfo FlashPix ImageInfo
|
22174
|
+
"\x05Operation" Operation FlashPix Operation
|
22175
|
+
"\x05Screen Nail" ScreenNail no
|
22176
|
+
"\x05SummaryInformation" SummaryInfo FlashPix SummaryInfo
|
22177
|
+
"\x05Transform" Transform FlashPix Transform
|
22178
|
+
'Audio Stream' AudioStream no
|
22179
|
+
'BasicFileInfo' BasicFileInfo no
|
22180
|
+
'Contents' Contents XMP
|
22181
|
+
'Current User' CurrentUser no
|
22182
|
+
'ICC Profile 0001' ICC_Profile ICC_Profile
|
22183
|
+
'IeImg' EmbeddedImage no
|
22184
|
+
'IeImg_class' EmbeddedImageClass no
|
22185
|
+
'IeImg_rect' EmbeddedImageRectangle no
|
22186
|
+
'Preview' PreviewImage no
|
22187
|
+
'Property' PreviewInfo FlashPix PreviewInfo
|
22188
|
+
'Subimage 0000 Header' SubimageHdr FlashPix SubimageHdr
|
22189
|
+
'WordDocument' WordDocument FlashPix WordDocument
|
22170
22190
|
|
22171
22191
|
=head3 FlashPix CompObj Tags
|
22172
22192
|
|
@@ -430,32 +430,32 @@ sub AddImageDataMD5($$$)
|
|
430
430
|
my $verbose = $et->Options('Verbose');
|
431
431
|
my $md5 = $$et{ImageDataMD5};
|
432
432
|
my $raf = $$dirInfo{RAF};
|
433
|
-
my $base = $$dirInfo{Base} || 0;
|
434
433
|
|
435
434
|
foreach $tagID (sort keys %$offsetInfo) {
|
436
435
|
next unless ref $$offsetInfo{$tagID} eq 'ARRAY'; # ignore scalar tag values used for Validate
|
437
436
|
my $tagInfo = $$offsetInfo{$tagID}[0];
|
438
|
-
next unless $$tagInfo{IsImageData}
|
437
|
+
next unless $$tagInfo{IsImageData}; # only consider image data
|
439
438
|
my $sizeID = $$tagInfo{OffsetPair};
|
440
|
-
|
439
|
+
my @sizes;
|
440
|
+
if ($$tagInfo{NotRealPair}) {
|
441
|
+
@sizes = 999999999; # (Panasonic hack: raw data runs to end of file)
|
442
|
+
} elsif ($sizeID and $$offsetInfo{$sizeID}) {
|
443
|
+
@sizes = split ' ', $$offsetInfo{$sizeID}[1];
|
444
|
+
} else {
|
445
|
+
next;
|
446
|
+
}
|
441
447
|
my @offsets = split ' ', $$offsetInfo{$tagID}[1];
|
442
|
-
|
448
|
+
$sizes[0] = 999999999 if $$tagInfo{NotRealPair};
|
443
449
|
my $total = 0;
|
444
450
|
foreach $offset (@offsets) {
|
445
451
|
my $size = shift @sizes;
|
446
452
|
next unless $offset =~ /^\d+$/ and $size and $size =~ /^\d+$/ and $size;
|
447
|
-
next unless $raf->Seek($offset
|
448
|
-
|
449
|
-
my $bytes = $size > 65536 ? 65536 : $size;
|
450
|
-
$raf->Read($buff, $bytes) or last;
|
451
|
-
$md5->add($buff);
|
452
|
-
$total += length($buff);
|
453
|
-
$size -= $bytes;
|
454
|
-
}
|
453
|
+
next unless $raf->Seek($offset, 0); # (offset is absolute)
|
454
|
+
$total += $et->ImageDataMD5($raf, $size);
|
455
455
|
}
|
456
456
|
if ($verbose) {
|
457
457
|
my $name = "$$dirInfo{DirName}:$$tagInfo{Name}";
|
458
|
-
$name =~ s/Offsets
|
458
|
+
$name =~ s/Offsets?|Start$//;
|
459
459
|
$et->VPrint(0, "$$et{INDENT}(ImageDataMD5: $total bytes of $name data)\n");
|
460
460
|
}
|
461
461
|
}
|
@@ -1490,7 +1490,7 @@ sub WriteXMP($$;$)
|
|
1490
1490
|
my @ns = sort keys %nsCur;
|
1491
1491
|
$long[-2] .= "$nl$sp<$prop rdf:about='${about}'";
|
1492
1492
|
# generate et:toolkit attribute if this is an exiftool RDF/XML output file
|
1493
|
-
if (@ns and $nsCur{$ns[0]} =~ m{^http://ns.exiftool.(?:ca|org)/}) {
|
1493
|
+
if ($$et{XMP_NO_XMPMETA} and @ns and $nsCur{$ns[0]} =~ m{^http://ns.exiftool.(?:ca|org)/}) {
|
1494
1494
|
$long[-2] .= "\n$sp${sp}xmlns:et='http://ns.exiftool.org/1.0/'" .
|
1495
1495
|
" et:toolkit='Image::ExifTool $Image::ExifTool::VERSION'";
|
1496
1496
|
}
|
@@ -1321,6 +1321,7 @@ sub SetNewValuesFromFile($$;@)
|
|
1321
1321
|
XMPAutoConv => $$options{XMPAutoConv},
|
1322
1322
|
);
|
1323
1323
|
$$srcExifTool{GLOBAL_TIME_OFFSET} = $$self{GLOBAL_TIME_OFFSET};
|
1324
|
+
$$srcExifTool{ALT_EXIFTOOL} = $$self{ALT_EXIFTOOL};
|
1324
1325
|
foreach $tag (@setTags) {
|
1325
1326
|
next if ref $tag;
|
1326
1327
|
if ($tag =~ /^-(.*)/) {
|
@@ -1387,7 +1388,7 @@ sub SetNewValuesFromFile($$;@)
|
|
1387
1388
|
# transfer specified tags in the proper order
|
1388
1389
|
#
|
1389
1390
|
# 1) loop through input list of tags to set, and build @setList
|
1390
|
-
my (@setList, $set, %setMatches, $t);
|
1391
|
+
my (@setList, $set, %setMatches, $t, %altFiles);
|
1391
1392
|
foreach $t (@setTags) {
|
1392
1393
|
if (ref $t eq 'HASH') {
|
1393
1394
|
# update current options
|
@@ -1424,6 +1425,7 @@ sub SetNewValuesFromFile($$;@)
|
|
1424
1425
|
$opt = $1 if $tag =~ s/^([-+])\s*//;
|
1425
1426
|
}
|
1426
1427
|
}
|
1428
|
+
$$opts{Replace} = 0 if $dstTag =~ s/^\+//;
|
1427
1429
|
# validate tag name(s)
|
1428
1430
|
unless ($$opts{EXPR} or ValidTagName($tag)) {
|
1429
1431
|
$self->Warn("Invalid tag name '${tag}'. Use '=' not '<' to assign a tag value");
|
@@ -1440,6 +1442,8 @@ sub SetNewValuesFromFile($$;@)
|
|
1440
1442
|
$$opts{Type} = 'ValueConv' if $dstTag =~ s/#$//;
|
1441
1443
|
# replace tag name of 'all' with '*'
|
1442
1444
|
$dstTag = '*' if $dstTag eq 'all';
|
1445
|
+
} else {
|
1446
|
+
$$opts{Replace} = 0 if $tag =~ s/^\+//;
|
1443
1447
|
}
|
1444
1448
|
unless ($$opts{EXPR}) {
|
1445
1449
|
$isExclude = ($tag =~ s/^-//);
|
@@ -1449,7 +1453,17 @@ sub SetNewValuesFromFile($$;@)
|
|
1449
1453
|
# save family/groups in list (ignoring 'all' and '*')
|
1450
1454
|
next unless length($_) and /^(\d+)?(.*)/;
|
1451
1455
|
my ($f, $g) = ($1, $2);
|
1452
|
-
$f = 7 if $g =~ s/^ID-//i;
|
1456
|
+
$f = 7 if (not $f or $f eq '7') and $g =~ s/^ID-//i;
|
1457
|
+
if ($g =~ /^file\d+$/i and (not $f or $f eq '8')) {
|
1458
|
+
$f = 8;
|
1459
|
+
my $g8 = ucfirst $g;
|
1460
|
+
if ($$srcExifTool{ALT_EXIFTOOL}{$g8}) {
|
1461
|
+
$$opts{GROUP8} = $g8;
|
1462
|
+
$altFiles{$g8} or $altFiles{$g8} = [ ];
|
1463
|
+
# save list of requested tags for this alternate ExifTool object
|
1464
|
+
push @{$altFiles{$g8}}, "$grp:$tag";
|
1465
|
+
}
|
1466
|
+
}
|
1453
1467
|
push @fg, [ $f, $g ] unless $g eq '*' or $g eq 'all';
|
1454
1468
|
}
|
1455
1469
|
}
|
@@ -1486,26 +1500,44 @@ sub SetNewValuesFromFile($$;@)
|
|
1486
1500
|
# save in reverse order so we don't set tags before an exclude
|
1487
1501
|
unshift @setList, [ \@fg, $tag, $dst, $opts ];
|
1488
1502
|
}
|
1503
|
+
# 1b) copy requested tags for each alternate ExifTool object
|
1504
|
+
my $g8;
|
1505
|
+
foreach $g8 (sort keys %altFiles) {
|
1506
|
+
# request specific alternate tags to load them from the alternate ExifTool object
|
1507
|
+
my $altInfo = $srcExifTool->GetInfo($altFiles{$g8});
|
1508
|
+
# add to tags list after dummy entry to signify start of tags for this alt file
|
1509
|
+
if (%$altInfo) {
|
1510
|
+
push @tags, 'Warning DUMMY', reverse sort keys %$altInfo;
|
1511
|
+
$$info{$_} = $$altInfo{$_} foreach keys %$altInfo;
|
1512
|
+
}
|
1513
|
+
}
|
1489
1514
|
# 2) initialize lists of matching tags for each setTag
|
1490
1515
|
foreach $set (@setList) {
|
1491
1516
|
$$set[2] and $setMatches{$set} = [ ];
|
1492
1517
|
}
|
1493
1518
|
# 3) loop through all tags in source image and save tags matching each setTag
|
1494
|
-
my %rtnInfo;
|
1519
|
+
my (%rtnInfo, $isAlt);
|
1495
1520
|
foreach $tag (@tags) {
|
1496
1521
|
# don't try to set errors or warnings
|
1497
1522
|
if ($tag =~ /^(Error|Warning)( |$)/) {
|
1498
|
-
$
|
1523
|
+
if ($tag eq 'Warning DUMMY') {
|
1524
|
+
$isAlt = 1; # start of the alt tags
|
1525
|
+
} else {
|
1526
|
+
$rtnInfo{$tag} = $$info{$tag};
|
1527
|
+
}
|
1499
1528
|
next;
|
1500
1529
|
}
|
1501
1530
|
# only set specified tags
|
1502
1531
|
my $lcTag = lc(GetTagName($tag));
|
1503
1532
|
my (@grp, %grp);
|
1504
1533
|
SET: foreach $set (@setList) {
|
1534
|
+
my $opts = $$set[3];
|
1535
|
+
next if $$opts{EXPR}; # (expressions handled in step 4)
|
1536
|
+
next if $$opts{GROUP8} xor $isAlt;
|
1505
1537
|
# check first for matching tag
|
1506
1538
|
unless ($$set[1] eq $lcTag or $$set[1] eq '*') {
|
1507
1539
|
# handle wildcards
|
1508
|
-
next unless $$
|
1540
|
+
next unless $$opts{WILD} and $lcTag =~ /^$$set[1]$/;
|
1509
1541
|
}
|
1510
1542
|
# then check for matching group
|
1511
1543
|
if (@{$$set[0]}) {
|
@@ -1837,6 +1869,27 @@ sub RestoreNewValues($)
|
|
1837
1869
|
$$self{DEL_GROUP} = \%delGrp;
|
1838
1870
|
}
|
1839
1871
|
|
1872
|
+
#------------------------------------------------------------------------------
|
1873
|
+
# Set alternate file for extracting information
|
1874
|
+
# Inputs: 0) ExifTool ref, 1) family 8 group name (of the form "File#" where # is any number)
|
1875
|
+
# 2) alternate file name, or undef to reset
|
1876
|
+
# Returns: 1 on success, or 0 on invalid group name
|
1877
|
+
sub SetAlternateFile($$$)
|
1878
|
+
{
|
1879
|
+
my ($self, $g8, $file) = @_;
|
1880
|
+
$g8 = ucfirst lc $g8;
|
1881
|
+
return 0 unless $g8 =~ /^File\d+$/;
|
1882
|
+
# keep the same file if already initialized (possibly has metadata extracted)
|
1883
|
+
if (not defined $file) {
|
1884
|
+
delete $$self{ALT_EXIFTOOL}{$g8};
|
1885
|
+
} elsif (not ($$self{ALT_EXIFTOOL}{$g8} and $$self{ALT_EXIFTOOL}{$g8}{ALT_FILE} eq $file)) {
|
1886
|
+
my $altExifTool = Image::ExifTool->new;
|
1887
|
+
$$altExifTool{ALT_FILE} = $file;
|
1888
|
+
$$self{ALT_EXIFTOOL}{$g8} = $altExifTool;
|
1889
|
+
}
|
1890
|
+
return 1;
|
1891
|
+
}
|
1892
|
+
|
1840
1893
|
#------------------------------------------------------------------------------
|
1841
1894
|
# Set filesystem time from from FileModifyDate or FileCreateDate tag
|
1842
1895
|
# Inputs: 0) ExifTool object reference, 1) file name or file ref
|
@@ -2724,6 +2777,7 @@ sub GetAllGroups($;$)
|
|
2724
2777
|
$family == 4 and return('Copy#');
|
2725
2778
|
$family == 5 and return('[too many possibilities to list]');
|
2726
2779
|
$family == 6 and return(@Image::ExifTool::Exif::formatName[1..$#Image::ExifTool::Exif::formatName]);
|
2780
|
+
$family == 8 and return('File#');
|
2727
2781
|
|
2728
2782
|
LoadAllTables(); # first load all our tables
|
2729
2783
|
|
@@ -3163,42 +3217,46 @@ sub InsertTagValues($$$;$$$)
|
|
3163
3217
|
$tag = $docGrp . ':' . $tag;
|
3164
3218
|
$lcTag = lc $tag;
|
3165
3219
|
}
|
3220
|
+
my $et = $self;
|
3221
|
+
if ($tag =~ s/(\bfile\d+)://i) {
|
3222
|
+
$et = $$self{ALT_EXIFTOOL}{ucfirst lc $1} or $et=$self, $tag = 'no_alt_file';
|
3223
|
+
}
|
3166
3224
|
if ($lcTag eq 'all') {
|
3167
3225
|
$val = 1; # always some tag available
|
3168
|
-
} elsif (defined $$
|
3169
|
-
$val = $$
|
3226
|
+
} elsif (defined $$et{OPTIONS}{UserParam}{$lcTag}) {
|
3227
|
+
$val = $$et{OPTIONS}{UserParam}{$lcTag};
|
3170
3228
|
} elsif ($tag =~ /(.*):(.+)/) {
|
3171
3229
|
my $group;
|
3172
3230
|
($group, $tag) = ($1, $2);
|
3173
3231
|
if (lc $tag eq 'all') {
|
3174
3232
|
# see if any tag from the specified group exists
|
3175
|
-
my $match = $
|
3233
|
+
my $match = $et->GroupMatches($group, $foundTags);
|
3176
3234
|
$val = $match ? 1 : 0;
|
3177
3235
|
} else {
|
3178
3236
|
# find the specified tag
|
3179
3237
|
my @matches = grep /^$tag(\s|$)/i, @$foundTags;
|
3180
|
-
@matches = $
|
3238
|
+
@matches = $et->GroupMatches($group, \@matches);
|
3181
3239
|
foreach $tg (@matches) {
|
3182
3240
|
if (defined $val and $tg =~ / \((\d+)\)$/) {
|
3183
3241
|
# take the most recently extracted tag
|
3184
3242
|
my $tagNum = $1;
|
3185
3243
|
next if $tag !~ / \((\d+)\)$/ or $1 > $tagNum;
|
3186
3244
|
}
|
3187
|
-
$val = $
|
3245
|
+
$val = $et->GetValue($tg, $type);
|
3188
3246
|
$tag = $tg;
|
3189
3247
|
last unless $tag =~ / /; # all done if we got our best match
|
3190
3248
|
}
|
3191
3249
|
}
|
3192
3250
|
} elsif ($tag eq 'self') {
|
3193
|
-
$val = $
|
3251
|
+
$val = $et; # ("$self{var}" or "$file1:self{var}" in string)
|
3194
3252
|
} else {
|
3195
3253
|
# get the tag value
|
3196
|
-
$val = $
|
3254
|
+
$val = $et->GetValue($tag, $type);
|
3197
3255
|
unless (defined $val) {
|
3198
3256
|
# check for tag name with different case
|
3199
3257
|
($tg) = grep /^$tag$/i, @$foundTags;
|
3200
3258
|
if (defined $tg) {
|
3201
|
-
$val = $
|
3259
|
+
$val = $et->GetValue($tg, $type);
|
3202
3260
|
$tag = $tg;
|
3203
3261
|
}
|
3204
3262
|
}
|
@@ -3266,15 +3324,19 @@ sub InsertTagValues($$$;$$$)
|
|
3266
3324
|
undef $advFmtSelf;
|
3267
3325
|
$didExpr = 1; # set flag indicating an expression was evaluated
|
3268
3326
|
}
|
3269
|
-
unless (defined $val
|
3327
|
+
unless (defined $val) {
|
3270
3328
|
$val = $$self{OPTIONS}{MissingTagValue};
|
3271
3329
|
unless (defined $val) {
|
3272
3330
|
my $g3 = ($docGrp and $var !~ /\b(main|doc\d+):/i) ? $docGrp . ':' : '';
|
3273
3331
|
my $msg = $didExpr ? "Advanced formatting expression returned undef for '$g3${var}'" :
|
3274
3332
|
"Tag '$g3${var}' not defined";
|
3275
|
-
|
3276
|
-
|
3277
|
-
$
|
3333
|
+
if (ref $opt) {
|
3334
|
+
$self->Warn($msg,2) or $val = '';
|
3335
|
+
} elsif ($opt) {
|
3336
|
+
no strict 'refs';
|
3337
|
+
($opt eq 'Silent' or &$opt($self, $msg, 2)) and return $$self{FMT_EXPR} = undef;
|
3338
|
+
$val = '';
|
3339
|
+
}
|
3278
3340
|
}
|
3279
3341
|
}
|
3280
3342
|
if (ref $opt eq 'HASH') {
|
@@ -5508,7 +5570,7 @@ sub WriteJPEG($$)
|
|
5508
5570
|
$s =~ /^JFXX\0\x10/ and $dirName = 'JFXX';
|
5509
5571
|
$s =~ /^(II|MM).{4}HEAPJPGM/s and $dirName = 'CIFF';
|
5510
5572
|
} elsif ($marker == 0xe1) {
|
5511
|
-
if ($s =~ /^(.{0,4})
|
5573
|
+
if ($s =~ /^(.{0,4})Exif\0.(.{1,4})/is) {
|
5512
5574
|
$dirName = 'IFD0';
|
5513
5575
|
my ($junk, $bytes) = ($1, $2);
|
5514
5576
|
# support multi-segment EXIF
|
@@ -6074,7 +6136,7 @@ sub WriteJPEG($$)
|
|
6074
6136
|
}
|
6075
6137
|
} elsif ($marker == 0xe1) { # APP1 (EXIF, XMP)
|
6076
6138
|
# check for EXIF data
|
6077
|
-
if ($$segDataPt =~ /^(.{0,4})
|
6139
|
+
if ($$segDataPt =~ /^(.{0,4})Exif\0./is) {
|
6078
6140
|
my $hdrLen = length $exifAPP1hdr;
|
6079
6141
|
if (length $1) {
|
6080
6142
|
$hdrLen += length $1;
|
@@ -6809,6 +6871,36 @@ sub SetFileTime($$;$$$$)
|
|
6809
6871
|
return 1; # (nothing to do)
|
6810
6872
|
}
|
6811
6873
|
|
6874
|
+
#------------------------------------------------------------------------------
|
6875
|
+
# Add data to MD5 checksum
|
6876
|
+
# Inputs: 0) ExifTool ref, 1) RAF ref, 2) data size (or undef to read to end of file),
|
6877
|
+
# 3) data name (or undef for no warnings or messages), 4) flag for no verbose message
|
6878
|
+
# Returns: number of bytes read and MD5'd
|
6879
|
+
sub ImageDataMD5($$$;$$)
|
6880
|
+
{
|
6881
|
+
my ($self, $raf, $size, $type, $noMsg) = @_;
|
6882
|
+
my $md5 = $$self{ImageDataMD5} or return;
|
6883
|
+
my ($bytesRead, $n) = (0, 65536);
|
6884
|
+
my $buff;
|
6885
|
+
for (;;) {
|
6886
|
+
if (defined $size) {
|
6887
|
+
last unless $size;
|
6888
|
+
$n = $size > 65536 ? 65536 : $size;
|
6889
|
+
$size -= $n;
|
6890
|
+
}
|
6891
|
+
unless ($raf->Read($buff, $n)) {
|
6892
|
+
$self->Warn("Error reading $type data") if $type and defined $size;
|
6893
|
+
last;
|
6894
|
+
}
|
6895
|
+
$md5->add($buff);
|
6896
|
+
$bytesRead += length $buff;
|
6897
|
+
}
|
6898
|
+
if ($$self{OPTIONS}{Verbose} and $bytesRead and $type and not $noMsg) {
|
6899
|
+
$self->VPrint(0, "$$self{INDENT}(ImageDataMD5: $bytesRead bytes of $type data)\n");
|
6900
|
+
}
|
6901
|
+
return $bytesRead;
|
6902
|
+
}
|
6903
|
+
|
6812
6904
|
#------------------------------------------------------------------------------
|
6813
6905
|
# Copy data block from RAF to output file in max 64kB chunks
|
6814
6906
|
# Inputs: 0) RAF ref, 1) outfile ref, 2) block size
|
@@ -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.58';
|
54
54
|
@ISA = qw(Exporter);
|
55
55
|
@EXPORT_OK = qw(EscapeXML UnescapeXML);
|
56
56
|
|
@@ -753,6 +753,10 @@ my %sRangeMask = (
|
|
753
753
|
Name => 'album',
|
754
754
|
SubDirectory => { TagTable => 'Image::ExifTool::XMP::Album' },
|
755
755
|
},
|
756
|
+
et => {
|
757
|
+
Name => 'et',
|
758
|
+
SubDirectory => { TagTable => 'Image::ExifTool::XMP::ExifTool' },
|
759
|
+
},
|
756
760
|
prism => {
|
757
761
|
Name => 'prism',
|
758
762
|
SubDirectory => { TagTable => 'Image::ExifTool::XMP::prism' },
|
@@ -2550,6 +2554,14 @@ my %sPantryItem = (
|
|
2550
2554
|
Notes => { },
|
2551
2555
|
);
|
2552
2556
|
|
2557
|
+
# ExifTool namespace properties (et)
|
2558
|
+
%Image::ExifTool::XMP::ExifTool = (
|
2559
|
+
%xmpTableDefaults,
|
2560
|
+
GROUPS => { 1 => 'XMP-et', 2 => 'Image' },
|
2561
|
+
NAMESPACE => 'et',
|
2562
|
+
OriginalImageMD5 => { Notes => 'used to store ExifTool ImageDataMD5 digest' },
|
2563
|
+
);
|
2564
|
+
|
2553
2565
|
# table to add tags in other namespaces
|
2554
2566
|
%Image::ExifTool::XMP::other = (
|
2555
2567
|
GROUPS => { 2 => 'Unknown' },
|
@@ -3539,6 +3551,7 @@ NoLoop:
|
|
3539
3551
|
DirLen => length $$dataPt,
|
3540
3552
|
IgnoreProp => $$subdir{IgnoreProp}, # (allow XML to ignore specified properties)
|
3541
3553
|
IsExtended => 1, # (hack to avoid Duplicate warning for embedded XMP)
|
3554
|
+
NoStruct => 1, # (don't try to build structures since this isn't true XMP)
|
3542
3555
|
);
|
3543
3556
|
my $oldOrder = GetByteOrder();
|
3544
3557
|
SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder};
|
@@ -4375,8 +4388,10 @@ sub ProcessXMP($$;$)
|
|
4375
4388
|
|
4376
4389
|
# restore structures if necessary
|
4377
4390
|
if ($$et{IsStruct}) {
|
4378
|
-
|
4379
|
-
|
4391
|
+
unless ($$dirInfo{NoStruct}) {
|
4392
|
+
require 'Image/ExifTool/XMPStruct.pl';
|
4393
|
+
RestoreStruct($et, $keepFlat);
|
4394
|
+
}
|
4380
4395
|
delete $$et{IsStruct};
|
4381
4396
|
}
|
4382
4397
|
# reset NO_LIST flag (must do this _after_ RestoreStruct() above)
|
@@ -843,7 +843,8 @@ my %prismPublicationDate = (
|
|
843
843
|
AVOID => 1,
|
844
844
|
NOTES => q{
|
845
845
|
Publishing Requirements for Industry Standard Metadata 3.0 namespace
|
846
|
-
tags. (see
|
846
|
+
tags. (see
|
847
|
+
L<https://www.w3.org/Submission/2020/SUBM-prism-20200910/prism-basic.html/>)
|
847
848
|
},
|
848
849
|
academicField => { }, # (3.0)
|
849
850
|
aggregateIssueNumber => { Writable => 'integer' }, # (3.0)
|