exiftool_vendored 11.94.0 → 11.96.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of exiftool_vendored might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/bin/Changes +16 -2
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/exiftool +28 -3
- data/bin/lib/Image/ExifTool.pm +20 -15
- data/bin/lib/Image/ExifTool.pod +6 -5
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +3 -2
- data/bin/lib/Image/ExifTool/Geotag.pm +69 -21
- data/bin/lib/Image/ExifTool/MWG.pm +9 -1
- data/bin/lib/Image/ExifTool/QuickTime.pm +16 -7
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +15 -0
- data/bin/lib/Image/ExifTool/RIFF.pm +109 -1
- data/bin/lib/Image/ExifTool/TagLookup.pm +2 -0
- data/bin/lib/Image/ExifTool/TagNames.pod +3 -2
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +3 -0
- data/bin/lib/Image/ExifTool/Writer.pl +9 -3
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5a75cdf33b026b2b63463fbcb090685d29bbcbc336814074ab715d6c6218bea7
|
4
|
+
data.tar.gz: 0c75f45324460338a833b814fa05a6a9b6c9737380b5e0d47e0dfa00d9edfcbe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3e543aba5a56b22240e4f76d84665bf0c0912410062e70b503f157c87023c8db7f1386ea50ece249a38c8e903056f9bb6bfa45a17d266834d940cf485010350
|
7
|
+
data.tar.gz: 810e53957fbe2aecb16a80a9ae9364c8160bcbe68050bc0432399cefb92da1e3ad3b45ffd5919877614809ec1e007a16de539f7bb4c77171cc3cb3a919548e8f
|
data/bin/Changes
CHANGED
@@ -7,12 +7,26 @@ RSS feed: https://exiftool.org/rss.xml
|
|
7
7
|
Note: The most recent production release is Version 11.85. (Other versions are
|
8
8
|
considered development releases, and are not uploaded to CPAN.)
|
9
9
|
|
10
|
+
Apr. 24, 2020 - Version 11.96
|
11
|
+
|
12
|
+
- Decode streaming GPS from Lucas LK-7900 Ace AVI videos
|
13
|
+
- Changed new Exit/ExitDir function names to End/EndDir
|
14
|
+
- Fixed inconsistencies when using "-use mwg" together with the -wm option
|
15
|
+
|
16
|
+
Apr. 23, 2020 - Version 11.95
|
17
|
+
|
18
|
+
- Added Exit() and ExitDir() functions for use in -if conditions
|
19
|
+
- Enhanced -geotag feature to support a more flexible input CSV file format
|
20
|
+
- Enhanced -if and API Filter options to allow access to ExifTool object via
|
21
|
+
$self
|
22
|
+
- Fixed problem reading HEIC Exif with a missing header
|
23
|
+
|
10
24
|
Apr. 17, 2020 - Version 11.94
|
11
25
|
|
12
|
-
- Added
|
26
|
+
- Added support for QuickTime ItemList:GPSCoordinates
|
13
27
|
- Added additional Validate test for overlapping EXIF values
|
28
|
+
- Added a new Sony LensType (thanks Jos Roost)
|
14
29
|
- Added a new Nikon LensID
|
15
|
-
- Added support for QuickTime ItemList:GPSCoordinates
|
16
30
|
- Decode a few more Nikon tags (thanks Warren Hatch)
|
17
31
|
- Decode Pentax ShutterType
|
18
32
|
- Changed color of locked highlighted selection in -htmlDump output
|
data/bin/META.json
CHANGED
data/bin/META.yml
CHANGED
data/bin/README
CHANGED
@@ -105,8 +105,8 @@ your home directory, then you would type the following commands in a
|
|
105
105
|
terminal window to extract and run ExifTool:
|
106
106
|
|
107
107
|
cd ~/Desktop
|
108
|
-
gzip -dc Image-ExifTool-11.
|
109
|
-
cd Image-ExifTool-11.
|
108
|
+
gzip -dc Image-ExifTool-11.96.tar.gz | tar -xf -
|
109
|
+
cd Image-ExifTool-11.96
|
110
110
|
./exiftool t/images/ExifTool.jpg
|
111
111
|
|
112
112
|
Note: These commands extract meta information from one of the test images.
|
data/bin/exiftool
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
use strict;
|
11
11
|
require 5.004;
|
12
12
|
|
13
|
-
my $version = '11.
|
13
|
+
my $version = '11.96';
|
14
14
|
|
15
15
|
# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
|
16
16
|
my $exeDir;
|
@@ -289,6 +289,10 @@ my %altRecommends = (
|
|
289
289
|
|
290
290
|
my %unescapeChar = ( 't'=>"\t", 'n'=>"\n", 'r'=>"\r" );
|
291
291
|
|
292
|
+
# special subroutines used in -if condition
|
293
|
+
sub Image::ExifTool::EndDir() { return $$mt{EndDir} = 1 }
|
294
|
+
sub Image::ExifTool::End() { return $$mt{End} = 1 }
|
295
|
+
|
292
296
|
# exit routine
|
293
297
|
sub Exit {
|
294
298
|
if ($pause) {
|
@@ -1932,7 +1936,8 @@ sub GetImageInfo($$)
|
|
1932
1936
|
# set package so eval'd functions are in Image::ExifTool namespace
|
1933
1937
|
package Image::ExifTool;
|
1934
1938
|
|
1935
|
-
|
1939
|
+
my $self = $et;
|
1940
|
+
#### eval "-if" condition (%info, $self)
|
1936
1941
|
$result = eval $cond;
|
1937
1942
|
|
1938
1943
|
$@ and $evalWarning = $@;
|
@@ -3508,9 +3513,11 @@ sub ProcessFiles($;$)
|
|
3508
3513
|
push(@$list, $file);
|
3509
3514
|
} else {
|
3510
3515
|
GetImageInfo($et, $file);
|
3516
|
+
$$et{End} and Warn("End called - $file\n");
|
3511
3517
|
}
|
3512
3518
|
}
|
3513
3519
|
$et->Options(CharsetFileName => $enc) if $utf8FileName{$file};
|
3520
|
+
last if $$et{End};
|
3514
3521
|
}
|
3515
3522
|
}
|
3516
3523
|
|
@@ -3588,6 +3595,7 @@ sub ScanDir($$;$)
|
|
3588
3595
|
next if $file =~ /^\./ and ($recurse == 1 or $file eq '.' or $file eq '..');
|
3589
3596
|
next if $ignore{$file} or ($ignore{SYMLINKS} and -l $path);
|
3590
3597
|
ScanDir($et, $path, $list);
|
3598
|
+
last if $$et{End};
|
3591
3599
|
next;
|
3592
3600
|
}
|
3593
3601
|
# apply rules from -ext options
|
@@ -3626,6 +3634,15 @@ sub ScanDir($$;$)
|
|
3626
3634
|
push(@$list, $path);
|
3627
3635
|
} else {
|
3628
3636
|
GetImageInfo($et, $path);
|
3637
|
+
if ($$et{End}) {
|
3638
|
+
Warn("End called - $file\n");
|
3639
|
+
last;
|
3640
|
+
}
|
3641
|
+
if ($$et{EndDir}) {
|
3642
|
+
$dir =~ s(/$)();
|
3643
|
+
Warn("EndDir called - $path\n");
|
3644
|
+
last;
|
3645
|
+
}
|
3629
3646
|
}
|
3630
3647
|
}
|
3631
3648
|
++$countDir;
|
@@ -5210,7 +5227,7 @@ with this command:
|
|
5210
5227
|
|
5211
5228
|
produces output like this:
|
5212
5229
|
|
5213
|
-
-- Generated by ExifTool 11.
|
5230
|
+
-- Generated by ExifTool 11.96 --
|
5214
5231
|
File: a.jpg - 2003:10:31 15:44:19
|
5215
5232
|
(f/5.6, 1/60s, ISO 100)
|
5216
5233
|
File: b.jpg - 2006:05:23 11:57:38
|
@@ -5687,6 +5704,14 @@ processing pass is done at the level specified by the B<-fast> option. For
|
|
5687
5704
|
example, using B<-if4> is possible if I<EXPR> uses only pseudo System tags,
|
5688
5705
|
and may significantly speed processing if enough files fail the condition.
|
5689
5706
|
|
5707
|
+
The expression has access to the current ExifTool object through C<$self>,
|
5708
|
+
and the following special functions are available to allow short-circuiting
|
5709
|
+
of the file processing. Both functions have a return value of 1. Case is
|
5710
|
+
significant for function names.
|
5711
|
+
|
5712
|
+
End() - end processing after this file
|
5713
|
+
EndDir() - end processing of files in this directory
|
5714
|
+
|
5690
5715
|
Notes:
|
5691
5716
|
|
5692
5717
|
1) The B<-n> and B<-b> options also apply to tags used in I<EXPR>.
|
data/bin/lib/Image/ExifTool.pm
CHANGED
@@ -28,7 +28,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
28
28
|
%mimeType $swapBytes $swapWords $currentByteOrder %unpackStd
|
29
29
|
%jpegMarker %specialTags %fileTypeLookup $testLen $exePath);
|
30
30
|
|
31
|
-
$VERSION = '11.
|
31
|
+
$VERSION = '11.96';
|
32
32
|
$RELEASE = '';
|
33
33
|
@ISA = qw(Exporter);
|
34
34
|
%EXPORT_TAGS = (
|
@@ -91,7 +91,7 @@ sub GetExtended($$);
|
|
91
91
|
sub Set64u(@);
|
92
92
|
sub DecodeBits($$;$);
|
93
93
|
sub EncodeBits($$;$$);
|
94
|
-
sub Filter(
|
94
|
+
sub Filter($$@);
|
95
95
|
sub HexDump($;$%);
|
96
96
|
sub DumpTrailer($$);
|
97
97
|
sub DumpUnknownTrailer($$);
|
@@ -3198,7 +3198,7 @@ sub GetValue($$;$)
|
|
3198
3198
|
# $valueConv is undefined if there was no print conversion done
|
3199
3199
|
$valueConv = $value;
|
3200
3200
|
}
|
3201
|
-
Filter($$self{OPTIONS}{Filter}, \$value);
|
3201
|
+
$self->Filter($$self{OPTIONS}{Filter}, \$value);
|
3202
3202
|
# return Both values as a list (ValueConv, PrintConv)
|
3203
3203
|
return ($valueConv, $value);
|
3204
3204
|
}
|
@@ -3206,7 +3206,7 @@ sub GetValue($$;$)
|
|
3206
3206
|
DoEscape($value, $$self{ESCAPE_PROC}) if $$self{ESCAPE_PROC};
|
3207
3207
|
|
3208
3208
|
# filter if necessary
|
3209
|
-
Filter($$self{OPTIONS}{Filter}, \$value) if $$self{OPTIONS}{Filter} and $type eq 'PrintConv';
|
3209
|
+
$self->Filter($$self{OPTIONS}{Filter}, \$value) if $$self{OPTIONS}{Filter} and $type eq 'PrintConv';
|
3210
3210
|
|
3211
3211
|
if (ref $value eq 'ARRAY') {
|
3212
3212
|
if (defined $$self{OPTIONS}{ListItem}) {
|
@@ -5415,11 +5415,12 @@ sub GetDescriptions($$)
|
|
5415
5415
|
|
5416
5416
|
#------------------------------------------------------------------------------
|
5417
5417
|
# Apply filter to value(s) if necessary
|
5418
|
-
# Inputs: 0) filter expression,
|
5418
|
+
# Inputs: 0) ExifTool ref, 1) filter expression, 2-N) references to value(s) to filter
|
5419
5419
|
# Returns: nothing, but changes values if necessary
|
5420
|
-
sub Filter(
|
5420
|
+
sub Filter($$@)
|
5421
5421
|
{
|
5422
5422
|
local $_;
|
5423
|
+
my $self = shift;
|
5423
5424
|
my $filter = shift;
|
5424
5425
|
return unless defined $filter;
|
5425
5426
|
while (@_) {
|
@@ -5427,20 +5428,20 @@ sub Filter($@)
|
|
5427
5428
|
next unless defined $$valPt;
|
5428
5429
|
if (not ref $$valPt) {
|
5429
5430
|
$_ = $$valPt;
|
5430
|
-
#### eval Filter ($_)
|
5431
|
+
#### eval Filter ($_, $self)
|
5431
5432
|
eval $filter;
|
5432
5433
|
$$valPt = $_ if defined $_;
|
5433
5434
|
} elsif (ref $$valPt eq 'SCALAR') {
|
5434
5435
|
my $val = $$$valPt; # make a copy to avoid filtering twice
|
5435
|
-
Filter($filter, \$val);
|
5436
|
+
$self->Filter($filter, \$val);
|
5436
5437
|
$$valPt = \$val;
|
5437
5438
|
} elsif (ref $$valPt eq 'ARRAY') {
|
5438
5439
|
my @val = @{$$valPt}; # make a copy to avoid filtering twice
|
5439
|
-
Filter($filter, \$_) foreach @val;
|
5440
|
+
$self->Filter($filter, \$_) foreach @val;
|
5440
5441
|
$$valPt = \@val;
|
5441
5442
|
} elsif (ref $$valPt eq 'HASH') {
|
5442
5443
|
my %val = %{$$valPt}; # make a copy to avoid filtering twice
|
5443
|
-
Filter($filter, \$val{$_}) foreach keys %val;
|
5444
|
+
$self->Filter($filter, \$val{$_}) foreach keys %val;
|
5444
5445
|
$$valPt = \%val;
|
5445
5446
|
}
|
5446
5447
|
}
|
@@ -5644,7 +5645,7 @@ sub ConvertUnixTime($;$$)
|
|
5644
5645
|
|
5645
5646
|
#------------------------------------------------------------------------------
|
5646
5647
|
# Get Unix time from EXIF-formatted date/time string with optional timezone
|
5647
|
-
# Inputs: 0) EXIF date/time string, 1) non-zero if time is local
|
5648
|
+
# Inputs: 0) EXIF date/time string, 1) non-zero if time is local, or 2 to assume UTC
|
5648
5649
|
# Returns: Unix time (seconds since 0:00 GMT Jan 1, 1970) or undefined on error
|
5649
5650
|
sub GetUnixTime($;$)
|
5650
5651
|
{
|
@@ -5655,10 +5656,14 @@ sub GetUnixTime($;$)
|
|
5655
5656
|
my ($tzStr, $tzSec) = (pop(@tm), 0);
|
5656
5657
|
# use specified timezone offset (if given) instead of local system time
|
5657
5658
|
# if we are converting a local time value
|
5658
|
-
if ($isLocal
|
5659
|
-
|
5660
|
-
|
5661
|
-
|
5659
|
+
if ($isLocal) {
|
5660
|
+
if ($tzStr =~ /(?:Z|([-+])(\d+):(\d+))/i) {
|
5661
|
+
# use specified timezone if one exists
|
5662
|
+
$tzSec = ($2 * 60 + $3) * ($1 eq '-' ? -60 : 60) if $1;
|
5663
|
+
undef $isLocal; # convert using GMT corrected for specified timezone
|
5664
|
+
} elsif ($isLocal eq '2') {
|
5665
|
+
undef $isLocal;
|
5666
|
+
}
|
5662
5667
|
}
|
5663
5668
|
$tm[1] -= 1; # convert month
|
5664
5669
|
@tm = reverse @tm; # change to order required by timelocal()
|
data/bin/lib/Image/ExifTool.pod
CHANGED
@@ -652,16 +652,17 @@ based on the file's extension. Default is undef.
|
|
652
652
|
|
653
653
|
Perl expression used to filter values for all tags. The expression acts on
|
654
654
|
the value of the Perl default variable ($_), and changes the value of this
|
655
|
-
variable as required. The
|
656
|
-
|
657
|
-
|
655
|
+
variable as required. The current ExifTool object may be accessed through
|
656
|
+
$self. The value is not changed if $_ is set to undef. List items are
|
657
|
+
filtered individually. Applies to all returned values unless PrintConv
|
658
|
+
option is disabled.
|
658
659
|
|
659
660
|
=item FilterW
|
660
661
|
|
661
662
|
Perl expression used to filter PrintConv values when writing. The
|
662
663
|
expression acts on the value of the Perl default variable ($_), and changes
|
663
|
-
the value of this variable as required. The
|
664
|
-
set to undef.
|
664
|
+
the value of this variable as required. The current ExifTool object may be
|
665
|
+
accessed through $self. The value is not changed if $_ is set to undef.
|
665
666
|
|
666
667
|
=item FixBase
|
667
668
|
|
@@ -35,7 +35,7 @@ use Image::ExifTool::Sony;
|
|
35
35
|
use Image::ExifTool::Validate;
|
36
36
|
use Image::ExifTool::MacOS;
|
37
37
|
|
38
|
-
$VERSION = '3.
|
38
|
+
$VERSION = '3.35';
|
39
39
|
@ISA = qw(Exporter);
|
40
40
|
|
41
41
|
sub NumbersFirst($$);
|
@@ -1474,7 +1474,8 @@ TagID: foreach $tagID (@keys) {
|
|
1474
1474
|
my $tag;
|
1475
1475
|
foreach $tag (sort keys %$struct) {
|
1476
1476
|
my $tagInfo = $$struct{$tag};
|
1477
|
-
next unless ref $tagInfo eq 'HASH' and $tag ne 'NAMESPACE';
|
1477
|
+
next unless ref $tagInfo eq 'HASH' and $tag ne 'NAMESPACE' and $tag ne 'GROUPS';
|
1478
|
+
warn "WARNING: $strName Struct containes $tag\n" if $Image::ExifTool::specialTags{$tag};
|
1478
1479
|
my $writable = $$tagInfo{Writable};
|
1479
1480
|
my @vals;
|
1480
1481
|
unless ($writable) {
|
@@ -25,8 +25,9 @@ package Image::ExifTool::Geotag;
|
|
25
25
|
use strict;
|
26
26
|
use vars qw($VERSION);
|
27
27
|
use Image::ExifTool qw(:Public);
|
28
|
+
use Image::ExifTool::GPS;
|
28
29
|
|
29
|
-
$VERSION = '1.
|
30
|
+
$VERSION = '1.62';
|
30
31
|
|
31
32
|
sub JITTER() { return 2 } # maximum time jitter
|
32
33
|
|
@@ -229,9 +230,41 @@ sub LoadTrackLog($$;$)
|
|
229
230
|
$format = 'Winplus';
|
230
231
|
} elsif (/^\s*\d+\s+.*\sypr\s*$/ and (@tmp=split) == 12) {
|
231
232
|
$format = 'Bramor';
|
232
|
-
} elsif (/\
|
233
|
+
} elsif (/\b(GPS)?Date/i and /\b(GPS)?(Date)?Time/i and /,/) {
|
234
|
+
chomp;
|
233
235
|
@csvHeadings = split ',';
|
234
236
|
$format = 'CSV';
|
237
|
+
# convert recognized headings to our parameter names
|
238
|
+
foreach (@csvHeadings) {
|
239
|
+
my $param;
|
240
|
+
s/^GPS ?//; # remove leading "GPS" to simplify regex patterns
|
241
|
+
if (/^Date ?Time/i) { # ExifTool addition
|
242
|
+
$param = 'datetime';
|
243
|
+
} elsif (/^Date/i) {
|
244
|
+
$param = 'date';
|
245
|
+
} elsif (/^Time/i) {
|
246
|
+
$param = 'time';
|
247
|
+
} elsif (/^(Pos)?Lat/i) {
|
248
|
+
$param = 'lat';
|
249
|
+
} elsif (/^(Pos)?Lon/i) {
|
250
|
+
$param = 'lon';
|
251
|
+
} elsif (/^(Pos)?Alt/i) {
|
252
|
+
$param = 'alt';
|
253
|
+
} elsif (/^(Angle)?(Heading|Track)/i) {
|
254
|
+
$param = 'track';
|
255
|
+
} elsif (/^(Angle)?Pitch/i or /^Camera ?Elevation ?Angle/i) {
|
256
|
+
$param = 'pitch';
|
257
|
+
} elsif (/^(Angle)?Roll/i) {
|
258
|
+
$param = 'roll';
|
259
|
+
}
|
260
|
+
if ($param) {
|
261
|
+
$et->VPrint(2, "CSV column '${_}' is $param\n");
|
262
|
+
$_ = $param;
|
263
|
+
} else {
|
264
|
+
$et->VPrint(2, "CSV column '${_}' ignored\n");
|
265
|
+
$_ = ''; # ignore this column
|
266
|
+
}
|
267
|
+
}
|
235
268
|
next;
|
236
269
|
} else {
|
237
270
|
# search only first 50 lines of file for a valid fix
|
@@ -388,35 +421,50 @@ DoneFix: $isDate = 1;
|
|
388
421
|
# set necessary flags for extra available information
|
389
422
|
@$has{qw(alt track orient)} = (1,1,1);
|
390
423
|
goto DoneFix; # save this fix
|
424
|
+
} elsif ($format eq 'CSV') {
|
425
|
+
chomp;
|
426
|
+
my @vals = split ',';
|
391
427
|
#
|
392
428
|
# CSV format output of GPS/IMU POS system
|
429
|
+
# Date* - date in DD/MM/YYYY format
|
430
|
+
# Time* - time in HH:MM:SS.SSS format
|
431
|
+
# [Pos]Lat* - latitude in decimal degrees
|
432
|
+
# [Pos]Lon* - longitude in decimal degrees
|
433
|
+
# [Pos]Alt* - altitude in m relative to sea level
|
434
|
+
# [Angle]Heading* - GPSTrack in degrees true
|
435
|
+
# [Angle]Pitch* - pitch angle in degrees
|
436
|
+
# [Angle]Roll* - roll angle in degrees
|
437
|
+
# (ExifTool enhancements allow for standard tag names or descriptions as the column headings,
|
438
|
+
# add support for time zones and flexible coordinates, and allow a new DateTime column)
|
393
439
|
#
|
394
|
-
|
395
|
-
|
396
|
-
my ($label, $date, $secs);
|
397
|
-
foreach $label (@csvHeadings) {
|
440
|
+
my ($param, $date, $secs);
|
441
|
+
foreach $param (@csvHeadings) {
|
398
442
|
my $val = shift @vals;
|
399
443
|
last unless defined $val;
|
400
|
-
|
444
|
+
next unless $param;
|
445
|
+
if ($param eq 'datetime') {
|
446
|
+
local $SIG{'__WARN__'} = sub { };
|
447
|
+
my $dateTime = $et->InverseDateTime($val);
|
448
|
+
if ($dateTime) {
|
449
|
+
$date = Image::ExifTool::GetUnixTime($val, 2);
|
450
|
+
$secs = 0;
|
451
|
+
}
|
452
|
+
} elsif ($param eq 'date') {
|
401
453
|
if ($val =~ m{^(\d{2})/(\d{2})/(\d{4})$}) {
|
402
454
|
$date = Time::Local::timegm(0,0,0,$1,$2-1,$3);
|
455
|
+
} elsif ($val =~ /(\d{4}).*?(\d{2}).*?(\d{2})/) {
|
456
|
+
$date = Time::Local::timegm(0,0,0,$3,$2-1,$1);
|
403
457
|
}
|
404
|
-
} elsif ($
|
405
|
-
if ($val =~ /^(\d{1,2}):(\d{2}):(\d{2}(\.\d+)?)
|
458
|
+
} elsif ($param eq 'time') {
|
459
|
+
if ($val =~ /^(\d{1,2}):(\d{2}):(\d{2}(\.\d+)?).*?(([-+])(\d{1,2}):?(\d{2}))?/) {
|
406
460
|
$secs = (($1 * 60) + $2) * 60 + $3;
|
461
|
+
# adjust for time zone if specified
|
462
|
+
$secs += ($7 * 60 + $8) * ($6 eq '-' ? 60 : -60) if $5;
|
407
463
|
}
|
408
|
-
} elsif ($
|
409
|
-
$$fix{
|
410
|
-
}
|
411
|
-
$$fix{
|
412
|
-
} elsif ($label =~ /^(Pos)?Alt/) {
|
413
|
-
$$fix{alt} = $val;
|
414
|
-
} elsif ($label =~ /^(Angle)?Heading/) {
|
415
|
-
$$fix{track} = $val;
|
416
|
-
} elsif ($label =~ /^(Angle)?Pitch/) {
|
417
|
-
$$fix{pitch} = $val;
|
418
|
-
} elsif ($label =~ /^(Angle)?Roll/) {
|
419
|
-
$$fix{roll} = $val;
|
464
|
+
} elsif ($param eq 'lat' or $param eq 'lon') {
|
465
|
+
$$fix{$param} = Image::ExifTool::GPS::ToDegrees($val, 1);
|
466
|
+
} else {
|
467
|
+
$$fix{$param} = $val;
|
420
468
|
}
|
421
469
|
}
|
422
470
|
if ($date and defined $secs and defined $$fix{lat} and defined $$fix{lon}) {
|
@@ -16,7 +16,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
16
16
|
use Image::ExifTool::Exif;
|
17
17
|
use Image::ExifTool::XMP;
|
18
18
|
|
19
|
-
$VERSION = '1.
|
19
|
+
$VERSION = '1.24';
|
20
20
|
|
21
21
|
sub RecoverTruncatedIPTC($$$);
|
22
22
|
sub ListToString($);
|
@@ -629,6 +629,14 @@ sub OverwriteStringList($$$$)
|
|
629
629
|
local $_;
|
630
630
|
my ($et, $nvHash, $val, $newValuePt) = @_;
|
631
631
|
my (@new, $delIndex);
|
632
|
+
my $writeMode = $et->Options('WriteMode');
|
633
|
+
if ($writeMode ne 'wcg') {
|
634
|
+
if (defined $val) {
|
635
|
+
$writeMode =~ /w/i or return 0;
|
636
|
+
} else {
|
637
|
+
$writeMode =~ /c/i or return 0;
|
638
|
+
}
|
639
|
+
}
|
632
640
|
if ($$nvHash{DelValue} and defined $val) {
|
633
641
|
# preserve specified old values
|
634
642
|
my $old = StringToList($val, $et);
|
@@ -46,7 +46,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
46
46
|
use Image::ExifTool::Exif;
|
47
47
|
use Image::ExifTool::GPS;
|
48
48
|
|
49
|
-
$VERSION = '2.
|
49
|
+
$VERSION = '2.47';
|
50
50
|
|
51
51
|
sub ProcessMOV($$;$);
|
52
52
|
sub ProcessKeys($$$);
|
@@ -8229,13 +8229,22 @@ sub HandleItemInfo($)
|
|
8229
8229
|
my ($start, $subTable, $proc);
|
8230
8230
|
my $pos = $$item{Extents}[0][1] + $base;
|
8231
8231
|
if ($name eq 'EXIF' and length $buff >= 4) {
|
8232
|
-
|
8233
|
-
|
8234
|
-
|
8235
|
-
|
8236
|
-
$
|
8237
|
-
$
|
8232
|
+
if ($buff =~ /^(MM\0\x2a|II\x2a\0)/) {
|
8233
|
+
$et->Warn('Missing Exif header');
|
8234
|
+
$start = 0;
|
8235
|
+
} else {
|
8236
|
+
my $n = unpack('N', $buff);
|
8237
|
+
$start = 4 + $n; # skip "Exif\0\0" header if it exists
|
8238
|
+
if ($start > length($buff)) {
|
8239
|
+
$et->Warn('Invalid EXIF header');
|
8240
|
+
next;
|
8241
|
+
}
|
8242
|
+
if ($$et{HTML_DUMP}) {
|
8243
|
+
$et->HDump($pos, 4, 'Exif header length', "Value: $n");
|
8244
|
+
$et->HDump($pos+4, $start-4, 'Exif header') if $n;
|
8245
|
+
}
|
8238
8246
|
}
|
8247
|
+
$subTable = GetTagTable('Image::ExifTool::Exif::Main');
|
8239
8248
|
$proc = \&Image::ExifTool::ProcessTIFF;
|
8240
8249
|
} else {
|
8241
8250
|
$start = 0;
|
@@ -133,6 +133,21 @@ my %insvLimit = (
|
|
133
133
|
SampleTime => { Groups => { 2 => 'Video' }, PrintConv => 'ConvertDuration($val)', Notes => 'sample decoding time' },
|
134
134
|
SampleDuration=>{ Groups => { 2 => 'Video' }, PrintConv => 'ConvertDuration($val)' },
|
135
135
|
UserLabel => { Groups => { 2 => 'Other' } },
|
136
|
+
SampleDateTime => {
|
137
|
+
Groups => { 2 => 'Time' },
|
138
|
+
ValueConv => q{
|
139
|
+
my $str = ConvertUnixTime($val);
|
140
|
+
my $frac = $val - int($val);
|
141
|
+
if ($frac != 0) {
|
142
|
+
$frac = sprintf('%.6f', $frac);
|
143
|
+
$frac =~ s/^0//;
|
144
|
+
$frac =~ s/0+$//;
|
145
|
+
$str .= $frac;
|
146
|
+
}
|
147
|
+
return $str;
|
148
|
+
},
|
149
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
150
|
+
},
|
136
151
|
#
|
137
152
|
# timed metadata decoded based on MetaFormat (format of 'meta' or 'data' sample description)
|
138
153
|
# [or HandlerType, or specific 'vide' type if specified]
|
@@ -29,11 +29,12 @@ use strict;
|
|
29
29
|
use vars qw($VERSION);
|
30
30
|
use Image::ExifTool qw(:DataAccess :Utils);
|
31
31
|
|
32
|
-
$VERSION = '1.
|
32
|
+
$VERSION = '1.55';
|
33
33
|
|
34
34
|
sub ConvertTimecode($);
|
35
35
|
sub ProcessSGLT($$$);
|
36
36
|
sub ProcessSLLT($$$);
|
37
|
+
sub ProcessLucas($$$);
|
37
38
|
|
38
39
|
# recognized RIFF variants
|
39
40
|
my %riffType = (
|
@@ -433,6 +434,14 @@ my %code2charset = (
|
|
433
434
|
Condition => '$$valPt =~ /^PENTDigital Camera/',
|
434
435
|
SubDirectory => { TagTable => 'Image::ExifTool::Pentax::Junk2' },
|
435
436
|
},
|
437
|
+
{
|
438
|
+
Name => 'LucasJunk', # (Lucas LK-7900 Ace)
|
439
|
+
Condition => '$$valPt =~ /^0G(DA|PS)/',
|
440
|
+
SubDirectory => {
|
441
|
+
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
442
|
+
ProcessProc => \&ProcessLucas,
|
443
|
+
},
|
444
|
+
},
|
436
445
|
{
|
437
446
|
Name => 'TextJunk',
|
438
447
|
# try to interpret unknown junk as an ASCII string
|
@@ -1621,6 +1630,105 @@ sub ProcessSLLT($$$)
|
|
1621
1630
|
return 1;
|
1622
1631
|
}
|
1623
1632
|
|
1633
|
+
#------------------------------------------------------------------------------
|
1634
|
+
# Process Lucas streaming GPS information (Lucas LK-7900 Ace) (ref PH)
|
1635
|
+
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
|
1636
|
+
# Returns: 1 on success
|
1637
|
+
sub ProcessLucas($$$)
|
1638
|
+
{
|
1639
|
+
my ($et, $dirInfo, $tagTbl) = @_;
|
1640
|
+
my $dataPt = $$dirInfo{DataPt};
|
1641
|
+
my $dataLen = length $$dataPt;
|
1642
|
+
|
1643
|
+
unless ($et->Options('ExtractEmbedded')) {
|
1644
|
+
$et->Warn('Use ExtractEmbedded option to extract timed GPS', 3);
|
1645
|
+
return 1;
|
1646
|
+
}
|
1647
|
+
my %recLen = ( # record lengths (not including 4-byte ID)
|
1648
|
+
'0GDA' => 24,
|
1649
|
+
'0GPS' => 48,
|
1650
|
+
);
|
1651
|
+
my ($date,$time,$lat,$lon,$alt,$spd,$sat,$dop,$ew,$ns);
|
1652
|
+
$$et{SET_GROUP0} = $$et{SET_GROUP1} = 'RIFF';
|
1653
|
+
while ($$dataPt =~ /(0GDA|0GPS)/g) {
|
1654
|
+
my ($rec, $pos) = ($1, pos $$dataPt);
|
1655
|
+
$pos + $recLen{$rec} > $dataLen and $et->Warn("Truncated $1 record"), last;
|
1656
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
1657
|
+
# records start with int64u sample date/time in ms since 1970
|
1658
|
+
$et->HandleTag($tagTbl, SampleDateTime => Get64u($dataPt, $pos) / 1000);
|
1659
|
+
if ($rec eq '0GPS') {
|
1660
|
+
my $len = Get32u($dataPt, $pos+8);
|
1661
|
+
my $endPos = $pos + $recLen{$rec} + $len;
|
1662
|
+
$endPos > $dataLen and $et->Warn('Truncated 0GPS record'), last;
|
1663
|
+
my $buff = substr($$dataPt, $pos+$recLen{$rec}, $len);
|
1664
|
+
while ($buff =~ /\$(GC|GA),(\d+),/g) {
|
1665
|
+
my $p = pos $buff;
|
1666
|
+
$time = $2;
|
1667
|
+
if ($1 eq 'GC') {
|
1668
|
+
# time date dist ? sat dop alt A
|
1669
|
+
# $GC,052350,180914,0000955,1,08,1.1,0017,,A*45\x0d\x0a\0
|
1670
|
+
if ($buff =~ /\G(\d+),\d*,\d*,(\d+),([-\d.]+),(\d+),\d*,A/g) {
|
1671
|
+
($date,$sat,$dop,$alt) = ($1,$2,$3,$4);
|
1672
|
+
}
|
1673
|
+
} else {
|
1674
|
+
# time A lat lon spd N W
|
1675
|
+
# $GA,052351,A,0949.6626,07635.4439,049,N,E,*4C\x0d\x0a\0
|
1676
|
+
if ($buff =~ /\GA,([\d.]+),([\d.]+),(\d+),([NS]),([EW])/g) {
|
1677
|
+
($lat,$lon,$spd,$ns,$ew) = ($1,$2,$3,$4,$5,$6);
|
1678
|
+
# lat/long are in DDDMM.MMMM format
|
1679
|
+
my $deg = int($lat / 100);
|
1680
|
+
$lat = $deg + ($lat - $deg * 100) / 60;
|
1681
|
+
$deg = int($lon / 100);
|
1682
|
+
$lon = $deg + ($lon - $deg * 100) / 60;
|
1683
|
+
$lat *= -1 if $ns eq 'S';
|
1684
|
+
$lon *= -1 if $ew eq 'W';
|
1685
|
+
}
|
1686
|
+
}
|
1687
|
+
# look ahead to next NMEA-like sentence, and store the fix
|
1688
|
+
# now only if the next sentence is not at the same time
|
1689
|
+
if ($buff !~ /\$(GC|GA),$time,/g) {
|
1690
|
+
pos($$dataPt) = $endPos;
|
1691
|
+
if ($$dataPt !~ /\$(GC|GA),(\d+)/ or $1 ne $time) {
|
1692
|
+
$time =~ s/(\d{2})(\d{2})(\d{2})/$1:$2:$3Z/;
|
1693
|
+
if ($date) {
|
1694
|
+
$date =~ s/(\d{2})(\d{2})(\d{2})/20$3:$2:$1/;
|
1695
|
+
$et->HandleTag($tagTbl, GPSDateTime => "$date $time");
|
1696
|
+
} else {
|
1697
|
+
$et->HandleTag($tagTbl, GPSTimeStamp => $time);
|
1698
|
+
}
|
1699
|
+
if (defined $lat) {
|
1700
|
+
$et->HandleTag($tagTbl, GPSLatitude => $lat);
|
1701
|
+
$et->HandleTag($tagTbl, GPSLongitude => $lon);
|
1702
|
+
$et->HandleTag($tagTbl, GPSSpeed => $spd);
|
1703
|
+
}
|
1704
|
+
if (defined $alt) {
|
1705
|
+
$et->HandleTag($tagTbl, GPSAltitude => $alt);
|
1706
|
+
$et->HandleTag($tagTbl, GPSSatellites => $sat);
|
1707
|
+
$et->HandleTag($tagTbl, GPSDOP => $dop);
|
1708
|
+
}
|
1709
|
+
undef $lat;
|
1710
|
+
undef $alt;
|
1711
|
+
}
|
1712
|
+
}
|
1713
|
+
pos($buff) = $p;
|
1714
|
+
}
|
1715
|
+
$pos += $len;
|
1716
|
+
} else { # this is an accelerometer (0GDA) record
|
1717
|
+
# record has 4 more int32s values (the last is always 57 or 58 --
|
1718
|
+
# maybe related to sample time in ms? -- not extracted)
|
1719
|
+
my @acc = unpack('x'.($pos+8).'V3', $$dataPt);
|
1720
|
+
# change to signed integer and divide by 256
|
1721
|
+
map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
|
1722
|
+
$et->HandleTag($tagTbl, Accelerometer => "@acc");
|
1723
|
+
}
|
1724
|
+
pos($$dataPt) = $pos + $recLen{$rec};
|
1725
|
+
}
|
1726
|
+
delete $$et{SET_GROUP0};
|
1727
|
+
delete $$et{SET_GROUP1};
|
1728
|
+
$$et{DOC_NUM} = 0;
|
1729
|
+
return 1;
|
1730
|
+
}
|
1731
|
+
|
1624
1732
|
#------------------------------------------------------------------------------
|
1625
1733
|
# Extract information from a RIFF file
|
1626
1734
|
# Inputs: 0) ExifTool object reference, 1) DirInfo reference
|
@@ -8711,6 +8711,7 @@ my %tagExists = (
|
|
8711
8711
|
'lotus' => 1,
|
8712
8712
|
'lr' => 1,
|
8713
8713
|
'lslv' => 1,
|
8714
|
+
'lucasjunk' => 1,
|
8714
8715
|
'luminance' => 1,
|
8715
8716
|
'luminanceconsts' => 1,
|
8716
8717
|
'lyricist' => 1,
|
@@ -9965,6 +9966,7 @@ my %tagExists = (
|
|
9965
9966
|
'rvmi_srev' => 1,
|
9966
9967
|
's2n' => 1,
|
9967
9968
|
'sampleblacksequence' => 1,
|
9969
|
+
'sampledatetime' => 1,
|
9968
9970
|
'sampledegradationpriority' => 1,
|
9969
9971
|
'sampleduration' => 1,
|
9970
9972
|
'sampleflag' => 1,
|
@@ -12,7 +12,7 @@ meta information extracted from or written to a file.
|
|
12
12
|
=head1 TAG TABLES
|
13
13
|
|
14
14
|
The tables listed below give the names of all tags recognized by ExifTool.
|
15
|
-
They contain a total of
|
15
|
+
They contain a total of 23364 tags, with 15306 unique tag names.
|
16
16
|
|
17
17
|
B<Tag ID>, B<Index#> or B<Sequence> is given in the first column of each
|
18
18
|
table. A B<Tag ID> is the computer-readable equivalent of a tag name, and
|
@@ -3643,7 +3643,6 @@ is to write ImageRegion as a structure with these tags as new fields.
|
|
3643
3643
|
GPSAltitude rational
|
3644
3644
|
GPSLatitude string
|
3645
3645
|
GPSLongitude string
|
3646
|
-
GROUPS string
|
3647
3646
|
Identifier string+
|
3648
3647
|
LocationId string+
|
3649
3648
|
LocationName lang-alt
|
@@ -25098,6 +25097,7 @@ formats of timed GPS metadata from video files.
|
|
25098
25097
|
RVMI_gReV QuickTime RVMI_gReV
|
25099
25098
|
RVMI_sReV QuickTime RVMI_sReV
|
25100
25099
|
RawGSensor no
|
25100
|
+
SampleDateTime no
|
25101
25101
|
SampleDuration no
|
25102
25102
|
SampleTime no
|
25103
25103
|
Text no
|
@@ -28947,6 +28947,7 @@ sub-documents, but the Duration is calculated for the full video.
|
|
28947
28947
|
RicohJunk Ricoh AVI
|
28948
28948
|
PentaxJunk Pentax Junk
|
28949
28949
|
PentaxJunk2 Pentax Junk2
|
28950
|
+
LucasJunk QuickTime Stream
|
28950
28951
|
TextJunk no
|
28951
28952
|
'JUNQ' OldXMP no
|
28952
28953
|
'LIST_INF0' Info RIFF Info
|
@@ -499,6 +499,9 @@ sub WriteItemInfo($$$)
|
|
499
499
|
if (not length $buff) {
|
500
500
|
# create EXIF from scratch
|
501
501
|
$hdr = "\0\0\0\x06Exif\0\0";
|
502
|
+
} elsif ($buff =~ /^(MM\0\x2a|II\x2a\0)/) {
|
503
|
+
$et->Warn('Missing Exif header');
|
504
|
+
$hdr = '';
|
502
505
|
} elsif (length($buff) >= 4 and length($buff) >= 4 + unpack('N',$buff)) {
|
503
506
|
$hdr = substr($buff, 0, 4 + unpack('N',$buff));
|
504
507
|
} else {
|
@@ -359,7 +359,7 @@ 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) if $convType eq 'PrintConv';
|
363
363
|
|
364
364
|
my (@wantGroup, $family2);
|
365
365
|
my $wantGroup = $options{Group};
|
@@ -2967,9 +2967,13 @@ sub InsertTagValues($$$;$$$)
|
|
2967
2967
|
my (@tags, $val, $tg, @val, $type, $expr, $didExpr, $level, $asList);
|
2968
2968
|
# "$$" represents a "$" symbol, and "$/" is a newline
|
2969
2969
|
if ($var eq '$' or $var eq '/') {
|
2970
|
-
$var = "\n" if $var eq '/';
|
2971
|
-
$rtnStr .= "$pre$var";
|
2972
2970
|
$line =~ s/^\s*\}// if $bra;
|
2971
|
+
if ($var eq '/') {
|
2972
|
+
$var = "\n";
|
2973
|
+
} elsif ($line =~ /^self\b/ and not $rtnStr =~ /\$$/) {
|
2974
|
+
$var = '$$'; # ("$$self{var}" in string)
|
2975
|
+
}
|
2976
|
+
$rtnStr .= "$pre$var";
|
2973
2977
|
next;
|
2974
2978
|
}
|
2975
2979
|
# allow multiple group names
|
@@ -3074,6 +3078,8 @@ sub InsertTagValues($$$;$$$)
|
|
3074
3078
|
last unless $tag =~ / /; # all done if we got our best match
|
3075
3079
|
}
|
3076
3080
|
}
|
3081
|
+
} elsif ($tag eq 'self') {
|
3082
|
+
$val = $self; # ("$self{var}" or "$self->{var}" in string)
|
3077
3083
|
} else {
|
3078
3084
|
# get the tag value
|
3079
3085
|
$val = $self->GetValue($tag, $type);
|
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: 11.
|
4
|
+
version: 11.96.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: 2020-04-
|
12
|
+
date: 2020-04-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: exiftool
|
@@ -450,8 +450,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
450
450
|
- !ruby/object:Gem::Version
|
451
451
|
version: '0'
|
452
452
|
requirements: []
|
453
|
-
|
454
|
-
rubygems_version: 2.6.11
|
453
|
+
rubygems_version: 3.1.2
|
455
454
|
signing_key:
|
456
455
|
specification_version: 4
|
457
456
|
summary: Vendored version of exiftool
|