exiftool_vendored 12.57.0 → 12.59.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +39 -0
  3. data/bin/MANIFEST +3 -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/config_files/rotate_regions.config +1 -1
  9. data/bin/exiftool +76 -57
  10. data/bin/lib/Image/ExifTool/AIFF.pm +2 -2
  11. data/bin/lib/Image/ExifTool/APE.pm +2 -2
  12. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +13 -14
  13. data/bin/lib/Image/ExifTool/Canon.pm +26 -6
  14. data/bin/lib/Image/ExifTool/DJI.pm +28 -2
  15. data/bin/lib/Image/ExifTool/Exif.pm +24 -5
  16. data/bin/lib/Image/ExifTool/FlashPix.pm +28 -10
  17. data/bin/lib/Image/ExifTool/FujiFilm.pm +1 -0
  18. data/bin/lib/Image/ExifTool/JPEG.pm +14 -2
  19. data/bin/lib/Image/ExifTool/LIF.pm +10 -2
  20. data/bin/lib/Image/ExifTool/LNK.pm +5 -4
  21. data/bin/lib/Image/ExifTool/MPEG.pm +2 -2
  22. data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -2
  23. data/bin/lib/Image/ExifTool/Minolta.pm +6 -7
  24. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +9 -1
  25. data/bin/lib/Image/ExifTool/Nikon.pm +390 -114
  26. data/bin/lib/Image/ExifTool/Olympus.pm +87 -7
  27. data/bin/lib/Image/ExifTool/PNG.pm +15 -2
  28. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
  29. data/bin/lib/Image/ExifTool/Pentax.pm +8 -5
  30. data/bin/lib/Image/ExifTool/PhaseOne.pm +14 -1
  31. data/bin/lib/Image/ExifTool/Photoshop.pm +3 -3
  32. data/bin/lib/Image/ExifTool/QuickTime.pm +16 -11
  33. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +38 -6
  34. data/bin/lib/Image/ExifTool/README +8 -0
  35. data/bin/lib/Image/ExifTool/RIFF.pm +41 -13
  36. data/bin/lib/Image/ExifTool/Rawzor.pm +2 -2
  37. data/bin/lib/Image/ExifTool/Sigma.pm +4 -4
  38. data/bin/lib/Image/ExifTool/Sony.pm +23 -1
  39. data/bin/lib/Image/ExifTool/TagLookup.pm +4464 -4441
  40. data/bin/lib/Image/ExifTool/TagNames.pod +117 -36
  41. data/bin/lib/Image/ExifTool/Validate.pm +5 -5
  42. data/bin/lib/Image/ExifTool/WriteExif.pl +49 -0
  43. data/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
  44. data/bin/lib/Image/ExifTool/Writer.pl +74 -14
  45. data/bin/lib/Image/ExifTool/XMP.pm +19 -4
  46. data/bin/lib/Image/ExifTool/XMP2.pl +2 -1
  47. data/bin/lib/Image/ExifTool.pm +131 -17
  48. data/bin/lib/Image/ExifTool.pod +40 -5
  49. data/bin/perl-Image-ExifTool.spec +1 -1
  50. data/lib/exiftool_vendored/version.rb +1 -1
  51. 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 26359 tags, with 16845 unique tag names.
15
+ They contain a total of 26390 tags, with 16859 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
@@ -28,7 +28,8 @@ gives the order of values for a serial data stream.
28
28
  A B<Tag Name> is the handle by which the information is accessed in
29
29
  ExifTool. In some instances, more than one name may correspond to a single
30
30
  tag ID. In these cases, the actual name used depends on the context in
31
- which the information is found. Case is not significant for tag names. A
31
+ which the information is found. Valid characters in a tag name are A-Z,
32
+ a-z, 0-9, hyphen (-) and underline (_). Case is not significant. A
32
33
  question mark (C<?>) after a tag name indicates that the information is
33
34
  either not understood, not verified, or not very useful -- these tags are
34
35
  not extracted by ExifTool unless the Unknown (-u) option is enabled. Be
@@ -124,6 +125,8 @@ L<https://www.w3.org/Graphics/JPEG/jfif3.pdf> for the JPEG specification.
124
125
  FPXR FlashPix
125
126
  InfiRayFactory InfiRay Factory
126
127
  ThermalParams DJI ThermalParams
128
+ ThermalParams2 DJI ThermalParams2
129
+ ThermalParams3 DJI ThermalParams3
127
130
  PreviewImage no
128
131
  'APP5' RMETA Ricoh RMETA
129
132
  SamsungUniqueID Samsung APP5
@@ -140,6 +143,7 @@ L<https://www.w3.org/Graphics/JPEG/jfif3.pdf> for the JPEG specification.
140
143
  Huawei Unknown
141
144
  Qualcomm Qualcomm
142
145
  InfiRayOpMode InfiRay OpMode
146
+ DJI-DBG DJI Info
143
147
  'APP8' SPIFF JPEG SPIFF
144
148
  InfiRayIsothermal InfiRay Isothermal
145
149
  'APP9' MediaJukebox JPEG MediaJukebox
@@ -1283,6 +1287,7 @@ L<http://www.adobe.com/devnet/xmp/> for the official XMP specification.
1283
1287
  digiKam XMP digiKam
1284
1288
  drone-dji DJI XMP
1285
1289
  dwc DarwinCore
1290
+ et XMP ExifTool
1286
1291
  exif XMP exif
1287
1292
  exifEX XMP exifEX
1288
1293
  expressionmedia XMP ExpressionMedia
@@ -4030,6 +4035,14 @@ These tags belong to the ExifTool XMP-digiKam family 1 group.
4030
4035
  PickLabel string
4031
4036
  TagsList string+
4032
4037
 
4038
+ =head3 XMP ExifTool Tags
4039
+
4040
+ These tags belong to the ExifTool XMP-et family 1 group.
4041
+
4042
+ Tag Name Writable
4043
+ -------- --------
4044
+ OriginalImageMD5 string
4045
+
4033
4046
  =head3 XMP exif Tags
4034
4047
 
4035
4048
  EXIF namespace for EXIF tags. See
@@ -5303,7 +5316,8 @@ These tags belong to the ExifTool XMP-pmi family 1 group.
5303
5316
  =head3 XMP prism Tags
5304
5317
 
5305
5318
  Publishing Requirements for Industry Standard Metadata 3.0 namespace
5306
- tags. (see L<http://www.prismstandard.org/>)
5319
+ tags. (see
5320
+ L<https://www.w3.org/Submission/2020/SUBM-prism-20200910/prism-basic.html/>)
5307
5321
 
5308
5322
  These tags belong to the ExifTool XMP-prism family 1 group.
5309
5323
 
@@ -10866,6 +10880,30 @@ Thermal parameters extracted from APP4 of DJI RJPEG files from the ZH20T.
10866
10880
  86 DB no
10867
10881
  88 KK no
10868
10882
 
10883
+ =head3 DJI ThermalParams2 Tags
10884
+
10885
+ Thermal parameters extracted from APP4 of DJI M3T RJPEG files.
10886
+
10887
+ Index1 Tag Name Writable
10888
+ ------ -------- --------
10889
+ 0 AmbientTemperature no
10890
+ 4 ObjectDistance no
10891
+ 8 Emissivity no
10892
+ 12 RelativeHumidity no
10893
+ 16 ReflectedTemperature no
10894
+ 101 IDString no
10895
+
10896
+ =head3 DJI ThermalParams3 Tags
10897
+
10898
+ Thermal parameters extracted from APP4 of some DJI RJPEG files.
10899
+
10900
+ Index1 Tag Name Writable
10901
+ ------ -------- --------
10902
+ 4 RelativeHumidity no
10903
+ 6 ObjectDistance no
10904
+ 8 Emissivity no
10905
+ 10 ReflectedTemperature no
10906
+
10869
10907
  =head2 FLIR Tags
10870
10908
 
10871
10909
  Information extracted from the maker notes of JPEG images from thermal
@@ -13707,6 +13745,8 @@ DiMAGE X and Xt.
13707
13745
  ShotInfoD300b Nikon ShotInfoD300b
13708
13746
  ShotInfoD300S Nikon ShotInfoD300S
13709
13747
  ShotInfoD700 Nikon ShotInfoD700
13748
+ ShotInfoD780 Nikon ShotInfoD780
13749
+ ShotInfoD7500 Nikon ShotInfoD7500
13710
13750
  ShotInfoD800 Nikon ShotInfoD800
13711
13751
  ShotInfoD810 Nikon ShotInfoD810
13712
13752
  ShotInfoD850 Nikon ShotInfoD850
@@ -14246,6 +14286,34 @@ firmware 1.02f.
14246
14286
  647 ShutterCount int32u
14247
14287
  804 CustomSettingsD700 NikonCustom SettingsD700
14248
14288
 
14289
+ =head3 Nikon ShotInfoD780 Tags
14290
+
14291
+ These tags are extracted from encrypted data in images from the D780.
14292
+
14293
+ Index Tag Name Writable
14294
+ ----- -------- --------
14295
+ 0 ShotInfoVersion no
14296
+ 4 FirmwareVersion no
14297
+ 156 OrientOffset Nikon OrientationInfo
14298
+
14299
+ =head3 Nikon OrientationInfo Tags
14300
+
14301
+ Index1 Tag Name Writable
14302
+ ------ -------- --------
14303
+ 0 RollAngle fixed32u
14304
+ 4 PitchAngle fixed32u
14305
+ 8 YawAngle fixed32u
14306
+
14307
+ =head3 Nikon ShotInfoD7500 Tags
14308
+
14309
+ These tags are extracted from encrypted data in images from the D7500.
14310
+
14311
+ Index Tag Name Writable
14312
+ ----- -------- --------
14313
+ 0 ShotInfoVersion no
14314
+ 4 FirmwareVersion no
14315
+ 160 OrientOffset Nikon OrientationInfo
14316
+
14249
14317
  =head3 Nikon ShotInfoD800 Tags
14250
14318
 
14251
14319
  These tags are extracted from encrypted data in images from the D800.
@@ -14299,14 +14367,6 @@ These tags are extracted from encrypted data in images from the D810.
14299
14367
  4 ISOAutoShutterTime int8u & 0x3f
14300
14368
  5 ISOAutoHiLimit int8u & 0xff
14301
14369
 
14302
- =head3 Nikon OrientationInfo Tags
14303
-
14304
- Index1 Tag Name Writable
14305
- ------ -------- --------
14306
- 0 RollAngle fixed32u
14307
- 4 PitchAngle fixed32u
14308
- 8 YawAngle fixed32u
14309
-
14310
14370
  =head3 Nikon ShotInfoD850 Tags
14311
14371
 
14312
14372
  These tags are extracted from encrypted data in images from the D850.
@@ -14606,6 +14666,7 @@ These tags are extracted from encrypted data in images from the Z9.
14606
14666
  0 ShotInfoVersion no
14607
14667
  4 FirmwareVersion no
14608
14668
  48 SequenceOffset Nikon SeqInfoZ9
14669
+ 88 Offset13 Nikon Offset13InfoZ9
14609
14670
  132 OrientOffset Nikon OrientationInfo
14610
14671
  140 MenuOffset Nikon MenuInfoZ9
14611
14672
 
@@ -14616,6 +14677,15 @@ These tags are extracted from encrypted data in images from the Z9.
14616
14677
  32 FocusShiftShooting int8u~
14617
14678
  40 IntervalShooting int16u~
14618
14679
 
14680
+ =head3 Nikon Offset13InfoZ9 Tags
14681
+
14682
+ Index1 Tag Name Writable
14683
+ ------ -------- --------
14684
+ 3048 AFAreaInitialXPosition int8s~
14685
+ 3049 AFAreaInitialYPosition int8s~
14686
+ 3050 AFAreaInitialWidth no
14687
+ 3051 AFAreaInitialHeight no
14688
+
14619
14689
  =head3 Nikon MenuInfoZ9 Tags
14620
14690
 
14621
14691
  Index1 Tag Name Writable
@@ -14662,6 +14732,7 @@ These tags are used by the Z9.
14662
14732
  556 SecondarySlotFunction int8u
14663
14733
  572 DXCropAlert int8u
14664
14734
  574 SubjectDetection int8u
14735
+ 576 DynamicAFAreaSize int8u
14665
14736
  604 MovieImageArea? int8u & 0x01
14666
14737
  614 MovieType? int8u
14667
14738
  616 MovieISOAutoHiLimit? int16u
@@ -14737,6 +14808,7 @@ These tags are used by the Z9 firmware 3.00.
14737
14808
  576 SecondarySlotFunction int8u
14738
14809
  592 DXCropAlert int8u
14739
14810
  594 SubjectDetection int8u
14811
+ 596 DynamicAFAreaSize int8u
14740
14812
  636 HighFrequencyFlickerReductionShooting? int8u
14741
14813
  646 MovieImageArea? int8u & 0x01
14742
14814
  656 MovieType? int8u
@@ -14938,15 +15010,16 @@ Tags found in the encrypted LensData from cameras such as the Z6 and Z7.
14938
15010
  18 MaxApertureAtMaxFocal int8u
14939
15011
  19 MCUVersion int8u
14940
15012
  20 EffectiveMaxAperture int8u
15013
+ 47 NewLensData undef[17]
14941
15014
  48 LensID int16u
14942
- 53 LensMountType? int8u
15015
+ 53 LensMountType int8u
14943
15016
  54 MaxAperture int16u
14944
15017
  56 FNumber int16u
14945
15018
  60 FocalLength int16u
14946
15019
  76 FocusDistanceRangeWidth? int8u
14947
15020
  78 FocusDistance int16u~
14948
15021
  86 LensDriveEnd? int8u
14949
- 90 LensPositionAbsolute? int32s
15022
+ 90 LensPositionAbsolute int32s
14950
15023
 
14951
15024
  =head3 Nikon LensDataUnknown Tags
14952
15025
 
@@ -17266,6 +17339,8 @@ any information found here will be extracted, even if the tag is not listed.
17266
17339
  0x0304 FocusStepNear int16u
17267
17340
  0x0305 FocusDistance rational64u
17268
17341
  0x0308 AFPoint int16u
17342
+ 0x031b AFPointDetails no
17343
+ AFPointDetails int16u
17269
17344
  0x0328 AFInfo Olympus AFInfo
17270
17345
  0x1201 ExternalFlash int16u[2]
17271
17346
  0x1203 ExternalFlashGuideNumber? rational64s
@@ -21799,7 +21874,10 @@ These tags are found in IFD0 of Panasonic/Leica RAW, RW2 and RWL images.
21799
21874
  0x011c Gamma int16u
21800
21875
  0x0120 CameraIFD PanasonicRaw CameraIFD
21801
21876
  0x0121 Multishot int32u
21877
+ 0x0127 JpgFromRaw2 no
21878
+ 0x013b Artist string
21802
21879
  0x02bc ApplicationNotes XMP
21880
+ 0x8298 Copyright string
21803
21881
  0x83bb IPTC-NAA IPTC
21804
21882
  0x8769 ExifOffset EXIF
21805
21883
  0x8825 GPSInfo GPS
@@ -22080,30 +22158,32 @@ Note that Microsoft is not consistent with the time zone used for some
22080
22158
  date/time tags, and it may be either UTC or local time depending on the
22081
22159
  software used to create the file.
22082
22160
 
22083
- Tag ID Tag Name Writable
22084
- ------ -------- --------
22085
- "\x01CompObj" CompObj FlashPix CompObj
22086
- "\x05Audio Info" AudioInfo FlashPix AudioInfo
22087
- "\x05Data Object" DataObject FlashPix DataObject
22161
+ Tag ID Tag Name Writable
22162
+ ------ -------- --------
22163
+ "\x01CompObj" CompObj FlashPix CompObj
22164
+ "\x05Audio Info" AudioInfo FlashPix AudioInfo
22165
+ "\x05Data Object" DataObject FlashPix DataObject
22088
22166
  "\x05DocumentSummaryInformation" DocumentInfo FlashPix DocumentInfo
22089
- "\x05Extension List" Extensions FlashPix Extensions
22090
- "\x05Global Info" GlobalInfo FlashPix GlobalInfo
22091
- "\x05Image Contents" Image FlashPix Image
22092
- "\x05Image Info" ImageInfo FlashPix ImageInfo
22093
- "\x05Operation" Operation FlashPix Operation
22094
- "\x05Screen Nail" ScreenNail no
22095
- "\x05SummaryInformation" SummaryInfo FlashPix SummaryInfo
22096
- "\x05Transform" Transform FlashPix Transform
22097
- 'Audio Stream' AudioStream no
22098
- 'BasicFileInfo' BasicFileInfo no
22099
- 'Contents' Contents XMP
22100
- 'Current User' CurrentUser no
22101
- 'ICC Profile 0001' ICC_Profile ICC_Profile
22102
- 'IeImg' EmbeddedImage no
22103
- 'Preview' PreviewImage no
22104
- 'Property' PreviewInfo FlashPix PreviewInfo
22105
- 'Subimage 0000 Header' SubimageHdr FlashPix SubimageHdr
22106
- 'WordDocument' WordDocument FlashPix WordDocument
22167
+ "\x05Extension List" Extensions FlashPix Extensions
22168
+ "\x05Global Info" GlobalInfo FlashPix GlobalInfo
22169
+ "\x05Image Contents" Image FlashPix Image
22170
+ "\x05Image Info" ImageInfo FlashPix ImageInfo
22171
+ "\x05Operation" Operation FlashPix Operation
22172
+ "\x05Screen Nail" ScreenNail no
22173
+ "\x05SummaryInformation" SummaryInfo FlashPix SummaryInfo
22174
+ "\x05Transform" Transform FlashPix Transform
22175
+ 'Audio Stream' AudioStream no
22176
+ 'BasicFileInfo' BasicFileInfo no
22177
+ 'Contents' Contents XMP
22178
+ 'Current User' CurrentUser no
22179
+ 'ICC Profile 0001' ICC_Profile ICC_Profile
22180
+ 'IeImg' EmbeddedImage no
22181
+ 'IeImg_class' EmbeddedImageClass no
22182
+ 'IeImg_rect' EmbeddedImageRectangle no
22183
+ 'Preview' PreviewImage no
22184
+ 'Property' PreviewInfo FlashPix PreviewInfo
22185
+ 'Subimage 0000 Header' SubimageHdr FlashPix SubimageHdr
22186
+ 'WordDocument' WordDocument FlashPix WordDocument
22107
22187
 
22108
22188
  =head3 FlashPix CompObj Tags
22109
22189
 
@@ -38055,6 +38135,7 @@ FileName.
38055
38135
  ICC_Profile ICC_Profile yes!
38056
38136
  ID3Size File no
38057
38137
  IPTC IPTC yes!
38138
+ ImageDataMD5 File no
38058
38139
  ImageHeight File no
38059
38140
  ImageWidth File no
38060
38141
  JPEGDigest File no
@@ -17,7 +17,7 @@ package Image::ExifTool::Validate;
17
17
  use strict;
18
18
  use vars qw($VERSION %exifSpec);
19
19
 
20
- $VERSION = '1.19';
20
+ $VERSION = '1.20';
21
21
 
22
22
  use Image::ExifTool qw(:Utils);
23
23
  use Image::ExifTool::Exif;
@@ -437,8 +437,8 @@ sub ValidateExif($$$$$$$$)
437
437
  $et->Warn(sprintf('Wrong IFD for 0x%.4x %s (should be %s not %s)', $tag, $$ti{Name}, $wgp, $ifd));
438
438
  }
439
439
  }
440
- } elsif (not $otherSpec{$$et{VALUE}{FileType}} or
441
- (not $otherSpec{$$et{VALUE}{FileType}}{$tag} and not $otherSpec{$$et{VALUE}{FileType}}{All}))
440
+ } elsif (not $otherSpec{$$et{FileType}} or
441
+ (not $otherSpec{$$et{FileType}}{$tag} and not $otherSpec{$$et{FileType}}{All}))
442
442
  {
443
443
  if ($tagTablePtr eq \%Image::ExifTool::Exif::Main or $$tagInfo{Unknown}) {
444
444
  $et->Warn(sprintf('Non-standard %s tag 0x%.4x %s', $ifd, $tag, $$ti{Name}), 1);
@@ -459,8 +459,8 @@ sub ValidateExif($$$$$$$$)
459
459
  $et->Warn(sprintf('Non-standard count (%d) for %s 0x%.4x %s', $count, $ifd, $tag, $$ti{Name}));
460
460
  }
461
461
  }
462
- } elsif (not $otherSpec{$$et{VALUE}{FileType}} or
463
- (not $otherSpec{$$et{VALUE}{FileType}}{$tag} and not $otherSpec{$$et{VALUE}{FileType}}{All}))
462
+ } elsif (not $otherSpec{$$et{FileType}} or
463
+ (not $otherSpec{$$et{FileType}}{$tag} and not $otherSpec{$$et{FileType}}{All}))
464
464
  {
465
465
  $et->Warn(sprintf('Unknown %s tag 0x%.4x', $ifd, $tag), 1);
466
466
  }
@@ -419,6 +419,55 @@ sub ValidateImageData($$$;$)
419
419
  }
420
420
  }
421
421
 
422
+ #------------------------------------------------------------------------------
423
+ # Add specified image data to ImageDataMD5 hash
424
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) lookup for [tagInfo,value] based on tagID
425
+ sub AddImageDataMD5($$$)
426
+ {
427
+ my ($et, $dirInfo, $offsetInfo) = @_;
428
+ my ($tagID, $offset, $buff);
429
+
430
+ my $verbose = $et->Options('Verbose');
431
+ my $md5 = $$et{ImageDataMD5};
432
+ my $raf = $$dirInfo{RAF};
433
+ my $base = $$dirInfo{Base} || 0;
434
+
435
+ foreach $tagID (sort keys %$offsetInfo) {
436
+ next unless ref $$offsetInfo{$tagID} eq 'ARRAY'; # ignore scalar tag values used for Validate
437
+ my $tagInfo = $$offsetInfo{$tagID}[0];
438
+ next unless $$tagInfo{IsImageData}; # only consider image data
439
+ my $sizeID = $$tagInfo{OffsetPair};
440
+ my @sizes;
441
+ if ($$tagInfo{NotRealPair}) {
442
+ @sizes = 999999999; # (Panasonic hack: raw data runs to end of file)
443
+ } elsif ($sizeID and $$offsetInfo{$sizeID}) {
444
+ @sizes = split ' ', $$offsetInfo{$sizeID}[1];
445
+ } else {
446
+ next;
447
+ }
448
+ my @offsets = split ' ', $$offsetInfo{$tagID}[1];
449
+ $sizes[0] = 999999999 if $$tagInfo{NotRealPair};
450
+ my $total = 0;
451
+ foreach $offset (@offsets) {
452
+ my $size = shift @sizes;
453
+ next unless $offset =~ /^\d+$/ and $size and $size =~ /^\d+$/ and $size;
454
+ next unless $raf->Seek($offset+$base, 0);
455
+ while ($size) {
456
+ my $bytes = $size > 65536 ? 65536 : $size;
457
+ $raf->Read($buff, $bytes) or last;
458
+ $md5->add($buff);
459
+ $total += length($buff);
460
+ $size -= $bytes;
461
+ }
462
+ }
463
+ if ($verbose) {
464
+ my $name = "$$dirInfo{DirName}:$$tagInfo{Name}";
465
+ $name =~ s/Offsets?|Start$//;
466
+ $et->VPrint(0, "$$et{INDENT}(ImageDataMD5: $total bytes of $name data)\n");
467
+ }
468
+ }
469
+ }
470
+
422
471
  #------------------------------------------------------------------------------
423
472
  # Handle error while writing EXIF
424
473
  # Inputs: 0) ExifTool ref, 1) error string, 2) tag table ref
@@ -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
@@ -1419,9 +1420,12 @@ sub SetNewValuesFromFile($$;@)
1419
1420
  $tag =~ s/(.+?)\s*(>|<) ?//;
1420
1421
  $$opts{EXPR} = 1; # flag this expression
1421
1422
  } else {
1423
+ # (not sure why this is here because sign should be before '<')
1424
+ # (--> allows "<+" or "<-", which is an undocumented feature)
1422
1425
  $opt = $1 if $tag =~ s/^([-+])\s*//;
1423
1426
  }
1424
1427
  }
1428
+ $$opts{Replace} = 0 if $dstTag =~ s/^\+//;
1425
1429
  # validate tag name(s)
1426
1430
  unless ($$opts{EXPR} or ValidTagName($tag)) {
1427
1431
  $self->Warn("Invalid tag name '${tag}'. Use '=' not '<' to assign a tag value");
@@ -1438,6 +1442,8 @@ sub SetNewValuesFromFile($$;@)
1438
1442
  $$opts{Type} = 'ValueConv' if $dstTag =~ s/#$//;
1439
1443
  # replace tag name of 'all' with '*'
1440
1444
  $dstTag = '*' if $dstTag eq 'all';
1445
+ } else {
1446
+ $$opts{Replace} = 0 if $tag =~ s/^\+//;
1441
1447
  }
1442
1448
  unless ($$opts{EXPR}) {
1443
1449
  $isExclude = ($tag =~ s/^-//);
@@ -1447,7 +1453,17 @@ sub SetNewValuesFromFile($$;@)
1447
1453
  # save family/groups in list (ignoring 'all' and '*')
1448
1454
  next unless length($_) and /^(\d+)?(.*)/;
1449
1455
  my ($f, $g) = ($1, $2);
1450
- $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
+ }
1451
1467
  push @fg, [ $f, $g ] unless $g eq '*' or $g eq 'all';
1452
1468
  }
1453
1469
  }
@@ -1484,26 +1500,44 @@ sub SetNewValuesFromFile($$;@)
1484
1500
  # save in reverse order so we don't set tags before an exclude
1485
1501
  unshift @setList, [ \@fg, $tag, $dst, $opts ];
1486
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
+ }
1487
1514
  # 2) initialize lists of matching tags for each setTag
1488
1515
  foreach $set (@setList) {
1489
1516
  $$set[2] and $setMatches{$set} = [ ];
1490
1517
  }
1491
1518
  # 3) loop through all tags in source image and save tags matching each setTag
1492
- my %rtnInfo;
1519
+ my (%rtnInfo, $isAlt);
1493
1520
  foreach $tag (@tags) {
1494
1521
  # don't try to set errors or warnings
1495
1522
  if ($tag =~ /^(Error|Warning)( |$)/) {
1496
- $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
+ }
1497
1528
  next;
1498
1529
  }
1499
1530
  # only set specified tags
1500
1531
  my $lcTag = lc(GetTagName($tag));
1501
1532
  my (@grp, %grp);
1502
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;
1503
1537
  # check first for matching tag
1504
1538
  unless ($$set[1] eq $lcTag or $$set[1] eq '*') {
1505
1539
  # handle wildcards
1506
- next unless $$set[3]{WILD} and $lcTag =~ /^$$set[1]$/;
1540
+ next unless $$opts{WILD} and $lcTag =~ /^$$set[1]$/;
1507
1541
  }
1508
1542
  # then check for matching group
1509
1543
  if (@{$$set[0]}) {
@@ -1835,6 +1869,27 @@ sub RestoreNewValues($)
1835
1869
  $$self{DEL_GROUP} = \%delGrp;
1836
1870
  }
1837
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
+
1838
1893
  #------------------------------------------------------------------------------
1839
1894
  # Set filesystem time from from FileModifyDate or FileCreateDate tag
1840
1895
  # Inputs: 0) ExifTool object reference, 1) file name or file ref
@@ -2722,6 +2777,7 @@ sub GetAllGroups($;$)
2722
2777
  $family == 4 and return('Copy#');
2723
2778
  $family == 5 and return('[too many possibilities to list]');
2724
2779
  $family == 6 and return(@Image::ExifTool::Exif::formatName[1..$#Image::ExifTool::Exif::formatName]);
2780
+ $family == 8 and return('File#');
2725
2781
 
2726
2782
  LoadAllTables(); # first load all our tables
2727
2783
 
@@ -3161,42 +3217,46 @@ sub InsertTagValues($$$;$$$)
3161
3217
  $tag = $docGrp . ':' . $tag;
3162
3218
  $lcTag = lc $tag;
3163
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
+ }
3164
3224
  if ($lcTag eq 'all') {
3165
3225
  $val = 1; # always some tag available
3166
- } elsif (defined $$self{OPTIONS}{UserParam}{$lcTag}) {
3167
- $val = $$self{OPTIONS}{UserParam}{$lcTag};
3226
+ } elsif (defined $$et{OPTIONS}{UserParam}{$lcTag}) {
3227
+ $val = $$et{OPTIONS}{UserParam}{$lcTag};
3168
3228
  } elsif ($tag =~ /(.*):(.+)/) {
3169
3229
  my $group;
3170
3230
  ($group, $tag) = ($1, $2);
3171
3231
  if (lc $tag eq 'all') {
3172
3232
  # see if any tag from the specified group exists
3173
- my $match = $self->GroupMatches($group, $foundTags);
3233
+ my $match = $et->GroupMatches($group, $foundTags);
3174
3234
  $val = $match ? 1 : 0;
3175
3235
  } else {
3176
3236
  # find the specified tag
3177
3237
  my @matches = grep /^$tag(\s|$)/i, @$foundTags;
3178
- @matches = $self->GroupMatches($group, \@matches);
3238
+ @matches = $et->GroupMatches($group, \@matches);
3179
3239
  foreach $tg (@matches) {
3180
3240
  if (defined $val and $tg =~ / \((\d+)\)$/) {
3181
3241
  # take the most recently extracted tag
3182
3242
  my $tagNum = $1;
3183
3243
  next if $tag !~ / \((\d+)\)$/ or $1 > $tagNum;
3184
3244
  }
3185
- $val = $self->GetValue($tg, $type);
3245
+ $val = $et->GetValue($tg, $type);
3186
3246
  $tag = $tg;
3187
3247
  last unless $tag =~ / /; # all done if we got our best match
3188
3248
  }
3189
3249
  }
3190
3250
  } elsif ($tag eq 'self') {
3191
- $val = $self; # ("$self{var}" or "$self->{var}" in string)
3251
+ $val = $et; # ("$self{var}" or "$file1:self{var}" in string)
3192
3252
  } else {
3193
3253
  # get the tag value
3194
- $val = $self->GetValue($tag, $type);
3254
+ $val = $et->GetValue($tag, $type);
3195
3255
  unless (defined $val) {
3196
3256
  # check for tag name with different case
3197
3257
  ($tg) = grep /^$tag$/i, @$foundTags;
3198
3258
  if (defined $tg) {
3199
- $val = $self->GetValue($tg, $type);
3259
+ $val = $et->GetValue($tg, $type);
3200
3260
  $tag = $tg;
3201
3261
  }
3202
3262
  }
@@ -4204,7 +4264,7 @@ sub WriteDirectory($$$;$)
4204
4264
  return '' unless $dataPt or $$dirInfo{RAF}; # nothing to do if block never existed
4205
4265
  # don't allow MakerNotes to be removed from RAW files
4206
4266
  if ($blockName eq 'MakerNotes' and $rawType{$$self{FileType}}) {
4207
- $self->Warn("Can't delete MakerNotes from $$self{VALUE}{FileType}",1);
4267
+ $self->Warn("Can't delete MakerNotes from $$self{FileType}",1);
4208
4268
  return undef;
4209
4269
  }
4210
4270
  $verb = 'Deleting';
@@ -50,7 +50,7 @@ use Image::ExifTool::Exif;
50
50
  use Image::ExifTool::GPS;
51
51
  require Exporter;
52
52
 
53
- $VERSION = '3.56';
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' },
@@ -3097,7 +3109,7 @@ sub ScanForXMP($$)
3097
3109
  undef $buff;
3098
3110
  }
3099
3111
  }
3100
- unless ($$et{VALUE}{FileType}) {
3112
+ unless ($$et{FileType}) {
3101
3113
  $$et{FILE_TYPE} = $$et{FILE_EXT};
3102
3114
  $et->SetFileType('<unknown file containing XMP>', undef, '');
3103
3115
  }
@@ -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)