exiftool_vendored 12.68.0 → 12.70.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +63 -15
  3. data/bin/META.json +1 -1
  4. data/bin/META.yml +1 -1
  5. data/bin/README +2 -2
  6. data/bin/exiftool +13 -13
  7. data/bin/lib/Image/ExifTool/CBOR.pm +18 -2
  8. data/bin/lib/Image/ExifTool/Canon.pm +68 -16
  9. data/bin/lib/Image/ExifTool/DJI.pm +3 -2
  10. data/bin/lib/Image/ExifTool/DNG.pm +25 -2
  11. data/bin/lib/Image/ExifTool/EXE.pm +54 -6
  12. data/bin/lib/Image/ExifTool/Exif.pm +175 -14
  13. data/bin/lib/Image/ExifTool/FujiFilm.pm +142 -20
  14. data/bin/lib/Image/ExifTool/GIF.pm +5 -1
  15. data/bin/lib/Image/ExifTool/ID3.pm +70 -7
  16. data/bin/lib/Image/ExifTool/InDesign.pm +1 -1
  17. data/bin/lib/Image/ExifTool/JPEG.pm +1 -1
  18. data/bin/lib/Image/ExifTool/Jpeg2000.pm +30 -15
  19. data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -2
  20. data/bin/lib/Image/ExifTool/Nikon.pm +58 -18
  21. data/bin/lib/Image/ExifTool/Olympus.pm +7 -1
  22. data/bin/lib/Image/ExifTool/PNG.pm +8 -13
  23. data/bin/lib/Image/ExifTool/Panasonic.pm +15 -2
  24. data/bin/lib/Image/ExifTool/PhotoMechanic.pm +2 -2
  25. data/bin/lib/Image/ExifTool/QuickTime.pm +32 -5
  26. data/bin/lib/Image/ExifTool/README +14 -5
  27. data/bin/lib/Image/ExifTool/RIFF.pm +60 -10
  28. data/bin/lib/Image/ExifTool/Sony.pm +95 -34
  29. data/bin/lib/Image/ExifTool/TagLookup.pm +6937 -6714
  30. data/bin/lib/Image/ExifTool/TagNames.pod +812 -332
  31. data/bin/lib/Image/ExifTool/Text.pm +4 -5
  32. data/bin/lib/Image/ExifTool/Validate.pm +23 -20
  33. data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +2 -2
  34. data/bin/lib/Image/ExifTool/WriteExif.pl +14 -4
  35. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +1 -0
  36. data/bin/lib/Image/ExifTool/WriteRIFF.pl +31 -6
  37. data/bin/lib/Image/ExifTool/Writer.pl +40 -14
  38. data/bin/lib/Image/ExifTool/XMP.pm +67 -2
  39. data/bin/lib/Image/ExifTool/XMP2.pl +35 -0
  40. data/bin/lib/Image/ExifTool.pm +79 -40
  41. data/bin/lib/Image/ExifTool.pod +9 -3
  42. data/bin/perl-Image-ExifTool.spec +1 -1
  43. data/lib/exiftool_vendored/version.rb +1 -1
  44. metadata +2 -2
@@ -18,12 +18,13 @@ use strict;
18
18
  use vars qw($VERSION);
19
19
  use Image::ExifTool qw(:DataAccess :Utils);
20
20
 
21
- $VERSION = '1.58';
21
+ $VERSION = '1.59';
22
22
 
23
23
  sub ProcessID3v2($$$);
24
24
  sub ProcessPrivate($$$);
25
25
  sub ProcessSynText($$$);
26
26
  sub ProcessID3Dir($$$);
27
+ sub ProcessGEOB($$$);
27
28
  sub ConvertID3v1Text($$);
28
29
  sub ConvertTimeStamp($);
29
30
 
@@ -419,7 +420,7 @@ my %genre = (
419
420
 
420
421
  # Tags for ID2v2.2
421
422
  %Image::ExifTool::ID3::v2_2 = (
422
- PROCESS_PROC => \&Image::ExifTool::ID3::ProcessID3v2,
423
+ PROCESS_PROC => \&ProcessID3v2,
423
424
  GROUPS => { 1 => 'ID3v2_2', 2 => 'Audio' },
424
425
  NOTES => q{
425
426
  ExifTool extracts mainly text-based tags from ID3v2 information. The tags
@@ -511,6 +512,9 @@ my %genre = (
511
512
  TSC => 'ComposerSortOrder',
512
513
  ITU => { Name => 'iTunesU', Description => 'iTunes U', Binary => 1, Unknown => 1 },
513
514
  PCS => { Name => 'Podcast', Binary => 1, Unknown => 1 },
515
+ GP1 => 'Grouping', #github142 (NC)
516
+ MVN => 'MovementName', #github142 (NC)
517
+ MVI => 'MovementNumber', #github142 (NC)
514
518
  );
515
519
 
516
520
  # tags common to ID3v2.3 and ID3v2.4
@@ -534,7 +538,10 @@ my %id3v2_common = (
534
538
  # COMR => 'Commercial',
535
539
  # ENCR => 'EncryptionMethod',
536
540
  # ETCO => 'EventTimingCodes',
537
- # GEOB => 'GeneralEncapsulatedObject',
541
+ GEOB => {
542
+ Name => 'GeneralEncapsulatedObject',
543
+ SubDirectory => { TagTable => 'Image::ExifTool::ID3::GEOB' },
544
+ },
538
545
  # GRID => 'GroupIdentification',
539
546
  # LINK => 'LinkedInformation',
540
547
  MCDI => { Name => 'MusicCDIdentifier', Binary => 1 },
@@ -640,9 +647,25 @@ my %id3v2_common = (
640
647
  MVIN => 'MovementNumber', # (NC)
641
648
  );
642
649
 
650
+ %Image::ExifTool::ID3::GEOB = (
651
+ GROUPS => { 1 => 'ID3v2_3', 2 => 'Other' },
652
+ PROCESS_PROC => \&ProcessGEOB,
653
+ 'application/x-c2pa-manifest-store' => {
654
+ Name => 'JUMBF',
655
+ SubDirectory => {
656
+ TagTable => 'Image::ExifTool::Jpeg2000::Main',
657
+ ByteOrder => 'BigEndian',
658
+ },
659
+ },
660
+ 'GEOB-Mime' => { },
661
+ 'GEOB-File' => { },
662
+ 'GEOB-Desc' => { },
663
+ 'GEOB-Data' => { },
664
+ );
665
+
643
666
  # Tags for ID3v2.3 (http://www.id3.org/id3v2.3.0)
644
667
  %Image::ExifTool::ID3::v2_3 = (
645
- PROCESS_PROC => \&Image::ExifTool::ID3::ProcessID3v2,
668
+ PROCESS_PROC => \&ProcessID3v2,
646
669
  GROUPS => { 1 => 'ID3v2_3', 2 => 'Audio' },
647
670
  NOTES => q{
648
671
  ID3 version 2.3 tags. Includes some non-standard tags written by other
@@ -662,7 +685,7 @@ my %id3v2_common = (
662
685
 
663
686
  # Tags for ID3v2.4 (http://www.id3.org/id3v2.4.0-frames)
664
687
  %Image::ExifTool::ID3::v2_4 = (
665
- PROCESS_PROC => \&Image::ExifTool::ID3::ProcessID3v2,
688
+ PROCESS_PROC => \&ProcessID3v2,
666
689
  GROUPS => { 1 => 'ID3v2_4', 2 => 'Audio' },
667
690
  NOTES => q{
668
691
  ID3 version 2.4 tags. Includes some non-standard tags written by other
@@ -1101,7 +1124,11 @@ sub ProcessID3v2($$$)
1101
1124
  my $oldLen = $len;
1102
1125
  $len = UnSyncSafe($len);
1103
1126
  if (not defined $len or $offset + $len + 10 > $size) {
1104
- $et->Warn('Invalid ID3 frame size');
1127
+ if ($offset + $len == $size) {
1128
+ $et->Warn('Missing ID3 terminating frame', 1);
1129
+ } else {
1130
+ $et->Warn('Invalid ID3 frame size');
1131
+ }
1105
1132
  last;
1106
1133
  }
1107
1134
  # check next ID to see if it makes sense
@@ -1218,7 +1245,7 @@ sub ProcessID3v2($$$)
1218
1245
  my @vals = DecodeString($et, $val);
1219
1246
  foreach (0..1) { $vals[$_] = '' unless defined $vals[$_]; }
1220
1247
  ($val = "($vals[0]) $vals[1]") =~ s/^\(\) //;
1221
- } elsif ($id =~ /^T/ or $id =~ /^(IPL|IPLS)$/) {
1248
+ } elsif ($id =~ /^T/ or $id =~ /^(IPL|IPLS|GP1|MVI|MVN)$/) {
1222
1249
  $val = DecodeString($et, $val);
1223
1250
  } elsif ($id =~ /^(WXX|WXXX)$/) {
1224
1251
  # one encoded string and one Latin string separated by a null
@@ -1582,6 +1609,42 @@ sub ProcessID3Dir($$$)
1582
1609
  return ProcessID3($et, $dirInfo);
1583
1610
  }
1584
1611
 
1612
+ #------------------------------------------------------------------------------
1613
+ # Process ID3 General Encapsulated Object
1614
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
1615
+ # Returns: 1 on success
1616
+ sub ProcessGEOB($$$)
1617
+ {
1618
+ my ($et, $dirInfo, $tagTablePtr) = @_;
1619
+ $et->VerboseDir('GEOB', undef, length ${$$dirInfo{DataPt}});
1620
+ my $dataPt = $$dirInfo{DataPt};
1621
+ my $len = length $$dataPt;
1622
+ $len >= 4 or $et->Warn("Short GEOB frame"), return 0;
1623
+ my ($hdr, $attr);
1624
+ my $enc = unpack('C', $$dataPt);
1625
+ if ($enc == 1 or $enc == 2) {
1626
+ $hdr = ".(.*?)\0((?:..)*?)\0\0((?:..)*?)\0\0";
1627
+ } else {
1628
+ $hdr = ".(.*?)\0(.*?)\0(.*?)\0";
1629
+ }
1630
+ # remove header (encoding, mime, filename, description)
1631
+ $$dataPt =~ s/^$hdr//s or $et->Warn("Invalid GEOB frame"), return 0;
1632
+ my ($mime, $file, $desc) = ($1, DecodeString($et, $2, $enc), DecodeString($et, $3, $enc));
1633
+ $et->HandleTag($tagTablePtr, 'GEOB-Mime', $mime) if length $mime;
1634
+ $et->HandleTag($tagTablePtr, 'GEOB-File', $file) if length $file;
1635
+ $et->HandleTag($tagTablePtr, 'GEOB-Desc', $desc) if length $desc;
1636
+ if ($$tagTablePtr{$mime}) {
1637
+ $et->HandleTag($tagTablePtr, $mime, undef,
1638
+ DataPt => $dataPt,
1639
+ Start => 0,
1640
+ Size => length($$dataPt),
1641
+ );
1642
+ } else {
1643
+ $et->HandleTag($tagTablePtr, 'GEOB-Data', $dataPt);
1644
+ }
1645
+ return 1;
1646
+ }
1647
+
1585
1648
  #------------------------------------------------------------------------------
1586
1649
  # Extract ID3 information from an MP3 audio file
1587
1650
  # Inputs: 0) ExifTool object reference, 1) dirInfo reference
@@ -122,7 +122,7 @@ sub ProcessIND($$)
122
122
  # memory troubles (with its apparent 1 GB limit) if the XMP is larger
123
123
  # than about 400 MB, so guard against this
124
124
  if ($len > 300 * 1024 * 1024) {
125
- my $msg = sprintf('Insanely large XMP (%.0f MB)', $len / (1024 * 1024));
125
+ my $msg = sprintf('Insanely large XMP (%.0f MiB)', $len / (1024 * 1024));
126
126
  if ($outfile) {
127
127
  $et->Error($msg, 2) and $err = 1, last;
128
128
  } elsif ($et->Options('IgnoreMinorErrors')) {
@@ -251,7 +251,7 @@ sub ProcessJPEG_HDR($$$);
251
251
  Name => 'JUMBF',
252
252
  Condition => '$$valPt =~ /^JP/',
253
253
  SubDirectory => { TagTable => 'Image::ExifTool::Jpeg2000::Main' },
254
- # Note: The recommended options for reading C2PA JUMBF metadata are "-G3 -b -j -u"
254
+ # Note: The suggested options for reading C2PA CAI JUMBF metadata are "-G3 -b -j -u"
255
255
  }],
256
256
  APP12 => [{
257
257
  Name => 'PictureInfo',
@@ -89,12 +89,14 @@ my %uuid = (
89
89
  # JPEG2000 codestream markers (ref ISO/IEC FCD15444-1/2)
90
90
  my %j2cMarker = (
91
91
  0x4f => 'SOC', # start of codestream
92
+ # 0x50 - seen in JPH codestream
92
93
  0x51 => 'SIZ', # image and tile size
93
94
  0x52 => 'COD', # coding style default
94
95
  0x53 => 'COC', # coding style component
95
96
  0x55 => 'TLM', # tile-part lengths
96
97
  0x57 => 'PLM', # packet length, main header
97
98
  0x58 => 'PLT', # packet length, tile-part header
99
+ # 0x59 - seen in JPH codestream
98
100
  0x5c => 'QCD', # quantization default
99
101
  0x5d => 'QCC', # quantization component
100
102
  0x5e => 'RGN', # region of interest
@@ -128,12 +130,21 @@ my %j2cMarker = (
128
130
  WRITE_PROC => \&ProcessJpeg2000Box,
129
131
  PREFERRED => 1, # always add these tags when writing
130
132
  NOTES => q{
131
- The tags below are found in JPEG 2000 images and the JUMBF metadata in JPEG
132
- images, but not all of these are extracted. Note that ExifTool currently
133
- writes only EXIF, IPTC and XMP tags in Jpeg2000 images, and EXIF and XMP in
134
- JXL images. ExifTool will read/write Brotli-compressed EXIF and XMP in JXL
135
- images, but the API L<Compress|../ExifTool.html#Compress> option must be set to create new EXIF and XMP
136
- in compressed format.
133
+ The tags below are found in JPEG 2000 images and the C2PA CAI JUMBF metadata
134
+ in various file types (see below). Note that ExifTool currently writes only
135
+ EXIF, IPTC and XMP tags in Jpeg2000 images, and EXIF and XMP in JXL images.
136
+ ExifTool will read/write Brotli-compressed EXIF and XMP in JXL images, but
137
+ the API L<Compress|../ExifTool.html#Compress> option must be set to create new EXIF and XMP in compressed
138
+ format.
139
+
140
+ C2PA (Coalition for Content Provenance and Authenticity) CAI (Content
141
+ Authenticity Initiative) JUMBF (JPEG Universal Metadata Box Format) metdata
142
+ is currently extracted from JPEG, PNG, TIFF-based (eg. TIFF, DNG),
143
+ QuickTime-based (eg. MP4, MOV, HEIF, AVIF), RIFF-based (eg. WAV, AVI, WebP),
144
+ GIF files and ID3v2 metadata. The suggested ExifTool command-line arguments
145
+ for reading C2PA metadata are C<-jumbf:all -G3 -b -j -u -struct>. This
146
+ metadata may be deleted from writable JPEG, PNG, WebP, TIFF-based, and
147
+ QuickTime-based files by deleting the JUMBF group with C<-jumbf:all=>.
137
148
  },
138
149
  #
139
150
  # NOTE: ONLY TAGS WITH "Format" DEFINED ARE EXTRACTED!
@@ -345,13 +356,6 @@ my %j2cMarker = (
345
356
  Start => '$valuePtr + 16',
346
357
  },
347
358
  },
348
- {
349
- Name => 'UUID-Signature', # (seen in JUMB data of JPEG images)
350
- # (may be able to remove this when JUMBF specification is finalized)
351
- Condition => '$$valPt=~/^casg\x00\x11\x00\x10\x80\x00\x00\xaa\x00\x38\x9b\x71/',
352
- Format => 'undef',
353
- ValueConv => 'substr($val,16)',
354
- },
355
359
  {
356
360
  Name => 'UUID-C2PAClaimSignature', # (seen in incorrectly-formatted JUMB data of JPEG images)
357
361
  # (may be able to remove this when JUMBF specification is finalized)
@@ -361,6 +365,13 @@ my %j2cMarker = (
361
365
  Start => '$valuePtr + 16',
362
366
  },
363
367
  },
368
+ {
369
+ Name => 'UUID-Signature', # (seen in JUMB data of JPEG images)
370
+ # (may be able to remove this when JUMBF specification is finalized)
371
+ Condition => '$$valPt=~/^casg\x00\x11\x00\x10\x80\x00\x00\xaa\x00\x38\x9b\x71/',
372
+ Format => 'undef',
373
+ ValueConv => 'substr($val,16)',
374
+ },
364
375
  {
365
376
  Name => 'UUID-Unknown',
366
377
  },
@@ -549,6 +560,7 @@ my %j2cMarker = (
549
560
  'jpm ' => 'JPEG 2000 Compound Image (.JPM)', # image/jpm
550
561
  'jpx ' => 'JPEG 2000 with extensions (.JPX)', # image/jpx
551
562
  'jxl ' => 'JPEG XL Image (.JXL)', # image/jxl
563
+ 'jph ' => 'High-throughput JPEG 2000 (.JPH)', # image/jph
552
564
  },
553
565
  },
554
566
  1 => {
@@ -993,10 +1005,12 @@ sub ProcessJpeg2000Box($$$)
993
1005
  my $dirLen = $$dirInfo{DirLen} || 0;
994
1006
  my $dirStart = $$dirInfo{DirStart} || 0;
995
1007
  my $base = $$dirInfo{Base} || 0;
996
- my $raf = $$dirInfo{RAF};
997
1008
  my $outfile = $$dirInfo{OutFile};
998
1009
  my $dirEnd = $dirStart + $dirLen;
999
- my ($err, $outBuff, $verbose, $doColour, $hash);
1010
+ my ($err, $outBuff, $verbose, $doColour, $hash, $raf);
1011
+
1012
+ # read from RAF unless reading from buffer
1013
+ $raf = $$dirInfo{RAF} unless $dataPt;
1000
1014
 
1001
1015
  if ($outfile) {
1002
1016
  unless ($raf) {
@@ -1516,6 +1530,7 @@ sub ProcessJP2($$)
1516
1530
  $fileType = 'JPX' if $1 eq 'jpx ';
1517
1531
  $fileType = 'JPM' if $1 eq 'jpm ';
1518
1532
  $fileType = 'JXL' if $1 eq 'jxl ';
1533
+ $fileType = 'JPH' if $1 eq 'jph ';
1519
1534
  }
1520
1535
  $raf->Seek(-length($buff), 1) if defined $buff;
1521
1536
  $et->SetFileType($fileType);
@@ -21,7 +21,7 @@ sub ProcessKodakPatch($$$);
21
21
  sub WriteUnknownOrPreview($$$);
22
22
  sub FixLeicaBase($$;$);
23
23
 
24
- $VERSION = '2.14';
24
+ $VERSION = '2.15';
25
25
 
26
26
  my $debug; # set to 1 to enable debugging code
27
27
 
@@ -694,7 +694,7 @@ my $debug; # set to 1 to enable debugging code
694
694
  Name => 'MakerNoteLeica8', # used by the Q (Type 116)
695
695
  # (Q (Typ 116) starts with "LEICA\0\x08\0", Make is "LEICA CAMERA AG")
696
696
  # (SL (Typ 601) and CL start with "LEICA\0\x09\0", Make is "LEICA CAMERA AG")
697
- Condition => '$$valPt =~ /^LEICA\0[\x08\x09]\0/',
697
+ Condition => '$$valPt =~ /^LEICA\0[\x08\x09\x0a]\0/',
698
698
  SubDirectory => {
699
699
  TagTable => 'Image::ExifTool::Panasonic::Leica5',
700
700
  Start => '$valuePtr + 8',
@@ -65,7 +65,7 @@ use Image::ExifTool::Exif;
65
65
  use Image::ExifTool::GPS;
66
66
  use Image::ExifTool::XMP;
67
67
 
68
- $VERSION = '4.26';
68
+ $VERSION = '4.27';
69
69
 
70
70
  sub LensIDConv($$$);
71
71
  sub ProcessNikonAVI($$$);
@@ -962,8 +962,8 @@ my %imageAreaZ9b = (
962
962
  );
963
963
 
964
964
  my %infoZSeries = (
965
- Condition => '$$self{Model} =~ /^NIKON Z (30|5|50|6|6_2|7|7_2|8|fc|9)\b/i',
966
- Notes => 'Z Series cameras thru July 2023',
965
+ Condition => '$$self{Model} =~ /^NIKON Z (30|5|50|6|6_2|7|7_2|8|f|fc|9)\b/i',
966
+ Notes => 'Z Series cameras thru October 2023',
967
967
  );
968
968
 
969
969
  my %iSOAutoHiLimitZ7 = (
@@ -2582,9 +2582,21 @@ my %base64coord = (
2582
2582
  DirOffset => 4,
2583
2583
  },
2584
2584
  },
2585
- { # (D5200/D7100=0218, D5300=0219, D610/Df=0220, D3300=0221, CoolpixA=0601)
2586
- Name => 'ColorBalanceUnknown02',
2587
- Condition => '$$valPt =~ /^0[26]/',
2585
+ { #PH (NC)
2586
+ # (D5300=0219, D3300=0221, D4S=0222, D750/D810=0223, D3400/D3500/D5500/D5600/D7200=0224)
2587
+ Condition => '$$valPt =~ /^02(19|2[1234])/',
2588
+ Name => 'ColorBalance0219',
2589
+ SubDirectory => {
2590
+ TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
2591
+ ProcessProc => \&ProcessNikonEncrypted,
2592
+ WriteProc => \&ProcessNikonEncrypted,
2593
+ DecryptStart => 4,
2594
+ DirOffset => 0x7c,
2595
+ },
2596
+ },
2597
+ { # (D610/Df=0220, CoolpixA=0601)
2598
+ Name => 'ColorBalanceUnknown1',
2599
+ Condition => '$$valPt =~ /^0(220|6)/',
2588
2600
  SubDirectory => {
2589
2601
  TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown',
2590
2602
  ProcessProc => \&ProcessNikonEncrypted,
@@ -2592,11 +2604,12 @@ my %base64coord = (
2592
2604
  DecryptStart => 284,
2593
2605
  },
2594
2606
  },
2595
- { # (1J1/1J2/1V1=0400, 1V2=0401, 1J3/1S1=0402, 1AW1=0403, Z6/Z7=0800)
2596
- Name => 'ColorBalanceUnknown04',
2597
- Condition => '$$valPt =~ /^0[48]/',
2607
+ { # (D5200/D7200=0218, D5/D500=0225, D7500=0226, D850=0227, D6/D780=0228,
2608
+ # 1J1/1J2/1V1=0400, 1V2=0401, 1J3/1S1=0402, 1AW1=0403, Z6/Z7=0800)
2609
+ Name => 'ColorBalanceUnknown2',
2610
+ Condition => '$$valPt =~ /^0(18|[248])/',
2598
2611
  SubDirectory => {
2599
- TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown',
2612
+ TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown2',
2600
2613
  ProcessProc => \&ProcessNikonEncrypted,
2601
2614
  WriteProc => \&ProcessNikonEncrypted, # (necessary to recrypt this if serial number changed)
2602
2615
  DecryptStart => 4,
@@ -4588,7 +4601,7 @@ my %base64coord = (
4588
4601
  RawConv => '$$self{AFInfo2Version} = $val',
4589
4602
  },
4590
4603
  5 => { #28
4591
- Name => 'AFAreaMode', #reflects the mode active when the shutter is tripped, not the position of the Focus Mode button (which is recorded in MenuSettingsZ9 tag also named AfAreaMode)
4604
+ Name => 'AFAreaMode', #reflects the mode active when the shutter is tripped, not the position of the Focus Mode button (which is recorded in MenuSettingsZ9 tag also named AfAreaMode)
4592
4605
  PrintConv => {
4593
4606
  192 => 'Pinpoint',
4594
4607
  193 => 'Single',
@@ -4604,7 +4617,7 @@ my %base64coord = (
4604
4617
  },
4605
4618
  10 => {
4606
4619
  Name => 'AFPointsUsed',
4607
- Condition => '$$self{AFAreaMode} == 6', #only valid for Auto AF Area mode. Other modes handled via AFAreaXPosition/AFAreaYPosition
4620
+ Condition => 'defined $$self{AFAreaMode} and $$self{AFAreaMode} == 6', #only valid for Auto AF Area mode. Other modes handled via AFAreaXPosition/AFAreaYPosition
4608
4621
  Format => 'undef[51]',
4609
4622
  ValueConv => 'join(" ", unpack("H2"x51, $val))',
4610
4623
  ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
@@ -4956,6 +4969,16 @@ my %nrwLevels = (
4956
4969
  },
4957
4970
  );
4958
4971
 
4972
+ %Image::ExifTool::Nikon::ColorBalanceUnknown2 = (
4973
+ %binaryDataAttrs,
4974
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4975
+ FORMAT => 'int16u',
4976
+ 0 => {
4977
+ Name => 'ColorBalanceVersion',
4978
+ Format => 'undef[4]',
4979
+ },
4980
+ );
4981
+
4959
4982
  %Image::ExifTool::Nikon::Type2 = (
4960
4983
  WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
4961
4984
  CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
@@ -5442,6 +5465,13 @@ my %nikonFocalConversions = (
5442
5465
  37 => 'Nikkor Z 600mm f/4 TC VR S', #28
5443
5466
  38 => 'Nikkor Z 85mm f/1.2 S', #28
5444
5467
  39 => 'Nikkor Z 17-28mm f/2.8', #IB
5468
+ 40 => 'NIKKOR Z 26mm f/2.8', #28
5469
+ 41 => 'NIKKOR Z DX 12-28mm f/3.5-5.6 PZ VR', #28
5470
+ 42 => 'Nikkor Z 180-600mm f/5.6-6.3 VR', #30
5471
+ 43 => 'NIKKOR Z DX 24mm f/1.7', #28
5472
+ 44 => 'NIKKOR Z 70-180mm f/2.8', #28
5473
+ 45 => 'NIKKOR Z 600mm f/6.3 VR S', #28
5474
+ 46 => 'Nikkor Z 135mm f/1.8 S Plena', #28
5445
5475
  32768 => 'Nikkor Z 400mm f/2.8 TC VR S TC-1.4x', #28
5446
5476
  32769 => 'Nikkor Z 600mm f/4 TC VR S TC-1.4x', #28
5447
5477
  },
@@ -8188,7 +8218,7 @@ my %nikonFocalConversions = (
8188
8218
  CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
8189
8219
  VARS => { ID_LABEL => 'Index', NIKON_OFFSETS => 0x24 },
8190
8220
  DATAMEMBER => [ 0x04 ],
8191
- IS_SUBDIR => [ 0x30, 0x38, 0x98, 0xa0 ],
8221
+ IS_SUBDIR => [ 0x30, 0x38, 0x88, 0x98, 0xa0 ],
8192
8222
  WRITABLE => 1,
8193
8223
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8194
8224
  NOTES => 'These tags are extracted from encrypted data in images from the Z7II.',
@@ -8238,9 +8268,19 @@ my %nikonFocalConversions = (
8238
8268
  Start => '$val',
8239
8269
  }
8240
8270
  },
8271
+ 0x88 => {
8272
+ Name => 'OrientationOffset',
8273
+ Format => 'int32u',
8274
+ Condition => '$$self{Model} =~ /^NIKON Z f\b/i',
8275
+ SubDirectory => {
8276
+ TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8277
+ Start => '$val',
8278
+ }
8279
+ },
8241
8280
  0x98 => {
8242
8281
  Name => 'OrientationOffset',
8243
8282
  Format => 'int32u',
8283
+ Condition => '$$self{Model} =~ /^NIKON Z (30|5|50|6|6_2|7|7_2|8|fc)\b/i', #models other then the Z f
8244
8284
  SubDirectory => {
8245
8285
  TagTable => 'Image::ExifTool::Nikon::OrientationInfo',
8246
8286
  Start => '$val',
@@ -8507,7 +8547,7 @@ my %nikonFocalConversions = (
8507
8547
  0x002a => {
8508
8548
  Name => 'IntervalFrame',
8509
8549
  RawConv => '$$self{IntervalFrame} = $val',
8510
- Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{FocusShiftShooting} > 0', #not valid for C30/C60/C120
8550
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and $$self{IntervalShooting} > 0', #not valid for C30/C60/C120
8511
8551
  Format => 'int16u',
8512
8552
  Hidden => 1,
8513
8553
  },
@@ -8520,7 +8560,7 @@ my %nikonFocalConversions = (
8520
8560
  DATAMEMBER => [ 0x0bea, 0x0beb ],
8521
8561
  0x0be8 => {
8522
8562
  Name => 'AFAreaInitialXPosition', #stored as a representation of the horizontal position of the center of the portion of the focus box positioned top left when in Wide Area (L/S/C1/C2) focus modes (before subject detection potentially refines focus)
8523
- Condition => '$$self{ShutterMode} ne 96 and $$self{AFAreaMode} < 2 ', #not valid for C30/C60/C120 or for Area Modes 1:1 and 16:19
8563
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and defined $$self{AFAreaMode} and $$self{AFAreaMode} < 2 ', #not valid for C30/C60/C120 or for Area Modes 1:1 and 16:19
8524
8564
  Format => 'int8s',
8525
8565
  PrintConv => q{
8526
8566
  #in FX mode and Single-point, the 29 horizontal focus points are spaced 259 pixels apart starting at pixel 502 and ending at 7754. Spacing is the same for Wide(L/C1/C2) with different start points.
@@ -8582,7 +8622,7 @@ my %nikonFocalConversions = (
8582
8622
  },
8583
8623
  0x0be9 => {
8584
8624
  Name =>'AFAreaInitialYPosition', #stored as a representation of the vertical position of the center of the portion of the focus box positioned top left when in Wide Area (L/S/C1/C2) focus modes (before subject detection potentially refines focus)
8585
- Condition => '$$self{ShutterMode} ne 96 and $$self{AFAreaMode} < 2', #not valid for C30/C60/C120 or for Area Modes 1:1 and 16:19
8625
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96 and defined $$self{AFAreaMode} and $$self{AFAreaMode} < 2', #not valid for C30/C60/C120 or for Area Modes 1:1 and 16:19
8586
8626
  Format => 'int8s',
8587
8627
  PrintConv => q{
8588
8628
  #in FX mode and Single-point, the 17 vertical focus points are spaced 291 pixels apart starting at pixel 424 and ending at 5080. Spacing is the same for Wide(L/C1/C2)
@@ -8646,13 +8686,13 @@ my %nikonFocalConversions = (
8646
8686
  },
8647
8687
  0x0bea => {
8648
8688
  Name => 'AFAreaInitialWidth',
8649
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8689
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8650
8690
  ValueConv => '$$self{VALUE}{PhotoShootingMenuBankImageArea} eq 0 ? $val : int($val * 2 / 3)', #DX mode requires scaling down TODO: add support ImageAreas 1:1 and 16:9
8651
8691
  RawConv => '$$self{AFAreaInitialWidth} = 1 + int ($val / 4)', #convert from [3, 11, 19, 35, 51, 75] to [1, 3, 5, 9 13, 19] to match camera options for C1/C2 focus modes .. input/output of 11/3 is for Wide(S)
8652
8692
  },
8653
8693
  0x0beb => {
8654
8694
  Name => 'AFAreaInitialHeight',
8655
- Condition => '$$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8695
+ Condition => '$$self{ShutterMode} and $$self{ShutterMode} ne 96', #not valid for C30/C60/C120
8656
8696
  ValueConv => '$$self{VALUE}{PhotoShootingMenuBankImageArea} eq 0 ? $val : int($val * 2 / 3)', #DX mode requires scaling down TODO: add support ImageAreas 1:1 and 16:9
8657
8697
  RawConv => '$$self{AFAreaInitialHeight} = 1 + int ($val / 7) ', #convert from [6, 20, 33, 46, 73] to [1, 3, 5, 7, 11] to match camera options for C1/C2 focus modes .. input/output of 33/5 is for Wide(L)
8658
8698
  },
@@ -40,7 +40,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
40
40
  use Image::ExifTool::Exif;
41
41
  use Image::ExifTool::APP12;
42
42
 
43
- $VERSION = '2.81';
43
+ $VERSION = '2.82';
44
44
 
45
45
  sub PrintLensInfo($$$);
46
46
 
@@ -186,7 +186,9 @@ my %olympusLensTypes = (
186
186
  '2 36 10' => 'Leica DG Elmarit 200mm F2.8 Power OIS', #IB
187
187
  '2 37 10' => 'Leica DG Vario-Elmarit 50-200mm F2.8-4 Asph. Power OIS', #IB
188
188
  '2 38 10' => 'Leica DG Vario-Summilux 10-25mm F1.7 Asph.', #IB
189
+ '2 39 10' => 'Leica DG Summilux 25mm F1.4 II Asph.', #forum15345
189
190
  '2 40 10' => 'Leica DG Vario-Summilux 25-50mm F1.7 Asph.', #IB (H-X2550)
191
+ '2 41 10' => 'Leica DG Summilux 9mm F1.7 Asph.', #forum15345
190
192
  '3 01 00' => 'Leica D Vario Elmarit 14-50mm F2.8-3.5 Asph.', #11
191
193
  '3 02 00' => 'Leica D Summilux 25mm F1.4 Asph.', #11
192
194
  # Tamron lenses
@@ -358,6 +360,7 @@ my %olympusCameraTypes = (
358
360
  D4521 => 'SH-25MR',
359
361
  D4523 => 'SP-720UZ',
360
362
  D4529 => 'VG170',
363
+ D4530 => 'VH210',
361
364
  D4531 => 'XZ-2',
362
365
  D4535 => 'SP-620UZ',
363
366
  D4536 => 'TG-320',
@@ -383,9 +386,11 @@ my %olympusCameraTypes = (
383
386
  D4585 => 'SH-2 / SH-3',
384
387
  D4586 => 'TG-4',
385
388
  D4587 => 'TG-860',
389
+ D4590 => 'TG-TRACKER',
386
390
  D4591 => 'TG-870',
387
391
  D4593 => 'TG-5', #IB
388
392
  D4603 => 'TG-6', #IB
393
+ D4605 => 'TG-7',
389
394
  D4809 => 'C2500L',
390
395
  D4842 => 'E-10',
391
396
  D4856 => 'C-1',
@@ -431,6 +436,7 @@ my %olympusCameraTypes = (
431
436
  S0076 => 'E-PL9', #IB
432
437
  S0080 => 'E-M1X', #IB
433
438
  S0085 => 'E-PL10', #IB
439
+ S0088 => 'E-M10MarkIV',
434
440
  S0089 => 'E-M5MarkIII',
435
441
  S0092 => 'E-M1MarkIII', #IB
436
442
  S0093 => 'E-P7', #IB
@@ -80,6 +80,7 @@ my %pngMap = (
80
80
  ICC_Profile => 'PNG',
81
81
  Photoshop => 'PNG',
82
82
  'PNG-pHYs' => 'PNG',
83
+ JUMBF => 'PNG',
83
84
  IPTC => 'Photoshop',
84
85
  MakerNotes => 'ExifIFD',
85
86
  );
@@ -341,6 +342,7 @@ my %noLeapFrog = ( SAVE => 1, SEEK => 1, IHDR => 1, JHDR => 1, IEND => 1, MEND =
341
342
  },
342
343
  caBX => { # C2PA metadata
343
344
  Name => 'JUMBF',
345
+ Deletable => 1,
344
346
  SubDirectory => { TagTable => 'Image::ExifTool::Jpeg2000::Main' },
345
347
  },
346
348
  cICP => {
@@ -973,20 +975,13 @@ sub FoundPNG($$$$;$$$$)
973
975
  undef $processProc if $wasCompressed and $processProc and $processProc eq \&ProcessPNG_Compressed;
974
976
  # rewrite this directory if necessary (but always process TextualData normally)
975
977
  if ($outBuff and not $processProc and $subTable ne \%Image::ExifTool::PNG::TextualData) {
976
- # allow JUMBF to be deleted (may want to expand this for other types too?)
977
- if ($dirName eq 'JUMBF' and $$et{DEL_GROUP}{$dirName}) {
978
- $$outBuff = '';
979
- ++$$et{CHANGED};
980
- $et->VPrint(0, " Deleting $dirName");
981
- } else {
982
- return 1 unless $$et{EDIT_DIRS}{$dirName};
983
- $$outBuff = $et->WriteDirectory(\%subdirInfo, $subTable);
984
- if ($tagName eq 'XMP' and $$outBuff) {
985
- # make sure the XMP is marked as read-only
986
- Image::ExifTool::XMP::ValidateXMP($outBuff,'r');
987
- }
988
- DoneDir($et, $dirName, $outBuff, $$tagInfo{NonStandard});
978
+ return 1 unless $$et{EDIT_DIRS}{$dirName};
979
+ $$outBuff = $et->WriteDirectory(\%subdirInfo, $subTable);
980
+ if ($tagName eq 'XMP' and $$outBuff) {
981
+ # make sure the XMP is marked as read-only
982
+ Image::ExifTool::XMP::ValidateXMP($outBuff,'r');
989
983
  }
984
+ DoneDir($et, $dirName, $outBuff, $$tagInfo{NonStandard});
990
985
  } else {
991
986
  $processed = $et->ProcessDirectory(\%subdirInfo, $subTable, $processProc);
992
987
  }
@@ -37,7 +37,7 @@ use vars qw($VERSION %leicaLensTypes);
37
37
  use Image::ExifTool qw(:DataAccess :Utils);
38
38
  use Image::ExifTool::Exif;
39
39
 
40
- $VERSION = '2.19';
40
+ $VERSION = '2.21';
41
41
 
42
42
  sub ProcessLeicaLEIC($$$);
43
43
  sub WhiteBalanceConv($;$$);
@@ -1991,6 +1991,15 @@ my %shootingMode = (
1991
1991
  },
1992
1992
  PrintConvInv => '$_=$val; tr/A-Z0-9//dc; s/(.{3})(19|20)/$1/; $_',
1993
1993
  },
1994
+ 0x05ff => {
1995
+ Name => 'CameraIFD', # (Leica Q3)
1996
+ Condition => '$$valPt =~ /^(II\x2a\0\x08\0\0\0|MM\0\x2a\0\0\0\x08)/',
1997
+ SubDirectory => {
1998
+ TagTable => 'Image::ExifTool::PanasonicRaw::CameraIFD',
1999
+ Base => '$start',
2000
+ ProcessProc => \&Image::ExifTool::ProcessTIFF,
2001
+ },
2002
+ },
1994
2003
  );
1995
2004
 
1996
2005
  # Leica type5 ShotInfo (ref PH) (X2)
@@ -2834,10 +2843,14 @@ sub ProcessLeicaTrailer($;$)
2834
2843
  my $val = Image::ExifTool::Exif::RebuildMakerNotes($et, \%dirInfo, $tagTablePtr);
2835
2844
  unless (defined $val) {
2836
2845
  $et->Warn('Error rebuilding maker notes (may be corrupt)') if $len > 4;
2837
- $val = $buff,
2846
+ $val = $buff;
2838
2847
  }
2839
2848
  my $key = $et->FoundTag($tagInfo, $val);
2840
2849
  $et->SetGroup($key, 'ExifIFD');
2850
+ if ($$et{MAKER_NOTE_FIXUP}) {
2851
+ $$et{TAG_EXTRA}{$key}{Fixup} = $$et{MAKER_NOTE_FIXUP};
2852
+ delete $$et{MAKER_NOTE_FIXUP};
2853
+ }
2841
2854
  }
2842
2855
  }
2843
2856
  SetByteOrder($oldOrder);
@@ -15,7 +15,7 @@ use Image::ExifTool::Exif;
15
15
  use Image::ExifTool::IPTC;
16
16
  use Image::ExifTool::XMP;
17
17
 
18
- $VERSION = '1.07';
18
+ $VERSION = '1.08';
19
19
 
20
20
  sub ProcessPhotoMechanic($$);
21
21
 
@@ -138,7 +138,7 @@ my %rawCropConv = (
138
138
  ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
139
139
  ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
140
140
  },
141
- CreatorIdentity => { },
141
+ CreatorIdentity => { List => 'Seq' },
142
142
  );
143
143
 
144
144
  #------------------------------------------------------------------------------