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