exiftool_vendored 11.84.0 → 11.86.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 +4 -4
- data/bin/Changes +24 -4
- data/bin/MANIFEST +1 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +3 -2
- data/bin/config_files/acdsee.config +73 -0
- data/bin/exiftool +10 -2
- data/bin/fmt_files/kml.fmt +4 -4
- data/bin/lib/Image/ExifTool.pm +18 -9
- data/bin/lib/Image/ExifTool.pod +30 -30
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +8 -8
- data/bin/lib/Image/ExifTool/Canon.pm +4 -2
- data/bin/lib/Image/ExifTool/Exif.pm +64 -4
- data/bin/lib/Image/ExifTool/FlashPix.pm +28 -28
- data/bin/lib/Image/ExifTool/FujiFilm.pm +2 -1
- data/bin/lib/Image/ExifTool/JPEG.pm +8 -5
- data/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/it.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/pl.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/ru.pm +2 -2
- data/bin/lib/Image/ExifTool/MakerNotes.pm +1 -2
- data/bin/lib/Image/ExifTool/Nikon.pm +8 -5
- data/bin/lib/Image/ExifTool/Olympus.pm +2 -1
- data/bin/lib/Image/ExifTool/Pentax.pm +3 -1
- data/bin/lib/Image/ExifTool/QuickTime.pm +13 -2
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +73 -16
- data/bin/lib/Image/ExifTool/Sony.pm +4 -1
- data/bin/lib/Image/ExifTool/TagLookup.pm +9 -0
- data/bin/lib/Image/ExifTool/TagNames.pod +26 -10
- data/bin/lib/Image/ExifTool/WritePhotoshop.pl +4 -0
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +27 -10
- data/bin/lib/Image/ExifTool/Writer.pl +2 -2
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -2
@@ -1086,7 +1086,7 @@ my %fpxFileType = (
|
|
1086
1086
|
0x0807 => 'German (Swiss)',
|
1087
1087
|
0x0408 => 'Greek',
|
1088
1088
|
0x0409 => 'English (US)',
|
1089
|
-
0x0809 => 'English (British)',
|
1089
|
+
0x0809 => 'English (British)',
|
1090
1090
|
0x0c09 => 'English (Australian)',
|
1091
1091
|
0x040a => 'Spanish (Castilian)',
|
1092
1092
|
0x080a => 'Spanish (Mexican)',
|
@@ -1109,7 +1109,7 @@ my %fpxFileType = (
|
|
1109
1109
|
0x0415 => 'Polish',
|
1110
1110
|
0x0416 => 'Portuguese (Brazilian)',
|
1111
1111
|
0x0816 => 'Portuguese',
|
1112
|
-
0x0417 => 'Rhaeto-Romanic',
|
1112
|
+
0x0417 => 'Rhaeto-Romanic',
|
1113
1113
|
0x0418 => 'Romanian',
|
1114
1114
|
0x0419 => 'Russian',
|
1115
1115
|
0x041a => 'Croato-Serbian (Latin)',
|
@@ -1646,14 +1646,14 @@ sub ProcessCommentBy($$$)
|
|
1646
1646
|
my $pos = $$dirInfo{DirStart};
|
1647
1647
|
my $end = $$dirInfo{DirLen} + $pos;
|
1648
1648
|
$et->VerboseDir($$dirInfo{DirName});
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1649
|
+
while ($pos + 2 < $end) {
|
1650
|
+
my $len = Get16u($dataPt, $pos);
|
1651
|
+
$pos += 2;
|
1652
|
+
last if $pos + $len * 2 > $end;
|
1653
|
+
my $author = $et->Decode(substr($$dataPt, $pos, $len*2), 'UCS2');
|
1654
|
+
$pos += $len * 2;
|
1655
|
+
$et->HandleTag($tagTablePtr, CommentBy => $author);
|
1656
|
+
}
|
1657
1657
|
return 1;
|
1658
1658
|
}
|
1659
1659
|
|
@@ -1669,24 +1669,24 @@ sub ProcessLastSavedBy($$$)
|
|
1669
1669
|
my $end = $$dirInfo{DirLen} + $pos;
|
1670
1670
|
return 0 if $pos + 6 > $end;
|
1671
1671
|
$et->VerboseDir($$dirInfo{DirName});
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1672
|
+
my $num = Get16u($dataPt, $pos+2);
|
1673
|
+
$pos += 6;
|
1674
|
+
while ($num >= 2) {
|
1675
|
+
last if $pos + 2 > $end;
|
1676
|
+
my $len = Get16u($dataPt, $pos);
|
1677
|
+
$pos += 2;
|
1678
|
+
last if $pos + $len * 2 > $end;
|
1679
|
+
my $author = $et->Decode(substr($$dataPt, $pos, $len*2), 'UCS2');
|
1680
|
+
$pos += $len * 2;
|
1681
|
+
last if $pos + 2 > $end;
|
1682
|
+
$len = Get16u($dataPt, $pos);
|
1683
|
+
$pos += 2;
|
1684
|
+
last if $pos + $len * 2 > $end;
|
1685
|
+
my $path = $et->Decode(substr($$dataPt, $pos, $len*2), 'UCS2');
|
1686
|
+
$pos += $len * 2;
|
1687
|
+
$et->HandleTag($tagTablePtr, LastSavedBy => "$author ($path)");
|
1688
|
+
$num -= 2;
|
1689
|
+
}
|
1690
1690
|
return 1;
|
1691
1691
|
}
|
1692
1692
|
|
@@ -31,7 +31,7 @@ use vars qw($VERSION);
|
|
31
31
|
use Image::ExifTool qw(:DataAccess :Utils);
|
32
32
|
use Image::ExifTool::Exif;
|
33
33
|
|
34
|
-
$VERSION = '1.
|
34
|
+
$VERSION = '1.76';
|
35
35
|
|
36
36
|
sub ProcessFujiDir($$$);
|
37
37
|
sub ProcessFaceRec($$$);
|
@@ -302,6 +302,7 @@ my %faceCategories = (
|
|
302
302
|
PrintConv => {
|
303
303
|
0 => 'Auto',
|
304
304
|
1 => 'Manual',
|
305
|
+
65535 => 'Movie', #forum10766
|
305
306
|
},
|
306
307
|
},
|
307
308
|
0x1022 => { #8/forum6579
|
@@ -11,7 +11,7 @@ use strict;
|
|
11
11
|
use vars qw($VERSION);
|
12
12
|
use Image::ExifTool qw(:DataAccess :Utils);
|
13
13
|
|
14
|
-
$VERSION = '1.
|
14
|
+
$VERSION = '1.30';
|
15
15
|
|
16
16
|
sub ProcessOcad($$$);
|
17
17
|
sub ProcessJPEG_HDR($$$);
|
@@ -247,14 +247,17 @@ sub ProcessJPEG_HDR($$$);
|
|
247
247
|
Name => 'Samsung',
|
248
248
|
Condition => '$$valPt =~ /QDIOBS$/',
|
249
249
|
SubDirectory => { TagTable => 'Image::ExifTool::Samsung::Trailer' },
|
250
|
-
}, {
|
251
|
-
Name => 'PreviewImage',
|
252
|
-
Condition => '$$valPt =~ /^\xff\xd8\xff/',
|
253
|
-
Writable => 2, # (for docs only)
|
254
250
|
}, {
|
255
251
|
Name => 'EmbeddedVideo',
|
256
252
|
Notes => 'extracted only when ExtractEmbedded option is used',
|
257
253
|
Condition => '$$valPt =~ /^.{4}ftyp/s',
|
254
|
+
}, {
|
255
|
+
Name => 'Insta360',
|
256
|
+
Condition => '$$valPt =~ /8db42d694ccc418790edff439fe026bf$/',
|
257
|
+
}, {
|
258
|
+
Name => 'PreviewImage',
|
259
|
+
Condition => '$$valPt =~ /^\xff\xd8\xff/',
|
260
|
+
Writable => 2, # (for docs only)
|
258
261
|
}],
|
259
262
|
);
|
260
263
|
|
@@ -7713,7 +7713,7 @@ $VERSION = '1.35';
|
|
7713
7713
|
Description => 'Unterdatei-Typ',
|
7714
7714
|
PrintConv => {
|
7715
7715
|
'Alternate reduced-resolution image' => 'Alternatives Bild in reduzierter Auflösung',
|
7716
|
-
'Full-resolution
|
7716
|
+
'Full-resolution image' => 'Bild in voller Auflösung',
|
7717
7717
|
'Reduced-resolution image' => 'Bild in reduzierter Auflösung',
|
7718
7718
|
'Single page of multi-page image' => 'Einzelbild eines mehrseitigen Bildes',
|
7719
7719
|
'Single page of multi-page reduced-resolution image' => 'Einzelbild eines mehrseitigen Bildes in reduzierter Auflösung',
|
@@ -7060,7 +7060,7 @@ $VERSION = '1.14';
|
|
7060
7060
|
'SubfileType' => {
|
7061
7061
|
Description => 'Tipo sotto-file',
|
7062
7062
|
PrintConv => {
|
7063
|
-
'Full-resolution
|
7063
|
+
'Full-resolution image' => 'Immagine con risoluzione originale',
|
7064
7064
|
'Reduced-resolution image' => 'Immagine a risoluzione ridotta',
|
7065
7065
|
'Single page of multi-page image' => 'Singola pagina di un\'immagine multi-pagina',
|
7066
7066
|
'Single page of multi-page reduced-resolution image' => 'Singola pagina di un\'immagine multi-pagina a risoluzione ridotta',
|
@@ -1064,7 +1064,7 @@ $VERSION = '1.12';
|
|
1064
1064
|
'SubfileType' => {
|
1065
1065
|
Description => 'Typ podsekcji',
|
1066
1066
|
PrintConv => {
|
1067
|
-
'Full-resolution
|
1067
|
+
'Full-resolution image' => 'Obraz w pełnej rozdzielczości',
|
1068
1068
|
'Reduced-resolution image' => 'Obraz o zredukowanej rozdzielczości',
|
1069
1069
|
'Single page of multi-page image' => 'Jedna strona obrazu wielostronicowego',
|
1070
1070
|
'Single page of multi-page reduced-resolution image' => 'Jedna strona obrazu wielostronicowego o zredukowanej rozdzielczości',
|
@@ -811,7 +811,7 @@ $VERSION = '1.08';
|
|
811
811
|
'ColorSpecMethod' => {
|
812
812
|
Description => 'Спецификация цвета – Метод',
|
813
813
|
PrintConv => {
|
814
|
-
'Any ICC' => 'Любой ICC
|
814
|
+
'Any ICC' => 'Любой ICC',
|
815
815
|
'Enumerated' => 'Перечислимый',
|
816
816
|
'Restricted ICC' => 'Ограниченный ICC',
|
817
817
|
'Vendor Color' => 'Цвет поставщика',
|
@@ -5118,7 +5118,7 @@ $VERSION = '1.08';
|
|
5118
5118
|
PrintConv => {
|
5119
5119
|
'Alternate reduced-resolution image' => 'Альтернативное изображение с пониженным разрешением',
|
5120
5120
|
'Color IW44' => 'Цветной IW44',
|
5121
|
-
'Full-resolution
|
5121
|
+
'Full-resolution image' => 'Изображение с полным разрешением',
|
5122
5122
|
'Grayscale IW44' => 'Градация серого IW44',
|
5123
5123
|
'Multi-page document' => 'Многостраничный документ',
|
5124
5124
|
'Reduced-resolution image' => 'Изображение с пониженным разрешением',
|
@@ -21,7 +21,7 @@ sub ProcessKodakPatch($$$);
|
|
21
21
|
sub WriteUnknownOrPreview($$$);
|
22
22
|
sub FixLeicaBase($$;$);
|
23
23
|
|
24
|
-
$VERSION = '2.
|
24
|
+
$VERSION = '2.10';
|
25
25
|
|
26
26
|
my $debug; # set to 1 to enable debugging code
|
27
27
|
|
@@ -691,7 +691,6 @@ my $debug; # set to 1 to enable debugging code
|
|
691
691
|
SubDirectory => {
|
692
692
|
TagTable => 'Image::ExifTool::Panasonic::Leica9',
|
693
693
|
Start => '$valuePtr + 8',
|
694
|
-
Base => '$start - 8',
|
695
694
|
ByteOrder => 'Unknown',
|
696
695
|
},
|
697
696
|
},
|
@@ -61,7 +61,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
61
61
|
use Image::ExifTool::Exif;
|
62
62
|
use Image::ExifTool::GPS;
|
63
63
|
|
64
|
-
$VERSION = '3.
|
64
|
+
$VERSION = '3.78';
|
65
65
|
|
66
66
|
sub LensIDConv($$$);
|
67
67
|
sub ProcessNikonAVI($$$);
|
@@ -1369,14 +1369,15 @@ my %binaryDataAttrs = (
|
|
1369
1369
|
2 => 'G',
|
1370
1370
|
3 => 'VR',
|
1371
1371
|
4 => '1', #PH
|
1372
|
-
|
1372
|
+
5 => 'FT-1', #PH/IB
|
1373
1373
|
6 => 'E', #PH (electromagnetic aperture mechanism)
|
1374
|
-
|
1374
|
+
7 => 'AF-P', #PH/IB
|
1375
1375
|
}) : 'AF';
|
1376
1376
|
# remove commas and change "D G" to just "G"
|
1377
1377
|
s/,//g; s/\bD G\b/G/;
|
1378
|
-
s/ E\b// and s/^(G )?/E /;
|
1379
|
-
s/ 1// and $_ = "1 $_";
|
1378
|
+
s/ E\b// and s/^(G )?/E /; # put "E" at the start instead of "G"
|
1379
|
+
s/ 1// and $_ = "1 $_"; # put "1" at start
|
1380
|
+
s/FT-1 // and $_ .= ' FT-1'; # put "FT-1" at end
|
1380
1381
|
return $_;
|
1381
1382
|
],
|
1382
1383
|
PrintConvInv => q[
|
@@ -1386,6 +1387,8 @@ my %binaryDataAttrs = (
|
|
1386
1387
|
$bits |= 0x06 if $val =~ /\bG\b/i; # bits 1 and 2
|
1387
1388
|
$bits |= 0x08 if $val =~ /\bVR\b/i; # bit 3
|
1388
1389
|
$bits |= 0x10 if $val =~ /\b1\b/; # bit 4
|
1390
|
+
$bits |= 0x20 if $val =~ /\bFT-1/i; # bit 5
|
1391
|
+
$bits |= 0x80 if $val =~ /\bAF-P/i; # bit 7 (not used by all models)
|
1389
1392
|
$bits |= 0x46 if $val =~ /\bE\b/i; # bits 1, 2 and 6
|
1390
1393
|
return $bits;
|
1391
1394
|
],
|
@@ -39,7 +39,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
39
39
|
use Image::ExifTool::Exif;
|
40
40
|
use Image::ExifTool::APP12;
|
41
41
|
|
42
|
-
$VERSION = '2.
|
42
|
+
$VERSION = '2.63';
|
43
43
|
|
44
44
|
sub PrintLensInfo($$$);
|
45
45
|
|
@@ -416,6 +416,7 @@ my %olympusCameraTypes = (
|
|
416
416
|
S0068 => 'E-M10MarkIII',
|
417
417
|
S0076 => 'E-PL9', #IB
|
418
418
|
S0080 => 'E-M1X', #IB
|
419
|
+
S0085 => 'E-PL10', #IB
|
419
420
|
S0089 => 'E-M5MarkIII',
|
420
421
|
SR45 => 'D220',
|
421
422
|
SR55 => 'D320L',
|
@@ -58,7 +58,7 @@ use Image::ExifTool::Exif;
|
|
58
58
|
use Image::ExifTool::GPS;
|
59
59
|
use Image::ExifTool::HP;
|
60
60
|
|
61
|
-
$VERSION = '3.
|
61
|
+
$VERSION = '3.30';
|
62
62
|
|
63
63
|
sub CryptShutterCount($$);
|
64
64
|
sub PrintFilter($$$);
|
@@ -178,6 +178,7 @@ sub DecodeAFPoints($$$$;$);
|
|
178
178
|
'4 2' => 'smc PENTAX-FA 80-320mm F4.5-5.6',
|
179
179
|
'4 3' => 'smc PENTAX-FA 43mm F1.9 Limited',
|
180
180
|
'4 6' => 'smc PENTAX-FA 35-80mm F4-5.6',
|
181
|
+
'4 8' => 'Irix 150mm F2.8 Macro', #exiv2 issue 1084
|
181
182
|
'4 9' => 'Irix 11mm F4 Firefly', #27
|
182
183
|
'4 10' => 'Irix 15mm F2.4', #27
|
183
184
|
'4 12' => 'smc PENTAX-FA 50mm F1.4', #17
|
@@ -336,6 +337,7 @@ sub DecodeAFPoints($$$$;$);
|
|
336
337
|
'8 62' => 'HD PENTAX-D FA 24-70mm F2.8 ED SDM WR', #PH
|
337
338
|
'8 63' => 'HD PENTAX-D FA 15-30mm F2.8 ED SDM WR', #PH
|
338
339
|
'8 64' => 'HD PENTAX-D FA* 50mm F1.4 SDM AW', #27
|
340
|
+
'8 65' => 'HD PENTAX-D FA 70-210mm F4 ED SDM WR', #PH
|
339
341
|
'8 196' => 'HD PENTAX-DA* 11-18mm F2.8 ED DC AW', #29
|
340
342
|
'8 197' => 'HD PENTAX-DA 55-300mm F4.5-6.3 ED PLM WR RE', #29
|
341
343
|
'8 198' => 'smc PENTAX-DA L 18-50mm F4-5.6 DC WR RE', #29
|
@@ -45,7 +45,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
45
45
|
use Image::ExifTool::Exif;
|
46
46
|
use Image::ExifTool::GPS;
|
47
47
|
|
48
|
-
$VERSION = '2.
|
48
|
+
$VERSION = '2.42';
|
49
49
|
|
50
50
|
sub ProcessMOV($$;$);
|
51
51
|
sub ProcessKeys($$$);
|
@@ -1064,7 +1064,10 @@ my %eeBox = (
|
|
1064
1064
|
PROCESS_PROC => \&ProcessMOV,
|
1065
1065
|
WRITE_PROC => \&WriteQuickTime,
|
1066
1066
|
GROUPS => { 2 => 'Video' },
|
1067
|
-
|
1067
|
+
mfhd => {
|
1068
|
+
Name => 'MovieFragmentHeader',
|
1069
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MovieFragHdr' },
|
1070
|
+
},
|
1068
1071
|
traf => {
|
1069
1072
|
Name => 'TrackFragment',
|
1070
1073
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TrackFragment' },
|
@@ -1075,6 +1078,14 @@ my %eeBox = (
|
|
1075
1078
|
},
|
1076
1079
|
);
|
1077
1080
|
|
1081
|
+
# (ref CFFMediaFormat-2_1.pdf)
|
1082
|
+
%Image::ExifTool::QuickTime::MovieFragHdr = (
|
1083
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
1084
|
+
GROUPS => { 2 => 'Video' },
|
1085
|
+
FORMAT => 'int32u',
|
1086
|
+
1 => 'MovieFragmentSequence',
|
1087
|
+
);
|
1088
|
+
|
1078
1089
|
# (ref CFFMediaFormat-2_1.pdf)
|
1079
1090
|
%Image::ExifTool::QuickTime::TrackFragment = (
|
1080
1091
|
PROCESS_PROC => \&ProcessMOV,
|
@@ -86,7 +86,9 @@ my %insvLimit = (
|
|
86
86
|
GROUPS => { 2 => 'Location' },
|
87
87
|
NOTES => q{
|
88
88
|
Timed metadata extracted from QuickTime media data and some AVI videos when
|
89
|
-
the ExtractEmbedded option is used.
|
89
|
+
the ExtractEmbedded option is used. Although most of these tags are
|
90
|
+
combined into the single table below, ExifTool currently reads 37 different
|
91
|
+
formats of timed GPS metadata from video files.
|
90
92
|
},
|
91
93
|
VARS => { NO_ID => 1 },
|
92
94
|
GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
|
@@ -249,7 +251,10 @@ my %insvLimit = (
|
|
249
251
|
Condition => 'length $$valPt > 12 and Get32u($valPt,4) == length($$valPt) and $$valPt =~ /^.{8}\xff\xd8\xff/s',
|
250
252
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::PreviewInfo' },
|
251
253
|
},
|
252
|
-
INSV => {
|
254
|
+
INSV => {
|
255
|
+
Groups => { 0 => 'Trailer', 1 => 'Insta360' }, # (so these groups will appear in the -listg options)
|
256
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::INSV_MakerNotes' },
|
257
|
+
},
|
253
258
|
Unknown00 => { Unknown => 1 },
|
254
259
|
Unknown01 => { Unknown => 1 },
|
255
260
|
Unknown02 => { Unknown => 1 },
|
@@ -1152,6 +1157,26 @@ sub ProcessFreeGPS($$$)
|
|
1152
1157
|
$trk = GetFloat($dataPt, 0x38);
|
1153
1158
|
SetByteOrder('MM');
|
1154
1159
|
|
1160
|
+
} elsif ($$dataPt =~ /^.{60}A\0{3}.{4}([NS])\0{3}.{4}([EW])\0{3}/s) {
|
1161
|
+
|
1162
|
+
# decode freeGPS from Akaso dashcam
|
1163
|
+
# 0000: 00 00 80 00 66 72 65 65 47 50 53 20 60 00 00 00 [....freeGPS `...]
|
1164
|
+
# 0000: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx............]
|
1165
|
+
# 0000: 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 [00000...........]
|
1166
|
+
# 0000: 12 00 00 00 2f 00 00 00 19 00 00 00 41 00 00 00 [..../.......A...]
|
1167
|
+
# 0000: 13 b3 ca 44 4e 00 00 00 29 92 fb 45 45 00 00 00 [...DN...)..EE...]
|
1168
|
+
# 0000: d9 ee b4 41 ec d1 d3 42 e4 07 00 00 01 00 00 00 [...A...B........]
|
1169
|
+
# 0000: 0c 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 [................]
|
1170
|
+
($latRef, $lonRef) = ($1, $2);
|
1171
|
+
($hr, $min, $sec, $yr, $mon, $day) = unpack('x48V3x28V3', $$dataPt);
|
1172
|
+
SetByteOrder('II');
|
1173
|
+
$lat = GetFloat($dataPt, 0x40);
|
1174
|
+
$lon = GetFloat($dataPt, 0x48);
|
1175
|
+
$spd = GetFloat($dataPt, 0x50);
|
1176
|
+
$trk = GetFloat($dataPt, 0x54) + 180; # (why is this off by 180?)
|
1177
|
+
$trk -= 360 if $trk >= 360;
|
1178
|
+
SetByteOrder('MM');
|
1179
|
+
|
1155
1180
|
} else {
|
1156
1181
|
|
1157
1182
|
# decode binary GPS format (Viofo A119S, ref 2)
|
@@ -1359,11 +1384,11 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
1359
1384
|
# 0x7c - int32s[3] accelerometer * 1000
|
1360
1385
|
($latRef, $lonRef) = ($1, $2);
|
1361
1386
|
($hr,$min,$sec,$yr,$mon,$day,@acc) = unpack('x48V3x52V6', $$dataPt);
|
1387
|
+
map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1000 } @acc;
|
1362
1388
|
$lat = GetDouble($dataPt, 0x40);
|
1363
1389
|
$lon = GetDouble($dataPt, 0x50);
|
1364
1390
|
$spd = GetDouble($dataPt, 0x60) * $knotsToKph;
|
1365
1391
|
$trk = GetDouble($dataPt, 0x68);
|
1366
|
-
map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1000 } @acc;
|
1367
1392
|
|
1368
1393
|
} elsif ($$dataPt =~ /^.{72}A([NS])([EW])/s) {
|
1369
1394
|
|
@@ -1977,26 +2002,54 @@ sub ProcessTTAD($$$)
|
|
1977
2002
|
}
|
1978
2003
|
|
1979
2004
|
#------------------------------------------------------------------------------
|
1980
|
-
# Extract information from Insta360 trailer (ref PH)
|
1981
|
-
# Inputs: 0) ExifTool ref
|
1982
|
-
|
2005
|
+
# Extract information from Insta360 trailer (INSV and INSP files) (ref PH)
|
2006
|
+
# Inputs: 0) ExifTool ref, 1) Optional dirInfo ref for returning trailer info
|
2007
|
+
# Returns: true on success
|
2008
|
+
sub ProcessInsta360($;$)
|
1983
2009
|
{
|
1984
2010
|
local $_;
|
1985
|
-
my $et =
|
2011
|
+
my ($et, $dirInfo) = @_;
|
1986
2012
|
my $raf = $$et{RAF};
|
2013
|
+
my $offset = $dirInfo ? $$dirInfo{Offset} || 0 : 0;
|
1987
2014
|
my $buff;
|
1988
2015
|
|
1989
|
-
return unless $raf->Seek(-78, 2) and $raf->Read($buff, 78) == 78 and
|
2016
|
+
return 0 unless $raf->Seek(-78-$offset, 2) and $raf->Read($buff, 78) == 78 and
|
1990
2017
|
substr($buff,-32) eq "8db42d694ccc418790edff439fe026bf"; # check magic number
|
1991
2018
|
|
2019
|
+
my $verbose = $et->Options('Verbose');
|
1992
2020
|
my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
1993
2021
|
my $fileEnd = $raf->Tell();
|
1994
2022
|
my $trailerLen = unpack('x38V', $buff);
|
1995
|
-
$trailerLen > $fileEnd and $et->Warn('Bad
|
2023
|
+
$trailerLen > $fileEnd and $et->Warn('Bad Insta360 trailer size'), return 0;
|
2024
|
+
if ($dirInfo) {
|
2025
|
+
$$dirInfo{DirLen} = $trailerLen if $dirInfo;
|
2026
|
+
$$dirInfo{DataPos} = $fileEnd - $trailerLen;
|
2027
|
+
if ($$dirInfo{OutFile}) {
|
2028
|
+
if ($$et{DEL_GROUP}{Insta360}) {
|
2029
|
+
++$$et{CHANGED};
|
2030
|
+
# just copy the trailer when writing
|
2031
|
+
} elsif ($trailerLen > $fileEnd or not $raf->Seek($$dirInfo{DataPos}, 0) or
|
2032
|
+
$raf->Read(${$$dirInfo{OutFile}}, $trailerLen) != $trailerLen)
|
2033
|
+
{
|
2034
|
+
return 0;
|
2035
|
+
} else {
|
2036
|
+
return 1;
|
2037
|
+
}
|
2038
|
+
}
|
2039
|
+
$et->DumpTrailer($dirInfo) if $verbose or $$et{HTML_DUMP};
|
2040
|
+
}
|
2041
|
+
unless ($et->Options('ExtractEmbedded')) {
|
2042
|
+
# can arrive here when reading Insta360 trailer on JPEG image (INSP file)
|
2043
|
+
$et->WarnOnce('Use ExtractEmbedded option to extract timed metadata from Insta360 trailer',3);
|
2044
|
+
return 1;
|
2045
|
+
}
|
2046
|
+
|
1996
2047
|
my $unknown = $et->Options('Unknown');
|
1997
|
-
|
1998
|
-
my $epos = -78;
|
2048
|
+
# position relative to end of trailer (avoids using large offsets for files > 2 GB)
|
2049
|
+
my $epos = -78-$offset;
|
1999
2050
|
my ($i, $p);
|
2051
|
+
$$et{SET_GROUP0} = 'Trailer';
|
2052
|
+
$$et{SET_GROUP1} = 'Insta360';
|
2000
2053
|
SetByteOrder('II');
|
2001
2054
|
# loop through all records in the trailer, from last to first
|
2002
2055
|
for (;;) {
|
@@ -2005,18 +2058,18 @@ sub ProcessINSVTrailer($)
|
|
2005
2058
|
$raf->Seek($epos, 2) or last;
|
2006
2059
|
my $dlen = $insvDataLen{$id};
|
2007
2060
|
if ($verbose) {
|
2008
|
-
$et->VPrint(0, sprintf("
|
2061
|
+
$et->VPrint(0, sprintf("Insta360 Record 0x%x (offset 0x%x, %d bytes):\n", $id, $fileEnd + $epos, $len));
|
2009
2062
|
}
|
2010
2063
|
# limit the number of records we read if necessary
|
2011
2064
|
if ($insvLimit{$id} and $len > $insvLimit{$id}[1] * $dlen and
|
2012
|
-
$et->Warn("
|
2065
|
+
$et->Warn("Insta360 $insvLimit{$id}[0] data is huge. Processing only the first $insvLimit{$id}[1] records",2))
|
2013
2066
|
{
|
2014
2067
|
$len = $insvLimit{$id}[1] * $dlen;
|
2015
2068
|
}
|
2016
2069
|
$raf->Read($buff, $len) == $len or last;
|
2017
2070
|
$et->VerboseDump(\$buff) if $verbose > 2;
|
2018
2071
|
if ($dlen) {
|
2019
|
-
$len % $dlen and $et->Warn(sprintf('Unexpected
|
2072
|
+
$len % $dlen and $et->Warn(sprintf('Unexpected Insta360 record 0x%x length',$id)), last;
|
2020
2073
|
if ($id == 0x300) {
|
2021
2074
|
for ($p=0; $p<$len; $p+=$dlen) {
|
2022
2075
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
@@ -2068,7 +2121,11 @@ sub ProcessINSVTrailer($)
|
|
2068
2121
|
$raf->Seek($epos, 2) or last;
|
2069
2122
|
$raf->Read($buff, 6) == 6 or last;
|
2070
2123
|
}
|
2124
|
+
$$et{DOC_NUM} = 0;
|
2071
2125
|
SetByteOrder('MM');
|
2126
|
+
delete $$et{SET_GROUP0};
|
2127
|
+
delete $$et{SET_GROUP1};
|
2128
|
+
return 1;
|
2072
2129
|
}
|
2073
2130
|
|
2074
2131
|
#------------------------------------------------------------------------------
|
@@ -2149,8 +2206,8 @@ sub ScanMediaData($)
|
|
2149
2206
|
SetByteOrder($oldByteOrder);
|
2150
2207
|
$$et{INDENT} = substr $$et{INDENT}, 0, -2;
|
2151
2208
|
}
|
2152
|
-
# process
|
2153
|
-
|
2209
|
+
# process Insta360 trailer if it exists
|
2210
|
+
ProcessInsta360($et);
|
2154
2211
|
}
|
2155
2212
|
|
2156
2213
|
1; # end
|