exiftool_vendored 11.94.0 → 12.06.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.

Potentially problematic release.


This version of exiftool_vendored might be problematic. Click here for more details.

Files changed (62) hide show
  1. checksums.yaml +5 -5
  2. data/bin/Changes +163 -3
  3. data/bin/MANIFEST +5 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +32 -32
  7. data/bin/exiftool +152 -52
  8. data/bin/lib/Image/ExifTool.pm +166 -115
  9. data/bin/lib/Image/ExifTool.pod +108 -81
  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 -7
  13. data/bin/lib/Image/ExifTool/Canon.pm +6 -3
  14. data/bin/lib/Image/ExifTool/CanonCustom.pm +82 -16
  15. data/bin/lib/Image/ExifTool/DPX.pm +56 -2
  16. data/bin/lib/Image/ExifTool/DarwinCore.pm +16 -3
  17. data/bin/lib/Image/ExifTool/Exif.pm +15 -6
  18. data/bin/lib/Image/ExifTool/Font.pm +9 -2
  19. data/bin/lib/Image/ExifTool/GIF.pm +5 -0
  20. data/bin/lib/Image/ExifTool/GeoTiff.pm +2 -0
  21. data/bin/lib/Image/ExifTool/Geotag.pm +69 -21
  22. data/bin/lib/Image/ExifTool/GoPro.pm +10 -1
  23. data/bin/lib/Image/ExifTool/H264.pm +1 -1
  24. data/bin/lib/Image/ExifTool/HtmlDump.pm +2 -2
  25. data/bin/lib/Image/ExifTool/ID3.pm +91 -12
  26. data/bin/lib/Image/ExifTool/Lang/de.pm +3 -1
  27. data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
  28. data/bin/lib/Image/ExifTool/M2TS.pm +44 -24
  29. data/bin/lib/Image/ExifTool/MWG.pm +9 -1
  30. data/bin/lib/Image/ExifTool/MacOS.pm +1 -1
  31. data/bin/lib/Image/ExifTool/Minolta.pm +3 -2
  32. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +11 -10
  33. data/bin/lib/Image/ExifTool/Nikon.pm +156 -18
  34. data/bin/lib/Image/ExifTool/Olympus.pm +34 -17
  35. data/bin/lib/Image/ExifTool/PNG.pm +14 -3
  36. data/bin/lib/Image/ExifTool/PPM.pm +5 -5
  37. data/bin/lib/Image/ExifTool/Panasonic.pm +147 -13
  38. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +33 -0
  39. data/bin/lib/Image/ExifTool/Parrot.pm +2 -1
  40. data/bin/lib/Image/ExifTool/Pentax.pm +3 -1
  41. data/bin/lib/Image/ExifTool/Photoshop.pm +2 -1
  42. data/bin/lib/Image/ExifTool/QuickTime.pm +277 -33
  43. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +460 -67
  44. data/bin/lib/Image/ExifTool/README +21 -20
  45. data/bin/lib/Image/ExifTool/RIFF.pm +123 -3
  46. data/bin/lib/Image/ExifTool/RTF.pm +12 -7
  47. data/bin/lib/Image/ExifTool/Ricoh.pm +19 -1
  48. data/bin/lib/Image/ExifTool/Shift.pl +1 -0
  49. data/bin/lib/Image/ExifTool/SigmaRaw.pm +40 -33
  50. data/bin/lib/Image/ExifTool/Sony.pm +379 -12
  51. data/bin/lib/Image/ExifTool/TagLookup.pm +1959 -1874
  52. data/bin/lib/Image/ExifTool/TagNames.pod +346 -55
  53. data/bin/lib/Image/ExifTool/Validate.pm +4 -4
  54. data/bin/lib/Image/ExifTool/WriteExif.pl +3 -2
  55. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +26 -15
  56. data/bin/lib/Image/ExifTool/Writer.pl +52 -23
  57. data/bin/lib/Image/ExifTool/XMP.pm +41 -4
  58. data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
  59. data/bin/lib/Image/ExifTool/ZISRAW.pm +123 -0
  60. data/bin/perl-Image-ExifTool.spec +31 -31
  61. data/lib/exiftool_vendored/version.rb +1 -1
  62. metadata +4 -4
@@ -17,7 +17,7 @@ package Image::ExifTool::Validate;
17
17
  use strict;
18
18
  use vars qw($VERSION %exifSpec);
19
19
 
20
- $VERSION = '1.17';
20
+ $VERSION = '1.18';
21
21
 
22
22
  use Image::ExifTool qw(:Utils);
23
23
  use Image::ExifTool::Exif;
@@ -214,11 +214,11 @@ my %validValue = (
214
214
  IFD0 => {
215
215
  0x100 => 'defined $val', # ImageWidth
216
216
  0x101 => 'defined $val', # ImageLength
217
- 0x102 => 'defined $val', # BitsPerSample
217
+ # (default is 1) 0x102 => 'defined $val', # BitsPerSample
218
218
  0x103 => q{
219
219
  not defined $val or $val =~ /^(1|5|6|32773)$/ or
220
220
  ($val == 2 and (not defined $val{0x102} or $val{0x102} == 1));
221
- }, # Compression
221
+ }, # Compression
222
222
  0x106 => '$val =~ /^[0123]$/', # PhotometricInterpretation
223
223
  0x111 => 'defined $val', # StripOffsets
224
224
  # SamplesPerPixel
@@ -237,7 +237,7 @@ my %validValue = (
237
237
  0x117 => 'defined $val', # StripByteCounts
238
238
  0x11a => 'defined $val', # XResolution
239
239
  0x11b => 'defined $val', # YResolution
240
- 0x128 => '$val =~ /^[123]$/', # ResolutionUnit
240
+ 0x128 => 'not defined $val or $val =~ /^[123]$/', # ResolutionUnit
241
241
  # ColorMap (must be palette image with correct number of colors)
242
242
  0x140 => q{
243
243
  return '' if defined $val{0x106} and $val{0x106} == 3 xor defined $val;
@@ -1832,6 +1832,7 @@ NoOverwrite: next if $isNew > 0;
1832
1832
  warn "Internal error writing offsets for $$newInfo{Name}\n";
1833
1833
  return undef;
1834
1834
  }
1835
+ $newValuePt = \$newValue;
1835
1836
  }
1836
1837
  $offsetInfo or $offsetInfo = $offsetInfo[$ifd] = { };
1837
1838
  # save location of valuePtr in new directory
@@ -2297,8 +2298,8 @@ NoOverwrite: next if $isNew > 0;
2297
2298
  } elsif ($ifd < 0) {
2298
2299
  # pad if necessary (but don't pad contiguous image blocks)
2299
2300
  my $pad = 0;
2300
- ++$pad if $size & 0x01 and ($n+1 >= $count or not $oldEnd or
2301
- $oldEnd != $$oldOffset[$n+1]);
2301
+ ++$pad if ($blockSize + $size) & 0x01 and ($n+1 >= $count or
2302
+ not $oldEnd or $oldEnd != $$oldOffset[$n+1]);
2302
2303
  # preserve original image padding if specified
2303
2304
  if ($$origDirInfo{PreserveImagePadding} and $n+1 < $count and
2304
2305
  $oldEnd and $$oldOffset[$n+1] > $oldEnd)
@@ -300,15 +300,19 @@ sub CheckQTValue($$$)
300
300
 
301
301
  #------------------------------------------------------------------------------
302
302
  # Format QuickTime value for writing
303
- # Inputs: 0) ExifTool ref, 1) value ref, 2) Format (or undef)
303
+ # Inputs: 0) ExifTool ref, 1) value ref, 2) Format (or undef), 3) Writable (or undef)
304
304
  # Returns: Flags for QT data type, and reformats value as required
305
- sub FormatQTValue($$;$)
305
+ sub FormatQTValue($$;$$)
306
306
  {
307
- my ($et, $valPt, $format) = @_;
307
+ my ($et, $valPt, $format, $writable) = @_;
308
308
  my $flags;
309
309
  if ($format and $format ne 'string') {
310
310
  $$valPt = WriteValue($$valPt, $format);
311
- $flags = $qtFormat{$format} || 0;
311
+ if ($writable and $qtFormat{$writable}) {
312
+ $flags = $qtFormat{$writable};
313
+ } else {
314
+ $flags = $qtFormat{$format} || 0;
315
+ }
312
316
  } elsif ($$valPt =~ /^\xff\xd8\xff/) {
313
317
  $flags = 0x0d; # JPG
314
318
  } elsif ($$valPt =~ /^(\x89P|\x8aM|\x8bJ)NG\r\n\x1a\n/) {
@@ -499,6 +503,9 @@ sub WriteItemInfo($$$)
499
503
  if (not length $buff) {
500
504
  # create EXIF from scratch
501
505
  $hdr = "\0\0\0\x06Exif\0\0";
506
+ } elsif ($buff =~ /^(MM\0\x2a|II\x2a\0)/) {
507
+ $et->Warn('Missing Exif header');
508
+ $hdr = '';
502
509
  } elsif (length($buff) >= 4 and length($buff) >= 4 + unpack('N',$buff)) {
503
510
  $hdr = substr($buff, 0, 4 + unpack('N',$buff));
504
511
  } else {
@@ -1119,9 +1126,9 @@ sub WriteQuickTime($$$)
1119
1126
  my $newVal = $et->GetNewValue($nvHash);
1120
1127
  next unless defined $newVal;
1121
1128
  my $prVal = $newVal;
1122
- my $flags = FormatQTValue($et, \$newVal, $format);
1129
+ my $flags = FormatQTValue($et, \$newVal, $format, $$tagInfo{Writable});
1123
1130
  next unless defined $newVal;
1124
- my ($ctry, $lang) = (0, $undLang);
1131
+ my ($ctry, $lang) = (0, 0);
1125
1132
  if ($$ti{LangCode}) {
1126
1133
  unless ($$ti{LangCode} =~ /^([A-Z]{3})?[-_]?([A-Z]{2})?$/i) {
1127
1134
  $et->Warn("Invalid language code for $$ti{Name}");
@@ -1177,7 +1184,11 @@ sub WriteQuickTime($$$)
1177
1184
  } else {
1178
1185
  if ($format) {
1179
1186
  # update flags for the format we are writing
1180
- $flags = $qtFormat{$format} if $qtFormat{$format};
1187
+ if ($$tagInfo{Writable} and $qtFormat{$$tagInfo{Writable}}) {
1188
+ $flags = $qtFormat{$$tagInfo{Writable}};
1189
+ } elsif ($qtFormat{$format}) {
1190
+ $flags = $qtFormat{$format};
1191
+ }
1181
1192
  } else {
1182
1193
  $format = QuickTimeFormat($flags, $len);
1183
1194
  }
@@ -1196,12 +1207,13 @@ sub WriteQuickTime($$$)
1196
1207
  }
1197
1208
  my $prVal = $newVal;
1198
1209
  # format new value for writing (and get new flags)
1199
- $flags = FormatQTValue($et, \$newVal, $format);
1210
+ $flags = FormatQTValue($et, \$newVal, $format, $$tagInfo{Writable});
1200
1211
  my $grp = $et->GetGroup($langInfo, 1);
1201
1212
  $et->VerboseValue("- $grp:$$langInfo{Name}", $val);
1202
1213
  $et->VerboseValue("+ $grp:$$langInfo{Name}", $prVal);
1203
1214
  $newData = substr($buff, 0, $pos-16) unless defined $newData;
1204
- $newData .= pack('Na4Nnn', length($newVal)+16, $type, $flags, $ctry, $lang);
1215
+ my $wLang = $lang eq $undLang ? 0 : $lang;
1216
+ $newData .= pack('Na4Nnn', length($newVal)+16, $type, $flags, $ctry, $wLang);
1205
1217
  $newData .= $newVal;
1206
1218
  ++$$et{CHANGED};
1207
1219
  } elsif (defined $newData) {
@@ -1265,10 +1277,11 @@ sub WriteQuickTime($$$)
1265
1277
  # add back necessary header and encode as necessary
1266
1278
  if (defined $lang) {
1267
1279
  $newData = $et->Encode($newData, $lang < 0x400 ? $charsetQuickTime : 'UTF8');
1280
+ my $wLang = $lang eq $undLang ? 0 : $lang;
1268
1281
  if ($$tagInfo{IText} and $$tagInfo{IText} == 6) {
1269
- $newData = pack('Nn', 0, $lang) . $newData . "\0";
1282
+ $newData = pack('Nn', 0, $wLang) . $newData . "\0";
1270
1283
  } else {
1271
- $newData = pack('nn', length($newData), $lang) . $newData;
1284
+ $newData = pack('nn', length($newData), $wLang) . $newData;
1272
1285
  }
1273
1286
  } elsif (not $format or $format =~ /^string/ and
1274
1287
  not $$tagInfo{Binary} and not $$tagInfo{ValueConv})
@@ -1403,9 +1416,9 @@ sub WriteQuickTime($$$)
1403
1416
  my $newVal = $et->GetNewValue($nvHash);
1404
1417
  next unless defined $newVal;
1405
1418
  my $prVal = $newVal;
1406
- my $flags = FormatQTValue($et, \$newVal, $$tagInfo{Format});
1419
+ my $flags = FormatQTValue($et, \$newVal, $$tagInfo{Format}, $$tagInfo{Writable});
1407
1420
  next unless defined $newVal;
1408
- my ($ctry, $lang) = (0,0);
1421
+ my ($ctry, $lang) = (0, 0);
1409
1422
  # handle alternate languages
1410
1423
  if ($$tagInfo{LangCode}) {
1411
1424
  $tag = substr($tag, 0, 4); # strip language code from tag ID
@@ -1421,10 +1434,8 @@ sub WriteQuickTime($$$)
1421
1434
  }
1422
1435
  if ($$dirInfo{HasData}) {
1423
1436
  # add 'data' header
1424
- $lang or $lang = $undLang;
1425
1437
  $newVal = pack('Na4Nnn',16+length($newVal),'data',$flags,$ctry,$lang).$newVal;
1426
1438
  } elsif ($tag =~ /^\xa9/ or $$tagInfo{IText}) {
1427
- $lang or $lang = $undLang;
1428
1439
  if ($ctry) {
1429
1440
  my $grp = $et->GetGroup($tagInfo,1);
1430
1441
  $et->Warn("Can't use country code for $grp:$$tagInfo{Name}");
@@ -359,21 +359,25 @@ sub SetNewValue($;$$%)
359
359
  my $convType = $options{Type} || ($$self{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv');
360
360
 
361
361
  # filter value if necessary
362
- Filter($$self{OPTIONS}{FilterW}, \$value) if $convType eq 'PrintConv';
362
+ $self->Filter($$self{OPTIONS}{FilterW}, \$value) or return 0 if $convType eq 'PrintConv';
363
363
 
364
364
  my (@wantGroup, $family2);
365
365
  my $wantGroup = $options{Group};
366
366
  if ($wantGroup) {
367
367
  foreach (split /:/, $wantGroup) {
368
368
  next unless length($_) and /^(\d+)?(.*)/; # separate family number and group name
369
- my ($f, $g) = ($1, lc $2);
369
+ my ($f, $g) = ($1, $2);
370
+ my $lcg = lc $g;
370
371
  # save group/family unless '*' or 'all'
371
- push @wantGroup, [ $f, $g ] unless $g eq '*' or $g eq 'all';
372
- if (defined $f) {
373
- $f > 2 and return 0; # only allow family 0, 1 or 2
374
- $family2 = 1 if $f == 2; # set flag indicating family 2 was used
372
+ push @wantGroup, [ $f, $lcg ] unless $lcg eq '*' or $lcg eq 'all';
373
+ if ($g =~ s/^ID-//i) { # family 7 is a tag ID
374
+ return 0 if defined $f and $f ne 7;
375
+ $wantGroup[-1] = [ 7, $g ]; # group name with 'ID-' removed and case preserved
376
+ } elsif (defined $f) {
377
+ $f > 2 and return 0; # only allow family 0, 1 or 2
378
+ $family2 = 1 if $f == 2; # set flag indicating family 2 was used
375
379
  } else {
376
- $family2 = 1 if $family2groups{$g};
380
+ $family2 = 1 if $family2groups{$lcg};
377
381
  }
378
382
  }
379
383
  undef $wantGroup unless @wantGroup;
@@ -622,6 +626,8 @@ TAG: foreach $tagInfo (@matchingTags) {
622
626
  next;
623
627
  }
624
628
  next if $lcWant eq lc $grp[2];
629
+ } elsif ($fam == 7) {
630
+ next if IsSameID($$tagInfo{TagID}, $lcWant);
625
631
  } elsif ($fam != 1 and not $$tagInfo{AllowGroup}) {
626
632
  next if $lcWant eq lc $grp[$fam];
627
633
  if ($wgAll and not $fam and $allFam0{$lcWant}) {
@@ -1258,6 +1264,7 @@ sub SetNewValuesFromFile($$;@)
1258
1264
  Filter => $$options{Filter},
1259
1265
  FixBase => $$options{FixBase},
1260
1266
  GlobalTimeShift => $$options{GlobalTimeShift},
1267
+ HexTagIDs => $$options{HexTagIDs},
1261
1268
  IgnoreMinorErrors=>$$options{IgnoreMinorErrors},
1262
1269
  Lang => $$options{Lang},
1263
1270
  LargeFileSupport=> $$options{LargeFileSupport},
@@ -1409,7 +1416,9 @@ sub SetNewValuesFromFile($$;@)
1409
1416
  foreach (split /:/, $grp) {
1410
1417
  # save family/groups in list (ignoring 'all' and '*')
1411
1418
  next unless length($_) and /^(\d+)?(.*)/;
1412
- push @fg, [ $1, $2 ] unless $2 eq '*' or $2 eq 'all';
1419
+ my ($f, $g) = ($1, $2);
1420
+ $f = 7 if $g =~ s/^ID-//i;
1421
+ push @fg, [ $f, $g ] unless $g eq '*' or $g eq 'all';
1413
1422
  }
1414
1423
  }
1415
1424
  # allow ValueConv to be specified by a '#' on the tag name
@@ -1475,10 +1484,12 @@ SET: foreach $set (@setList) {
1475
1484
  }
1476
1485
  foreach (@{$$set[0]}) {
1477
1486
  my ($f, $g) = @$_;
1478
- if (defined $f) {
1479
- next SET unless defined $grp[$f] and $g eq $grp[$f];
1480
- } else {
1487
+ if (not defined $f) {
1481
1488
  next SET unless $grp{$g};
1489
+ } elsif ($f == 7) {
1490
+ next SET unless IsSameID($srcExifTool->GetTagID($tag), $g);
1491
+ } else {
1492
+ next SET unless defined $grp[$f] and $g eq $grp[$f];
1482
1493
  }
1483
1494
  }
1484
1495
  }
@@ -1598,21 +1609,25 @@ sub GetNewValue($$;$)
1598
1609
  $nvHash = $self->GetNewValueHash($tagInfo);
1599
1610
  } else {
1600
1611
  # separate group from tag name
1601
- $group = $1 if $tag =~ s/(.*)://;
1612
+ my @groups;
1613
+ @groups = split ':', $1 if $tag =~ s/(.*)://;
1602
1614
  my @tagInfoList = FindTagInfo($tag);
1603
1615
  # decide which tag we want
1604
1616
  GNV_TagInfo: foreach $tagInfo (@tagInfoList) {
1605
1617
  my $nvh = $self->GetNewValueHash($tagInfo) or next;
1606
- # select tag in specified group if necessary
1607
- while ($group and $group ne $$nvh{WriteGroup}) {
1618
+ # select tag in specified group(s) if necessary
1619
+ foreach (@groups) {
1620
+ next if $_ eq $$nvh{WriteGroup};
1608
1621
  my @grps = $self->GetGroup($tagInfo);
1609
1622
  if ($grps[0] eq $$nvh{WriteGroup}) {
1610
1623
  # check family 1 group only if WriteGroup is not specific
1611
- last if $group eq $grps[1];
1624
+ next if $_ eq $grps[1];
1612
1625
  } else {
1613
1626
  # otherwise check family 0 group
1614
- last if $group eq $grps[0];
1627
+ next if $_ eq $grps[0];
1615
1628
  }
1629
+ # also check family 7
1630
+ next if /^ID-(.*)/i and IsSameID($$tagInfo{TagID}, $1);
1616
1631
  # step to next entry in list
1617
1632
  $nvh = $$nvh{Next} or next GNV_TagInfo;
1618
1633
  }
@@ -2007,7 +2022,7 @@ sub SetFileName($$;$$$)
2007
2022
 
2008
2023
  #------------------------------------------------------------------------------
2009
2024
  # Set file permissions, group/user id and various MDItem tags from new tag values
2010
- # Inputs: 0) Exiftool ref, 1) file name or glob (must be a name for MDItem tags)
2025
+ # Inputs: 0) ExifTool ref, 1) file name or glob (must be a name for MDItem tags)
2011
2026
  # Returns: 1=something was set OK, 0=didn't try, -1=error (and warning set)
2012
2027
  # Notes: There may be errors even if 1 is returned
2013
2028
  sub SetSystemTags($$)
@@ -2967,9 +2982,13 @@ sub InsertTagValues($$$;$$$)
2967
2982
  my (@tags, $val, $tg, @val, $type, $expr, $didExpr, $level, $asList);
2968
2983
  # "$$" represents a "$" symbol, and "$/" is a newline
2969
2984
  if ($var eq '$' or $var eq '/') {
2970
- $var = "\n" if $var eq '/';
2971
- $rtnStr .= "$pre$var";
2972
2985
  $line =~ s/^\s*\}// if $bra;
2986
+ if ($var eq '/') {
2987
+ $var = "\n";
2988
+ } elsif ($line =~ /^self\b/ and not $rtnStr =~ /\$$/) {
2989
+ $var = '$$'; # ("$$self{var}" in string)
2990
+ }
2991
+ $rtnStr .= "$pre$var";
2973
2992
  next;
2974
2993
  }
2975
2994
  # allow multiple group names
@@ -3074,6 +3093,8 @@ sub InsertTagValues($$$;$$$)
3074
3093
  last unless $tag =~ / /; # all done if we got our best match
3075
3094
  }
3076
3095
  }
3096
+ } elsif ($tag eq 'self') {
3097
+ $val = $self; # ("$self{var}" or "$self->{var}" in string)
3077
3098
  } else {
3078
3099
  # get the tag value
3079
3100
  $val = $self->GetValue($tag, $type);
@@ -3263,7 +3284,7 @@ sub IsSameFile($$$)
3263
3284
 
3264
3285
  #------------------------------------------------------------------------------
3265
3286
  # Is this a raw file type?
3266
- # Inputs: 0) Exiftool ref
3287
+ # Inputs: 0) ExifTool ref
3267
3288
  # Returns: true if FileType is a type of RAW image
3268
3289
  sub IsRawType($)
3269
3290
  {
@@ -5519,7 +5540,11 @@ sub WriteJPEG($$)
5519
5540
  my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr, \&WriteTIFF);
5520
5541
  if (defined $buff and length $buff) {
5521
5542
  if (length($buff) + length($exifAPP1hdr) > $maxSegmentLen) {
5522
- $self->Warn('Creating multi-segment EXIF',1);
5543
+ if ($self->Options('NoMultiExif')) {
5544
+ $self->Error('EXIF is too large for JPEG segment');
5545
+ } else {
5546
+ $self->Warn('Creating multi-segment EXIF',1);
5547
+ }
5523
5548
  }
5524
5549
  # switch to buffered output if required
5525
5550
  if (($$self{PREVIEW_INFO} or $$self{LeicaTrailer}) and not $oldOutfile) {
@@ -5991,7 +6016,11 @@ sub WriteJPEG($$)
5991
6016
  # delete segment if IFD contains no entries
5992
6017
  length $$segDataPt or $del = 1, last;
5993
6018
  if (length($$segDataPt) + length($exifAPP1hdr) > $maxSegmentLen) {
5994
- $self->Warn('Writing multi-segment EXIF',1);
6019
+ if ($self->Options('NoMultiExif')) {
6020
+ $self->Error('EXIF is too large for JPEG segment');
6021
+ } else {
6022
+ $self->Warn('Writing multi-segment EXIF',1);
6023
+ }
5995
6024
  }
5996
6025
  # switch to buffered output if required
5997
6026
  if (($$self{PREVIEW_INFO} or $$self{LeicaTrailer}) and not $oldOutfile) {
@@ -6773,7 +6802,7 @@ sub WriteBinaryData($$$)
6773
6802
  my $val = ReadValue($dataPt, $entry, $format, $count, $dirLen-$entry);
6774
6803
  next unless defined $val;
6775
6804
  my $nvHash = $self->GetNewValueHash($tagInfo, $$self{CUR_WRITE_GROUP});
6776
- next unless $self->IsOverwriting($nvHash, $val);
6805
+ next unless $self->IsOverwriting($nvHash, $val) > 0;
6777
6806
  my $newVal = $self->GetNewValue($nvHash);
6778
6807
  next unless defined $newVal; # can't delete from a binary table
6779
6808
  # update DataMember with new value if necessary
@@ -49,7 +49,7 @@ use Image::ExifTool::Exif;
49
49
  use Image::ExifTool::GPS;
50
50
  require Exporter;
51
51
 
52
- $VERSION = '3.32';
52
+ $VERSION = '3.35';
53
53
  @ISA = qw(Exporter);
54
54
  @EXPORT_OK = qw(EscapeXML UnescapeXML);
55
55
 
@@ -889,6 +889,7 @@ my %sRetouchArea = (
889
889
  ModifyDate => { Groups => { 2 => 'Time' }, %dateTimeInfo, Priority => 0 },
890
890
  Nickname => { },
891
891
  Rating => { Writable => 'real', Notes => 'a value from 0 to 5, or -1 for "rejected"' },
892
+ RatingPercent=>{ Writable => 'real', Avoid => 1, Notes => 'non-standard' },
892
893
  Thumbnails => {
893
894
  FlatName => 'Thumbnail',
894
895
  Struct => \%sThumbnail,
@@ -1483,8 +1484,35 @@ my %sPantryItem = (
1483
1484
  STRUCT_NAME => 'Look',
1484
1485
  NAMESPACE => 'crs',
1485
1486
  Name => { },
1487
+ Amount => { },
1488
+ Cluster=> { },
1489
+ UUID => { },
1490
+ SupportsMonochrome => { },
1486
1491
  }
1487
1492
  },
1493
+ # more again (ref forum11258)
1494
+ GrainSeed => { },
1495
+ ClipboardOrientation => { Writable => 'integer' },
1496
+ ClipboardAspectRatio => { Writable => 'integer' },
1497
+ PresetType => { },
1498
+ Cluster => { },
1499
+ UUID => { Avoid => 1 },
1500
+ SupportsAmount => { Writable => 'boolean' },
1501
+ SupportsColor => { Writable => 'boolean' },
1502
+ SupportsMonochrome => { Writable => 'boolean' },
1503
+ SupportsHighDynamicRange=> { Writable => 'boolean' },
1504
+ SupportsNormalDynamicRange=> { Writable => 'boolean' },
1505
+ SupportsSceneReferred => { Writable => 'boolean' },
1506
+ SupportsOutputReferred => { Writable => 'boolean' },
1507
+ CameraModelRestriction => { },
1508
+ Copyright => { Avoid => 1 },
1509
+ ContactInfo => { },
1510
+ GrainSeed => { Writable => 'integer' },
1511
+ Name => { Writable => 'lang-alt', Avoid => 1 },
1512
+ ShortName => { Writable => 'lang-alt' },
1513
+ SortName => { Writable => 'lang-alt' },
1514
+ Group => { Writable => 'lang-alt', Avoid => 1 },
1515
+ Description => { Writable => 'lang-alt', Avoid => 1 },
1488
1516
  );
1489
1517
 
1490
1518
  # Tiff namespace properties (tiff)
@@ -2935,13 +2963,15 @@ sub PrintLensID(@)
2935
2963
  # for Pentax, CS4 stores an int16u, but we use 2 x int8u
2936
2964
  $id = join(' ', unpack('C*', pack('n', $id)));
2937
2965
  }
2938
- my $str = $$printConv{$id} || "Unknown ($id)";
2939
2966
  # Nikon is a special case because Adobe doesn't store the full LensID
2967
+ # (Apple Photos does, but we have to convert back to hex)
2940
2968
  if ($mk eq 'Nikon') {
2941
- my $hex = sprintf("%.2X", $id);
2969
+ $id = sprintf('%X', $id);
2970
+ $id = "0$id" if length($id) & 0x01; # pad with leading 0 if necessary
2971
+ $id =~ s/(..)/$1 /g and $id =~ s/ $//; # put spaces between bytes
2942
2972
  my (%newConv, %used);
2943
2973
  my $i = 0;
2944
- foreach (grep /^$hex /, keys %$printConv) {
2974
+ foreach (grep /^$id/, keys %$printConv) {
2945
2975
  my $lens = $$printConv{$_};
2946
2976
  next if $used{$lens}; # avoid duplicates
2947
2977
  $used{$lens} = 1;
@@ -2950,6 +2980,7 @@ sub PrintLensID(@)
2950
2980
  }
2951
2981
  $printConv = \%newConv;
2952
2982
  }
2983
+ my $str = $$printConv{$id} || "Unknown ($id)";
2953
2984
  return Image::ExifTool::Exif::PrintLensID($et, $str, $printConv,
2954
2985
  undef, $id, $focalLength, $sa, $maxAv, $sf, $lf, $lensModel);
2955
2986
  }
@@ -3187,6 +3218,7 @@ NoLoop:
3187
3218
  #} elsif (grep / /, @$props) {
3188
3219
  # $$tagInfo{List} = 1;
3189
3220
  }
3221
+ #PHIL why flat tag added here???? (try a.xmp)
3190
3222
  AddTagToTable($tagTablePtr, $tagID, $tagInfo);
3191
3223
  $added = 1;
3192
3224
  last;
@@ -3531,6 +3563,11 @@ sub ParseXMPElement($$$;$$$$)
3531
3563
  # add svg namespace prefix if missing to ignore these entries in the tag name
3532
3564
  $$propList[-1] = "svg:$prop";
3533
3565
  }
3566
+ } elsif ($$et{XmpIgnoreProps}) { # ignore specified properties for tag name
3567
+ foreach (@{$$et{XmpIgnoreProps}}) {
3568
+ last unless @$propList;
3569
+ pop @$propList if $_ eq $$propList[0];
3570
+ }
3534
3571
  }
3535
3572
 
3536
3573
  # handle properties inside element attributes (RDF shorthand format):
@@ -519,6 +519,7 @@ sub AddNewStruct($$$$$$)
519
519
  next unless $$fieldInfo{List};
520
520
  my $i = 0;
521
521
  my ($item, $p);
522
+ my $level = scalar(() = ($propPath =~ / \d+/g));
522
523
  # loop through all list items (note: can't yet write multi-dimensional lists)
523
524
  foreach $item (@{$val}) {
524
525
  if ($i) {
@@ -533,7 +534,8 @@ sub AddNewStruct($$$$$$)
533
534
  if (ref $item eq 'HASH') {
534
535
  my $subStruct = $$fieldInfo{Struct} or next;
535
536
  AddNewStruct($et, $tagInfo, $capture, $p, $item, $subStruct) or next;
536
- } elsif (length $item) { # don't write empty items in list
537
+ # don't write empty items in upper-level list
538
+ } elsif (length $item or (defined $item and $level == 1)) {
537
539
  AddNewTag($et, $fieldInfo, $capture, $p, \$item, \%langIdx);
538
540
  $addedTag = 1;
539
541
  }