exiftool_vendored 13.26.0 → 13.29.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.
- checksums.yaml +4 -4
- data/bin/Changes +40 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/arg_files/exif2xmp.args +2 -1
- data/bin/arg_files/xmp2exif.args +2 -1
- data/bin/exiftool +16 -14
- data/bin/lib/Image/ExifTool/Canon.pm +2 -2
- data/bin/lib/Image/ExifTool/GIMP.pm +1 -1
- data/bin/lib/Image/ExifTool/JPEG.pm +20 -8
- data/bin/lib/Image/ExifTool/LigoGPS.pm +16 -2
- data/bin/lib/Image/ExifTool/MPF.pm +5 -1
- data/bin/lib/Image/ExifTool/Olympus.pm +1 -1
- data/bin/lib/Image/ExifTool/Panasonic.pm +9 -1
- data/bin/lib/Image/ExifTool/Parrot.pm +54 -7
- data/bin/lib/Image/ExifTool/Pentax.pm +101 -1
- data/bin/lib/Image/ExifTool/Plot.pm +36 -15
- data/bin/lib/Image/ExifTool/QuickTime.pm +53 -5
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +70 -14
- data/bin/lib/Image/ExifTool/README +12 -2
- data/bin/lib/Image/ExifTool/Sony.pm +5 -0
- data/bin/lib/Image/ExifTool/TagLookup.pm +12 -2
- data/bin/lib/Image/ExifTool/TagNames.pod +131 -86
- data/bin/lib/Image/ExifTool/WriteExif.pl +2 -0
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +3 -0
- data/bin/lib/Image/ExifTool/Writer.pl +17 -6
- data/bin/lib/Image/ExifTool/XMP.pm +2 -2
- data/bin/lib/Image/ExifTool.pm +7 -3
- data/bin/lib/Image/ExifTool.pod +11 -11
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
@@ -11,7 +11,7 @@ package Image::ExifTool::Plot;
|
|
11
11
|
use strict;
|
12
12
|
use vars qw($VERSION);
|
13
13
|
|
14
|
-
$VERSION = '1.
|
14
|
+
$VERSION = '1.03';
|
15
15
|
|
16
16
|
# default plot settings (lower-case settings may be overridden by the user)
|
17
17
|
my %defaults = (
|
@@ -262,23 +262,35 @@ sub Draw($$)
|
|
262
262
|
{
|
263
263
|
my ($self, $fp) = @_;
|
264
264
|
my ($min, $max, $xmin, $xmax, $name, $style) = @$self{qw(Min Max XMin XMax Name style)};
|
265
|
+
my ($plotNum, $multiMulti);
|
265
266
|
|
266
267
|
if (not defined $min or not defined $xmin) {
|
267
268
|
$$self{Error} = 'Nothing to plot';
|
268
269
|
return;
|
269
270
|
}
|
270
|
-
my ($i, $n, %col, %class, $dx, $dy, $dx2, $xAxis, $x, $y, $px, $py, @og);
|
271
|
-
my ($noLegend, $xname, $xdat, $xdiff, $diff, %markID, $plotNum);
|
272
271
|
my $scat = $$self{type} =~ /^s/ ? 1 : 0;
|
273
272
|
my $hist = $$self{type} =~ /^h/ ? [ ] : 0;
|
274
|
-
my $multi =
|
273
|
+
my $multi = $$self{multi} || 0;
|
274
|
+
my @multi = $multi =~ /\d+/g;
|
275
|
+
my @names = @$name;
|
276
|
+
shift @names if $scat;
|
277
|
+
$multi = shift @multi;
|
275
278
|
$multi = 0 unless $multi > 0;
|
276
279
|
$style or $style = $hist ? 'line+fill' : 'line';
|
277
280
|
unless ($style =~ /\b[mpl]/ or ($hist and $style =~ /\bf/)) {
|
278
281
|
$$self{Error} = 'Invalid plot Style setting';
|
279
282
|
return;
|
280
283
|
}
|
281
|
-
my $numPlots =
|
284
|
+
my $numPlots = 0;
|
285
|
+
if ($multi) {
|
286
|
+
my $n;
|
287
|
+
for ($n=0; $n<scalar(@$name)-$scat; ++$numPlots) {
|
288
|
+
$n += ($multi[$numPlots] || 1);
|
289
|
+
$multiMulti = 1 if $multi[$numPlots] and $multi[$numPlots] > 1;
|
290
|
+
}
|
291
|
+
} else {
|
292
|
+
$numPlots = 1;
|
293
|
+
}
|
282
294
|
my @size = @{$$self{size}};
|
283
295
|
my $sy = $size[1];
|
284
296
|
if ($multi) {
|
@@ -293,6 +305,8 @@ sub Draw($$)
|
|
293
305
|
<title>$tmp</title>};
|
294
306
|
# loop through all plots
|
295
307
|
for ($plotNum=0; $plotNum<$numPlots; ++$plotNum) {
|
308
|
+
my ($i, $n, %col, %class, $dx, $dy, $dx2, $xAxis, $x, $y, $px, $py, @og);
|
309
|
+
my ($noLegend, $xname, $xdat, $xdiff, $diff, %markID);
|
296
310
|
if ($numPlots > 1) {
|
297
311
|
print $fp "\n<g transform='translate(", ($plotNum % $multi) * $size[0],
|
298
312
|
',', int($plotNum/$multi) * $size[1], ")'>";
|
@@ -304,14 +318,19 @@ sub Draw($$)
|
|
304
318
|
}
|
305
319
|
$name = $$self{Name} = [ ];
|
306
320
|
push @{$$self{Name}}, $$self{SaveName}[0] if $scat;
|
307
|
-
|
308
|
-
|
321
|
+
foreach (0 .. (($multi[$plotNum] || 1) - 1)) {
|
322
|
+
push @{$$self{Name}}, shift(@names);
|
323
|
+
}
|
324
|
+
warn "@{$$self{Name}}\n";
|
309
325
|
undef $min; undef $max;
|
310
|
-
foreach (
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
326
|
+
foreach ($scat .. (@{$$self{Name}} - 1)) {
|
327
|
+
my $dat = $$self{Data}{$$self{Name}[$_]};
|
328
|
+
foreach (@$dat) {
|
329
|
+
defined or next;
|
330
|
+
defined $min or $min = $max = $_, next;
|
331
|
+
$min > $_ and $min = $_;
|
332
|
+
$max < $_ and $max = $_;
|
333
|
+
}
|
315
334
|
}
|
316
335
|
}
|
317
336
|
my ($data, $title, $xlabel, $ylabel, $cols, $marks, $tpad, $wid) =
|
@@ -321,12 +340,12 @@ sub Draw($$)
|
|
321
340
|
|
322
341
|
# set reasonable default titles and labels
|
323
342
|
$xname = shift @name if $scat;
|
324
|
-
$title = "$name[0] vs $xname" if $scat and defined $title and not $title and @name == 1;
|
343
|
+
$title = "$name[0] vs $xname" if $scat and defined $title and not $title and @name == 1 and not $multi;
|
325
344
|
if ($scat || $hist and defined $xlabel and not $xlabel) {
|
326
345
|
$xlabel = $$name[0];
|
327
346
|
$noLegend = 1 if $hist;
|
328
347
|
}
|
329
|
-
if (defined $ylabel and not $ylabel and @name == 1) {
|
348
|
+
if (defined $ylabel and not $ylabel and @name == 1 and not $multiMulti) {
|
330
349
|
$ylabel = $hist ? 'Count' : $name[0];
|
331
350
|
$noLegend = 1 unless $hist;
|
332
351
|
}
|
@@ -645,7 +664,9 @@ Change plot settings.
|
|
645
664
|
Title, XLabel, YLabel - plot title and x/y axis labels (no default)
|
646
665
|
XMin, XMax - x axis minimum/maximum (autoscaling if not set)
|
647
666
|
YMin, YMax - y axis minimum/maximum
|
648
|
-
Multi -
|
667
|
+
Multi - number of columns when drawing multiple plots,
|
668
|
+
followed optional number of datasets for each
|
669
|
+
plot (1 by default) using any separator
|
649
670
|
Split - flag to split strings of numbers into lists
|
650
671
|
(> 1 to split into lists of N items)
|
651
672
|
"Grid=darkgray" - grid color
|
@@ -49,7 +49,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
49
49
|
use Image::ExifTool::Exif;
|
50
50
|
use Image::ExifTool::GPS;
|
51
51
|
|
52
|
-
$VERSION = '3.
|
52
|
+
$VERSION = '3.16';
|
53
53
|
|
54
54
|
sub ProcessMOV($$;$);
|
55
55
|
sub ProcessKeys($$$);
|
@@ -815,6 +815,13 @@ my %userDefined = (
|
|
815
815
|
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
816
816
|
ProcessProc => 'Image::ExifTool::LigoGPS::ProcessLigoJSON',
|
817
817
|
},
|
818
|
+
},{
|
819
|
+
Name => 'GKUData',
|
820
|
+
Condition => '$$valPt =~ /^.{8}__V35AX_QVDATA__/',
|
821
|
+
SubDirectory => {
|
822
|
+
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
823
|
+
ProcessProc => 'Image::ExifTool::LigoGPS::ProcessGKU',
|
824
|
+
},
|
818
825
|
},{
|
819
826
|
Name => 'FLIRData',
|
820
827
|
SubDirectory => { TagTable => 'Image::ExifTool::FLIR::UserData' },
|
@@ -945,7 +952,7 @@ my %userDefined = (
|
|
945
952
|
Notes => 'MP4-format video saved in Samsung motion-photo HEIC images.',
|
946
953
|
Binary => 1,
|
947
954
|
# note that this may be written and/or deleted, but can't currently be added back again
|
948
|
-
Writable =>
|
955
|
+
Writable => 'undef',
|
949
956
|
},
|
950
957
|
# '35AX'? - seen "AT" (Yada RoadCam Pro 4K dashcam)
|
951
958
|
cust => 'CustomInfo', # 70mai A810
|
@@ -953,6 +960,15 @@ my %userDefined = (
|
|
953
960
|
Name => 'SEAL',
|
954
961
|
SubDirectory => { TagTable => 'Image::ExifTool::XMP::SEAL' },
|
955
962
|
},
|
963
|
+
inst => {
|
964
|
+
Name => 'Insta360Info',
|
965
|
+
DontRead => 1, # don't read into memory when extracting
|
966
|
+
WriteLast => 1, # must go at end of file
|
967
|
+
SubDirectory => {
|
968
|
+
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
969
|
+
ProcessProc => \&ProcessInsta360,
|
970
|
+
},
|
971
|
+
},
|
956
972
|
);
|
957
973
|
|
958
974
|
# stuff seen in 'skip' atom (70mai Pro Plus+ MP4 videos)
|
@@ -2387,6 +2403,19 @@ my %userDefined = (
|
|
2387
2403
|
Groups => { 2 => 'Preview' },
|
2388
2404
|
Binary => 1,
|
2389
2405
|
},
|
2406
|
+
# ---- Insta360 ----
|
2407
|
+
nail => {
|
2408
|
+
Name => 'ThumbnailTIFF',
|
2409
|
+
Notes => 'image found in some Insta360 videos, converted to TIFF format',
|
2410
|
+
Groups => { 2 => 'Preview' },
|
2411
|
+
RawConv => q{
|
2412
|
+
return undef if length $val < 8;
|
2413
|
+
my ($w, $h) = unpack('NN', $val);
|
2414
|
+
return undef if length $val < $w * $h + 8;
|
2415
|
+
return MakeTiffHeader($w, $h, 1, 8) . substr($val, 8, $w * $h);
|
2416
|
+
},
|
2417
|
+
Binary => 1,
|
2418
|
+
},
|
2390
2419
|
# ---- Nextbase ----
|
2391
2420
|
info => 'FirmwareVersion',
|
2392
2421
|
'time' => {
|
@@ -9743,6 +9772,7 @@ sub IdentifyTrailers($)
|
|
9743
9772
|
} else {
|
9744
9773
|
last;
|
9745
9774
|
}
|
9775
|
+
# 0) trailer type, 1) trailer start, 2) trailer length, 3) pointer to next trailer
|
9746
9776
|
$trailer = [ $type , $raf->Tell() - $len, $len, $nextTrail ];
|
9747
9777
|
$nextTrail = $trailer;
|
9748
9778
|
$offset += $len;
|
@@ -10017,7 +10047,7 @@ sub ProcessMOV($$;$)
|
|
10017
10047
|
}
|
10018
10048
|
}
|
10019
10049
|
}
|
10020
|
-
if (defined $tagInfo and not $ignore) {
|
10050
|
+
if (defined $tagInfo and not $ignore and not ($tagInfo and $$tagInfo{DontRead})) {
|
10021
10051
|
# set document number for this item property if necessary
|
10022
10052
|
if ($$et{IsItemProperty}) {
|
10023
10053
|
my $items = $$et{ItemInfo};
|
@@ -10070,7 +10100,7 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
10070
10100
|
# use value to get tag info if necessary
|
10071
10101
|
$tagInfo or $tagInfo = $et->GetTagInfo($tagTablePtr, $tag, \$val);
|
10072
10102
|
my $hasData = ($$dirInfo{HasData} and $val =~ /^....data\0/s);
|
10073
|
-
if ($verbose and not $hasData) {
|
10103
|
+
if ($verbose and defined $val and not $hasData) {
|
10074
10104
|
my $tval;
|
10075
10105
|
if ($tagInfo and $$tagInfo{Format}) {
|
10076
10106
|
$tval = ReadValue(\$val, 0, $$tagInfo{Format}, $$tagInfo{Count}, length($val));
|
@@ -10389,7 +10419,25 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
10389
10419
|
Size => $size,
|
10390
10420
|
Extra => sprintf(' at offset 0x%.4x', $raf->Tell()),
|
10391
10421
|
) if $verbose;
|
10392
|
-
|
10422
|
+
my $seekTo = $raf->Tell() + $size;
|
10423
|
+
if ($tagInfo and $$tagInfo{DontRead} and $$tagInfo{SubDirectory}) {
|
10424
|
+
# ignore first trailer if it is the payload of this box
|
10425
|
+
$trailer = $$trailer[3] if $trailer and $$trailer[1] == $raf->Tell();
|
10426
|
+
my $subdir = $$tagInfo{SubDirectory};
|
10427
|
+
my %dirInfo = (
|
10428
|
+
RAF => $raf,
|
10429
|
+
DirName => $$tagInfo{Name},
|
10430
|
+
DirID => $tag,
|
10431
|
+
DirEnd => $seekTo,
|
10432
|
+
);
|
10433
|
+
my $subTable = GetTagTable($$subdir{TagTable});
|
10434
|
+
my $proc = $$subdir{ProcessProc};
|
10435
|
+
# make ProcessMOV() the default processing procedure for subdirectories
|
10436
|
+
$proc = \&ProcessMOV unless $proc or $$subTable{PROCESS_PROC};
|
10437
|
+
$et->ProcessDirectory(\%dirInfo, $subTable, $proc);
|
10438
|
+
$raf->Seek($seekTo);
|
10439
|
+
}
|
10440
|
+
unless ($raf->Seek($seekTo-1) and $raf->Read($buff, 1) == 1) {
|
10393
10441
|
my $t = PrintableTagID($tag,2);
|
10394
10442
|
$warnStr = sprintf("Truncated '${t}' data at offset 0x%x", $lastPos);
|
10395
10443
|
last;
|
@@ -111,9 +111,8 @@ my %insvLimit = (
|
|
111
111
|
The tags below are extracted from timed metadata in QuickTime and other
|
112
112
|
formats of video files when the ExtractEmbedded option is used. Although
|
113
113
|
most of these tags are combined into the single table below, ExifTool
|
114
|
-
currently reads
|
114
|
+
currently reads 107 different types of timed GPS metadata from video files.
|
115
115
|
},
|
116
|
-
VARS => { NO_ID => 1 },
|
117
116
|
GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
|
118
117
|
GPSLongitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")' },
|
119
118
|
GPSLatitude2 => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")' },
|
@@ -318,7 +317,7 @@ my %insvLimit = (
|
|
318
317
|
ByteOrder => 'Little-Endian',
|
319
318
|
},
|
320
319
|
}],
|
321
|
-
mett => { # Parrot drones
|
320
|
+
mett => { # Parrot drones and iPhone/Android using ARCore
|
322
321
|
Name => 'mett',
|
323
322
|
SubDirectory => { TagTable => 'Image::ExifTool::Parrot::mett' },
|
324
323
|
},
|
@@ -336,11 +335,25 @@ my %insvLimit = (
|
|
336
335
|
Groups => { 0 => 'Trailer', 1 => 'Insta360' }, # (so these groups will appear in the -listg options)
|
337
336
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::INSV_MakerNotes' },
|
338
337
|
},
|
339
|
-
ssmd => {
|
340
|
-
Name => '
|
338
|
+
ssmd => [{
|
339
|
+
Name => 'RoveGPS', # Rove R2-4K new model
|
340
|
+
# double value of GPSLatitude is 4294967295 (00 00 e0 ff ff ff ef 41) for no GPS
|
341
|
+
Condition => 'length $$valPt == 32 and $$valPt !~ /^\0\0\xe0\xff\xff\xff\xef\x41/',
|
342
|
+
SubDirectory => {
|
343
|
+
TagTable => 'Image::ExifTool::QuickTime::RoveGPS',
|
344
|
+
ByteOrder => 'Little-Endian',
|
345
|
+
},
|
346
|
+
},{
|
347
|
+
Name => 'Accelerometer', # Rove R2-4K new model
|
348
|
+
Condition => 'length $$valPt == 12',
|
349
|
+
Format => 'float',
|
350
|
+
ByteOrder => 'Little-Endian',
|
351
|
+
},{
|
352
|
+
Name => 'PreviewImage', # Chigee AIO-5 dashcam
|
353
|
+
Condition => '$$valPt =~ /^\xff\xd8\xff/',
|
341
354
|
Groups => { 2 => 'Preview' },
|
342
355
|
RawConv => '$self->ValidateImage(\$val,$tag)',
|
343
|
-
},
|
356
|
+
}],
|
344
357
|
djmd => { # (DJI AC003 Osmo Action 4 cam)
|
345
358
|
Name => 'DJIMetadata',
|
346
359
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::Protobuf' },
|
@@ -358,6 +371,45 @@ my %insvLimit = (
|
|
358
371
|
MagneticVariation => { }, # (from LIGOGPSINFO)
|
359
372
|
);
|
360
373
|
|
374
|
+
# accelerometer from newer Rove R2-4K cam
|
375
|
+
%Image::ExifTool::QuickTime::RoveGPS = (
|
376
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
377
|
+
GROUPS => { 2 => 'Location' },
|
378
|
+
FIRST_ENTRY => 0,
|
379
|
+
0 => {
|
380
|
+
Name => 'GPSLatitude',
|
381
|
+
Format => 'double',
|
382
|
+
ValueConv => 'my $deg = int($val/100); $val = $deg + ($val - $deg * 100) / 60',
|
383
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
|
384
|
+
},
|
385
|
+
8 => {
|
386
|
+
Name => 'GPSLongitude',
|
387
|
+
Format => 'double',
|
388
|
+
ValueConv => 'my $deg = int($val/100); $val = $deg + ($val - $deg * 100) / 60',
|
389
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
|
390
|
+
},
|
391
|
+
20 => {
|
392
|
+
Name => 'GPSSpeed',
|
393
|
+
Format => 'int16u',
|
394
|
+
ValueConv => '$val * 1.852', # convert from knots to km/h
|
395
|
+
},
|
396
|
+
22 => {
|
397
|
+
Name => 'GPSDateTime',
|
398
|
+
Description => 'GPS Date/Time',
|
399
|
+
Groups => { 2 => 'Time' },
|
400
|
+
Format => 'int8u[6]',
|
401
|
+
ValueConv => q{
|
402
|
+
my @v = split ' ', $val;
|
403
|
+
$v[0] += 2000;
|
404
|
+
sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', @v);
|
405
|
+
},
|
406
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
407
|
+
},
|
408
|
+
# Seen this in the next 4 bytes:
|
409
|
+
# ff 01 01 00 - good GPS?
|
410
|
+
# ff 00 ff ff - no GPS?
|
411
|
+
);
|
412
|
+
|
361
413
|
# tags found in 'camm' type 0 timed metadata (ref 4)
|
362
414
|
%Image::ExifTool::QuickTime::camm0 = (
|
363
415
|
PROCESS_PROC => \&ProcessCAMM,
|
@@ -2351,12 +2403,12 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
2351
2403
|
}
|
2352
2404
|
SetByteOrder($oldOrder);
|
2353
2405
|
return $$et{DOC_NUM} ? 1 : 0 if $done;
|
2354
|
-
return 0 if defined $yr and $mon < 1 or $mon > 12; # quick sanity check
|
2406
|
+
return 0 if defined $yr and ($mon < 1 or $mon > 12); # quick sanity check
|
2355
2407
|
#
|
2356
2408
|
# save tag values extracted by above code
|
2357
2409
|
#
|
2358
2410
|
FoundSomething($et, $tagTbl, $$dirInfo{SampleTime}, $$dirInfo{SampleDuration});
|
2359
|
-
$sec = '0' . $sec
|
2411
|
+
$sec = '0' . $sec if defined $sec and $sec !~ /^\d{2}/; # pad integer part of seconds to 2 digits
|
2360
2412
|
if (defined $yr) {
|
2361
2413
|
$yr += 2000 if $yr < 2000;
|
2362
2414
|
my $time = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%sZ',$yr,$mon,$day,$hr,$min,$sec);
|
@@ -2368,8 +2420,8 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
2368
2420
|
if (defined $lat and defined $lon) {
|
2369
2421
|
# lat/long are in DDDMM.MMMM format unless $ddd is set
|
2370
2422
|
ConvertLatLon($lat, $lon) unless $ddd;
|
2371
|
-
$et->HandleTag($tagTbl, GPSLatitude => $lat * ($latRef eq 'S' ? -1 : 1));
|
2372
|
-
$et->HandleTag($tagTbl, GPSLongitude => $lon * ($lonRef eq 'W' ? -1 : 1));
|
2423
|
+
$et->HandleTag($tagTbl, GPSLatitude => $lat * (($latRef and $latRef eq 'S') ? -1 : 1));
|
2424
|
+
$et->HandleTag($tagTbl, GPSLongitude => $lon * (($lonRef and $lonRef eq 'W') ? -1 : 1));
|
2373
2425
|
}
|
2374
2426
|
$et->HandleTag($tagTbl, GPSAltitude => $alt) if defined $alt;
|
2375
2427
|
$et->HandleTag($tagTbl, GPSSpeed => $spd) if defined $spd;
|
@@ -3148,8 +3200,9 @@ sub ProcessTTAD($$$)
|
|
3148
3200
|
}
|
3149
3201
|
|
3150
3202
|
#------------------------------------------------------------------------------
|
3151
|
-
# Extract information from Insta360 trailer (INSV and
|
3203
|
+
# Extract information from Insta360 trailer (INSV, INSP and MP4 files) or 'inst' box (ref PH)
|
3152
3204
|
# Inputs: 0) ExifTool ref, 1) Optional dirInfo ref for returning trailer info
|
3205
|
+
# (dirInfo has Offset from end of trailer to end of file or DirEnd absolute end of trailer)
|
3153
3206
|
# Returns: true on success
|
3154
3207
|
# Notes: There looks to be some useful information by telemetry-parser, but
|
3155
3208
|
# the code is cryptic: https://github.com/AdrianEddy/telemetry-parser
|
@@ -3161,13 +3214,16 @@ sub ProcessInsta360($;$)
|
|
3161
3214
|
my $offset = $dirInfo ? $$dirInfo{Offset} || 0 : 0;
|
3162
3215
|
my ($buff, $dirTable, $dirTablePos);
|
3163
3216
|
|
3217
|
+
if ($dirInfo and $$dirInfo{DirEnd}) {
|
3218
|
+
$raf->Seek(0, 2);
|
3219
|
+
$offset = $raf->Tell() - $$dirInfo{DirEnd};
|
3220
|
+
}
|
3164
3221
|
return 0 unless $raf->Seek(-78-$offset, 2) and $raf->Read($buff, 78) == 78 and
|
3165
3222
|
substr($buff,-32) eq "8db42d694ccc418790edff439fe026bf"; # check magic number
|
3166
3223
|
|
3167
3224
|
my $verbose = $et->Options('Verbose');
|
3168
3225
|
my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
3169
|
-
my $
|
3170
|
-
my $trailEnd = $fileEnd - $offset;
|
3226
|
+
my $trailEnd = $raf->Tell();
|
3171
3227
|
my $trailerLen = unpack('x38V', $buff);
|
3172
3228
|
$trailerLen > $trailEnd and $et->Warn('Bad Insta360 trailer size'), return 0;
|
3173
3229
|
if ($dirInfo) {
|
@@ -3207,7 +3263,7 @@ sub ProcessInsta360($;$)
|
|
3207
3263
|
($epos -= $len) + $trailerLen < 0 and last;
|
3208
3264
|
$raf->Seek($epos-$offset, 2) or last;
|
3209
3265
|
if ($verbose) {
|
3210
|
-
$et->VPrint(0, sprintf("Insta360 Record 0x%x (offset 0x%x, %d bytes):\n", $id, $
|
3266
|
+
$et->VPrint(0, sprintf("Insta360 Record 0x%x (offset 0x%x, %d bytes):\n", $id, $trailEnd + $epos, $len));
|
3211
3267
|
}
|
3212
3268
|
# there are 2 types of record 0x300:
|
3213
3269
|
# 1. 56 byte records
|
@@ -982,6 +982,16 @@ numerical, and generated automatically otherwise.
|
|
982
982
|
for use when ExtractInfo is called with the ReEntry flag from
|
983
983
|
inside the RawConv of a tag.
|
984
984
|
|
985
|
+
ByteOrder : [Non-writable tags extracted with HandleTag and writable EXIF
|
986
|
+
offset-pair tags only] Specifies byte order if tag value is
|
987
|
+
stored with a constant byte order that is different from that
|
988
|
+
of the parent directory.
|
989
|
+
|
990
|
+
DontRead : [QuickTime tags with compatible SubDirectory entries only]
|
991
|
+
Avoid reading subdirectory data from file. Instead, pass RAF
|
992
|
+
reference (with current position at start of directory) and
|
993
|
+
DirEnd.
|
994
|
+
|
985
995
|
TagID : [reserved] Used internally to save the table key for this tag.
|
986
996
|
Note: For XMP tables this corresponds to the XMP property
|
987
997
|
name, but the table key may have a full XMP namespace prefix
|
@@ -1071,8 +1081,8 @@ numerical, and generated automatically otherwise.
|
|
1071
1081
|
ByteOrder : Specifies byte ordering if different than than the rest of the
|
1072
1082
|
file. Must be either BigEndian, LittleEndian or Unknown. If
|
1073
1083
|
Unknown is specified, the byte order will be determined from
|
1074
|
-
the directory count (however, this can not be done if
|
1075
|
-
is specified).
|
1084
|
+
the directory count for EXIF (however, this can not be done if
|
1085
|
+
OffsetPt is specified).
|
1076
1086
|
|
1077
1087
|
Validate : If given, specifies Perl expression which is used to validate
|
1078
1088
|
the subdirectory data (regardless of Validate option setting).
|
@@ -10766,6 +10766,11 @@ my %isoSetting2010 = (
|
|
10766
10766
|
0 => 'Sony:FocusPosition2',
|
10767
10767
|
1 => 'FocalLengthIn35mmFormat',
|
10768
10768
|
},
|
10769
|
+
# (NOTE: This calculation may be wrong. "Focus Distance 2 is the result of an erroneous
|
10770
|
+
# user supplied formula to exiftool. It does use data embedded in the raw file,
|
10771
|
+
# but it is not the data. The actual embedded data seems to be proportional to
|
10772
|
+
# magnification not a focus distance. The camera needs to calculate magnification
|
10773
|
+
# for translation stabilization.", ref https://www.fredmiranda.com/forum/topic/1858744/0)
|
10769
10774
|
ValueConv => q{
|
10770
10775
|
return undef unless $val;
|
10771
10776
|
return 'inf' if $val >= 255;
|
@@ -730,6 +730,7 @@ my %tagLookup = (
|
|
730
730
|
'afareas' => { 334 => 0x304 },
|
731
731
|
'afareaselectionmethod' => { 2 => 0xd },
|
732
732
|
'afareaselectmethod' => { 90 => 0x51b },
|
733
|
+
'afareasize' => { 358 => 0xde },
|
733
734
|
'afareawidth' => { 200 => 0x18, 201 => 0x4e, 203 => 0x32, 204 => 0x46 },
|
734
735
|
'afareaxposition' => { 200 => 0x14, 201 => 0x4a, 203 => 0x2e, 204 => 0x42, 428 => 0x1203 },
|
735
736
|
'afareaxposition1' => { 428 => 0x1201 },
|
@@ -795,12 +796,14 @@ my %tagLookup = (
|
|
795
796
|
'afpointsinfocus' => { 82 => 0xe, 199 => 0x2, 201 => 0x30, 369 => 0xb, 370 => 0x4, 394 => [0xf,0x3c] },
|
796
797
|
'afpointsinfocus5d' => { 19 => 0x38 },
|
797
798
|
'afpointspotmetering' => { 89 => 0xd },
|
798
|
-
'afpointsselected' => { 200 => 0x1c, 201 => 0x1c, 370 => '4.1', 497 => 0x4 },
|
799
|
+
'afpointsselected' => { 200 => 0x1c, 201 => 0x1c, 369 => 0x12a, 370 => '4.1', 497 => 0x4 },
|
799
800
|
'afpointsspecial' => { 370 => '4.2' },
|
801
|
+
'afpointsunknown' => { 369 => 0x18f },
|
800
802
|
'afpointsunknown1' => { 369 => 0x0 },
|
801
803
|
'afpointsunknown2' => { 369 => 0x2 },
|
802
804
|
'afpointsused' => { 200 => 0x8, 201 => [0x1c,0x8], 202 => 0x8, 203 => 0xa, 204 => 0xa, 441 => [0x10,0x16e] },
|
803
805
|
'afpointswitching' => { 2 => 0x4 },
|
806
|
+
'afpointvalues' => { 369 => 0x14 },
|
804
807
|
'afpredictor' => { 369 => 0x4 },
|
805
808
|
'afresponse' => { 246 => 0xad },
|
806
809
|
'afresult' => { 339 => 0x1038 },
|
@@ -6466,7 +6469,7 @@ my %tagLookup = (
|
|
6466
6469
|
'sensorserialnumber' => { 145 => 0x9ce },
|
6467
6470
|
'sensorshield' => { 253 => 0x76b, 254 => 0x77b, 255 => 0x66d, 256 => 0x69d, 257 => 0x705 },
|
6468
6471
|
'sensorsize' => { 163 => 'SensorSize', 394 => 0x35 },
|
6469
|
-
'sensortemperature' => { 337 => 0x1500, 339 => 0x1007, 399 => 0xc, 403 => 0x210, 438 => [0x39,0x55] },
|
6472
|
+
'sensortemperature' => { 337 => 0x1500, 339 => 0x1007, 399 => [0xc,0x2a], 403 => 0x210, 438 => [0x39,0x55] },
|
6470
6473
|
'sensortemperature2' => { 399 => 0xe, 403 => 0x211 },
|
6471
6474
|
'sensortopborder' => { 145 => 0x3ec },
|
6472
6475
|
'sensortopmargin' => { 403 => 0x10b },
|
@@ -7882,8 +7885,10 @@ my %tagExists = (
|
|
7882
7885
|
'archivallocation' => 1,
|
7883
7886
|
'archivedfilename' => 1,
|
7884
7887
|
'arcoreaccel' => 1,
|
7888
|
+
'arcoreaccel0' => 1,
|
7885
7889
|
'arcorecustom' => 1,
|
7886
7890
|
'arcoregyro' => 1,
|
7891
|
+
'arcoregyro0' => 1,
|
7887
7892
|
'arcorevideo' => 1,
|
7888
7893
|
'ardronefile' => 1,
|
7889
7894
|
'ardronetelemetry' => 1,
|
@@ -9804,6 +9809,7 @@ my %tagExists = (
|
|
9804
9809
|
'gipcver' => 1,
|
9805
9810
|
'givenname' => 1,
|
9806
9811
|
'gixiver' => 1,
|
9812
|
+
'gkudata' => 1,
|
9807
9813
|
'glamoursettings' => 1,
|
9808
9814
|
'globalinfo' => 1,
|
9809
9815
|
'globalpalette' => 1,
|
@@ -9936,6 +9942,8 @@ my %tagExists = (
|
|
9936
9942
|
'hdmioutputhdr' => 1,
|
9937
9943
|
'hdmioutputrange' => 1,
|
9938
9944
|
'hdrgaincurve' => 1,
|
9945
|
+
'hdrgaincurvesize' => 1,
|
9946
|
+
'hdrgaininfo' => 1,
|
9939
9947
|
'hdrgainmap' => 1,
|
9940
9948
|
'hdrgm' => 1,
|
9941
9949
|
'hdrimage' => 1,
|
@@ -10192,6 +10200,7 @@ my %tagExists = (
|
|
10192
10200
|
'insetnwpixelx' => 1,
|
10193
10201
|
'insetnwpixely' => 1,
|
10194
10202
|
'insta360' => 1,
|
10203
|
+
'insta360info' => 1,
|
10195
10204
|
'institution' => 1,
|
10196
10205
|
'instructionset' => 1,
|
10197
10206
|
'instruments' => 1,
|
@@ -12041,6 +12050,7 @@ my %tagExists = (
|
|
12041
12050
|
'rotationxyz' => 1,
|
12042
12051
|
'rotmode' => 1,
|
12043
12052
|
'roundtripversion' => 1,
|
12053
|
+
'rovegps' => 1,
|
12044
12054
|
'rowcount' => 1,
|
12045
12055
|
'rowinterleavefactor' => 1,
|
12046
12056
|
'rsrc' => 1,
|