exiftool_vendored 12.80.0 → 12.81.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.
@@ -785,6 +785,7 @@ sub WriteQuickTime($$$)
785
785
  $et or return 1; # allow dummy access to autoload this package
786
786
  my ($mdat, @mdat, @mdatEdit, $edit, $track, $outBuff, $co, $term, $delCount);
787
787
  my (%langTags, $canCreate, $delGrp, %boxPos, %didDir, $writeLast, $err, $atomCount);
788
+ my ($tag, $lastTag, $errStr);
788
789
  my $outfile = $$dirInfo{OutFile} || return 0;
789
790
  my $raf = $$dirInfo{RAF}; # (will be null for lower-level atoms)
790
791
  my $dataPt = $$dirInfo{DataPt}; # (will be null for top-level atoms)
@@ -857,7 +858,10 @@ sub WriteQuickTime($$$)
857
858
  }
858
859
  $atomCount = $$tagTablePtr{VARS}{ATOM_COUNT} if $$tagTablePtr{VARS};
859
860
 
861
+ $tag = $lastTag = '';
862
+
860
863
  for (;;) { # loop through all atoms at this level
864
+ $lastTag = $tag if $$tagTablePtr{$tag}; # keep track of last known tag
861
865
  if (defined $atomCount and --$atomCount < 0 and $dataPt) {
862
866
  # stop processing now and just copy the rest of the atom
863
867
  Write($outfile, substr($$dataPt, $raf->Tell())) or $rtnVal=$rtnErr, $err=1;
@@ -876,15 +880,15 @@ sub WriteQuickTime($$$)
876
880
  last;
877
881
  }
878
882
  my $size = Get32u(\$hdr, 0) - 8; # (atom size without 8-byte header)
879
- my $tag = substr($hdr, 4, 4);
883
+ $tag = substr($hdr, 4, 4);
880
884
  if ($size == -7) {
881
885
  # read the extended size
882
- $raf->Read($buff, 8) == 8 or $et->Error('Truncated extended atom'), last;
886
+ $raf->Read($buff, 8) == 8 or $errStr = 'Truncated extended atom', last;
883
887
  $hdr .= $buff;
884
888
  my ($hi, $lo) = unpack('NN', $buff);
885
889
  if ($hi or $lo > 0x7fffffff) {
886
890
  if ($hi > 0x7fffffff) {
887
- $et->Error('Invalid atom size');
891
+ $errStr = 'Invalid atom size';
888
892
  last;
889
893
  } elsif (not $et->Options('LargeFileSupport')) {
890
894
  $et->Error('End of processing at large atom (LargeFileSupport not enabled)');
@@ -892,7 +896,7 @@ sub WriteQuickTime($$$)
892
896
  }
893
897
  }
894
898
  $size = $hi * 4294967296 + $lo - 16;
895
- $size < 0 and $et->Error('Invalid extended atom size'), last;
899
+ $size < 0 and $errStr = 'Invalid extended atom size', last;
896
900
  } elsif ($size == -8) {
897
901
  if ($dataPt) {
898
902
  last if $$dirInfo{DirName} eq 'CanonCNTH'; # (this is normal for Canon CNTH atom)
@@ -908,7 +912,7 @@ sub WriteQuickTime($$$)
908
912
  }
909
913
  last;
910
914
  } elsif ($size < 0) {
911
- $et->Error('Invalid atom size');
915
+ $errStr = 'Invalid atom size';
912
916
  last;
913
917
  }
914
918
 
@@ -952,11 +956,11 @@ sub WriteQuickTime($$$)
952
956
  $tag = PrintableTagID($tag,3);
953
957
  if ($size > $maxReadLen and $got == 0x10000) {
954
958
  my $mb = int($size / 0x100000 + 0.5);
955
- $et->Error("'${tag}' atom is too large for rewriting ($mb MB)");
959
+ $errStr = "'${tag}' atom is too large for rewriting ($mb MB)";
956
960
  } else {
957
- $et->Error("Truncated '${tag}' atom");
961
+ $errStr = "Truncated '${tag}' atom";
958
962
  }
959
- return $rtnVal;
963
+ last;
960
964
  }
961
965
  }
962
966
  # save the handler type for this track
@@ -1446,6 +1450,22 @@ sub WriteQuickTime($$$)
1446
1450
  Write($outfile, $hdr, $buff) or $rtnVal=$rtnErr, $err=1, last;
1447
1451
  }
1448
1452
  }
1453
+ # ($errStr is set if there was an error that could possibly be due to an unknown trailer)
1454
+ if ($errStr) {
1455
+ if ($lastTag eq 'mdat' and not $dataPt and not $$tagTablePtr{$tag}) {
1456
+ my $nvTrail = $et->GetNewValueHash($Image::ExifTool::Extra{Trailer});
1457
+ if ($$et{DEL_GROUP}{Trailer} or ($nvTrail and not ($$nvTrail{Value} and $$nvTrail{Value}[0]))) {
1458
+ $errStr =~ s/ is too large.*//;
1459
+ $et->Warn('Deleted unknown trailer with ' . lcfirst($errStr));
1460
+ } else {
1461
+ $et->Warn('Unknown trailer with ' . lcfirst($errStr));
1462
+ $et->Error('Use "-trailer=" to delete unknown trailer');
1463
+ }
1464
+ } else {
1465
+ $et->Error($errStr);
1466
+ return $dataPt ? undef : 1;
1467
+ }
1468
+ }
1449
1469
  $et->VPrint(0, " [deleting $delCount $dirName tag".($delCount==1 ? '' : 's')."]\n") if $delCount;
1450
1470
 
1451
1471
  $createKeys &= ~0x01 unless $$addDirs{Keys}; # (Keys may have been written)
@@ -1297,6 +1297,7 @@ sub SetNewValuesFromFile($$;@)
1297
1297
  Filter => $$options{Filter},
1298
1298
  FixBase => $$options{FixBase},
1299
1299
  Geolocation => $$options{Geolocation},
1300
+ GeolocAltNames => $$options{GeolocAltNames},
1300
1301
  GeolocFeature => $$options{GeolocFeature},
1301
1302
  GeolocMinPop => $$options{GeolocMinPop},
1302
1303
  GeolocMaxDist => $$options{GeolocMaxDist},
@@ -1336,6 +1337,11 @@ sub SetNewValuesFromFile($$;@)
1336
1337
  XAttrTags => $$options{XAttrTags},
1337
1338
  XMPAutoConv => $$options{XMPAutoConv},
1338
1339
  );
1340
+ # reset Geolocation option if we aren't copying any geolocation tags
1341
+ if ($$options{Geolocation} and not grep /\bGeolocation/i, @setTags) {
1342
+ $self->VPrint(0, '(resetting unnecessary Geolocation option)');
1343
+ $$srcExifTool{OPTIONS}{Geolocation} = undef;
1344
+ }
1339
1345
  $$srcExifTool{GLOBAL_TIME_OFFSET} = $$self{GLOBAL_TIME_OFFSET};
1340
1346
  $$srcExifTool{ALT_EXIFTOOL} = $$self{ALT_EXIFTOOL};
1341
1347
  foreach $tag (@setTags) {
@@ -3806,7 +3812,7 @@ sub GetGeolocateTags($$;$)
3806
3812
  'iptc' => [ qw(City Province-State Country-PrimaryLocationCode Country-PrimaryLocationName) ],
3807
3813
  'gps' => [ qw(GPSLatitude GPSLongitude GPSLatitudeRef GPSLongitudeRef) ],
3808
3814
  'xmp-exif' => [ qw(GPSLatitude GPSLongitude) ],
3809
- 'keys' => [ 'GPSCoordinates' ],
3815
+ 'keys' => [ 'GPSCoordinates', 'LocationName' ],
3810
3816
  'itemlist' => [ 'GPSCoordinates' ],
3811
3817
  'userdata' => [ 'GPSCoordinates' ],
3812
3818
  # more general groups not in this lookup: XMP and QuickTime
@@ -3818,7 +3824,7 @@ sub GetGeolocateTags($$;$)
3818
3824
  }
3819
3825
  # set default XMP City tags if necessary
3820
3826
  if (not $writeGPS and ($grps{xmp} or (not @tags and not $grps{quicktime}))) {
3821
- push @tags, qw(XMP:City XMP:State XMP:CountryCode XMP:Country);
3827
+ push @tags, qw(XMP:City XMP:State XMP:CountryCode XMP:Country Keys:LocationName);
3822
3828
  }
3823
3829
  $writeGPS = 1 unless defined $writeGPS; # (delete both City and GPS)
3824
3830
  # set default QuickTime tag if necessary
@@ -2587,6 +2587,7 @@ my %sPantryItem = (
2587
2587
  EnhanceDenoiseAlreadyApplied => { Writable => 'boolean' }, #forum14760
2588
2588
  EnhanceDenoiseVersion => { }, #forum14760 integer?
2589
2589
  EnhanceDenoiseLumaAmount => { }, #forum14760 integer?
2590
+ # FujiRatingAlreadyApplied - boolean written by LR classic 13.2 (forum15815)
2590
2591
  );
2591
2592
 
2592
2593
  # IPTC Core namespace properties (Iptc4xmpCore) (ref 4)
@@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
29
29
  %jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
30
30
  %static_vars);
31
31
 
32
- $VERSION = '12.80';
32
+ $VERSION = '12.81';
33
33
  $RELEASE = '';
34
34
  @ISA = qw(Exporter);
35
35
  %EXPORT_TAGS = (
@@ -921,7 +921,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
921
921
  DICOM=> '(.{128}DICM|\0[\x02\x04\x06\x08]\0[\0-\x20]|[\x02\x04\x06\x08]\0[\0-\x20]\0)',
922
922
  DOCX => 'PK\x03\x04',
923
923
  DPX => '(SDPX|XPDS)',
924
- DR4 => 'IIII\x04\0\x04\0',
924
+ DR4 => 'IIII[\x04|\x05]\0\x04\0',
925
925
  DSS => '(\x02dss|\x03ds2)',
926
926
  DV => '\x1f\x07\0[\x3f\xbf]', # (not tested if extension recognized)
927
927
  DWF => '\(DWF V\d',
@@ -1103,6 +1103,7 @@ my @availableOptions = (
1103
1103
  [ 'FilterW', undef, 'input filter when writing tag values' ],
1104
1104
  [ 'FixBase', undef, 'fix maker notes base offsets' ],
1105
1105
  [ 'Geolocation', undef, 'generate geolocation tags' ],
1106
+ [ 'GeolocAltNames', 1, 'search alternate city names if available' ],
1106
1107
  [ 'GeolocFeature', undef, 'regular expression of geolocation features to match' ],
1107
1108
  [ 'GeolocMinPop', undef, 'minimum geolocation population' ],
1108
1109
  [ 'GeolocMaxDist', undef, 'maximum geolocation distance' ],
@@ -1691,7 +1692,7 @@ my %systemTagsNotes = (
1691
1692
  Flags => ['Writable' ,'Protected', 'Binary'],
1692
1693
  Permanent => 0, # (this is 1 by default for MakerNotes tags)
1693
1694
  WriteCheck => q{
1694
- return undef if $val =~ /^IIII\x04\0\x04\0/;
1695
+ return undef if $val =~ /^IIII[\x04|\x05]\0\x04\0/;
1695
1696
  return 'Invalid CanonDR4 data';
1696
1697
  },
1697
1698
  },
@@ -1988,27 +1989,34 @@ my %systemTagsNotes = (
1988
1989
  },
1989
1990
  ValueConvInv => q{
1990
1991
  require Image::ExifTool::Geolocation;
1991
- return $val if lc($val) eq 'geotag';
1992
+ # write this tag later if geotagging
1993
+ return $val if $val =~ /\bgeotag\b/i;
1994
+ $val .= ',both';
1992
1995
  my $opts = $$self{OPTIONS};
1993
- my $geo = Image::ExifTool::Geolocation::Geolocate($self->Encode($val,'UTF8'),
1994
- $$opts{GeolocMinPop}, $$opts{GeolocMaxDist}, $$opts{Lang}, undef, $$opts{GeolocFeature});
1995
- return '' unless $geo;
1996
- if ($$geo[12] and $self->Warn('Multiple matching cities found',2)) {
1996
+ my ($n, $i, $km, $be) = Image::ExifTool::Geolocation::Geolocate($self->Encode($val,'UTF8'), $opts);
1997
+ return '' unless $n;
1998
+ if ($n > 1 and $self->Warn('Multiple matching cities found',2)) {
1997
1999
  warn "$$self{VALUE}{Warning}\n";
1998
2000
  return '';
1999
2001
  }
2000
- my @tags = $self->GetGeolocateTags($wantGroup, defined $$geo[10] ? 0 : 1);
2002
+ my @geo = Image::ExifTool::Geolocation::GetEntry($i, $$opts{Lang});
2003
+ my @tags = $self->GetGeolocateTags($wantGroup, $km ? 0 : 1);
2001
2004
  my %geoNum = ( City => 0, Province => 1, State => 1, Code => 3, Country => 4,
2002
2005
  Coordinates => 89, Latitude => 8, Longitude => 9 );
2003
2006
  my ($tag, $value);
2004
2007
  foreach $tag (@tags) {
2005
2008
  if ($tag =~ /GPS(Coordinates|Latitude|Longitude)?/) {
2006
- $value = $geoNum{$1} == 89 ? "$$geo[8],$$geo[9]" : $$geo[$geoNum{$1}];
2009
+ $value = $geoNum{$1} == 89 ? "$geo[8],$geo[9]" : $geo[$geoNum{$1}];
2007
2010
  } elsif ($tag =~ /(Code)/ or $tag =~ /(City|Province|State|Country)/) {
2008
- $value = $$geo[$geoNum{$1}];
2011
+ $value = $geo[$geoNum{$1}];
2009
2012
  next unless defined $value;
2010
2013
  $value = $self->Decode($value,'UTF8');
2011
2014
  $value .= ' ' if $tag eq 'iptc:Country-PrimaryLocationCode'; # (IPTC requires 3-char code)
2015
+ } elsif ($tag =~ /LocationName/) {
2016
+ $value = $geo[0] or next;
2017
+ $value .= ', ' . $geo[1] if $geo[1];
2018
+ $value .= ', ' . $geo[4] if $geo[4];
2019
+ $value = $self->Decode($value, 'UTF8');
2012
2020
  } else {
2013
2021
  next; # (shouldn't happen)
2014
2022
  }
@@ -2017,13 +2025,15 @@ my %systemTagsNotes = (
2017
2025
  return '';
2018
2026
  },
2019
2027
  PrintConvInv => q{
2020
- return $val unless $val =~ /^([-+]?\d.*?[NS]?), ?([-+]?\d.*?[EW]?)$/ or
2021
- $val =~ /^\s*(-?\d+(?:\.\d+)?)\s*(-?\d+(?:\.\d+)?)\s*$/;
2022
- my ($lat, $lon) = ($1, $2);
2023
- require Image::ExifTool::GPS;
2024
- $lat = Image::ExifTool::GPS::ToDegrees($lat, 1, "lat");
2025
- $lon = Image::ExifTool::GPS::ToDegrees($lon, 1, "lon");
2026
- return "$lat, $lon";
2028
+ my @args = split /\s*,\s*/, $val;
2029
+ my $lat = 1;
2030
+ foreach (@args) {
2031
+ next unless /^[-+]?\d/;
2032
+ require Image::ExifTool::GPS;
2033
+ $_ = Image::ExifTool::GPS::ToDegrees($_, 1, $lat ? 'lat' : 'lon');
2034
+ $lat ^= 1;
2035
+ }
2036
+ return join(',', @args);
2027
2037
  },
2028
2038
  },
2029
2039
  GeolocationBearing => { %geoInfo,
@@ -4338,25 +4348,27 @@ sub DoneExtract($)
4338
4348
  }
4339
4349
  local $SIG{'__WARN__'} = \&SetWarning;
4340
4350
  undef $evalWarning;
4341
- my $geo = Image::ExifTool::Geolocation::Geolocate($arg, $$opts{GeolocMinPop},
4342
- $$opts{GeolocMaxDist}, $$opts{Lang}, $$opts{Duplicates},
4343
- $$opts{GeolocFeature});
4344
- # ($$geo[0] will be an ARRAY ref if multiple matches were found and the Duplicates option is set)
4345
- if ($geo and (ref $$geo[0] or not $$geo[12] or not $self->Warn('Multiple Geolocation cities are possible',2))) {
4346
- my $geoList = ref $$geo[0] ? $geo : [ $geo ]; # make a list if not done alreaday
4347
- foreach $geo (@$geoList) {
4348
- $self->FoundTag(GeolocationCity => $$geo[0]);
4349
- $self->FoundTag(GeolocationRegion => $$geo[1]) if $$geo[1];
4350
- $self->FoundTag(GeolocationSubregion => $$geo[2]) if $$geo[2];
4351
- $self->FoundTag(GeolocationCountryCode => $$geo[3]);
4352
- $self->FoundTag(GeolocationCountry => $$geo[4]) if $$geo[4];
4353
- $self->FoundTag(GeolocationTimeZone => $$geo[5]) if $$geo[5];
4354
- $self->FoundTag(GeolocationFeatureCode => $$geo[6]);
4355
- $self->FoundTag(GeolocationPopulation => $$geo[7]);
4356
- $self->FoundTag(GeolocationPosition => "$$geo[8] $$geo[9]");
4357
- $self->FoundTag(GeolocationDistance => $$geo[10]) if defined $$geo[10];
4358
- $self->FoundTag(GeolocationBearing => $$geo[11]) if defined $$geo[11];
4359
- $self->FoundTag(GeolocationWarning => "Search matched $$geo[12] cities") if $$geo[12] and $geo eq $$geoList[0];
4351
+ $$opts{GeolocMulti} = $$opts{Duplicates};
4352
+ my ($n, $i, $km, $be) = Image::ExifTool::Geolocation::Geolocate($arg, $opts);
4353
+ delete $$opts{GeolocMulti};
4354
+ # ($i will be an ARRAY ref if multiple matches were found and the Duplicates option is set)
4355
+ if ($n and (ref $i or $n < 2 or not $self->Warn('Multiple Geolocation cities are possible',2))) {
4356
+ my $list = ref $i ? $i : [ $i ]; # make a list if not done alreaday
4357
+ foreach $i (@$list) {
4358
+ my @geo = Image::ExifTool::Geolocation::GetEntry($i, $$opts{Lang});
4359
+ $self->FoundTag(GeolocationCity => $geo[0]);
4360
+ $self->FoundTag(GeolocationRegion => $geo[1]) if $geo[1];
4361
+ $self->FoundTag(GeolocationSubregion => $geo[2]) if $geo[2];
4362
+ $self->FoundTag(GeolocationCountryCode => $geo[3]);
4363
+ $self->FoundTag(GeolocationCountry => $geo[4]) if $geo[4];
4364
+ $self->FoundTag(GeolocationTimeZone => $geo[5]) if $geo[5];
4365
+ $self->FoundTag(GeolocationFeatureCode => $geo[6]);
4366
+ $self->FoundTag(GeolocationPopulation => $geo[7]);
4367
+ $self->FoundTag(GeolocationPosition => "$geo[8] $geo[9]");
4368
+ next if $i != $$list[0];
4369
+ $self->FoundTag(GeolocationDistance => $km) if defined $km;
4370
+ $self->FoundTag(GeolocationBearing => $be) if defined $be;
4371
+ $self->FoundTag(GeolocationWarning => "Search matched $n cities") if $n > 1;
4360
4372
  }
4361
4373
  } elsif ($evalWarning) {
4362
4374
  $self->Warn(CleanWarning());
@@ -5040,6 +5052,7 @@ sub SetFoundTags($)
5040
5052
  $allTag = 1;
5041
5053
  } elsif ($tag =~ /[*?]/) {
5042
5054
  # allow wildcards in tag names
5055
+ $tag =~ tr/-_A-Za-z0-9*?//dc; # sterilize
5043
5056
  $tag =~ s/\*/[-\\w]*/g;
5044
5057
  $tag =~ s/\?/[-\\w]/g;
5045
5058
  $tag .= '( \\(.*)?' if $doDups or $allGrp;
@@ -5047,6 +5060,7 @@ sub SetFoundTags($)
5047
5060
  next unless @matches; # don't want entry in list for wildcard tags
5048
5061
  $allTag = 1;
5049
5062
  } elsif ($doDups or defined $group) {
5063
+ $tag =~ tr/-_A-Za-z0-9//dc; # sterilize
5050
5064
  # must also look for tags like "Tag (1)"
5051
5065
  # (but be sure not to match temporary ValueConv entries like "Tag #")
5052
5066
  @matches = grep(/^$tag( \(|$)/i, keys %$tagHash);
@@ -728,6 +728,12 @@ to use for the geolocation input. May also include regular expressions for
728
728
  more flexible matching. See L<https://exiftool.org/geolocation.html> for
729
729
  more details. Default is undef.
730
730
 
731
+ =item GeolocAltNames
732
+
733
+ Flag to search alternate Geolocation city names if available (ie. if
734
+ $Image::ExifTool::Geolocation::altDir has been set). Set to 0 to disable
735
+ use of the alternate names. Default is 1.
736
+
731
737
  =item GeolocFeature
732
738
 
733
739
  Comma-separated list of feature codes to include in city search, or exclude
@@ -1,6 +1,6 @@
1
1
  Summary: perl module for image data extraction
2
2
  Name: perl-Image-ExifTool
3
- Version: 12.80
3
+ Version: 12.81
4
4
  Release: 1
5
5
  License: Artistic/GPL
6
6
  Group: Development/Libraries/Perl
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ExiftoolVendored
4
- VERSION = Gem::Version.new('12.80.0')
4
+ VERSION = Gem::Version.new('12.81.0')
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exiftool_vendored
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.80.0
4
+ version: 12.81.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew McEachen
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-03-21 00:00:00.000000000 Z
12
+ date: 2024-03-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: exiftool