exiftool_vendored 12.42.0 → 12.52.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +226 -6
  3. data/bin/MANIFEST +14 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +45 -44
  7. data/bin/config_files/acdsee.config +2 -1
  8. data/bin/config_files/frameCount.config +56 -0
  9. data/bin/config_files/tiff_version.config +1 -1
  10. data/bin/exiftool +116 -97
  11. data/bin/fmt_files/gpx.fmt +3 -0
  12. data/bin/fmt_files/gpx_wpt.fmt +3 -0
  13. data/bin/lib/Image/ExifTool/Apple.pm +16 -3
  14. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +23 -12
  15. data/bin/lib/Image/ExifTool/Canon.pm +66 -37
  16. data/bin/lib/Image/ExifTool/CanonRaw.pm +8 -1
  17. data/bin/lib/Image/ExifTool/CanonVRD.pm +7 -8
  18. data/bin/lib/Image/ExifTool/Casio.pm +3 -3
  19. data/bin/lib/Image/ExifTool/DJI.pm +2 -1
  20. data/bin/lib/Image/ExifTool/DarwinCore.pm +13 -1
  21. data/bin/lib/Image/ExifTool/EXE.pm +9 -1
  22. data/bin/lib/Image/ExifTool/Exif.pm +17 -12
  23. data/bin/lib/Image/ExifTool/FLAC.pm +17 -3
  24. data/bin/lib/Image/ExifTool/FLIR.pm +9 -7
  25. data/bin/lib/Image/ExifTool/FlashPix.pm +26 -3
  26. data/bin/lib/Image/ExifTool/FujiFilm.pm +51 -4
  27. data/bin/lib/Image/ExifTool/GPS.pm +31 -5
  28. data/bin/lib/Image/ExifTool/Geotag.pm +36 -8
  29. data/bin/lib/Image/ExifTool/ICC_Profile.pm +3 -2
  30. data/bin/lib/Image/ExifTool/ICO.pm +143 -0
  31. data/bin/lib/Image/ExifTool/ID3.pm +6 -6
  32. data/bin/lib/Image/ExifTool/IPTC.pm +5 -1
  33. data/bin/lib/Image/ExifTool/JPEG.pm +1 -0
  34. data/bin/lib/Image/ExifTool/Jpeg2000.pm +24 -3
  35. data/bin/lib/Image/ExifTool/LNK.pm +5 -2
  36. data/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
  37. data/bin/lib/Image/ExifTool/Lang/fr.pm +6015 -759
  38. data/bin/lib/Image/ExifTool/Lang/sk.pm +1927 -0
  39. data/bin/lib/Image/ExifTool/M2TS.pm +98 -8
  40. data/bin/lib/Image/ExifTool/MIE.pm +9 -3
  41. data/bin/lib/Image/ExifTool/MISB.pm +494 -0
  42. data/bin/lib/Image/ExifTool/MakerNotes.pm +3 -1
  43. data/bin/lib/Image/ExifTool/Matroska.pm +272 -48
  44. data/bin/lib/Image/ExifTool/Motorola.pm +8 -2
  45. data/bin/lib/Image/ExifTool/Nikon.pm +746 -382
  46. data/bin/lib/Image/ExifTool/NikonCustom.pm +139 -106
  47. data/bin/lib/Image/ExifTool/NikonSettings.pm +5 -3
  48. data/bin/lib/Image/ExifTool/Olympus.pm +6 -4
  49. data/bin/lib/Image/ExifTool/PNG.pm +8 -1
  50. data/bin/lib/Image/ExifTool/Panasonic.pm +21 -4
  51. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +25 -5
  52. data/bin/lib/Image/ExifTool/Parrot.pm +96 -2
  53. data/bin/lib/Image/ExifTool/Pentax.pm +7 -2
  54. data/bin/lib/Image/ExifTool/Photoshop.pm +29 -3
  55. data/bin/lib/Image/ExifTool/QuickTime.pm +166 -13
  56. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +161 -22
  57. data/bin/lib/Image/ExifTool/README +15 -4
  58. data/bin/lib/Image/ExifTool/RIFF.pm +106 -9
  59. data/bin/lib/Image/ExifTool/Samsung.pm +2 -2
  60. data/bin/lib/Image/ExifTool/Sigma.pm +27 -1
  61. data/bin/lib/Image/ExifTool/SigmaRaw.pm +37 -13
  62. data/bin/lib/Image/ExifTool/Sony.pm +75 -47
  63. data/bin/lib/Image/ExifTool/TagInfoXML.pm +13 -6
  64. data/bin/lib/Image/ExifTool/TagLookup.pm +4791 -4519
  65. data/bin/lib/Image/ExifTool/TagNames.pod +2056 -1446
  66. data/bin/lib/Image/ExifTool/Text.pm +3 -4
  67. data/bin/lib/Image/ExifTool/Torrent.pm +2 -3
  68. data/bin/lib/Image/ExifTool/Validate.pm +3 -3
  69. data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +7 -0
  70. data/bin/lib/Image/ExifTool/WriteExif.pl +100 -23
  71. data/bin/lib/Image/ExifTool/WriteIPTC.pl +2 -6
  72. data/bin/lib/Image/ExifTool/WritePhotoshop.pl +5 -5
  73. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +12 -7
  74. data/bin/lib/Image/ExifTool/WriteRIFF.pl +359 -0
  75. data/bin/lib/Image/ExifTool/WriteXMP.pl +15 -1
  76. data/bin/lib/Image/ExifTool/Writer.pl +46 -18
  77. data/bin/lib/Image/ExifTool/XMP.pm +78 -59
  78. data/bin/lib/Image/ExifTool/XMP2.pl +19 -4
  79. data/bin/lib/Image/ExifTool/ZIP.pm +19 -7
  80. data/bin/lib/Image/ExifTool.pm +146 -38
  81. data/bin/lib/Image/ExifTool.pod +83 -69
  82. data/bin/perl-Image-ExifTool.spec +43 -43
  83. data/lib/exiftool_vendored/version.rb +1 -1
  84. metadata +10 -4
@@ -14,9 +14,8 @@ package Image::ExifTool::Text;
14
14
  use strict;
15
15
  use vars qw($VERSION);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
- use Image::ExifTool::XMP;
18
17
 
19
- $VERSION = '1.03';
18
+ $VERSION = '1.04';
20
19
 
21
20
  # Text tags
22
21
  %Image::ExifTool::Text::Main = (
@@ -97,7 +96,7 @@ sub ProcessTXT($$)
97
96
  $nl =~ tr/\0//d; # remove nulls from newline sequence
98
97
  $isBOM = 1; # (we don't recognize UTF-16/UTF-32 without one)
99
98
  } else {
100
- $isUTF8 = Image::ExifTool::XMP::IsUTF8($dataPt, 1);
99
+ $isUTF8 = Image::ExifTool::IsUTF8($dataPt, 1);
101
100
  if ($isUTF8 == 0) {
102
101
  $enc = 'us-ascii';
103
102
  } elsif ($isUTF8 > 0) {
@@ -183,7 +182,7 @@ sub ProcessTXT($$)
183
182
  next if $raf->Tell() < 65536;
184
183
  # continue to check encoding after the first 64 kB
185
184
  if ($isUTF8 >= 0) { # (if ascii or utf8)
186
- $isUTF8 = Image::ExifTool::XMP::IsUTF8(\$buff);
185
+ $isUTF8 = Image::ExifTool::IsUTF8(\$buff);
187
186
  if ($isUTF8 > 0) {
188
187
  $enc = 'utf-8';
189
188
  } elsif ($isUTF8 < 0) {
@@ -13,9 +13,8 @@ package Image::ExifTool::Torrent;
13
13
  use strict;
14
14
  use vars qw($VERSION);
15
15
  use Image::ExifTool qw(:DataAccess :Utils);
16
- use Image::ExifTool::XMP;
17
16
 
18
- $VERSION = '1.05';
17
+ $VERSION = '1.06';
19
18
 
20
19
  sub ReadBencode($$$);
21
20
  sub ExtractTags($$$;$$@);
@@ -169,7 +168,7 @@ sub ReadBencode($$$)
169
168
  if (length($value) > 256) {
170
169
  $val = \$value;
171
170
  } elsif ($value =~ /[^\t\x20-\x7e]/) {
172
- if (Image::ExifTool::XMP::IsUTF8(\$value) >= 0) {
171
+ if (Image::ExifTool::IsUTF8(\$value) >= 0) {
173
172
  $val = $et->Decode($value, 'UTF8');
174
173
  } else {
175
174
  $val = \$value;
@@ -17,7 +17,7 @@ package Image::ExifTool::Validate;
17
17
  use strict;
18
18
  use vars qw($VERSION %exifSpec);
19
19
 
20
- $VERSION = '1.18';
20
+ $VERSION = '1.19';
21
21
 
22
22
  use Image::ExifTool qw(:Utils);
23
23
  use Image::ExifTool::Exif;
@@ -82,8 +82,8 @@ my %otherSpec = (
82
82
  CR2 => { 0xc5d8 => 1, 0xc5d9 => 1, 0xc5e0 => 1, 0xc640 => 1, 0xc6dc => 1, 0xc6dd => 1 },
83
83
  NEF => { 0x9216 => 1, 0x9217 => 1 },
84
84
  DNG => { 0x882a => 1, 0x9211 => 1, 0x9216 => 1 },
85
- ARW => { 0x7000 => 1, 0x7001 => 1, 0x7010 => 1, 0x7011 => 1, 0x7020 => 1,
86
- 0x7031 => 1, 0x7032 => 1, 0x7034 => 1, 0x7035 => 1, 0x7036 => 1, 0x7037 => 1,
85
+ ARW => { 0x7000 => 1, 0x7001 => 1, 0x7010 => 1, 0x7011 => 1, 0x7020 => 1, 0x7031 => 1,
86
+ 0x7032 => 1, 0x7034 => 1, 0x7035 => 1, 0x7036 => 1, 0x7037 => 1, 0x7038 => 1,
87
87
  0x7310 => 1, 0x7313 => 1, 0x7316 => 1, 0x74c7 => 1, 0x74c8 => 1, 0xa500 => 1 },
88
88
  RW2 => { All => 1 }, # ignore all unknown tags in RW2
89
89
  RWL => { All => 1 },
@@ -271,6 +271,13 @@ sub WriteCanonRaw($$$)
271
271
  $raf->Seek($blockStart+$blockSize-4, 0) or return 0;
272
272
  $raf->Read($buff, 4) == 4 or return 0;
273
273
  my $dirOffset = Get32u(\$buff,0) + $blockStart;
274
+ # avoid infinite recursion
275
+ $$et{ProcessedCanonRaw} or $$et{ProcessedCanonRaw} = { };
276
+ if ($$et{ProcessedCanonRaw}{$dirOffset}) {
277
+ $et->Error("Double-referenced $$dirInfo{DirName} directory");
278
+ return 0;
279
+ }
280
+ $$et{ProcessedCanonRaw}{$dirOffset} = 1;
274
281
  $raf->Seek($dirOffset, 0) or return 0;
275
282
  $raf->Read($buff, 2) == 2 or return 0;
276
283
  my $entries = Get16u(\$buff,0); # get number of entries in directory
@@ -586,7 +586,7 @@ sub WriteExif($$$)
586
586
  $et->Error("$str $name directory", 1);
587
587
  }
588
588
  }
589
- my ($index, $dirEnd, $numEntries);
589
+ my ($index, $dirEnd, $numEntries, %hasOldID, $unsorted);
590
590
  if ($dirStart + 4 < $dataLen) {
591
591
  $numEntries = Get16u($dataPt, $dirStart);
592
592
  $dirEnd = $dirStart + 2 + 12 * $numEntries;
@@ -596,19 +596,20 @@ sub WriteExif($$$)
596
596
  return undef unless $n and defined $rtn;
597
597
  $numEntries = $n; # continue processing the entries we have
598
598
  }
599
- # sort entries if necessary (but not in maker notes IFDs)
600
- unless ($inMakerNotes) {
601
- my $lastID = -1;
602
- for ($index=0; $index<$numEntries; ++$index) {
603
- my $tagID = Get16u($dataPt, $dirStart + 2 + 12 * $index);
604
- # check for proper sequence (but ignore null entries at end)
605
- if ($tagID < $lastID and ($tagID or $$tagTablePtr{0})) {
606
- SortIFD($dataPt, $dirStart, $numEntries, $$tagTablePtr{0});
607
- $et->Warn("Entries in $name were out of sequence. Fixed.",1);
608
- last;
609
- }
610
- $lastID = $tagID;
611
- }
599
+ # create lookup for existing tag ID's and determine if directory is sorted
600
+ my $lastID = -1;
601
+ for ($index=0; $index<$numEntries; ++$index) {
602
+ my $tagID = Get16u($dataPt, $dirStart + 2 + 12 * $index);
603
+ $hasOldID{$tagID} = 1;
604
+ # check for proper sequence (but ignore null entries at end)
605
+ $unsorted = 1 if $tagID < $lastID and ($tagID or $$tagTablePtr{0});
606
+ $lastID = $tagID;
607
+ }
608
+ # sort entries if out-of-order (but not in maker notes IFDs or RAW files)
609
+ if ($unsorted and not ($inMakerNotes or $et->IsRawType())) {
610
+ SortIFD($dataPt, $dirStart, $numEntries, $$tagTablePtr{0});
611
+ $et->Warn("Entries in $name were out of sequence. Fixed.",1);
612
+ $unsorted = 0;
612
613
  }
613
614
  } else {
614
615
  $numEntries = 0;
@@ -616,11 +617,12 @@ sub WriteExif($$$)
616
617
  }
617
618
 
618
619
  # loop through new values and accumulate all information for this IFD
619
- my (%set, %mayDelete, $tagInfo);
620
+ my (%set, %mayDelete, $tagInfo, %hasNewID);
620
621
  my $wrongDir = $crossDelete{$dirName};
621
622
  my @newTagInfo = $et->GetNewTagInfoList($tagTablePtr);
622
623
  foreach $tagInfo (@newTagInfo) {
623
624
  my $tagID = $$tagInfo{TagID};
625
+ $hasNewID{$tagID} = 1;
624
626
  # must evaluate Condition later when we have all DataMember's available
625
627
  $set{$tagID} = (ref $$tagTablePtr{$tagID} eq 'ARRAY' or $$tagInfo{Condition}) ? '' : $tagInfo;
626
628
  }
@@ -723,7 +725,7 @@ Entry: for (;;) {
723
725
  $readFormat = $oldFormat = Get16u($dataPt, $entry+2);
724
726
  $readCount = $oldCount = Get32u($dataPt, $entry+4);
725
727
  undef $oldImageData;
726
- if ($oldFormat < 1 or $oldFormat > 13) {
728
+ if ($oldFormat < 1 or $oldFormat > 13 and not ($oldFormat == 16 and $$et{Make} eq 'Apple' and $inMakerNotes)) {
727
729
  my $msg = "Bad format ($oldFormat) for $name entry $index";
728
730
  # patch to preserve invalid directory entries in SubIFD3 of
729
731
  # various Kodak Z-series cameras (Z812, Z1085IS, Z1275)
@@ -972,7 +974,7 @@ Entry: for (;;) {
972
974
  $readCount = $oldSize / $formatSize[$readFormat];
973
975
  }
974
976
  }
975
- if ($oldID <= $lastTagID and not $inMakerNotes) {
977
+ if ($oldID <= $lastTagID and not ($inMakerNotes or $et->IsRawType())) {
976
978
  my $str = $oldInfo ? "$$oldInfo{Name} tag" : sprintf('tag 0x%x',$oldID);
977
979
  if ($oldID == $lastTagID) {
978
980
  $et->Warn("Duplicate $str in $name");
@@ -1006,6 +1008,23 @@ Entry: for (;;) {
1006
1008
  }
1007
1009
  } else {
1008
1010
  $isNew = $oldID <=> $newID;
1011
+ # special logic needed if directory has out-of-order entries
1012
+ if ($unsorted and $isNew) {
1013
+ if ($isNew > 0 and $hasOldID{$newID}) {
1014
+ # we wanted to create the new tag, but an old tag
1015
+ # does exist with this ID, so defer writing the new tag
1016
+ $isNew = -1;
1017
+ }
1018
+ if ($isNew < 0 and $hasNewID{$oldID}) {
1019
+ # we wanted to write the old tag, but we have
1020
+ # a new tag with this ID, so move it up in the order
1021
+ my @tmpTags = ( $oldID );
1022
+ $_ == $oldID or push @tmpTags, $_ foreach @newTags;
1023
+ @newTags = @tmpTags;
1024
+ $newID = $oldID;
1025
+ $isNew = 0;
1026
+ }
1027
+ }
1009
1028
  }
1010
1029
  my $newInfo = $oldInfo;
1011
1030
  my $newFormat = $oldFormat;
@@ -2170,17 +2189,39 @@ NoOverwrite: next if $isNew > 0;
2170
2189
  my @offsetList;
2171
2190
  if ($ifd >= 0) {
2172
2191
  my $offsetInfo = $offsetInfo[$ifd] or next;
2192
+ if ($$offsetInfo{0x111} and $$offsetInfo{0x144}) {
2193
+ # SubIFD may contain double-referenced data as both strips and tiles
2194
+ # for Sony ARW files when SonyRawFileType is "Lossless Compressed RAW 2"
2195
+ if ($dirName eq 'SubIFD' and $$et{TIFF_TYPE} eq 'ARW' and
2196
+ $$offsetInfo{0x117} and $$offsetInfo{0x145} and
2197
+ $$offsetInfo{0x111}[2]==1) # (must be a single strip or the tile offsets could get out of sync)
2198
+ {
2199
+ # some Sony ARW images contain double-referenced raw data stored as both strips
2200
+ # and tiles. Copy the data using only the strip tags, but store the TileOffets
2201
+ # information for updating later (see PanasonicRaw:PatchRawDataOffset for a
2202
+ # description of offsetInfo elements)
2203
+ $$offsetInfo{0x111}[5] = $$offsetInfo{0x144}; # hack to save TileOffsets
2204
+ # delete tile information from offsetInfo because we will copy as strips
2205
+ delete $$offsetInfo{0x144};
2206
+ delete $$offsetInfo{0x145};
2207
+ } else {
2208
+ $et->Error("TIFF $dirName contains both strip and tile data");
2209
+ }
2210
+ }
2173
2211
  # patch Panasonic RAW/RW2 StripOffsets/StripByteCounts if necessary
2174
2212
  my $stripOffsets = $$offsetInfo{0x111};
2175
- if ($stripOffsets and $$stripOffsets[0]{PanasonicHack}) {
2213
+ my $rawDataOffset = $$offsetInfo{0x118};
2214
+ if ($stripOffsets and $$stripOffsets[0]{PanasonicHack} or
2215
+ $rawDataOffset and $$rawDataOffset[0]{PanasonicHack})
2216
+ {
2176
2217
  require Image::ExifTool::PanasonicRaw;
2177
2218
  my $err = Image::ExifTool::PanasonicRaw::PatchRawDataOffset($offsetInfo, $raf, $ifd);
2178
2219
  $err and $et->Error($err);
2179
2220
  }
2180
2221
  my $tagID;
2181
- # loop through all tags in reverse order so we save thumbnail
2222
+ # loop through all tags in reverse numerical order so we save thumbnail
2182
2223
  # data before main image data if both exist in the same IFD
2183
- foreach $tagID (reverse sort keys %$offsetInfo) {
2224
+ foreach $tagID (reverse sort { $a <=> $b } keys %$offsetInfo) {
2184
2225
  my $tagInfo = $$offsetInfo{$tagID}[0];
2185
2226
  next unless $$tagInfo{IsOffset}; # handle byte counts with offsets
2186
2227
  my $sizeInfo = $$offsetInfo{$$tagInfo{OffsetPair}};
@@ -2203,6 +2244,7 @@ NoOverwrite: next if $isNew > 0;
2203
2244
  }
2204
2245
  } else {
2205
2246
  last unless @writeLater;
2247
+ # finally, copy all deferred data
2206
2248
  @offsetList = @writeLater;
2207
2249
  }
2208
2250
  my $offsetPair;
@@ -2296,6 +2338,23 @@ NoOverwrite: next if $isNew > 0;
2296
2338
  $size = length($buff);
2297
2339
  Set32u($size, \$newData, $byteCountPos);
2298
2340
  } elsif ($ifd < 0) {
2341
+ # hack for fixed-offset data (Panasonic GH6)
2342
+ if ($$offsetPair[0][6]) {
2343
+ if ($count > 1) {
2344
+ $et->Error("Can't handle fixed offsets with count > 1");
2345
+ } else {
2346
+ my $fixedOffset = Get32u(\$newData, $offsets);
2347
+ my $padToFixedOffset = $fixedOffset - ($newOffset + $dpos);
2348
+ if ($padToFixedOffset < 0) {
2349
+ $et->Error('Metadata too large to fit before fixed-offset image data');
2350
+ } else {
2351
+ # add necessary padding before raw data
2352
+ push @imageData, [$offset+$dbase+$dpos, 0, $padToFixedOffset];
2353
+ $newOffset += $padToFixedOffset;
2354
+ $et->Warn("Adding $padToFixedOffset bytes of padding before fixed-offset image data", 1);
2355
+ }
2356
+ }
2357
+ }
2299
2358
  # pad if necessary (but don't pad contiguous image blocks)
2300
2359
  my $pad = 0;
2301
2360
  ++$pad if ($blockSize + $size) & 0x01 and ($n+1 >= $count or
@@ -2406,10 +2465,28 @@ NoOverwrite: next if $isNew > 0;
2406
2465
  # also add to subIfdDataFixup if necessary
2407
2466
  $subIfdDataFixup->AddFixup($offsetPos, $dataTag) if $subIfdDataFixup;
2408
2467
  # must also (sometimes) update StripOffsets in Panasonic RW2 images
2468
+ # and TileOffsets in Sony ARW images
2409
2469
  my $otherPos = $$offsetPair[0][5];
2410
- if ($otherPos and $$tagInfo{PanasonicHack}) {
2411
- Set32u($newOffset, \$newData, $otherPos);
2412
- $fixup->AddFixup($otherPos, $dataTag);
2470
+ if ($otherPos) {
2471
+ if ($$tagInfo{PanasonicHack}) {
2472
+ Set32u($newOffset, \$newData, $otherPos);
2473
+ $fixup->AddFixup($otherPos, $dataTag);
2474
+ } elsif (ref $otherPos eq 'ARRAY') {
2475
+ # the image data was copied as one large strip, and is double-referenced
2476
+ # as tile data, so all we need to do now is properly update the tile offsets
2477
+ my $oldRawDataOffset = $$offsetPair[0][3][0];
2478
+ my $count = $$otherPos[2];
2479
+ my $i;
2480
+ # point to offsets in value data if more than one pointer
2481
+ $$otherPos[1] = Get32u(\$newData, $$otherPos[1]) if $count > 1;
2482
+ for ($i=0; $i<$count; ++$i) {
2483
+ my $oldTileOffset = $$otherPos[3][$i];
2484
+ my $ptrPos = $$otherPos[1] + 4 * $i;
2485
+ Set32u($newOffset + $oldTileOffset - $oldRawDataOffset, \$newData, $ptrPos);
2486
+ $fixup->AddFixup($ptrPos, $dataTag);
2487
+ $subIfdDataFixup->AddFixup($ptrPos, $dataTag) if $subIfdDataFixup;
2488
+ }
2489
+ }
2413
2490
  }
2414
2491
  if ($ifd >= 0) {
2415
2492
  # buff length must be even (Note: may have changed since $size was set)
@@ -334,13 +334,9 @@ sub DoWriteIPTC($$$)
334
334
  # - improves speed
335
335
  # - avoids changing current MD5 digest unnecessarily
336
336
  # - avoids adding mandatory tags unless some other IPTC is changed
337
- unless (exists $$et{EDIT_DIRS}{$$dirInfo{DirName}} or
337
+ return undef unless exists $$et{EDIT_DIRS}{$$dirInfo{DirName}} or
338
338
  # standard IPTC tags in other locations should be edited too (eg. AFCP_IPTC)
339
- ($tagTablePtr eq \%Image::ExifTool::IPTC::Main and exists $$et{EDIT_DIRS}{IPTC}))
340
- {
341
- print $out "$$et{INDENT} [nothing changed]\n" if $verbose;
342
- return undef;
343
- }
339
+ ($tagTablePtr eq \%Image::ExifTool::IPTC::Main and exists $$et{EDIT_DIRS}{IPTC});
344
340
  my $dataPt = $$dirInfo{DataPt};
345
341
  unless ($dataPt) {
346
342
  my $emptyData = '';
@@ -138,13 +138,13 @@ sub WritePhotoshop($$$)
138
138
  unless ($tagInfo) {
139
139
  # process subdirectory anyway if writable (except EXIF to avoid recursion)
140
140
  # --> this allows IPTC to be processed if found here in TIFF images
141
- # (note that I have seen a case of XMP in PSD-EXIFInfo-IFD0, and the EXIF
142
- # exclusion means that this won't be written unless an EXIF tag is
143
- # specifically edited, see forum10768 -- maybe this should be changed
144
- # if it happens again)
141
+ # (but allow EXIF to be written in PSD files if XMP or IPTC tags are
142
+ # being written because I have seen cases of XMP in PSD-EXIFInfo-IFD0
143
+ # and IPTC in PSD-EXIFInfo-IFD0-IPTC, see forum10768 and forum13198)
145
144
  my $tmpInfo = $et->GetTagInfo($tagTablePtr, $tagID);
146
145
  if ($tmpInfo and $$tmpInfo{SubDirectory} and
147
- $tmpInfo->{SubDirectory}->{TagTable} ne 'Image::ExifTool::Exif::Main')
146
+ ($tmpInfo->{SubDirectory}->{TagTable} ne 'Image::ExifTool::Exif::Main' or
147
+ ($$et{FILE_TYPE} eq 'PSD' and ($$editDirs{0x0404} or $$editDirs{0x0424}))))
148
148
  {
149
149
  my $table = Image::ExifTool::GetTagTable($tmpInfo->{SubDirectory}->{TagTable});
150
150
  $tagInfo = $tmpInfo if $$table{WRITE_PROC};
@@ -306,14 +306,17 @@ sub CheckQTValue($$$)
306
306
 
307
307
  #------------------------------------------------------------------------------
308
308
  # Format QuickTime value for writing
309
- # Inputs: 0) ExifTool ref, 1) value ref, 2) Format (or undef), 3) Writable (or undef)
310
- # Returns: Flags for QT data type, and reformats value as required
309
+ # Inputs: 0) ExifTool ref, 1) value ref, 2) tagInfo ref, 3) Format (or undef)
310
+ # Returns: Flags for QT data type, and reformats value as required (sets to undef on error)
311
311
  sub FormatQTValue($$;$$)
312
312
  {
313
- my ($et, $valPt, $format, $writable) = @_;
313
+ my ($et, $valPt, $tagInfo, $format) = @_;
314
+ my $writable = $$tagInfo{Writable};
315
+ my $count = $$tagInfo{Count};
314
316
  my $flags;
317
+ $format or $format = $$tagInfo{Format};
315
318
  if ($format and $format ne 'string' or not $format and $writable and $writable ne 'string') {
316
- $$valPt = WriteValue($$valPt, $format || $writable);
319
+ $$valPt = WriteValue($$valPt, $format || $writable, $count);
317
320
  if ($writable and $qtFormat{$writable}) {
318
321
  $flags = $qtFormat{$writable};
319
322
  } else {
@@ -329,6 +332,7 @@ sub FormatQTValue($$;$$)
329
332
  $flags = 0x01; # UTF8
330
333
  $$valPt = $et->Encode($$valPt, 'UTF8');
331
334
  }
335
+ defined $$valPt or $et->WarnOnce("Error converting value for $$tagInfo{Name}");
332
336
  return $flags;
333
337
  }
334
338
 
@@ -1139,7 +1143,7 @@ sub WriteQuickTime($$$)
1139
1143
  my $newVal = $et->GetNewValue($nvHash);
1140
1144
  next unless defined $newVal;
1141
1145
  my $prVal = $newVal;
1142
- my $flags = FormatQTValue($et, \$newVal, $format, $$tagInfo{Writable});
1146
+ my $flags = FormatQTValue($et, \$newVal, $tagInfo, $format);
1143
1147
  next unless defined $newVal;
1144
1148
  my ($ctry, $lang) = (0, 0);
1145
1149
  if ($$ti{LangCode}) {
@@ -1220,7 +1224,8 @@ sub WriteQuickTime($$$)
1220
1224
  }
1221
1225
  my $prVal = $newVal;
1222
1226
  # format new value for writing (and get new flags)
1223
- $flags = FormatQTValue($et, \$newVal, $format, $$tagInfo{Writable});
1227
+ $flags = FormatQTValue($et, \$newVal, $tagInfo, $format);
1228
+ next unless defined $newVal;
1224
1229
  my $grp = $et->GetGroup($langInfo, 1);
1225
1230
  $et->VerboseValue("- $grp:$$langInfo{Name}", $val);
1226
1231
  $et->VerboseValue("+ $grp:$$langInfo{Name}", $prVal);
@@ -1463,7 +1468,7 @@ sub WriteQuickTime($$$)
1463
1468
  my $newVal = $et->GetNewValue($nvHash);
1464
1469
  next unless defined $newVal;
1465
1470
  my $prVal = $newVal;
1466
- my $flags = FormatQTValue($et, \$newVal, $$tagInfo{Format}, $$tagInfo{Writable});
1471
+ my $flags = FormatQTValue($et, \$newVal, $tagInfo);
1467
1472
  next unless defined $newVal;
1468
1473
  my ($ctry, $lang) = (0, 0);
1469
1474
  # handle alternate languages