exiftool_vendored 12.42.0 → 12.50.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/Changes +189 -6
- data/bin/MANIFEST +12 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +45 -44
- data/bin/config_files/acdsee.config +2 -1
- data/bin/config_files/frameCount.config +56 -0
- data/bin/config_files/tiff_version.config +1 -1
- data/bin/exiftool +113 -95
- data/bin/fmt_files/gpx.fmt +3 -0
- data/bin/fmt_files/gpx_wpt.fmt +3 -0
- data/bin/lib/Image/ExifTool/Apple.pm +16 -3
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +23 -12
- data/bin/lib/Image/ExifTool/Canon.pm +66 -37
- data/bin/lib/Image/ExifTool/CanonRaw.pm +8 -1
- data/bin/lib/Image/ExifTool/CanonVRD.pm +7 -8
- data/bin/lib/Image/ExifTool/DJI.pm +2 -1
- data/bin/lib/Image/ExifTool/DarwinCore.pm +13 -1
- data/bin/lib/Image/ExifTool/EXE.pm +9 -1
- data/bin/lib/Image/ExifTool/Exif.pm +17 -12
- data/bin/lib/Image/ExifTool/FLAC.pm +17 -3
- data/bin/lib/Image/ExifTool/FLIR.pm +4 -3
- data/bin/lib/Image/ExifTool/FlashPix.pm +26 -3
- data/bin/lib/Image/ExifTool/FujiFilm.pm +51 -4
- data/bin/lib/Image/ExifTool/GPS.pm +21 -1
- data/bin/lib/Image/ExifTool/Geotag.pm +25 -5
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +3 -2
- data/bin/lib/Image/ExifTool/ICO.pm +143 -0
- data/bin/lib/Image/ExifTool/ID3.pm +6 -6
- data/bin/lib/Image/ExifTool/IPTC.pm +5 -1
- data/bin/lib/Image/ExifTool/LNK.pm +5 -2
- data/bin/lib/Image/ExifTool/M2TS.pm +98 -8
- data/bin/lib/Image/ExifTool/MIE.pm +9 -3
- data/bin/lib/Image/ExifTool/MISB.pm +494 -0
- data/bin/lib/Image/ExifTool/MakerNotes.pm +3 -1
- data/bin/lib/Image/ExifTool/Matroska.pm +24 -16
- data/bin/lib/Image/ExifTool/Motorola.pm +8 -2
- data/bin/lib/Image/ExifTool/Nikon.pm +288 -122
- data/bin/lib/Image/ExifTool/NikonSettings.pm +5 -3
- data/bin/lib/Image/ExifTool/Olympus.pm +3 -2
- data/bin/lib/Image/ExifTool/Panasonic.pm +21 -4
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +25 -5
- data/bin/lib/Image/ExifTool/Parrot.pm +96 -2
- data/bin/lib/Image/ExifTool/Pentax.pm +7 -2
- data/bin/lib/Image/ExifTool/Photoshop.pm +29 -3
- data/bin/lib/Image/ExifTool/QuickTime.pm +163 -13
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +119 -13
- data/bin/lib/Image/ExifTool/README +13 -3
- data/bin/lib/Image/ExifTool/RIFF.pm +106 -9
- data/bin/lib/Image/ExifTool/Samsung.pm +2 -2
- data/bin/lib/Image/ExifTool/Sigma.pm +27 -1
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +37 -13
- data/bin/lib/Image/ExifTool/Sony.pm +71 -43
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +3 -1
- data/bin/lib/Image/ExifTool/TagLookup.pm +4737 -4517
- data/bin/lib/Image/ExifTool/TagNames.pod +1837 -1417
- data/bin/lib/Image/ExifTool/Text.pm +3 -4
- data/bin/lib/Image/ExifTool/Torrent.pm +2 -3
- data/bin/lib/Image/ExifTool/Validate.pm +3 -3
- data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +7 -0
- data/bin/lib/Image/ExifTool/WriteExif.pl +100 -23
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +2 -6
- data/bin/lib/Image/ExifTool/WritePhotoshop.pl +5 -5
- data/bin/lib/Image/ExifTool/WriteRIFF.pl +359 -0
- data/bin/lib/Image/ExifTool/Writer.pl +13 -5
- data/bin/lib/Image/ExifTool/XMP.pm +78 -59
- data/bin/lib/Image/ExifTool/XMP2.pl +19 -4
- data/bin/lib/Image/ExifTool.pm +111 -24
- data/bin/lib/Image/ExifTool.pod +83 -69
- data/bin/perl-Image-ExifTool.spec +43 -43
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +9 -4
@@ -47,7 +47,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
47
47
|
use Image::ExifTool::Exif;
|
48
48
|
use Image::ExifTool::GPS;
|
49
49
|
|
50
|
-
$VERSION = '2.
|
50
|
+
$VERSION = '2.80';
|
51
51
|
|
52
52
|
sub ProcessMOV($$;$);
|
53
53
|
sub ProcessKeys($$$);
|
@@ -66,6 +66,7 @@ sub ProcessRIFFTrailer($$$);
|
|
66
66
|
sub ProcessTTAD($$$);
|
67
67
|
sub ProcessNMEA($$$);
|
68
68
|
sub ProcessGPSLog($$$);
|
69
|
+
sub ProcessGarminGPS($$$);
|
69
70
|
sub SaveMetaKeys($$$);
|
70
71
|
# ++^^^^^^^^^^^^++
|
71
72
|
sub ParseItemLocation($$);
|
@@ -521,6 +522,12 @@ my %eeBox2 = (
|
|
521
522
|
return substr($val, 12, $len);
|
522
523
|
},
|
523
524
|
},
|
525
|
+
{
|
526
|
+
Name => 'SkipInfo', # (found in 70mai Pro Plus+ MP4 videos)
|
527
|
+
# (look for something that looks like a QuickTime atom header)
|
528
|
+
Condition => '$$valPt =~ /^\0[\0-\x04]..[a-zA-Z ]{4}/s',
|
529
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::SkipInfo' },
|
530
|
+
},
|
524
531
|
{ Name => 'Skip', Unknown => 1, Binary => 1 },
|
525
532
|
],
|
526
533
|
wide => { Unknown => 1, Binary => 1 },
|
@@ -556,12 +563,16 @@ my %eeBox2 = (
|
|
556
563
|
mdat => { Name => 'MediaData', Unknown => 1, Binary => 1 },
|
557
564
|
'mdat-size' => {
|
558
565
|
Name => 'MediaDataSize',
|
566
|
+
RawConv => '$$self{MediaDataSize} = $val',
|
559
567
|
Notes => q{
|
560
568
|
not a real tag ID, this tag represents the size of the 'mdat' data in bytes
|
561
569
|
and is used in the AvgBitrate calculation
|
562
570
|
},
|
563
571
|
},
|
564
|
-
'mdat-offset' =>
|
572
|
+
'mdat-offset' => {
|
573
|
+
Name => 'MediaDataOffset',
|
574
|
+
RawConv => '$$self{MediaDataOffset} = $val',
|
575
|
+
},
|
565
576
|
junk => { Unknown => 1, Binary => 1 }, #8
|
566
577
|
uuid => [
|
567
578
|
{ #9 (MP4 files)
|
@@ -754,6 +765,19 @@ my %eeBox2 = (
|
|
754
765
|
# 'samn'? - seen in Vantrue N2S sample video
|
755
766
|
);
|
756
767
|
|
768
|
+
# stuff seen in 'skip' atom (70mai Pro Plus+ MP4 videos)
|
769
|
+
%Image::ExifTool::QuickTime::SkipInfo = (
|
770
|
+
PROCESS_PROC => \&ProcessMOV,
|
771
|
+
GROUPS => { 2 => 'Video' },
|
772
|
+
'ver ' => 'Version',
|
773
|
+
# tima - int32u: seen 0x3c
|
774
|
+
thma => {
|
775
|
+
Name => 'ThumbnailImage',
|
776
|
+
Groups => { 2 => 'Preview' },
|
777
|
+
Binary => 1,
|
778
|
+
},
|
779
|
+
);
|
780
|
+
|
757
781
|
# MPEG-4 'ftyp' atom
|
758
782
|
# (ref http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html)
|
759
783
|
%Image::ExifTool::QuickTime::FileType = (
|
@@ -897,7 +921,7 @@ my %eeBox2 = (
|
|
897
921
|
},
|
898
922
|
colr => {
|
899
923
|
Name => 'ColorRepresentation',
|
900
|
-
|
924
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ColorRep' },
|
901
925
|
},
|
902
926
|
pasp => {
|
903
927
|
Name => 'PixelAspectRatio',
|
@@ -1118,6 +1142,23 @@ my %eeBox2 = (
|
|
1118
1142
|
Start => 16,
|
1119
1143
|
},
|
1120
1144
|
},
|
1145
|
+
{
|
1146
|
+
Name => 'GarminGPS',
|
1147
|
+
Condition => '$$valPt=~/^\x9b\x63\x0f\x8d\x63\x74\x40\xec\x82\x04\xbc\x5f\xf5\x09\x17\x28/ and $$self{OPTIONS}{ExtractEmbedded}',
|
1148
|
+
SubDirectory => {
|
1149
|
+
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
1150
|
+
ProcessProc => \&ProcessGarminGPS,
|
1151
|
+
},
|
1152
|
+
},
|
1153
|
+
{
|
1154
|
+
Name => 'GarminGPS',
|
1155
|
+
Condition => '$$valPt=~/^\x9b\x63\x0f\x8d\x63\x74\x40\xec\x82\x04\xbc\x5f\xf5\x09\x17\x28/',
|
1156
|
+
Notes => 'Garmin GPS sensor data',
|
1157
|
+
RawConv => q{
|
1158
|
+
$self->WarnOnce('Use the ExtractEmbedded option to decode timed Garmin GPS',3);
|
1159
|
+
return \$val;
|
1160
|
+
},
|
1161
|
+
},
|
1121
1162
|
{
|
1122
1163
|
Name => 'UUID-Unknown',
|
1123
1164
|
%unknownInfo,
|
@@ -2732,7 +2773,7 @@ my %eeBox2 = (
|
|
2732
2773
|
},
|
2733
2774
|
},{
|
2734
2775
|
Name => 'ColorRepresentation',
|
2735
|
-
|
2776
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ColorRep' },
|
2736
2777
|
}],
|
2737
2778
|
irot => {
|
2738
2779
|
Name => 'Rotation',
|
@@ -2792,6 +2833,78 @@ my %eeBox2 = (
|
|
2792
2833
|
},
|
2793
2834
|
);
|
2794
2835
|
|
2836
|
+
# ref https://aomediacodec.github.io/av1-spec/av1-spec.pdf
|
2837
|
+
%Image::ExifTool::QuickTime::ColorRep = (
|
2838
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
2839
|
+
GROUPS => { 2 => 'Video' },
|
2840
|
+
FIRST_ENTRY => 0,
|
2841
|
+
0 => { Name => 'ColorProfiles', Format => 'undef[4]' },
|
2842
|
+
4 => {
|
2843
|
+
Name => 'ColorPrimaries',
|
2844
|
+
Format => 'int16u',
|
2845
|
+
PrintConv => {
|
2846
|
+
1 => 'BT.709',
|
2847
|
+
2 => 'Unspecified',
|
2848
|
+
4 => 'BT.470 System M (historical)',
|
2849
|
+
5 => 'BT.470 System B, G (historical)',
|
2850
|
+
6 => 'BT.601',
|
2851
|
+
7 => 'SMPTE 240',
|
2852
|
+
8 => 'Generic film (color filters using illuminant C)',
|
2853
|
+
9 => 'BT.2020, BT.2100',
|
2854
|
+
10 => 'SMPTE 428 (CIE 1921 XYZ)',
|
2855
|
+
11 => 'SMPTE RP 431-2',
|
2856
|
+
12 => 'SMPTE EG 432-1',
|
2857
|
+
22 => 'EBU Tech. 3213-E',
|
2858
|
+
},
|
2859
|
+
},
|
2860
|
+
6 => {
|
2861
|
+
Name => 'TransferCharacteristics',
|
2862
|
+
Format => 'int16u',
|
2863
|
+
PrintConv => {
|
2864
|
+
0 => 'For future use (0)',
|
2865
|
+
1 => 'BT.709',
|
2866
|
+
2 => 'Unspecified',
|
2867
|
+
3 => 'For future use (3)',
|
2868
|
+
4 => 'BT.470 System M (historical)',
|
2869
|
+
5 => 'BT.470 System B, G (historical)',
|
2870
|
+
6 => 'BT.601',
|
2871
|
+
7 => 'SMPTE 240 M',
|
2872
|
+
8 => 'Linear',
|
2873
|
+
9 => 'Logarithmic (100 : 1 range)',
|
2874
|
+
10 => 'Logarithmic (100 * Sqrt(10) : 1 range)',
|
2875
|
+
11 => 'IEC 61966-2-4',
|
2876
|
+
12 => 'BT.1361',
|
2877
|
+
13 => 'sRGB or sYCC',
|
2878
|
+
14 => 'BT.2020 10-bit systems',
|
2879
|
+
15 => 'BT.2020 12-bit systems',
|
2880
|
+
16 => 'SMPTE ST 2084, ITU BT.2100 PQ',
|
2881
|
+
17 => 'SMPTE ST 428',
|
2882
|
+
18 => 'BT.2100 HLG, ARIB STD-B67',
|
2883
|
+
},
|
2884
|
+
},
|
2885
|
+
8 => {
|
2886
|
+
Name => 'MatrixCoefficients',
|
2887
|
+
Format => 'int16u',
|
2888
|
+
PrintConv => {
|
2889
|
+
0 => 'Identity matrix',
|
2890
|
+
1 => 'BT.709',
|
2891
|
+
2 => 'Unspecified',
|
2892
|
+
3 => 'For future use (3)',
|
2893
|
+
4 => 'US FCC 73.628',
|
2894
|
+
5 => 'BT.470 System B, G (historical)',
|
2895
|
+
6 => 'BT.601',
|
2896
|
+
7 => 'SMPTE 240 M',
|
2897
|
+
8 => 'YCgCo',
|
2898
|
+
9 => 'BT.2020 non-constant luminance, BT.2100 YCbCr',
|
2899
|
+
10 => 'BT.2020 constant luminance',
|
2900
|
+
11 => 'SMPTE ST 2085 YDzDx',
|
2901
|
+
12 => 'Chromaticity-derived non-constant luminance',
|
2902
|
+
13 => 'Chromaticity-derived constant luminance',
|
2903
|
+
14 => 'BT.2100 ICtCp',
|
2904
|
+
},
|
2905
|
+
},
|
2906
|
+
);
|
2907
|
+
|
2795
2908
|
# HEVC configuration (ref https://github.com/MPEGGroup/isobmff/blob/master/IsoLib/libisomediafile/src/HEVCConfigAtom.c)
|
2796
2909
|
%Image::ExifTool::QuickTime::HEVCConfig = (
|
2797
2910
|
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
@@ -7516,6 +7629,12 @@ my %eeBox2 = (
|
|
7516
7629
|
Format => 'undef[4]',
|
7517
7630
|
RawConv => '$$self{MetaFormat} = $val',
|
7518
7631
|
},
|
7632
|
+
8 => { # starts at 8 for MetaFormat eq 'camm', and 17 for 'mett'
|
7633
|
+
Name => 'MetaType',
|
7634
|
+
Format => 'undef[$size-8]',
|
7635
|
+
# may start at various locations!
|
7636
|
+
RawConv => '$$self{MetaType} = ($val=~/(application[^\0]+)/ ? $1 : undef)',
|
7637
|
+
},
|
7519
7638
|
#
|
7520
7639
|
# Observed offsets for child atoms of various MetaFormat types:
|
7521
7640
|
#
|
@@ -7548,6 +7667,11 @@ my %eeBox2 = (
|
|
7548
7667
|
Format => 'undef[4]',
|
7549
7668
|
RawConv => '$$self{MetaFormat} = $val', # (yes, use MetaFormat for this too)
|
7550
7669
|
},
|
7670
|
+
24 => {
|
7671
|
+
Condition => '$$self{MetaFormat} eq "tmcd"',
|
7672
|
+
Name => 'PlaybackFrameRate', # (may differ from recorded FrameRate eg. ../pics/FujiFilmX-H1.mov)
|
7673
|
+
Format => 'rational64u',
|
7674
|
+
},
|
7551
7675
|
#
|
7552
7676
|
# Observed offsets for child atoms of various OtherFormat types:
|
7553
7677
|
#
|
@@ -8000,9 +8124,12 @@ sub AUTOLOAD
|
|
8000
8124
|
# Returns: 9-element rotation matrix as a string (with 0 x/y offsets)
|
8001
8125
|
sub GetRotationMatrix($)
|
8002
8126
|
{
|
8003
|
-
my $ang = 3.
|
8127
|
+
my $ang = 3.14159265358979323846264 * shift() / 180;
|
8004
8128
|
my $cos = cos $ang;
|
8005
8129
|
my $sin = sin $ang;
|
8130
|
+
# round to zero
|
8131
|
+
$cos = 0 if abs($cos) < 1e-12;
|
8132
|
+
$sin = 0 if abs($sin) < 1e-12;
|
8006
8133
|
my $msn = -$sin;
|
8007
8134
|
return "$cos $sin 0 $msn $cos 0 0 0 1";
|
8008
8135
|
}
|
@@ -8583,7 +8710,7 @@ sub HandleItemInfo($)
|
|
8583
8710
|
$et->VPrint(0, "$$et{INDENT}Item $id) '${type}' ($len bytes)\n");
|
8584
8711
|
}
|
8585
8712
|
# get ExifTool name for this item
|
8586
|
-
my $name = { Exif => 'EXIF', 'application/rdf+xml' => 'XMP' }->{$type} || '';
|
8713
|
+
my $name = { Exif => 'EXIF', 'application/rdf+xml' => 'XMP', jpeg => 'PreviewImage' }->{$type} || '';
|
8587
8714
|
my ($warn, $extent);
|
8588
8715
|
$warn = "Can't currently decode encoded $type metadata" if $$item{ContentEncoding};
|
8589
8716
|
$warn = "Can't currently decode protected $type metadata" if $$item{ProtectionIndex};
|
@@ -8660,6 +8787,21 @@ sub HandleItemInfo($)
|
|
8660
8787
|
}
|
8661
8788
|
$subTable = GetTagTable('Image::ExifTool::Exif::Main');
|
8662
8789
|
$proc = \&Image::ExifTool::ProcessTIFF;
|
8790
|
+
} elsif ($name eq 'PreviewImage') {
|
8791
|
+
# take a quick stab at determining the size of the image
|
8792
|
+
# (based on JPEG previews found in Fuji X-H2S HIF images)
|
8793
|
+
my $type = 'PreviewImage';
|
8794
|
+
if ($buff =~ /^.{556}\xff\xc0\0\x11.(.{4})/s) {
|
8795
|
+
my ($h, $w) = unpack('n2', $1);
|
8796
|
+
# (not sure if $h is ever the long dimension, but test it just in case)
|
8797
|
+
if ($w == 160 or $h == 160) {
|
8798
|
+
$type = 'ThumbnailImage';
|
8799
|
+
} elsif ($w == 1920 or $h == 1920) {
|
8800
|
+
$type = 'OtherImage'; # (large preview)
|
8801
|
+
} # (PreviewImage is 640x480)
|
8802
|
+
}
|
8803
|
+
$et->FoundTag($type => $buff);
|
8804
|
+
next;
|
8663
8805
|
} else {
|
8664
8806
|
$start = 0;
|
8665
8807
|
$subTable = GetTagTable('Image::ExifTool::XMP::Main');
|
@@ -9100,12 +9242,13 @@ sub ProcessMOV($$;$)
|
|
9100
9242
|
# temporarily set ExtractEmbedded option for CRX files
|
9101
9243
|
$saveOptions{ExtractEmbedded} = $et->Options(ExtractEmbedded => 1) if $fileType eq 'CRX';
|
9102
9244
|
} else {
|
9103
|
-
$et->SetFileType();
|
9245
|
+
$et->SetFileType(); # MOV
|
9104
9246
|
}
|
9105
9247
|
SetByteOrder('MM');
|
9106
9248
|
$$et{PRIORITY_DIR} = 'XMP'; # have XMP take priority
|
9107
9249
|
}
|
9108
|
-
|
9250
|
+
my $fast = $$et{OPTIONS}{FastScan} || 0;
|
9251
|
+
$$raf{NoBuffer} = 1 if $fast; # disable buffering in FastScan mode
|
9109
9252
|
|
9110
9253
|
my $ee = $$et{OPTIONS}{ExtractEmbedded};
|
9111
9254
|
if ($ee) {
|
@@ -9133,8 +9276,10 @@ sub ProcessMOV($$;$)
|
|
9133
9276
|
$et->VPrint(0,"$$et{INDENT}Tag '${t}' extends to end of file");
|
9134
9277
|
if ($$tagTablePtr{"$tag-size"}) {
|
9135
9278
|
my $pos = $raf->Tell();
|
9136
|
-
$
|
9137
|
-
|
9279
|
+
unless ($fast) {
|
9280
|
+
$raf->Seek(0, 2);
|
9281
|
+
$et->HandleTag($tagTablePtr, "$tag-size", $raf->Tell() - $pos);
|
9282
|
+
}
|
9138
9283
|
$et->HandleTag($tagTablePtr, "$tag-offset", $pos) if $$tagTablePtr{"$tag-offset"};
|
9139
9284
|
}
|
9140
9285
|
}
|
@@ -9237,6 +9382,8 @@ sub ProcessMOV($$;$)
|
|
9237
9382
|
$et->HandleTag($tagTablePtr, "$tag-size", $size);
|
9238
9383
|
$et->HandleTag($tagTablePtr, "$tag-offset", $raf->Tell()) if $$tagTablePtr{"$tag-offset"};
|
9239
9384
|
}
|
9385
|
+
# stop processing at mdat/idat if -fast2 is used
|
9386
|
+
last if $fast > 1 and ($tag eq 'mdat' or $tag eq 'idat');
|
9240
9387
|
# load values only if associated with a tag (or verbose) and not too big
|
9241
9388
|
if ($size > 0x2000000) { # start to get worried above 32 MB
|
9242
9389
|
# check for RIFF trailer (written by Auto-Vox dashcam)
|
@@ -9555,10 +9702,14 @@ ItemID: foreach $id (keys %$items) {
|
|
9555
9702
|
require Image::ExifTool::Font;
|
9556
9703
|
$lang = $Image::ExifTool::Font::ttLang{Macintosh}{$lang};
|
9557
9704
|
}
|
9705
|
+
} else {
|
9706
|
+
# for the default language code of 0x0000, use UTF-8 instead
|
9707
|
+
# of the CharsetQuickTime setting if obviously UTF8
|
9708
|
+
$enc = 'UTF8' if Image::ExifTool::IsUTF8(\$str) > 0;
|
9558
9709
|
}
|
9559
9710
|
# the spec says only "Macintosh text encoding", but
|
9560
9711
|
# allow this to be configured by the user
|
9561
|
-
$enc = $charsetQuickTime;
|
9712
|
+
$enc = $charsetQuickTime unless $enc;
|
9562
9713
|
} else {
|
9563
9714
|
# convert language code to ASCII (ignore read-only bit)
|
9564
9715
|
$lang = UnpackLang($lang);
|
@@ -9599,8 +9750,7 @@ ItemID: foreach $id (keys %$items) {
|
|
9599
9750
|
if (not ref $$vp and length($$vp) <= 65536 and $$vp =~ /[\x80-\xff]/) {
|
9600
9751
|
# the encoding of this is not specified, so use CharsetQuickTime
|
9601
9752
|
# unless the string is valid UTF-8
|
9602
|
-
|
9603
|
-
my $enc = Image::ExifTool::XMP::IsUTF8($vp) > 0 ? 'UTF8' : $charsetQuickTime;
|
9753
|
+
my $enc = Image::ExifTool::IsUTF8($vp) > 0 ? 'UTF8' : $charsetQuickTime;
|
9604
9754
|
$$vp = $et->Decode($$vp, $enc);
|
9605
9755
|
}
|
9606
9756
|
}
|
@@ -27,6 +27,8 @@ sub ProcessFreeGPS2($$$);
|
|
27
27
|
sub Process360Fly($$$);
|
28
28
|
sub ProcessFMAS($$$);
|
29
29
|
|
30
|
+
my $debug; # set to 1 for extra debugging messages
|
31
|
+
|
30
32
|
# QuickTime data types that have ExifTool equivalents
|
31
33
|
# (ref https://developer.apple.com/library/content/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW35)
|
32
34
|
my %qtFmt = (
|
@@ -80,7 +82,7 @@ my %processByMetaFormat = (
|
|
80
82
|
|
81
83
|
# data lengths for each INSV record type
|
82
84
|
my %insvDataLen = (
|
83
|
-
0x300 =>
|
85
|
+
0x300 => 0, # accelerometer (could be either 20 or 56 bytes)
|
84
86
|
0x400 => 16, # exposure (ref 6)
|
85
87
|
0x600 => 8, # timestamps (ref 6)
|
86
88
|
0x700 => 53, # GPS
|
@@ -99,7 +101,7 @@ my %insvLimit = (
|
|
99
101
|
The tags below are extracted from timed metadata in QuickTime and other
|
100
102
|
formats of video files when the ExtractEmbedded option is used. Although
|
101
103
|
most of these tags are combined into the single table below, ExifTool
|
102
|
-
currently reads
|
104
|
+
currently reads 62 different formats of timed GPS metadata from video files.
|
103
105
|
},
|
104
106
|
VARS => { NO_ID => 1 },
|
105
107
|
GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
|
@@ -896,10 +898,15 @@ sub Process_text($$$)
|
|
896
898
|
my $time = "$1:$2:$3";
|
897
899
|
if ($$et{LastTime}) {
|
898
900
|
if ($$et{LastTime} eq $time) {
|
901
|
+
# combine with the previous NMEA sentence
|
899
902
|
$$et{DOC_NUM} = $$et{LastDoc};
|
900
903
|
} elsif (%tags) {
|
904
|
+
# handle existing tags and start a new document
|
905
|
+
# (see https://exiftool.org/forum/index.php?msg=75422)
|
901
906
|
HandleTextTags($et, $tagTbl, \%tags);
|
902
|
-
|
907
|
+
undef %tags;
|
908
|
+
# increment document number and update document count if necessary
|
909
|
+
$$et{DOC_COUNT} < ++$$et{DOC_NUM} and $$et{DOC_COUNT} = $$et{DOC_NUM};
|
903
910
|
}
|
904
911
|
}
|
905
912
|
$$et{LastTime} = $time;
|
@@ -918,7 +925,8 @@ sub Process_text($$$)
|
|
918
925
|
$$et{DOC_NUM} = $$et{LastDoc};
|
919
926
|
} elsif (%tags) {
|
920
927
|
HandleTextTags($et, $tagTbl, \%tags);
|
921
|
-
|
928
|
+
undef %tags;
|
929
|
+
$$et{DOC_COUNT} < ++$$et{DOC_NUM} and $$et{DOC_COUNT} = $$et{DOC_NUM};
|
922
930
|
}
|
923
931
|
}
|
924
932
|
$$et{LastTime} = $time;
|
@@ -1416,6 +1424,7 @@ sub ProcessFreeGPS($$$)
|
|
1416
1424
|
} elsif ($buf2 =~ /^.{173}([-+]\d{3})([-+]\d{3})([-+]\d{3})/s) { # (Azdome)
|
1417
1425
|
@acc = ($1/100, $2/100, $3/100);
|
1418
1426
|
}
|
1427
|
+
$debug and $et->FoundTag(GPSType => '1A');
|
1419
1428
|
|
1420
1429
|
} elsif ($$dataPt =~ /^.{52}(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/s) {
|
1421
1430
|
|
@@ -1444,6 +1453,7 @@ sub ProcessFreeGPS($$$)
|
|
1444
1453
|
# change to signed integer and divide by 256
|
1445
1454
|
map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
|
1446
1455
|
}
|
1456
|
+
$debug and $et->FoundTag(GPSType => '1B');
|
1447
1457
|
|
1448
1458
|
} elsif ($$dataPt =~ /^.{37}\0\0\0A([NS])([EW])/s) {
|
1449
1459
|
|
@@ -1454,13 +1464,27 @@ sub ProcessFreeGPS($$$)
|
|
1454
1464
|
# 0030: f1 47 40 46 66 66 d2 41 85 eb 83 41 00 00 00 00 [.G@Fff.A...A....]
|
1455
1465
|
($latRef, $lonRef) = ($1, $2);
|
1456
1466
|
($hr,$min,$sec,$yr,$mon,$day) = unpack('x16V6', $$dataPt);
|
1457
|
-
$yr
|
1467
|
+
if ($yr < 2000) {
|
1468
|
+
$yr += 2000;
|
1469
|
+
} else {
|
1470
|
+
# Kenwood dashcam sometimes stores absolute year and local time
|
1471
|
+
# (but sometimes year since 2000 and UTC time in same video!)
|
1472
|
+
require Time::Local;
|
1473
|
+
my $time = Image::ExifTool::TimeLocal($sec,$min,$hr,$day,$mon-1,$yr-1900);
|
1474
|
+
($sec,$min,$hr,$day,$mon,$yr) = gmtime($time);
|
1475
|
+
$yr += 1900;
|
1476
|
+
++$mon;
|
1477
|
+
$et->WarnOnce('Converting GPSDateTime to UTC based on local time zone',1);
|
1478
|
+
}
|
1458
1479
|
SetByteOrder('II');
|
1459
1480
|
$lat = GetFloat($dataPt, 0x2c);
|
1460
1481
|
$lon = GetFloat($dataPt, 0x30);
|
1461
1482
|
$spd = GetFloat($dataPt, 0x34) * $knotsToKph; # (convert knots to km/h)
|
1462
1483
|
$trk = GetFloat($dataPt, 0x38);
|
1484
|
+
@acc = unpack('x60V3', $$dataPt); # (may be all zeros if not valid)
|
1485
|
+
map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
|
1463
1486
|
SetByteOrder('MM');
|
1487
|
+
$debug and $et->FoundTag(GPSType => '1C');
|
1464
1488
|
|
1465
1489
|
} elsif ($$dataPt =~ /^.{21}\0\0\0A([NS])([EW])/s) {
|
1466
1490
|
|
@@ -1489,6 +1513,7 @@ sub ProcessFreeGPS($$$)
|
|
1489
1513
|
$acc[1] = GetFloat($dataPt, 0x30);
|
1490
1514
|
$acc[2] = GetFloat($dataPt, 0x34);
|
1491
1515
|
SetByteOrder('MM');
|
1516
|
+
$debug and $et->FoundTag(GPSType => '1D');
|
1492
1517
|
|
1493
1518
|
} elsif ($$dataPt =~ /^.{60}A\0{3}.{4}([NS])\0{3}.{4}([EW])\0{3}/s) {
|
1494
1519
|
|
@@ -1509,6 +1534,7 @@ sub ProcessFreeGPS($$$)
|
|
1509
1534
|
$trk = GetFloat($dataPt, 0x54) + 180; # (why is this off by 180?)
|
1510
1535
|
$trk -= 360 if $trk >= 360;
|
1511
1536
|
SetByteOrder('MM');
|
1537
|
+
$debug and $et->FoundTag(GPSType => '1E');
|
1512
1538
|
|
1513
1539
|
} elsif ($$dataPt =~ /^.{60}4W`b]S</s and length($$dataPt) >= 140) {
|
1514
1540
|
|
@@ -1526,8 +1552,9 @@ sub ProcessFreeGPS($$$)
|
|
1526
1552
|
$yr += ($yr >= 70 ? 1900 : 2000);
|
1527
1553
|
$spd = $9 * $knotsToKph if length $9;
|
1528
1554
|
$trk = $10 if length $10;
|
1555
|
+
$debug and $et->FoundTag(GPSType => '1F');
|
1529
1556
|
|
1530
|
-
} elsif ($$dataPt =~ /^.{64}[\x01-\x0c]\0{3}[\x01-\x1f]\0{3}A[NS][EW]\0/s) {
|
1557
|
+
} elsif ($$dataPt =~ /^.{64}[\x01-\x0c]\0{3}[\x01-\x1f]\0{3}A[NS][EW]\0{5}/s) {
|
1531
1558
|
|
1532
1559
|
# Akaso V1 dascham
|
1533
1560
|
# 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 00 00 00 [....freeGPS x...]
|
@@ -1569,6 +1596,7 @@ sub ProcessFreeGPS($$$)
|
|
1569
1596
|
|
1570
1597
|
SetByteOrder('MM');
|
1571
1598
|
#my $serialNum = substr($$dataPt, 0x68, 20);
|
1599
|
+
$debug and $et->FoundTag(GPSType => '1G');
|
1572
1600
|
|
1573
1601
|
} elsif ($$dataPt =~ /^.{12}\xac\0\0\0.{44}(.{72})/s) {
|
1574
1602
|
|
@@ -1591,6 +1619,7 @@ sub ProcessFreeGPS($$$)
|
|
1591
1619
|
# bytes 7-12 are the timestamp in ASCII HHMMSS after xor-ing with 0x70
|
1592
1620
|
substr($time,7,6) = pack 'C*', map { $_ ^= 0x70 } unpack 'C*', substr($time,7,6);
|
1593
1621
|
# (other values are currently unknown)
|
1622
|
+
$debug and $et->FoundTag(GPSType => '1H');
|
1594
1623
|
|
1595
1624
|
} elsif ($$dataPt =~ /^.{64}A([NS])([EW])\0/s) {
|
1596
1625
|
|
@@ -1616,6 +1645,7 @@ sub ProcessFreeGPS($$$)
|
|
1616
1645
|
$trk = GetFloat($dataPt, 0x68);
|
1617
1646
|
$alt = GetFloat($dataPt, 0x6c);
|
1618
1647
|
SetByteOrder('MM');
|
1648
|
+
$debug and $et->FoundTag(GPSType => '1I');
|
1619
1649
|
|
1620
1650
|
} else {
|
1621
1651
|
|
@@ -1624,6 +1654,9 @@ sub ProcessFreeGPS($$$)
|
|
1624
1654
|
# 0000: 00 00 80 00 66 72 65 65 47 50 53 20 4c 00 00 00 [....freeGPS L...]
|
1625
1655
|
# 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
|
1626
1656
|
# 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
|
1657
|
+
# 0030: 10 00 00 00 2d 00 00 00 14 00 00 00 11 00 00 00 [....-...........]
|
1658
|
+
# 0040: 0c 00 00 00 1f 00 00 00 41 4e 45 00 5d 9a a9 45 [........ANE.]..E]
|
1659
|
+
# 0050: ab 1e e5 44 ec 51 f0 40 b8 5e a5 43 00 00 00 00 [...D.Q.@.^.C....]
|
1627
1660
|
# (records are same structure as Type 3 Novatek GPS in ProcessFreeGPS2() below)
|
1628
1661
|
($hr,$min,$sec,$yr,$mon,$day,$stat,$latRef,$lonRef,$lat,$lon,$spd,$trk) =
|
1629
1662
|
unpack('x48V6a1a1a1x1V4', $$dataPt);
|
@@ -1649,6 +1682,7 @@ sub ProcessFreeGPS($$$)
|
|
1649
1682
|
$yr += 2000 if $yr < 2000;
|
1650
1683
|
$spd *= $knotsToKph; # convert speed to km/h
|
1651
1684
|
# ($trk is not confirmed; may be GPSImageDirection, ref PH)
|
1685
|
+
$debug and $et->FoundTag(GPSType => '1J');
|
1652
1686
|
}
|
1653
1687
|
#
|
1654
1688
|
# save tag values extracted by above code
|
@@ -1802,6 +1836,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
1802
1836
|
}
|
1803
1837
|
# save position of most recent record (needed when parsing the next freeGPS block)
|
1804
1838
|
$$et{FreeGPS2}{RecentRecPos} = $lastRecPos;
|
1839
|
+
$debug and $et->FoundTag(GPSType => '2A');
|
1805
1840
|
return 1;
|
1806
1841
|
|
1807
1842
|
} elsif ($$dataPt =~ /^.{60}A\0.{10}([NS])\0.{14}([EW])\0/s) {
|
@@ -1833,6 +1868,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
1833
1868
|
$lon = GetDouble($dataPt, 0x50);
|
1834
1869
|
$spd = GetDouble($dataPt, 0x60) * $knotsToKph;
|
1835
1870
|
$trk = GetDouble($dataPt, 0x68);
|
1871
|
+
$debug and $et->FoundTag(GPSType => '2B');
|
1836
1872
|
|
1837
1873
|
} elsif ($$dataPt =~ /^.{72}A([NS])([EW])/s) {
|
1838
1874
|
|
@@ -1869,6 +1905,8 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
1869
1905
|
$lon = abs Get32s($dataPt, 0x50) / 1e7;
|
1870
1906
|
$spd = Get32s($dataPt, 0x54) / 100 * $mpsToKph;
|
1871
1907
|
$alt = GetFloat($dataPt, 0x58) / 1000; # (NC)
|
1908
|
+
$debug and $et->FoundTag(GPSType => '2C');
|
1909
|
+
|
1872
1910
|
} else {
|
1873
1911
|
# Type 3 (ref 2)
|
1874
1912
|
# (no sample with this format)
|
@@ -1876,6 +1914,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
1876
1914
|
$lon = GetFloat($dataPt, 0x50);
|
1877
1915
|
$spd = GetFloat($dataPt, 0x54) * $knotsToKph;
|
1878
1916
|
$trk = GetFloat($dataPt, 0x58);
|
1917
|
+
$debug and $et->FoundTag(GPSType => '2D');
|
1879
1918
|
}
|
1880
1919
|
|
1881
1920
|
} elsif ($$dataPt =~ /^.{60}A\0.{6}([NS])\0.{6}([EW])\0/s and $dirLen >= 112) {
|
@@ -1896,6 +1935,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
1896
1935
|
$lon = GetFloat($dataPt, 0x48);
|
1897
1936
|
$spd = GetFloat($dataPt, 0x50);
|
1898
1937
|
$trk = GetFloat($dataPt, 0x54);
|
1938
|
+
$debug and $et->FoundTag(GPSType => '2E');
|
1899
1939
|
|
1900
1940
|
} elsif ($$dataPt =~ /^.{16}A([NS])([EW])\0/s) {
|
1901
1941
|
|
@@ -1916,6 +1956,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
1916
1956
|
$et->HandleTag($tagTbl, GPSTrack => $trk);
|
1917
1957
|
$et->HandleTag($tagTbl, Accelerometer => "@acc");
|
1918
1958
|
}
|
1959
|
+
$debug and $et->FoundTag(GPSType => '2F');
|
1919
1960
|
return 1;
|
1920
1961
|
|
1921
1962
|
} else {
|
@@ -1962,6 +2003,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
1962
2003
|
$et->HandleTag($tagTbl, GPSTrack => $trk);
|
1963
2004
|
last if $pos += 0x20 > length($$dataPt) - 0x1e;
|
1964
2005
|
}
|
2006
|
+
$debug and $et->FoundTag(GPSType => '2G');
|
1965
2007
|
return $$et{DOC_NUM} ? 1 : 0; # return 0 if nothing extracted
|
1966
2008
|
}
|
1967
2009
|
#
|
@@ -2530,7 +2572,7 @@ sub ProcessTTAD($$$)
|
|
2530
2572
|
# (I think "5" may be the number of satellites. seen: 5,6,7 - PH)
|
2531
2573
|
FoundSomething($et, $tagTbl, $sampleTime / 1000);
|
2532
2574
|
my $t = GetDouble($dataPt, $pos);
|
2533
|
-
$et->HandleTag($tagTbl, GPSDateTime => Image::ExifTool::ConvertUnixTime($t,undef,3).'Z');
|
2575
|
+
$et->HandleTag($tagTbl, GPSDateTime => Image::ExifTool::ConvertUnixTime($t,undef,3) . 'Z');
|
2534
2576
|
$et->HandleTag($tagTbl, GPSLatitude => GetDouble($dataPt, $pos+0x1c));
|
2535
2577
|
$et->HandleTag($tagTbl, GPSLongitude => GetDouble($dataPt, $pos+0x24));
|
2536
2578
|
$et->HandleTag($tagTbl, GPSAltitude => GetDouble($dataPt, $pos+0x14));
|
@@ -2621,8 +2663,33 @@ sub ProcessInsta360($;$)
|
|
2621
2663
|
if ($verbose) {
|
2622
2664
|
$et->VPrint(0, sprintf("Insta360 Record 0x%x (offset 0x%x, %d bytes):\n", $id, $fileEnd + $epos, $len));
|
2623
2665
|
}
|
2666
|
+
# there are 2 types of record 0x300:
|
2667
|
+
# 1. 56 byte records
|
2668
|
+
# 0000: 4a f7 02 00 00 00 00 00 00 00 00 00 00 1e e7 3f [J..............?]
|
2669
|
+
# 0010: 00 00 00 00 00 b2 ef bf 00 00 00 00 00 70 c1 bf [.............p..]
|
2670
|
+
# 0020: 00 00 00 e0 91 5c 8c bf 00 00 00 20 8f ff 87 bf [.....\..... ....]
|
2671
|
+
# 0030: 00 00 00 00 88 7f c9 bf
|
2672
|
+
# 2. 20 byte records
|
2673
|
+
# 0000: c1 d8 d9 0b 00 00 00 00 f5 83 14 80 df 7f fe 7f [................]
|
2674
|
+
# 0010: fe 7f 01 80
|
2675
|
+
if ($id == 0x300) {
|
2676
|
+
if ($len % 20 and not $len % 56) {
|
2677
|
+
$dlen = 56;
|
2678
|
+
} elsif ($len % 56 and not $len % 20) {
|
2679
|
+
$dlen = 20;
|
2680
|
+
} else {
|
2681
|
+
if ($raf->Read($buff, 20) == 20) {
|
2682
|
+
if (substr($buff, 16, 3) eq "\0\0\0") {
|
2683
|
+
$dlen = 56;
|
2684
|
+
} else {
|
2685
|
+
$dlen = 20;
|
2686
|
+
}
|
2687
|
+
}
|
2688
|
+
$raf->Seek($epos, 2) or last;
|
2689
|
+
}
|
2690
|
+
}
|
2624
2691
|
# limit the number of records we read if necessary
|
2625
|
-
if ($insvLimit{$id} and $len > $insvLimit{$id}[1] * $dlen and
|
2692
|
+
if ($dlen and $insvLimit{$id} and $len > $insvLimit{$id}[1] * $dlen and
|
2626
2693
|
$et->Warn("Insta360 $insvLimit{$id}[0] data is huge. Processing only the first $insvLimit{$id}[1] records",2))
|
2627
2694
|
{
|
2628
2695
|
$len = $insvLimit{$id}[1] * $dlen;
|
@@ -2630,11 +2697,18 @@ sub ProcessInsta360($;$)
|
|
2630
2697
|
$raf->Read($buff, $len) == $len or last;
|
2631
2698
|
$et->VerboseDump(\$buff) if $verbose > 2;
|
2632
2699
|
if ($dlen) {
|
2633
|
-
$len % $dlen
|
2634
|
-
|
2700
|
+
if ($len % $dlen) {
|
2701
|
+
$et->Warn(sprintf('Unexpected Insta360 record 0x%x length',$id));
|
2702
|
+
} elsif ($id == 0x300) {
|
2635
2703
|
for ($p=0; $p<$len; $p+=$dlen) {
|
2636
2704
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
2637
|
-
my @a
|
2705
|
+
my @a;
|
2706
|
+
if ($dlen == 56) {
|
2707
|
+
@a = map { GetDouble(\$buff, $p + 8 * $_) } 1..6;
|
2708
|
+
} else {
|
2709
|
+
@a = unpack("x${p}x8v6", $buff);
|
2710
|
+
map { $_ = ($_ - 0x8000) / 1000 } @a;
|
2711
|
+
}
|
2638
2712
|
$et->HandleTag($tagTbl, TimeCode => sprintf('%.3f', Get64u(\$buff, $p) / 1000));
|
2639
2713
|
$et->HandleTag($tagTbl, Accelerometer => "@a[0..2]"); # (NC)
|
2640
2714
|
$et->HandleTag($tagTbl, AngularVelocity => "@a[3..5]"); # (NC)
|
@@ -2699,6 +2773,38 @@ sub ProcessInsta360($;$)
|
|
2699
2773
|
return 1;
|
2700
2774
|
}
|
2701
2775
|
|
2776
|
+
#------------------------------------------------------------------------------
|
2777
|
+
# Process Garmin GPS 'uuid' atom (ref PH)
|
2778
|
+
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|
2779
|
+
# Returns: 1 on success
|
2780
|
+
# Note: This format is used by the Garmin DriveAssist 51, but the DriveAssist 50
|
2781
|
+
# uses a completely different format. :(
|
2782
|
+
sub ProcessGarminGPS($$$)
|
2783
|
+
{
|
2784
|
+
my ($et, $dirInfo, $tagTbl) = @_;
|
2785
|
+
my $dataPt = $$dirInfo{DataPt};
|
2786
|
+
my $dataLen = length $$dataPt;
|
2787
|
+
my $pos = 33;
|
2788
|
+
my $epoch = (66 * 365 + 17) * 24 * 3600; # time is relative to Jan 1, 1904
|
2789
|
+
my $scl = 180 / (32768 * 65536); # scaling factor for lat/lon
|
2790
|
+
$et->VerboseDir('GarminGPS');
|
2791
|
+
while ($pos + 20 <= $dataLen) {
|
2792
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
2793
|
+
my $time = Image::ExifTool::ConvertUnixTime(Get32u($dataPt, $pos) - $epoch) . 'Z';
|
2794
|
+
my $lat = Get32s($dataPt, $pos + 12) * $scl;
|
2795
|
+
my $lon = Get32s($dataPt, $pos + 16) * $scl;
|
2796
|
+
my $spd = Get16u($dataPt, $pos + 4); # (in mph)
|
2797
|
+
$et->HandleTag($tagTbl, 'GPSDateTime', $time);
|
2798
|
+
$et->HandleTag($tagTbl, 'GPSLatitude', $lat);
|
2799
|
+
$et->HandleTag($tagTbl, 'GPSLongitude', $lon);
|
2800
|
+
$et->HandleTag($tagTbl, 'GPSSpeed', $spd);
|
2801
|
+
$et->HandleTag($tagTbl, 'GPSSpeedRef', 'M');
|
2802
|
+
$pos += 20;
|
2803
|
+
}
|
2804
|
+
delete $$et{DOC_NUM};
|
2805
|
+
return 1;
|
2806
|
+
}
|
2807
|
+
|
2702
2808
|
#------------------------------------------------------------------------------
|
2703
2809
|
# Process 360Fly 'uuid' atom containing sensor data
|
2704
2810
|
# (ref https://github.com/JamesHeinrich/getID3/blob/master/getid3/module.audio-video.quicktime.php)
|
@@ -2776,9 +2882,9 @@ sub ScanMediaData($)
|
|
2776
2882
|
my ($pos, $buf2) = (0, '');
|
2777
2883
|
|
2778
2884
|
# don't rescan for freeGPS if we already found embedded metadata
|
2779
|
-
my $dataPos = $$et{
|
2885
|
+
my $dataPos = $$et{MediaDataOffset};
|
2780
2886
|
if ($dataPos and not $$et{DOC_COUNT}) {
|
2781
|
-
$dataLen = $$et{
|
2887
|
+
$dataLen = $$et{MediaDataSize};
|
2782
2888
|
if ($dataLen) {
|
2783
2889
|
if ($raf->Seek($dataPos, 0)) {
|
2784
2890
|
$$et{FreeGPS2} = { }; # initialize variable space for FreeGPS2()
|