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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +45 -3
  3. data/bin/MANIFEST +4 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +2 -2
  7. data/bin/config_files/example.config +1 -0
  8. data/bin/exiftool +81 -54
  9. data/bin/lib/Image/ExifTool/CanonRaw.pm +5 -1
  10. data/bin/lib/Image/ExifTool/DJI.pm +2 -2
  11. data/bin/lib/Image/ExifTool/Exif.pm +53 -14
  12. data/bin/lib/Image/ExifTool/FlashPix.pm +27 -9
  13. data/bin/lib/Image/ExifTool/FujiFilm.pm +6 -3
  14. data/bin/lib/Image/ExifTool/Geotag.pm +30 -7
  15. data/bin/lib/Image/ExifTool/LIF.pm +10 -2
  16. data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -1
  17. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -1
  18. data/bin/lib/Image/ExifTool/Nikon.pm +6 -5
  19. data/bin/lib/Image/ExifTool/Olympus.pm +87 -7
  20. data/bin/lib/Image/ExifTool/PNG.pm +10 -2
  21. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
  22. data/bin/lib/Image/ExifTool/PhaseOne.pm +14 -1
  23. data/bin/lib/Image/ExifTool/QuickTime.pm +21 -6
  24. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +37 -5
  25. data/bin/lib/Image/ExifTool/RIFF.pm +32 -11
  26. data/bin/lib/Image/ExifTool/Ricoh.pm +2 -1
  27. data/bin/lib/Image/ExifTool/SigmaRaw.pm +9 -3
  28. data/bin/lib/Image/ExifTool/Sony.pm +2 -1
  29. data/bin/lib/Image/ExifTool/TagLookup.pm +2254 -2246
  30. data/bin/lib/Image/ExifTool/TagNames.pod +45 -25
  31. data/bin/lib/Image/ExifTool/WriteExif.pl +13 -13
  32. data/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
  33. data/bin/lib/Image/ExifTool/Writer.pl +111 -19
  34. data/bin/lib/Image/ExifTool/XMP.pm +18 -3
  35. data/bin/lib/Image/ExifTool/XMP2.pl +2 -1
  36. data/bin/lib/Image/ExifTool.pm +109 -17
  37. data/bin/lib/Image/ExifTool.pod +40 -5
  38. data/bin/perl-Image-ExifTool.spec +1 -1
  39. data/lib/exiftool_vendored/version.rb +1 -1
  40. 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 26381 tags, with 16854 unique tag names.
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 L<http://www.prismstandard.org/>)
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 Tag Name Writable
22147
- ------ -------- --------
22148
- "\x01CompObj" CompObj FlashPix CompObj
22149
- "\x05Audio Info" AudioInfo FlashPix AudioInfo
22150
- "\x05Data Object" DataObject FlashPix DataObject
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" Extensions FlashPix Extensions
22153
- "\x05Global Info" GlobalInfo FlashPix GlobalInfo
22154
- "\x05Image Contents" Image FlashPix Image
22155
- "\x05Image Info" ImageInfo FlashPix ImageInfo
22156
- "\x05Operation" Operation FlashPix Operation
22157
- "\x05Screen Nail" ScreenNail no
22158
- "\x05SummaryInformation" SummaryInfo FlashPix SummaryInfo
22159
- "\x05Transform" Transform FlashPix Transform
22160
- 'Audio Stream' AudioStream no
22161
- 'BasicFileInfo' BasicFileInfo no
22162
- 'Contents' Contents XMP
22163
- 'Current User' CurrentUser no
22164
- 'ICC Profile 0001' ICC_Profile ICC_Profile
22165
- 'IeImg' EmbeddedImage no
22166
- 'Preview' PreviewImage no
22167
- 'Property' PreviewInfo FlashPix PreviewInfo
22168
- 'Subimage 0000 Header' SubimageHdr FlashPix SubimageHdr
22169
- 'WordDocument' WordDocument FlashPix WordDocument
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} and $$tagInfo{OffsetPair}; # only consider image data
437
+ next unless $$tagInfo{IsImageData}; # only consider image data
439
438
  my $sizeID = $$tagInfo{OffsetPair};
440
- next unless $sizeID and $$offsetInfo{$sizeID};
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
- my @sizes = split ' ', $$offsetInfo{$sizeID}[1];
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+$base, 0);
448
- while ($size) {
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|Start$//;
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
- $rtnInfo{$tag} = $$info{$tag};
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 $$set[3]{WILD} and $lcTag =~ /^$$set[1]$/;
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 $$self{OPTIONS}{UserParam}{$lcTag}) {
3169
- $val = $$self{OPTIONS}{UserParam}{$lcTag};
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 = $self->GroupMatches($group, $foundTags);
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 = $self->GroupMatches($group, \@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 = $self->GetValue($tg, $type);
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 = $self; # ("$self{var}" or "$self->{var}" in string)
3251
+ $val = $et; # ("$self{var}" or "$file1:self{var}" in string)
3194
3252
  } else {
3195
3253
  # get the tag value
3196
- $val = $self->GetValue($tag, $type);
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 = $self->GetValue($tg, $type);
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 or ref $opt) {
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
- no strict 'refs';
3276
- $opt and ($opt eq 'Silent' or &$opt($self, $msg, 2)) and return $$self{FMT_EXPR} = undef;
3277
- $val = '';
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})$exifAPP1hdr(.{1,4})/is) {
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})$exifAPP1hdr/is) {
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.57';
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
- require 'Image/ExifTool/XMPStruct.pl';
4379
- RestoreStruct($et, $keepFlat);
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 L<http://www.prismstandard.org/>)
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)