Skip to content

Commit

Permalink
Upgrading to exiftool v12.81
Browse files Browse the repository at this point in the history
  • Loading branch information
morozgrafix committed Mar 29, 2024
1 parent ac2173a commit 27befc8
Show file tree
Hide file tree
Showing 30 changed files with 6,263 additions and 5,406 deletions.
26 changes: 26 additions & 0 deletions bin/Changes
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@ RSS feed: https://exiftool.org/rss.xml
Note: The most recent production release is Version 12.76. (Other versions are
considered development releases, and are not uploaded to MetaCPAN.)

Mar. 27, 2024 - Version 12.81

- Added ability to read EXIF and XMP from EXR images
- Added ability to delete unknown trailer when writing MOV/MP4 videos
- Added ability to write a couple of Stable Diffusion PNG tags
- Added ability to write one of the Microsoft Xtra Description tags (github
#248)
- Added support for using alternate city names in reverse Geolocation
- Added support for reading timed GPS from DOD LS600W TS videos
- Added support for new version of Canon DR4 files
- Added a number of new iTunesInfo tags
- Added a new Olympus LensType
- Allow regular expressions to be used when writing Geolocate tag
- Decode a number of new Nikon tags (thanks Warren Hatch)
- Enhanced writing of Geolocate tag to also write Keys:LocationName
- Cache the results of the last reverse geolocation search to speed batch
processing when multiple files have the same search parameters
- Patched problem that could cause runtime errors with some invaid tag names
- Fixed a couple of newly added FujiFilm tags
- Fixed decoding of FujiFilm AFAreaZoneSize
- API Changes:
- Added GeolocAltNames option

Mar. 19, 2024 - Version 12.80

- Added GeolocationFeatureCode tag
Expand All @@ -19,6 +42,8 @@ Mar. 19, 2024 - Version 12.80
- Improved accuracy of Geolocation distance/bearing calculations
- Changed structure of Geolocation database (now version 1.02)
- Minor change to key format for user-defined Geolocation name translations
- Ignore API Geolocation option when copying tags if none of the Geolocation
tags are being copied
- Fixed case/spacing of "C2PA" in some CBOR tag descriptions
- Fixed bug extracting binary data from EXR files
- API Changes:
Expand All @@ -29,6 +54,7 @@ Mar. 15, 2024 - Version 12.79
- Improvements to new Geolocation feature:
- Added reverse Geolocation ability (obtain GPS coordinates from city
name), with support for regular expressions
- Added ability to geolocate while geotagging
- Added -listgeo option to list the Geolocation database
- Added the ability to include user-defined cities in the Geolocation
database
Expand Down
2 changes: 2 additions & 0 deletions bin/MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,8 @@ t/Geolocation_3.out
t/Geolocation_4.out
t/Geolocation_5.out
t/Geolocation_6.out
t/Geolocation_7.out
t/Geolocation_8.out
t/Geotag.t
t/Geotag_10.out
t/Geotag_11.out
Expand Down
2 changes: 1 addition & 1 deletion bin/META.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@
}
},
"release_status" : "stable",
"version" : "12.80"
"version" : "12.81"
}
2 changes: 1 addition & 1 deletion bin/META.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ recommends:
Time::HiRes: 0
requires:
perl: 5.004
version: 12.80
version: 12.81
5 changes: 3 additions & 2 deletions bin/README
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ your home directory, then you would type the following commands in a
terminal window to extract and run ExifTool:

cd ~/Desktop
gzip -dc Image-ExifTool-12.80.tar.gz | tar -xf -
cd Image-ExifTool-12.80
gzip -dc Image-ExifTool-12.81.tar.gz | tar -xf -
cd Image-ExifTool-12.81
./exiftool t/images/ExifTool.jpg

Note: These commands extract meta information from one of the test images.
Expand Down Expand Up @@ -238,6 +238,7 @@ information:
html/ExifTool.html - API documentation
html/TagNames/index.html - Tag name documentation
html/geotag.html - Geotag feature
html/geolocation.html - Geolocation feature
html/faq.html - Frequently asked questions
html/filename.html - Renaming/moving files
html/metafiles.html - Working with metadata sidecar files
Expand Down
34 changes: 25 additions & 9 deletions bin/exiftool
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use strict;
use warnings;
require 5.004;

my $version = '12.80';
my $version = '12.81';

# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
my $exePath;
Expand Down Expand Up @@ -723,17 +723,22 @@ for (;;) {
require Image::ExifTool::Geolocation;
my ($i, $entry);
print "Geolocation database:\n" unless $quiet;
print "City,Region,Subregion,CountryCode,Country,TimeZone,FeatureCode,Population,Latitude,Longitude\n";
my $isAlt = $mt->Options('GeolocAltNames') ? ',AltNames' : '';
$isAlt = '' if $isAlt and not Image::ExifTool::Geolocation::ReadAltNames();
print "City,Region,Subregion,CountryCode,Country,TimeZone,FeatureCode,Population,Latitude,Longitude$isAlt\n";
Image::ExifTool::Geolocation::SortDatabase('City') if $sortOpt;
my $minPop = $mt->Options('GeolocMinPop');
my $feature = $mt->Options('GeolocFeature') || '';
my $neg = $feature =~ s/^-//;
my %fcodes = map { lc($_) => 1 } split /\s*,\s*/, $feature;
my @isUTF8 = (0,1,2,4); # items that need converting from UTF8
push @isUTF8, 10 if $isAlt;
for ($i=0; ; ++$i) {
my @entry = Image::ExifTool::Geolocation::GetEntry($i,$langOpt) or last;
my @entry = Image::ExifTool::Geolocation::GetEntry($i,$langOpt,1) or last;
push @entry, Image::ExifTool::Geolocation::GetAltNames($i,1) if $isAlt;
next if $minPop and $entry[7] < $minPop;
next if %fcodes and $neg ? $fcodes{lc $entry[6]} : not $fcodes{lc $entry[6]};
$_ = defined $_ ? $mt->Decode($_, 'UTF8') : '' foreach @entry[0,1,2,4];
$_ = defined $_ ? $mt->Decode($_, 'UTF8') : '' foreach @entry[@isUTF8];
print join(',', @entry), "\n";
}
} else { # 'g(\d*)'
Expand Down Expand Up @@ -1365,11 +1370,11 @@ for (;;) {
$useMWG = 1;
} elsif (/^([-\w]+:)*(filename|directory|testname)\b/i) {
$doSetFileName = 1;
} elsif (/^([-\w]+:)*(geotag|geotime|geosync)\b/i) {
} elsif (/^([-\w]+:)*(geotag|geotime|geosync|geolocate)\b/i) {
if (lc $2 eq 'geotime') {
$addGeotime = '';
} else {
# add geotag/geosync commands first
# add geotag/geosync/geolocate commands first
unshift @newValues, pop @newValues;
if (lc $2 eq 'geotag' and (not defined $addGeotime or $addGeotime) and length $val) {
$addGeotime = ($1 || '') . 'Geotime<DateTimeOriginal#';
Expand Down Expand Up @@ -5657,7 +5662,7 @@ with this command:
produces output like this:
-- Generated by ExifTool 12.80 --
-- Generated by ExifTool 12.81 --
File: a.jpg - 2003:10:31 15:44:19
(f/5.6, 1/60s, ISO 100)
File: b.jpg - 2006:05:23 11:57:38
Expand Down Expand Up @@ -6435,8 +6440,9 @@ otherwise family 0 is assumed. The B<-l> option may be combined with
B<-listf>, B<-listr> or B<-listwf> to add file descriptions to the list.
The B<-lang> option may be combined with B<-listx> to output descriptions in
a single language, and the B<-sort> and/or B<-lang> options may be combined
with B<-listgeo>. Also, the API GeolocMinPop and GeolocFeature options
apply to the B<-listgeo> output. Here are some examples:
with B<-listgeo>. Also, the API GeolocMinPop, GeolocFeature and
GeolocAltNames options apply to the B<-listgeo> output. Here are some
examples:
-list # list all tag names
-list -EXIF:All # list all EXIF tags
Expand Down Expand Up @@ -6538,6 +6544,10 @@ examples. Also see "geotag.html" in the full ExifTool distribution and the
L<Image::ExifTool Options|Image::ExifTool/Options> for more details and for
information about geotag configuration options.
The API Geolocation option may be set to the value "geotag" to also write
the name, province/state and country of the nearest city while geotagging.
See L<https://exiftool.org/geolocation.html> for details.
=item B<-globalTimeShift> I<SHIFT>
Shift all formatted date/time values by the specified amount when reading.
Expand Down Expand Up @@ -7435,6 +7445,12 @@ Geotag an image (C<a.jpg>) from position information in a GPS track log
DateTimeOriginal is used for geotagging. Local system time is assumed
unless DateTimeOriginal contains a timezone.
=item exiftool -geotag track.log -geolocate=geotag a.jpg
Geotag an image and also write geolocation information of the nearest city
(city name, state/province and country). Read here for more details about
the Geolocation feature: L<https://exiftool.org/geolocation.html#Write>
=item exiftool -geotag t.log -geotime='2009:04:02 13:41:12-05:00' a.jpg
Geotag an image with the GPS position for a specific time.
Expand Down
88 changes: 51 additions & 37 deletions bin/lib/Image/ExifTool.pm
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
%jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
%static_vars);

$VERSION = '12.80';
$VERSION = '12.81';
$RELEASE = '';
@ISA = qw(Exporter);
%EXPORT_TAGS = (
Expand Down Expand Up @@ -921,7 +921,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
DICOM=> '(.{128}DICM|\0[\x02\x04\x06\x08]\0[\0-\x20]|[\x02\x04\x06\x08]\0[\0-\x20]\0)',
DOCX => 'PK\x03\x04',
DPX => '(SDPX|XPDS)',
DR4 => 'IIII\x04\0\x04\0',
DR4 => 'IIII[\x04|\x05]\0\x04\0',
DSS => '(\x02dss|\x03ds2)',
DV => '\x1f\x07\0[\x3f\xbf]', # (not tested if extension recognized)
DWF => '\(DWF V\d',
Expand Down Expand Up @@ -1103,6 +1103,7 @@ my @availableOptions = (
[ 'FilterW', undef, 'input filter when writing tag values' ],
[ 'FixBase', undef, 'fix maker notes base offsets' ],
[ 'Geolocation', undef, 'generate geolocation tags' ],
[ 'GeolocAltNames', 1, 'search alternate city names if available' ],
[ 'GeolocFeature', undef, 'regular expression of geolocation features to match' ],
[ 'GeolocMinPop', undef, 'minimum geolocation population' ],
[ 'GeolocMaxDist', undef, 'maximum geolocation distance' ],
Expand Down Expand Up @@ -1691,7 +1692,7 @@ my %systemTagsNotes = (
Flags => ['Writable' ,'Protected', 'Binary'],
Permanent => 0, # (this is 1 by default for MakerNotes tags)
WriteCheck => q{
return undef if $val =~ /^IIII\x04\0\x04\0/;
return undef if $val =~ /^IIII[\x04|\x05]\0\x04\0/;
return 'Invalid CanonDR4 data';
},
},
Expand Down Expand Up @@ -1988,27 +1989,34 @@ my %systemTagsNotes = (
},
ValueConvInv => q{
require Image::ExifTool::Geolocation;
return $val if lc($val) eq 'geotag';
# write this tag later if geotagging
return $val if $val =~ /\bgeotag\b/i;
$val .= ',both';
my $opts = $$self{OPTIONS};
my $geo = Image::ExifTool::Geolocation::Geolocate($self->Encode($val,'UTF8'),
$$opts{GeolocMinPop}, $$opts{GeolocMaxDist}, $$opts{Lang}, undef, $$opts{GeolocFeature});
return '' unless $geo;
if ($$geo[12] and $self->Warn('Multiple matching cities found',2)) {
my ($n, $i, $km, $be) = Image::ExifTool::Geolocation::Geolocate($self->Encode($val,'UTF8'), $opts);
return '' unless $n;
if ($n > 1 and $self->Warn('Multiple matching cities found',2)) {
warn "$$self{VALUE}{Warning}\n";
return '';
}
my @tags = $self->GetGeolocateTags($wantGroup, defined $$geo[10] ? 0 : 1);
my @geo = Image::ExifTool::Geolocation::GetEntry($i, $$opts{Lang});
my @tags = $self->GetGeolocateTags($wantGroup, $km ? 0 : 1);
my %geoNum = ( City => 0, Province => 1, State => 1, Code => 3, Country => 4,
Coordinates => 89, Latitude => 8, Longitude => 9 );
my ($tag, $value);
foreach $tag (@tags) {
if ($tag =~ /GPS(Coordinates|Latitude|Longitude)?/) {
$value = $geoNum{$1} == 89 ? "$$geo[8],$$geo[9]" : $$geo[$geoNum{$1}];
$value = $geoNum{$1} == 89 ? "$geo[8],$geo[9]" : $geo[$geoNum{$1}];
} elsif ($tag =~ /(Code)/ or $tag =~ /(City|Province|State|Country)/) {
$value = $$geo[$geoNum{$1}];
$value = $geo[$geoNum{$1}];
next unless defined $value;
$value = $self->Decode($value,'UTF8');
$value .= ' ' if $tag eq 'iptc:Country-PrimaryLocationCode'; # (IPTC requires 3-char code)
} elsif ($tag =~ /LocationName/) {
$value = $geo[0] or next;
$value .= ', ' . $geo[1] if $geo[1];
$value .= ', ' . $geo[4] if $geo[4];
$value = $self->Decode($value, 'UTF8');
} else {
next; # (shouldn't happen)
}
Expand All @@ -2017,13 +2025,15 @@ my %systemTagsNotes = (
return '';
},
PrintConvInv => q{
return $val unless $val =~ /^([-+]?\d.*?[NS]?), ?([-+]?\d.*?[EW]?)$/ or
$val =~ /^\s*(-?\d+(?:\.\d+)?)\s*(-?\d+(?:\.\d+)?)\s*$/;
my ($lat, $lon) = ($1, $2);
require Image::ExifTool::GPS;
$lat = Image::ExifTool::GPS::ToDegrees($lat, 1, "lat");
$lon = Image::ExifTool::GPS::ToDegrees($lon, 1, "lon");
return "$lat, $lon";
my @args = split /\s*,\s*/, $val;
my $lat = 1;
foreach (@args) {
next unless /^[-+]?\d/;
require Image::ExifTool::GPS;
$_ = Image::ExifTool::GPS::ToDegrees($_, 1, $lat ? 'lat' : 'lon');
$lat ^= 1;
}
return join(',', @args);
},
},
GeolocationBearing => { %geoInfo,
Expand Down Expand Up @@ -4338,25 +4348,27 @@ sub DoneExtract($)
}
local $SIG{'__WARN__'} = \&SetWarning;
undef $evalWarning;
my $geo = Image::ExifTool::Geolocation::Geolocate($arg, $$opts{GeolocMinPop},
$$opts{GeolocMaxDist}, $$opts{Lang}, $$opts{Duplicates},
$$opts{GeolocFeature});
# ($$geo[0] will be an ARRAY ref if multiple matches were found and the Duplicates option is set)
if ($geo and (ref $$geo[0] or not $$geo[12] or not $self->Warn('Multiple Geolocation cities are possible',2))) {
my $geoList = ref $$geo[0] ? $geo : [ $geo ]; # make a list if not done alreaday
foreach $geo (@$geoList) {
$self->FoundTag(GeolocationCity => $$geo[0]);
$self->FoundTag(GeolocationRegion => $$geo[1]) if $$geo[1];
$self->FoundTag(GeolocationSubregion => $$geo[2]) if $$geo[2];
$self->FoundTag(GeolocationCountryCode => $$geo[3]);
$self->FoundTag(GeolocationCountry => $$geo[4]) if $$geo[4];
$self->FoundTag(GeolocationTimeZone => $$geo[5]) if $$geo[5];
$self->FoundTag(GeolocationFeatureCode => $$geo[6]);
$self->FoundTag(GeolocationPopulation => $$geo[7]);
$self->FoundTag(GeolocationPosition => "$$geo[8] $$geo[9]");
$self->FoundTag(GeolocationDistance => $$geo[10]) if defined $$geo[10];
$self->FoundTag(GeolocationBearing => $$geo[11]) if defined $$geo[11];
$self->FoundTag(GeolocationWarning => "Search matched $$geo[12] cities") if $$geo[12] and $geo eq $$geoList[0];
$$opts{GeolocMulti} = $$opts{Duplicates};
my ($n, $i, $km, $be) = Image::ExifTool::Geolocation::Geolocate($arg, $opts);
delete $$opts{GeolocMulti};
# ($i will be an ARRAY ref if multiple matches were found and the Duplicates option is set)
if ($n and (ref $i or $n < 2 or not $self->Warn('Multiple Geolocation cities are possible',2))) {
my $list = ref $i ? $i : [ $i ]; # make a list if not done alreaday
foreach $i (@$list) {
my @geo = Image::ExifTool::Geolocation::GetEntry($i, $$opts{Lang});
$self->FoundTag(GeolocationCity => $geo[0]);
$self->FoundTag(GeolocationRegion => $geo[1]) if $geo[1];
$self->FoundTag(GeolocationSubregion => $geo[2]) if $geo[2];
$self->FoundTag(GeolocationCountryCode => $geo[3]);
$self->FoundTag(GeolocationCountry => $geo[4]) if $geo[4];
$self->FoundTag(GeolocationTimeZone => $geo[5]) if $geo[5];
$self->FoundTag(GeolocationFeatureCode => $geo[6]);
$self->FoundTag(GeolocationPopulation => $geo[7]);
$self->FoundTag(GeolocationPosition => "$geo[8] $geo[9]");
next if $i != $$list[0];
$self->FoundTag(GeolocationDistance => $km) if defined $km;
$self->FoundTag(GeolocationBearing => $be) if defined $be;
$self->FoundTag(GeolocationWarning => "Search matched $n cities") if $n > 1;
}
} elsif ($evalWarning) {
$self->Warn(CleanWarning());
Expand Down Expand Up @@ -5040,13 +5052,15 @@ sub SetFoundTags($)
$allTag = 1;
} elsif ($tag =~ /[*?]/) {
# allow wildcards in tag names
$tag =~ tr/-_A-Za-z0-9*?//dc; # sterilize
$tag =~ s/\*/[-\\w]*/g;
$tag =~ s/\?/[-\\w]/g;
$tag .= '( \\(.*)?' if $doDups or $allGrp;
@matches = grep(/^$tag$/i, keys %$tagHash);
next unless @matches; # don't want entry in list for wildcard tags
$allTag = 1;
} elsif ($doDups or defined $group) {
$tag =~ tr/-_A-Za-z0-9//dc; # sterilize
# must also look for tags like "Tag (1)"
# (but be sure not to match temporary ValueConv entries like "Tag #")
@matches = grep(/^$tag( \(|$)/i, keys %$tagHash);
Expand Down
6 changes: 6 additions & 0 deletions bin/lib/Image/ExifTool.pod
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,12 @@ to use for the geolocation input. May also include regular expressions for
more flexible matching. See L<https://exiftool.org/geolocation.html> for
more details. Default is undef.

=item GeolocAltNames

Flag to search alternate Geolocation city names if available (ie. if
$Image::ExifTool::Geolocation::altDir has been set). Set to 0 to disable
use of the alternate names. Default is 1.

=item GeolocFeature

Comma-separated list of feature codes to include in city search, or exclude
Expand Down
4 changes: 2 additions & 2 deletions bin/lib/Image/ExifTool/CanonVRD.pm
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use vars qw($VERSION);
use Image::ExifTool qw(:DataAccess :Utils);
use Image::ExifTool::Canon;

$VERSION = '1.38';
$VERSION = '1.39';

sub ProcessCanonVRD($$;$);
sub WriteCanonVRD($$;$);
Expand Down Expand Up @@ -1758,7 +1758,7 @@ sub ProcessDR4($$;$)
} else {
# load DR4 file into memory
my $buff;
$raf->Read($buff, 8) == 8 and $buff eq "IIII\x04\0\x04\0" or return 0;
$raf->Read($buff, 8) == 8 and $buff =~ /^IIII[\x04|\x05]\0\x04\0/ or return 0;
$et->SetFileType();
$raf->Seek(0, 2) or return $err = 1;
$dirLen = $raf->Tell();
Expand Down
Loading

0 comments on commit 27befc8

Please sign in to comment.