exiftool_vendored 12.57.0 → 12.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)