exiftool_vendored 13.10.0 → 13.12.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 +33 -0
- data/bin/MANIFEST +1 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +3 -3
- data/bin/exiftool +206 -148
- data/bin/lib/File/RandomAccess.pm +1 -1
- data/bin/lib/File/RandomAccess.pod +2 -2
- data/bin/lib/Image/ExifTool/AAC.pm +1 -1
- data/bin/lib/Image/ExifTool/AES.pm +1 -1
- data/bin/lib/Image/ExifTool/AFCP.pm +1 -1
- data/bin/lib/Image/ExifTool/AIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/APE.pm +1 -1
- data/bin/lib/Image/ExifTool/APP12.pm +1 -1
- data/bin/lib/Image/ExifTool/ASF.pm +1 -1
- data/bin/lib/Image/ExifTool/Apple.pm +1 -1
- data/bin/lib/Image/ExifTool/Audible.pm +1 -1
- data/bin/lib/Image/ExifTool/BMP.pm +1 -1
- data/bin/lib/Image/ExifTool/BPG.pm +1 -1
- data/bin/lib/Image/ExifTool/BZZ.pm +1 -1
- data/bin/lib/Image/ExifTool/BigTIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +6 -6
- data/bin/lib/Image/ExifTool/CBOR.pm +1 -1
- data/bin/lib/Image/ExifTool/Canon.pm +8 -4
- data/bin/lib/Image/ExifTool/CanonCustom.pm +1 -1
- data/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/CanonVRD.pm +1 -1
- data/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
- data/bin/lib/Image/ExifTool/Casio.pm +1 -1
- data/bin/lib/Image/ExifTool/Charset.pm +1 -1
- data/bin/lib/Image/ExifTool/DICOM.pm +1 -1
- data/bin/lib/Image/ExifTool/DJI.pm +96 -45
- data/bin/lib/Image/ExifTool/DNG.pm +1 -1
- data/bin/lib/Image/ExifTool/DPX.pm +1 -1
- data/bin/lib/Image/ExifTool/DV.pm +1 -1
- data/bin/lib/Image/ExifTool/DarwinCore.pm +1 -1
- data/bin/lib/Image/ExifTool/DjVu.pm +1 -1
- data/bin/lib/Image/ExifTool/EXE.pm +123 -32
- data/bin/lib/Image/ExifTool/Exif.pm +7 -4
- data/bin/lib/Image/ExifTool/FITS.pm +1 -1
- data/bin/lib/Image/ExifTool/FLAC.pm +1 -1
- data/bin/lib/Image/ExifTool/FLIF.pm +1 -1
- data/bin/lib/Image/ExifTool/FLIR.pm +1 -1
- data/bin/lib/Image/ExifTool/Fixup.pm +1 -1
- data/bin/lib/Image/ExifTool/Flash.pm +1 -1
- data/bin/lib/Image/ExifTool/FlashPix.pm +1 -1
- data/bin/lib/Image/ExifTool/Font.pm +1 -1
- data/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
- data/bin/lib/Image/ExifTool/FujiFilm.pm +1 -1
- data/bin/lib/Image/ExifTool/GE.pm +1 -1
- data/bin/lib/Image/ExifTool/GIF.pm +1 -1
- data/bin/lib/Image/ExifTool/GIMP.pm +1 -1
- data/bin/lib/Image/ExifTool/GM.pm +1 -1
- data/bin/lib/Image/ExifTool/GPS.pm +1 -1
- data/bin/lib/Image/ExifTool/GeoTiff.pm +1 -1
- data/bin/lib/Image/ExifTool/Geolocation.pm +1 -1
- data/bin/lib/Image/ExifTool/Geotag.pm +1 -1
- data/bin/lib/Image/ExifTool/GoPro.pm +1 -1
- data/bin/lib/Image/ExifTool/H264.pm +1 -1
- data/bin/lib/Image/ExifTool/HP.pm +1 -1
- data/bin/lib/Image/ExifTool/HTML.pm +1 -1
- data/bin/lib/Image/ExifTool/HtmlDump.pm +1 -1
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +1 -1
- data/bin/lib/Image/ExifTool/ICO.pm +1 -1
- data/bin/lib/Image/ExifTool/ID3.pm +1 -1
- data/bin/lib/Image/ExifTool/IPTC.pm +8 -5
- data/bin/lib/Image/ExifTool/ISO.pm +1 -1
- data/bin/lib/Image/ExifTool/ITC.pm +1 -1
- data/bin/lib/Image/ExifTool/Import.pm +5 -4
- data/bin/lib/Image/ExifTool/InDesign.pm +1 -1
- data/bin/lib/Image/ExifTool/InfiRay.pm +1 -1
- data/bin/lib/Image/ExifTool/JPEG.pm +1 -1
- data/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
- data/bin/lib/Image/ExifTool/JSON.pm +1 -1
- data/bin/lib/Image/ExifTool/JVC.pm +1 -1
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +1 -1
- data/bin/lib/Image/ExifTool/Kodak.pm +1 -1
- data/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/LIF.pm +1 -1
- data/bin/lib/Image/ExifTool/LNK.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/en_ca.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/en_gb.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/fi.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/fr.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/it.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/ja.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/ko.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/nl.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/pl.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/sk.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/tr.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
- data/bin/lib/Image/ExifTool/Leaf.pm +1 -1
- data/bin/lib/Image/ExifTool/LigoGPS.pm +408 -0
- data/bin/lib/Image/ExifTool/Lytro.pm +1 -1
- data/bin/lib/Image/ExifTool/M2TS.pm +22 -13
- data/bin/lib/Image/ExifTool/MIE.pm +1 -1
- data/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
- data/bin/lib/Image/ExifTool/MIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/MISB.pm +1 -1
- data/bin/lib/Image/ExifTool/MNG.pm +1 -1
- data/bin/lib/Image/ExifTool/MOI.pm +1 -1
- data/bin/lib/Image/ExifTool/MPC.pm +1 -1
- data/bin/lib/Image/ExifTool/MPEG.pm +1 -1
- data/bin/lib/Image/ExifTool/MPF.pm +1 -1
- data/bin/lib/Image/ExifTool/MRC.pm +1 -1
- data/bin/lib/Image/ExifTool/MWG.pm +1 -1
- data/bin/lib/Image/ExifTool/MXF.pm +1 -1
- data/bin/lib/Image/ExifTool/MacOS.pm +1 -1
- data/bin/lib/Image/ExifTool/MakerNotes.pm +1 -1
- data/bin/lib/Image/ExifTool/Matroska.pm +12 -4
- data/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
- data/bin/lib/Image/ExifTool/Minolta.pm +1 -1
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/Motorola.pm +1 -1
- data/bin/lib/Image/ExifTool/Nikon.pm +164 -35
- data/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
- data/bin/lib/Image/ExifTool/NikonCustom.pm +1 -1
- data/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
- data/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
- data/bin/lib/Image/ExifTool/OOXML.pm +1 -1
- data/bin/lib/Image/ExifTool/Ogg.pm +1 -1
- data/bin/lib/Image/ExifTool/Olympus.pm +1 -1
- data/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
- data/bin/lib/Image/ExifTool/Opus.pm +1 -1
- data/bin/lib/Image/ExifTool/Other.pm +1 -1
- data/bin/lib/Image/ExifTool/PCX.pm +1 -1
- data/bin/lib/Image/ExifTool/PDF.pm +1 -1
- data/bin/lib/Image/ExifTool/PGF.pm +1 -1
- data/bin/lib/Image/ExifTool/PICT.pm +1 -1
- data/bin/lib/Image/ExifTool/PLIST.pm +1 -1
- data/bin/lib/Image/ExifTool/PLUS.pm +1 -1
- data/bin/lib/Image/ExifTool/PNG.pm +1 -1
- data/bin/lib/Image/ExifTool/PPM.pm +1 -1
- data/bin/lib/Image/ExifTool/PSP.pm +1 -1
- data/bin/lib/Image/ExifTool/Palm.pm +1 -1
- data/bin/lib/Image/ExifTool/Panasonic.pm +20 -2
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/Parrot.pm +1 -1
- data/bin/lib/Image/ExifTool/Pentax.pm +1 -1
- data/bin/lib/Image/ExifTool/PhaseOne.pm +1 -1
- data/bin/lib/Image/ExifTool/PhotoCD.pm +1 -1
- data/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
- data/bin/lib/Image/ExifTool/Photoshop.pm +1 -1
- data/bin/lib/Image/ExifTool/PostScript.pm +1 -1
- data/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
- data/bin/lib/Image/ExifTool/Protobuf.pm +24 -14
- data/bin/lib/Image/ExifTool/Qualcomm.pm +1 -1
- data/bin/lib/Image/ExifTool/QuickTime.pm +46 -17
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +20 -302
- data/bin/lib/Image/ExifTool/README +4 -0
- data/bin/lib/Image/ExifTool/RIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/RSRC.pm +1 -1
- data/bin/lib/Image/ExifTool/RTF.pm +1 -1
- data/bin/lib/Image/ExifTool/Radiance.pm +1 -1
- data/bin/lib/Image/ExifTool/Rawzor.pm +1 -1
- data/bin/lib/Image/ExifTool/Real.pm +1 -1
- data/bin/lib/Image/ExifTool/Reconyx.pm +1 -1
- data/bin/lib/Image/ExifTool/Red.pm +1 -1
- data/bin/lib/Image/ExifTool/Ricoh.pm +1 -1
- data/bin/lib/Image/ExifTool/Samsung.pm +1 -1
- data/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
- data/bin/lib/Image/ExifTool/Scalado.pm +1 -1
- data/bin/lib/Image/ExifTool/Shift.pl +1 -1
- data/bin/lib/Image/ExifTool/Shortcuts.pm +1 -1
- data/bin/lib/Image/ExifTool/Sigma.pm +1 -1
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/Sony.pm +1 -1
- data/bin/lib/Image/ExifTool/SonyIDC.pm +1 -1
- data/bin/lib/Image/ExifTool/Stim.pm +1 -1
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +2 -2
- data/bin/lib/Image/ExifTool/TagLookup.pm +11 -5
- data/bin/lib/Image/ExifTool/TagNames.pod +84 -34
- data/bin/lib/Image/ExifTool/Text.pm +1 -1
- data/bin/lib/Image/ExifTool/Theora.pm +1 -1
- data/bin/lib/Image/ExifTool/Torrent.pm +1 -1
- data/bin/lib/Image/ExifTool/Unknown.pm +1 -1
- data/bin/lib/Image/ExifTool/VCard.pm +1 -1
- data/bin/lib/Image/ExifTool/Validate.pm +1 -1
- data/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
- data/bin/lib/Image/ExifTool/WPG.pm +1 -1
- data/bin/lib/Image/ExifTool/WTV.pm +1 -1
- data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePDF.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePostScript.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +5 -3
- data/bin/lib/Image/ExifTool/WriteRIFF.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
- data/bin/lib/Image/ExifTool/Writer.pl +9 -8
- data/bin/lib/Image/ExifTool/XISF.pm +1 -1
- data/bin/lib/Image/ExifTool/XMP.pm +1 -1
- data/bin/lib/Image/ExifTool/XMP2.pl +1 -1
- data/bin/lib/Image/ExifTool/XMPStruct.pl +1 -1
- data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
- data/bin/lib/Image/ExifTool/ZISRAW.pm +1 -1
- data/bin/lib/Image/ExifTool/iWork.pm +1 -1
- data/bin/lib/Image/ExifTool.pm +13 -7
- data/bin/lib/Image/ExifTool.pod +14 -5
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -2
@@ -0,0 +1,408 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
# File: LigoGPS.pm
|
3
|
+
#
|
4
|
+
# Description: Read LIGOGPSINFO timed GPS records
|
5
|
+
#
|
6
|
+
# Revisions: 2024-12-30 - P. Harvey Created
|
7
|
+
#------------------------------------------------------------------------------
|
8
|
+
package Image::ExifTool::LigoGPS;
|
9
|
+
|
10
|
+
use strict;
|
11
|
+
use vars qw($VERSION);
|
12
|
+
use Image::ExifTool;
|
13
|
+
|
14
|
+
$VERSION = '1.02';
|
15
|
+
|
16
|
+
sub ProcessLigoGPS($$$;$);
|
17
|
+
sub ProcessLigoJSON($$$);
|
18
|
+
sub OrderCipherDigits($$$;$);
|
19
|
+
|
20
|
+
my $knotsToKph = 1.852; # knots --> km/h
|
21
|
+
|
22
|
+
#------------------------------------------------------------------------------
|
23
|
+
# Clean up cipher variables and print warning if deciphering was unsuccessful
|
24
|
+
# Inputs: 0) ExifTool ref
|
25
|
+
sub CleanupCipher($)
|
26
|
+
{
|
27
|
+
my $et = shift;
|
28
|
+
if ($$et{LigoCipher} and $$et{LigoCipher}{'next'}) {
|
29
|
+
$et->Warn('Not enough GPS points to determine cipher for decoding LIGOGPSINFO');
|
30
|
+
}
|
31
|
+
delete $$et{LigoCipher};
|
32
|
+
}
|
33
|
+
|
34
|
+
#------------------------------------------------------------------------------
|
35
|
+
# Un-do LIGOGPS fuzzing
|
36
|
+
# Inputs: 0) fuzzed latitude, 1) fuzzed longitude, 2) scale factor
|
37
|
+
# Returns: 0) latitude, 1) longitude
|
38
|
+
sub UnfuzzLigoGPS($$$)
|
39
|
+
{
|
40
|
+
my ($lat, $lon, $scl) = @_;
|
41
|
+
my $lat2 = int($lat / 10) * 10;
|
42
|
+
my $lon2 = int($lon / 10) * 10;
|
43
|
+
return($lat2 + ($lon - $lon2) * $scl, $lon2 + ($lat - $lat2) * $scl);
|
44
|
+
}
|
45
|
+
|
46
|
+
#------------------------------------------------------------------------------
|
47
|
+
# Decrypt LIGOGPSINFO record (starting with "####")
|
48
|
+
# Inputs: 0) encrypted GPS record incuding 8-byte header
|
49
|
+
# Returns: decrypted record including 4-byte uint32 header, or undef on error
|
50
|
+
sub DecryptLigoGPS($)
|
51
|
+
{
|
52
|
+
my $str = shift;
|
53
|
+
my $num = unpack('x4V',$str);
|
54
|
+
return undef if $num < 4;
|
55
|
+
$num = 0x84 if $num > 0x84; # (be safe)
|
56
|
+
my @in = unpack("x8C$num",$str);
|
57
|
+
my @out;
|
58
|
+
while (@in) {
|
59
|
+
my $b = shift @in; # get next byte in data
|
60
|
+
# upper 3 bits steer the decryption for this round
|
61
|
+
my $steeringBits = $b & 0xe0;
|
62
|
+
if ($steeringBits >= 0xc0) {
|
63
|
+
return undef if @in < 4; # next 4 bytes are encrypted data
|
64
|
+
push @out, (shift(@in) | $b & 0x01) ^ 0x20,
|
65
|
+
(shift(@in) | $b & 0x02) ^ 0x20,
|
66
|
+
(shift(@in) | $b & 0x0c) ^ 0x20,
|
67
|
+
shift(@in) ^ 0x20 | $b & 0x30;
|
68
|
+
} elsif ($steeringBits >= 0x40) {
|
69
|
+
return undef if @in < 3; # next 3 bytes are encrypted data
|
70
|
+
if ($steeringBits == 0x40) {
|
71
|
+
push @out, 0x20,
|
72
|
+
(shift(@in) | $b & 0x01) ^ 0x20,
|
73
|
+
(shift(@in) | $b & 0x06) ^ 0x20,
|
74
|
+
(shift(@in) | $b & 0x18) ^ 0x20;
|
75
|
+
} elsif ($steeringBits == 0x60) {
|
76
|
+
push @out, (shift(@in) | $b & 0x03) ^ 0x20,
|
77
|
+
0x20,
|
78
|
+
(shift(@in) | $b & 0x04) ^ 0x20,
|
79
|
+
(shift(@in) | $b & 0x18) ^ 0x20;
|
80
|
+
} elsif ($steeringBits == 0x80) {
|
81
|
+
push @out, (shift(@in) | $b & 0x03) ^ 0x20,
|
82
|
+
(shift(@in) | $b & 0x0c) ^ 0x20,
|
83
|
+
0x20,
|
84
|
+
(shift(@in) | $b & 0x10) ^ 0x20;
|
85
|
+
} else {
|
86
|
+
push @out, (shift(@in) | $b & 0x01) ^ 0x20,
|
87
|
+
(shift(@in) | $b & 0x06) ^ 0x20,
|
88
|
+
(shift(@in) | $b & 0x18) ^ 0x20,
|
89
|
+
0x20;
|
90
|
+
}
|
91
|
+
} elsif ($steeringBits == 0x00) {
|
92
|
+
return undef if @in < 1; # next byte is encrypted data
|
93
|
+
push @out, shift(@in) | $b & 0x13;
|
94
|
+
} else {
|
95
|
+
return undef; # (shouldn't happen)
|
96
|
+
}
|
97
|
+
}
|
98
|
+
return pack 'C*', @out;
|
99
|
+
}
|
100
|
+
|
101
|
+
#------------------------------------------------------------------------------
|
102
|
+
# Determine correct ordering of enciphered digits (unit digits of seconds)
|
103
|
+
# Inputs: 0) starting character code, 1) lookup for next character(s) in sequence
|
104
|
+
# 2) i/o list of ordered characters, 3) hash of used characters
|
105
|
+
# Returns: true if a consistent ordering was found
|
106
|
+
# - loops through all possible orders based on $next sequence until a complete
|
107
|
+
# cycle is established
|
108
|
+
# - this complexity is necessary because GPS may skip some seconds
|
109
|
+
sub OrderCipherDigits($$$;$)
|
110
|
+
{
|
111
|
+
my ($ch, $next, $order, $did) = @_;
|
112
|
+
$did or $did = { };
|
113
|
+
while ($$next{$ch}) {
|
114
|
+
if (@$order < 10) {
|
115
|
+
last if $$did{$ch};
|
116
|
+
} else {
|
117
|
+
# success if we have cycled through all 10 digits and back to the first
|
118
|
+
return 1 if @$order == 10 and $ch eq $$order[0];
|
119
|
+
last;
|
120
|
+
}
|
121
|
+
push @$order, $ch;
|
122
|
+
$$did{$ch} = 1;
|
123
|
+
# continue with next character if there is only one possibility
|
124
|
+
@{$$next{$ch}} == 1 and $ch = $$next{$ch}[0], next;
|
125
|
+
# otherwise, test all possibilities
|
126
|
+
my $n = $#$order;
|
127
|
+
foreach (@{$$next{$ch}}) {
|
128
|
+
my %did = %$did; # make a copy of the used-character lookup
|
129
|
+
return 1 if OrderCipherDigits($_, $next, $order, \%did);
|
130
|
+
$#$order = $n; # restore order and try next possibility
|
131
|
+
}
|
132
|
+
last;
|
133
|
+
}
|
134
|
+
return 0; # failure
|
135
|
+
}
|
136
|
+
|
137
|
+
#------------------------------------------------------------------------------
|
138
|
+
# Decipher and parse LIGOGPSINFO record (starting with "####")
|
139
|
+
# Inputs: 0) ExifTool ref, 1) enciphered string, 2) tag table ref
|
140
|
+
# 3) true if GPS coordinates don't need de-fuzzing
|
141
|
+
# Returns: true if this looked like an enciphered string
|
142
|
+
# Notes: handles contained tags, but may defer handling until full cipher is known
|
143
|
+
sub DecipherLigoGPS($$$;$)
|
144
|
+
{
|
145
|
+
my ($et, $str, $tagTbl, $noFuzz) = @_;
|
146
|
+
|
147
|
+
# (enciphered characters must be in the range 0x30-0x5f ('0' - '_'))
|
148
|
+
$str =~ m[^####.{4}([0-_])[0-_]{3}/[0-_]{2}/[0-_]{2} ..([0-_])..([0-_]).([0-_]) ]s or return undef;
|
149
|
+
return undef unless $2 eq $3; # (colons in time string must be the same)
|
150
|
+
|
151
|
+
my $cipherInfo = $$et{LigoCipher};
|
152
|
+
unless ($cipherInfo) {
|
153
|
+
$cipherInfo = $$et{LigoCipher} = { cache => [ ], 'next' => { } };
|
154
|
+
$et->AddCleanup(\&CleanupCipher);
|
155
|
+
};
|
156
|
+
my $decipher = $$cipherInfo{decipher};
|
157
|
+
my $cache = $$cipherInfo{cache};
|
158
|
+
|
159
|
+
# determine the cipher code table based on the advancing 1's digit of seconds
|
160
|
+
unless ($decipher) {
|
161
|
+
push @$cache, $str; # cache records until we can decipher them
|
162
|
+
my $next = $$cipherInfo{next};
|
163
|
+
my ($millennium, $colon, $ch2) = ($1, $2, $4);
|
164
|
+
# determine the cipher lookup table
|
165
|
+
# (only characters in range 0x30-0x5f are encrypted)
|
166
|
+
my $ch1 = $$cipherInfo{ch1};
|
167
|
+
$$cipherInfo{ch1} = $ch2;
|
168
|
+
return 1 if not defined $ch1 or $ch1 eq $ch2; # ignore duplicate sequential digits
|
169
|
+
if ($$next{$ch1}) {
|
170
|
+
return 1 if grep /\Q$ch2\E/, @{$$next{$ch1}}; # don't add twice
|
171
|
+
push @{$$next{$ch1}}, $ch2;
|
172
|
+
} else {
|
173
|
+
$$next{$ch1} = [ $ch2 ];
|
174
|
+
}
|
175
|
+
# must wait until the lookup contains all 10 digits
|
176
|
+
scalar(keys %$next) < 10 and return 1;
|
177
|
+
# protect against trying to decipher bad data
|
178
|
+
scalar(keys %$next) > 10 and $$cipherInfo{'next'} = { }, return 1;
|
179
|
+
my (@order, $two);
|
180
|
+
return 1 unless OrderCipherDigits($ch1, $next, \@order);
|
181
|
+
# get index of enciphered "2" in ordered array
|
182
|
+
$order[$_] eq $millennium and $two = $_, last foreach 0..9;
|
183
|
+
defined $two or $et->Warn('Problem deciphering LIGOGPSINFO'), return 1;
|
184
|
+
delete $$cipherInfo{'next'}; # all done with 'next' lookup
|
185
|
+
my %decipher = ( $colon => ':' ); # (':' is the time separator)
|
186
|
+
foreach (0..9) {
|
187
|
+
my $ch = $order[($_ + $two - 2 + 10) % 10];
|
188
|
+
$decipher{$ch} = chr($_ + 0x30);
|
189
|
+
}
|
190
|
+
# may also know the lat/lon quadrant from the signs of the coordinates
|
191
|
+
if ($str =~ / ([0-_])$colon(-?).*? ([0-_])$colon(-?)/) {
|
192
|
+
@decipher{$1,$3} = ($2 ? 'S' : 'N', $4 ? 'W' : 'E');
|
193
|
+
unless ($2 or $4) {
|
194
|
+
my ($ns, $ew) = ($1, $3);
|
195
|
+
if ($$et{OPTIONS}{GPSQuadrant} and $$et{OPTIONS}{GPSQuadrant} =~ /^([NS])([EW])$/i) {
|
196
|
+
@decipher{$ns,$ew} = (uc($1), uc($2));
|
197
|
+
} else {
|
198
|
+
$et->Warn('May need to set API GPSQuadrant option (eg. "NW")');
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
# fill in unknown entries with '?' (only chars 0x30-0x5f are enciphered)
|
203
|
+
defined $decipher{$_} or $decipher{$_} = '?' foreach map(chr, 0x30..0x5f);
|
204
|
+
$decipher = $$cipherInfo{decipher} = \%decipher;
|
205
|
+
$str = shift @$cache; # start deciphering at oldest cache entry
|
206
|
+
}
|
207
|
+
|
208
|
+
# apply reverse cipher and extract GPS information
|
209
|
+
do {
|
210
|
+
my $pre = substr($str, 4, 4); # save second 4 bytes of header
|
211
|
+
($str = substr($str,8)) =~ s/\0+$//; # remove 8-byte header and null padding
|
212
|
+
$str =~ s/([0-_])/$$decipher{$1}/g; # decipher
|
213
|
+
if ($$et{OPTIONS}{Verbose} > 1) {
|
214
|
+
$et->VPrint(1, "$$et{INDENT}\(Deciphered: ".unpack('H8',$pre)." $str)\n");
|
215
|
+
}
|
216
|
+
# add back leading 4 bytes (int16u counter plus 2 unknown bytes), and parse
|
217
|
+
ParseLigoGPS($et, "$pre$str", $tagTbl, $noFuzz);
|
218
|
+
} while $str = shift @$cache;
|
219
|
+
|
220
|
+
return 1;
|
221
|
+
}
|
222
|
+
|
223
|
+
#------------------------------------------------------------------------------
|
224
|
+
# Parse decrypted/deciphered (but not defuzzed) LIGOGPSINFO record
|
225
|
+
# (record starts with 4-byte int32u counter followed by date/time, etc)
|
226
|
+
# Inputs: 0) ExifTool ref, 1) GPS string, 2) tag table ref, 3) not fuzzed
|
227
|
+
# Returns: nothing
|
228
|
+
sub ParseLigoGPS($$$;$)
|
229
|
+
{
|
230
|
+
my ($et, $str, $tagTbl, $noFuzz) = @_;
|
231
|
+
|
232
|
+
# example string input
|
233
|
+
# "....2022/09/19 12:45:24 N:31.285065 W:124.759483 46.93 km/h x:-0.000 y:-0.000 z:-0.000"
|
234
|
+
unless ($str=~ /^.{4}(\S+ \S+)\s+([NS?]):(-?)([.\d]+)\s+([EW?]):(-?)([\.\d]+)\s+([.\d]+)/s) {
|
235
|
+
$et->Warn('LIGOGPSINFO format error');
|
236
|
+
return;
|
237
|
+
}
|
238
|
+
my ($time,$latRef,$latNeg,$lat,$lonRef,$lonNeg,$lon,$spd) = ($1,$2,$3,$4,$5,$6,$7,$8);
|
239
|
+
my %gpsScl = ( 1 => 1.524855137, 2 => 1.456027985, 3 => 1.15368 );
|
240
|
+
my $spdScl = $noFuzz ? $knotsToKph : 1.85407333;
|
241
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
242
|
+
$time =~ tr(/)(:);
|
243
|
+
# convert from DDMM.MMMMMM to DD.DDDDDD if necessary
|
244
|
+
# (speed wasn't scaled in my 1 sample with this format)
|
245
|
+
$lat =~ /^\d{3}/ and Image::ExifTool::QuickTime::ConvertLatLon($lat,$lon), $spdScl = 1;
|
246
|
+
unless ($noFuzz) { # unfuzz the coordinates if necessary
|
247
|
+
my $scl = $$et{OPTIONS}{LigoGPSScale} || $$et{LigoGPSScale} || 1;
|
248
|
+
$scl = $gpsScl{$scl} if $gpsScl{$scl};
|
249
|
+
($lat, $lon) = UnfuzzLigoGPS($lat, $lon, $scl);
|
250
|
+
}
|
251
|
+
# a final sanity check
|
252
|
+
($lat > 90 or $lon > 180) and $et->Warn('LIGOGPSINFO coordinates out of range'), return;
|
253
|
+
$$et{SET_GROUP1} = 'LIGO';
|
254
|
+
$et->HandleTag($tagTbl, 'GPSDateTime', $time);
|
255
|
+
# (ignore N/S/E/W if coordinate is signed)
|
256
|
+
$et->HandleTag($tagTbl, 'GPSLatitude', $lat * (($latNeg or $latRef eq 'S') ? -1 : 1));
|
257
|
+
$et->HandleTag($tagTbl, 'GPSLongitude', $lon * (($lonNeg or $lonRef eq 'W') ? -1 : 1));
|
258
|
+
$et->HandleTag($tagTbl, 'GPSSpeed', $spd * $spdScl);
|
259
|
+
$et->HandleTag($tagTbl, 'GPSTrack', $1) if $str =~ /\bA:(\S+)/;
|
260
|
+
$et->HandleTag($tagTbl, 'GPSAltitude', $1) if $str =~ /\bH:(\S+)/;
|
261
|
+
$et->HandleTag($tagTbl, 'MagneticVariation', $1) if $str =~ /\bM:(\S+)/;
|
262
|
+
# (have a sample where tab is used to separate acc components)
|
263
|
+
$et->HandleTag($tagTbl, 'Accelerometer',"$1 $2 $3") if $str =~ /x:(\S+)\sy:(\S+)\sz:(\S+)/;
|
264
|
+
delete $$et{SET_GROUP1};
|
265
|
+
}
|
266
|
+
|
267
|
+
#------------------------------------------------------------------------------
|
268
|
+
# Process LIGOGPSINFO data (non-JSON format)
|
269
|
+
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|
270
|
+
# 3) 1=LIGOGPS lat/lon/spd weren't fuzzed
|
271
|
+
# Returns: 1 on success
|
272
|
+
sub ProcessLigoGPS($$$;$)
|
273
|
+
{
|
274
|
+
my ($et, $dirInfo, $tagTbl, $noFuzz) = @_;
|
275
|
+
my $dataPt = $$dirInfo{DataPt};
|
276
|
+
my $pos = ($$dirInfo{DirStart} || 0) + 0x14;
|
277
|
+
return undef if $pos > length $$dataPt;
|
278
|
+
my $cipherInfo = $$et{LigoCipher};
|
279
|
+
my $dirName = $$dirInfo{DirName} || 'LigoGPS';
|
280
|
+
push @{$$et{PATH}}, $dirName unless $$dirInfo{DirID};
|
281
|
+
# not fuzzed if header =~ /LIGOGPSINFO\0\0\0\0[\x01\x14]/ (\x01=BlueSkySeaDV688)
|
282
|
+
$noFuzz = 1 if substr($$dataPt, $pos-8, 4) =~ /^\0\0\0[\x01\x14]/;
|
283
|
+
$et->VerboseDir($dirName);
|
284
|
+
for (; $pos + 0x84 <= length($$dataPt); $pos+=0x84) {
|
285
|
+
my $dat = substr($$dataPt, $pos, 0x84);
|
286
|
+
$dat =~ /^####/ or next; # (have seen blank records filled with zeros, so keep trying)
|
287
|
+
# decipher if we already know the encryption
|
288
|
+
$cipherInfo and $$cipherInfo{decipher} and DecipherLigoGPS($et, $dat, $tagTbl, $noFuzz) and next;
|
289
|
+
my $str = DecryptLigoGPS($dat);
|
290
|
+
defined $str or DecipherLigoGPS($et, $dat, $tagTbl, $noFuzz), next; # try to decipher
|
291
|
+
$et->VPrint(1, "$$et{INDENT}\(Decrypted: ",unpack('V',$str),' ',substr($str,4),")\n") if $$et{OPTIONS}{Verbose} > 1;
|
292
|
+
ParseLigoGPS($et, $str, $tagTbl, $noFuzz);
|
293
|
+
}
|
294
|
+
pop @{$$et{PATH}} unless $$dirInfo{DirID};
|
295
|
+
delete $$et{DOC_NUM};
|
296
|
+
return 1;
|
297
|
+
}
|
298
|
+
|
299
|
+
#------------------------------------------------------------------------------
|
300
|
+
# Process LIGOGPSINFO JSON-format GPS (Yada RoadCam Pro 4K BT58189)
|
301
|
+
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
|
302
|
+
# Returns: 1 on success
|
303
|
+
# Sample data (chained 512-byte records starting like this):
|
304
|
+
# 0000: 4c 49 47 4f 47 50 53 49 4e 46 4f 20 7b 22 48 6f [LIGOGPSINFO {"Ho]
|
305
|
+
# 0010: 75 72 22 3a 20 22 32 33 22 2c 20 22 4d 69 6e 75 [ur": "23", "Minu]
|
306
|
+
# 0020: 74 65 22 3a 20 22 31 30 22 2c 20 22 53 65 63 6f [te": "10", "Seco]
|
307
|
+
# 0030: 6e 64 22 3a 20 22 32 32 22 2c 20 22 59 65 61 72 [nd": "22", "Year]
|
308
|
+
# 0040: 22 3a 20 22 32 30 32 33 22 2c 20 22 4d 6f 6e 74 [": "2023", "Mont]
|
309
|
+
# 0050: 68 22 3a 20 22 31 32 22 2c 20 22 44 61 79 22 3a [h": "12", "Day":]
|
310
|
+
# 0060: 20 22 32 38 22 2c 20 22 73 74 61 74 75 73 22 3a [ "28", "status":]
|
311
|
+
sub ProcessLigoJSON($$$)
|
312
|
+
{
|
313
|
+
my ($et, $dirInfo, $tagTbl) = @_;
|
314
|
+
my $dataPt = $$dirInfo{DataPt};
|
315
|
+
my $dirLen = $$dirInfo{DirLen};
|
316
|
+
require Image::ExifTool::Import;
|
317
|
+
$et->VerboseDir('LIGO_JSON', undef, length($$dataPt));
|
318
|
+
$$et{SET_GROUP1} = 'LIGO';
|
319
|
+
while ($$dataPt =~ /LIGOGPSINFO (\{.*?\})/g) {
|
320
|
+
my $json = $1;
|
321
|
+
my %dbase;
|
322
|
+
Image::ExifTool::Import::ReadJSON(\$json, \%dbase);
|
323
|
+
my $info = $dbase{'*'} or next;
|
324
|
+
# my sample contains the following JSON fields (in this order):
|
325
|
+
# Hour Minute Second Year Month Day (GPS UTC time)
|
326
|
+
# status NS EW Latitude Longitude Speed (speed in knots)
|
327
|
+
# GsensorX GsensorY GsensorZ (units? - only seen "000" for all)
|
328
|
+
# MHour MMinute MSecond MYear MMonth MDay (local dashcam clock time)
|
329
|
+
# OLatitude OLongitude (? same values as Latitude/Longitude)
|
330
|
+
next unless defined $$info{status} and $$info{status} eq 'A'; # only read if GPS is active
|
331
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
332
|
+
my $num = 0;
|
333
|
+
defined $$info{$_} and ++$num foreach qw(Year Month Day Hour Minute Second);
|
334
|
+
if ($num == 6) {
|
335
|
+
# this is the GPS time in UTC
|
336
|
+
my $time = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ',@$info{qw{Year Month Day Hour Minute Second}});
|
337
|
+
$et->HandleTag($tagTbl, GPSDateTime => $time);
|
338
|
+
}
|
339
|
+
if ($$info{Latitude} and $$info{Longitude}) {
|
340
|
+
my $lat = $$info{Latitude};
|
341
|
+
$lat = -$lat if $$info{NS} and $$info{NS} eq 'S';
|
342
|
+
my $lon = $$info{Longitude};
|
343
|
+
$lon = -$lon if $$info{EW} and $$info{EW} eq 'W';
|
344
|
+
$et->HandleTag($tagTbl, GPSLatitude => $lat);
|
345
|
+
$et->HandleTag($tagTbl, GPSLongitude => $lon);
|
346
|
+
}
|
347
|
+
$et->HandleTag($tagTbl, GPSSpeed => $$info{Speed} * $knotsToKph) if defined $$info{Speed};
|
348
|
+
if (defined $$info{GsensorX} and defined $$info{GsensorY} and defined $$info{GsensorZ}) {
|
349
|
+
# (don't know conversion factor for accel data, so leave it raw for now)
|
350
|
+
$et->HandleTag($tagTbl, Accelerometer => "$$info{GsensorX} $$info{GsensorY} $$info{GsensorZ}");
|
351
|
+
}
|
352
|
+
$num = 0;
|
353
|
+
defined $$info{$_} and ++$num foreach qw(MYear MMonth MDay MHour MMinute MSecond);
|
354
|
+
if ($num == 6) {
|
355
|
+
# this is the dashcam clock time (local time zone)
|
356
|
+
my $time = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d',@$info{qw{MYear MMonth MDay MHour MMinute MSecond}});
|
357
|
+
$et->HandleTag($tagTbl, DateTimeOriginal => $time);
|
358
|
+
}
|
359
|
+
if (defined $$info{OLatitude} and defined $$info{OLongitude}) {
|
360
|
+
my $lat = $$info{OLatitude};
|
361
|
+
$lat = -$lat if $$info{NS} and $$info{NS} eq 'S';
|
362
|
+
my $lon = $$info{OLongitude};
|
363
|
+
$lon = -$lon if $$info{EW} and $$info{EW} eq 'W';
|
364
|
+
$et->HandleTag($tagTbl, GPSLatitude2 => $lat);
|
365
|
+
$et->HandleTag($tagTbl, GPSLongitude2 => $lon);
|
366
|
+
}
|
367
|
+
unless ($et->Options('ExtractEmbedded')) {
|
368
|
+
$et->Warn('Use the ExtractEmbedded option to extract all timed GPS',3);
|
369
|
+
last;
|
370
|
+
}
|
371
|
+
}
|
372
|
+
delete $$et{DOC_NUM};
|
373
|
+
delete $$et{SET_GROUP1};
|
374
|
+
return 1;
|
375
|
+
}
|
376
|
+
|
377
|
+
1; #end
|
378
|
+
|
379
|
+
|
380
|
+
__END__
|
381
|
+
|
382
|
+
=head1 NAME
|
383
|
+
|
384
|
+
Image::ExifTool::LigoGPS - Read LIGOGPSINFO timed GPS records
|
385
|
+
|
386
|
+
=head1 SYNOPSIS
|
387
|
+
|
388
|
+
This module is loaded automatically by Image::ExifTool when required.
|
389
|
+
|
390
|
+
=head1 DESCRIPTION
|
391
|
+
|
392
|
+
This module decrypts, deciphers and decodes timed GPS metadata from
|
393
|
+
LIGOGPSINFO records found in various locations of MP4 and M2TS videos from a
|
394
|
+
variety of dashcam makes and models.
|
395
|
+
|
396
|
+
=head1 AUTHOR
|
397
|
+
|
398
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
399
|
+
|
400
|
+
This library is free software; you can redistribute it and/or modify it
|
401
|
+
under the same terms as Perl itself.
|
402
|
+
|
403
|
+
=head1 SEE ALSO
|
404
|
+
|
405
|
+
L<Image::ExifTool::TagNames/QuickTime Stream Tags>,
|
406
|
+
L<Image::ExifTool(3pm)|Image::ExifTool>
|
407
|
+
|
408
|
+
=cut
|
@@ -192,7 +192,7 @@ from Lytro Light Field Picture (LFP) files.
|
|
192
192
|
|
193
193
|
=head1 AUTHOR
|
194
194
|
|
195
|
-
Copyright 2003-
|
195
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
196
196
|
|
197
197
|
This library is free software; you can redistribute it and/or modify it
|
198
198
|
under the same terms as Perl itself.
|
@@ -32,7 +32,7 @@ use strict;
|
|
32
32
|
use vars qw($VERSION);
|
33
33
|
use Image::ExifTool qw(:DataAccess :Utils);
|
34
34
|
|
35
|
-
$VERSION = '1.
|
35
|
+
$VERSION = '1.29';
|
36
36
|
|
37
37
|
# program map table "stream_type" lookup (ref 6/1/9)
|
38
38
|
my %streamType = (
|
@@ -310,7 +310,7 @@ sub ParsePID($$$$$)
|
|
310
310
|
if ($$dataPt =~ /^LIGOGPSINFO/s) {
|
311
311
|
my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
312
312
|
my %dirInfo = ( DataPt => $dataPt, DirName => 'Ligo0x0300' );
|
313
|
-
Image::ExifTool::
|
313
|
+
Image::ExifTool::LigoGPS::ProcessLigoGPS($et, \%dirInfo, $tbl, 1);
|
314
314
|
$$et{FoundGoodGPS} = 1;
|
315
315
|
$more = 1;
|
316
316
|
}
|
@@ -437,13 +437,16 @@ sub ParsePID($$$$$)
|
|
437
437
|
$more = 1;
|
438
438
|
} elsif ($$dataPt =~ /\$GPRMC,/) {
|
439
439
|
# Jomise T860S-GM dashcam
|
440
|
-
# $GPRMC,hhmmss.ss,A,ddmm.mmmmm,N,dddmm.mmmmm,W,spd-kts,dir-dg,DDMMYY
|
441
|
-
# $GPRMC,172255.00,A,:985.95194,N,17170.14674,W,029.678,170.68,240822,,,D*7B
|
442
|
-
# $GPRMC,
|
443
|
-
#
|
444
|
-
#
|
445
|
-
#
|
446
|
-
#
|
440
|
+
# $GPRMC,hhmmss.ss,A,ddmm.mmmmm,N,dddmm.mmmmm,W,spd-kts,dir-dg,DDMMYY,,M*cs - lat,lon,spd from video
|
441
|
+
# $GPRMC,172255.00,A,:985.95194,N,17170.14674,W,029.678,170.68,240822,,,D*7B - N47.70428,W122.15338,35mph
|
442
|
+
# $GPRMC,192643.00,A,:987.94979,N,17171.07268,W,010.059,079.61,111122,,,A*73 - N47.71862,W122.16437,12mph
|
443
|
+
# $GPRMC,192743.00,A,:988.72110,N,17171.04873,W,017.477,001.03,111122,,,A*78 - N47.72421,W122.16408,20mph
|
444
|
+
# $GPRMC,192844.00,A,:989.43771,N,17171.03538,W,016.889,001.20,111122,,,A*7B - N47.72932,W122.16393,19mph
|
445
|
+
# $GPRMC,005241.00,A,:987.70873,N,17171.81293,W,000.284,354.78,141122,,,A*7F - N47.71687,W122.17318,0mph
|
446
|
+
# $GPRMC,005341.00,A,:987.90851,N,17171.85380,W,000.080,349.36,141122,,,A*7C - N47.71832,W122.17367,0mph
|
447
|
+
# $GPRMC,005441.00,A,:987.94538,N,17171.21783,W,029.686,091.09,141122,,,A*7A - N47.71859,W122.16630,35mph
|
448
|
+
# $GPRMC,002816.00,A,6820.67273,N,13424.26599,W,000.045,000.00,261122,,,A*79 - N29.52096,W95.55953,0mph (seattle)
|
449
|
+
# $GPRMC,035136.00,A,:981.47322,N,17170.14105,W,024.594,180.50,291122,,,D*79 - N47.67180,W122.15328,28mph
|
447
450
|
my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
448
451
|
while ($$dataPt =~ /\$[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(.{2})(\d{2}\.\d+),([NS]),(.{3})(\d{2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/g and
|
449
452
|
# do some basic sanity checks on the date
|
@@ -477,6 +480,11 @@ sub ParsePID($$$$$)
|
|
477
480
|
$et->HandleTag($tagTbl, GPSLongitude => (($lo || 0) + (($9-70.14674)/1.460987654320988+9.2028)/60) * ($10 eq 'E' ? 1 : -1));
|
478
481
|
}
|
479
482
|
}
|
483
|
+
} elsif ($$dataPt =~ /\$GSENSORD,\s*(\d+),\s*(\d+),\s*(\d+),/) {
|
484
|
+
# Jomise T860S-GM dashcam
|
485
|
+
my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
486
|
+
$$et{DOC_NUM} = $$et{DOC_COUNT};
|
487
|
+
$et->HandleTag($tagTbl, Accelerometer => "$1 $2 $3"); # (NC - values range from 0 to 6)
|
480
488
|
} elsif ($$dataPt =~ /^.{44}A\0{3}.{4}([NS])\0{3}.{4}([EW])\0{3}/s and length($$dataPt) >= 84) {
|
481
489
|
#forum11320
|
482
490
|
SetByteOrder('II');
|
@@ -531,7 +539,7 @@ sub ParsePID($$$$$)
|
|
531
539
|
# only extract data from the first one)
|
532
540
|
my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
533
541
|
my %dirInfo = ( DataPt => $dataPt, DirStart => 8, DirName => sprintf('Ligo0x%.4x',$pid));
|
534
|
-
Image::ExifTool::
|
542
|
+
Image::ExifTool::LigoGPS::ProcessLigoGPS($et, \%dirInfo, $tbl, 1);
|
535
543
|
$$et{FoundGoodGPS} = 1;
|
536
544
|
} elsif ($$et{FoundGoodGPS}) {
|
537
545
|
$more = 1;
|
@@ -592,7 +600,8 @@ sub ProcessM2TS($$)
|
|
592
600
|
my %gpsPID = (
|
593
601
|
0x0300 => 1, # Novatek INNOVV, DOD_LS600W
|
594
602
|
0x01e4 => 1, # vsys a6l dashcam
|
595
|
-
0x0e1b => 1, # Jomise T860S-GM dashcam
|
603
|
+
0x0e1b => 1, # Jomise T860S-GM dashcam GPS
|
604
|
+
0x0e1a => 1, # Jomise T860S-GM dashcam accelerometer
|
596
605
|
);
|
597
606
|
my $pEnd = 0;
|
598
607
|
|
@@ -980,7 +989,7 @@ sub ProcessM2TS($$)
|
|
980
989
|
if ($len < $raf->Tell() and $raf->Seek(-$len, 2) and $raf->Read($buff,$len) == $len) {
|
981
990
|
my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
982
991
|
my %dirInfo = ( DataPt => \$buff, DirStart => 8, DirName => 'LigoTrailer' );
|
983
|
-
Image::ExifTool::
|
992
|
+
Image::ExifTool::LigoGPS::ProcessLigoGPS($et, \%dirInfo, $tbl);
|
984
993
|
}
|
985
994
|
}
|
986
995
|
|
@@ -1007,7 +1016,7 @@ video.
|
|
1007
1016
|
|
1008
1017
|
=head1 AUTHOR
|
1009
1018
|
|
1010
|
-
Copyright 2003-
|
1019
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
1011
1020
|
|
1012
1021
|
This library is free software; you can redistribute it and/or modify it
|
1013
1022
|
under the same terms as Perl itself.
|
@@ -2557,7 +2557,7 @@ tag name. For example:
|
|
2557
2557
|
|
2558
2558
|
=head1 AUTHOR
|
2559
2559
|
|
2560
|
-
Copyright 2003-
|
2560
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
2561
2561
|
|
2562
2562
|
This library is free software; you can redistribute it and/or modify it
|
2563
2563
|
under the same terms as Perl itself. The MIE format itself is also
|
@@ -356,7 +356,7 @@ A few examples of combined units strings:
|
|
356
356
|
|
357
357
|
=head1 AUTHOR
|
358
358
|
|
359
|
-
Copyright 2003-
|
359
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
360
360
|
|
361
361
|
This library is free software; you can redistribute it and/or modify it
|
362
362
|
under the same terms as Perl itself.
|
@@ -255,7 +255,7 @@ This module contains routines required by Image::ExifTool to read MIFF
|
|
255
255
|
|
256
256
|
=head1 AUTHOR
|
257
257
|
|
258
|
-
Copyright 2003-
|
258
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
259
259
|
|
260
260
|
This library is free software; you can redistribute it and/or modify it
|
261
261
|
under the same terms as Perl itself.
|
@@ -468,7 +468,7 @@ Board (MISB) KLV-format metadata from M2TS videos.
|
|
468
468
|
|
469
469
|
=head1 AUTHOR
|
470
470
|
|
471
|
-
Copyright 2003-
|
471
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
472
472
|
|
473
473
|
This library is free software; you can redistribute it and/or modify it
|
474
474
|
under the same terms as Perl itself.
|
@@ -661,7 +661,7 @@ This module contains definitions required by Image::ExifTool to read MNG
|
|
661
661
|
|
662
662
|
=head1 AUTHOR
|
663
663
|
|
664
|
-
Copyright 2003-
|
664
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
665
665
|
|
666
666
|
This library is free software; you can redistribute it and/or modify it
|
667
667
|
under the same terms as Perl itself.
|
@@ -137,7 +137,7 @@ information from MOI files.
|
|
137
137
|
|
138
138
|
=head1 AUTHOR
|
139
139
|
|
140
|
-
Copyright 2003-
|
140
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
141
141
|
|
142
142
|
This library is free software; you can redistribute it and/or modify it
|
143
143
|
under the same terms as Perl itself.
|
@@ -134,7 +134,7 @@ information from Musepack (MPC) audio files.
|
|
134
134
|
|
135
135
|
=head1 AUTHOR
|
136
136
|
|
137
|
-
Copyright 2003-
|
137
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
138
138
|
|
139
139
|
This library is free software; you can redistribute it and/or modify it
|
140
140
|
under the same terms as Perl itself.
|
@@ -704,7 +704,7 @@ based on unofficial sources which may be incomplete, inaccurate or outdated.
|
|
704
704
|
|
705
705
|
=head1 AUTHOR
|
706
706
|
|
707
|
-
Copyright 2003-
|
707
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
708
708
|
|
709
709
|
This library is free software; you can redistribute it and/or modify it
|
710
710
|
under the same terms as Perl itself.
|
@@ -267,7 +267,7 @@ Format (MPF) information from JPEG images.
|
|
267
267
|
|
268
268
|
=head1 AUTHOR
|
269
269
|
|
270
|
-
Copyright 2003-
|
270
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
271
271
|
|
272
272
|
This library is free software; you can redistribute it and/or modify it
|
273
273
|
under the same terms as Perl itself.
|
@@ -315,7 +315,7 @@ metadata from Medical Research Council (MRC) images.
|
|
315
315
|
|
316
316
|
=head1 AUTHOR
|
317
317
|
|
318
|
-
Copyright 2003-
|
318
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
319
319
|
|
320
320
|
This library is free software; you can redistribute it and/or modify it
|
321
321
|
under the same terms as Perl itself.
|
@@ -757,7 +757,7 @@ must be loaded explicitly as described above.
|
|
757
757
|
|
758
758
|
=head1 AUTHOR
|
759
759
|
|
760
|
-
Copyright 2003-
|
760
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
761
761
|
|
762
762
|
This library is free software; you can redistribute it and/or modify it
|
763
763
|
under the same terms as Perl itself.
|
@@ -2987,7 +2987,7 @@ information from MXF (Material Exchange Format) files.
|
|
2987
2987
|
|
2988
2988
|
=head1 AUTHOR
|
2989
2989
|
|
2990
|
-
Copyright 2003-
|
2990
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
2991
2991
|
|
2992
2992
|
This library is free software; you can redistribute it and/or modify it
|
2993
2993
|
under the same terms as Perl itself.
|
@@ -737,7 +737,7 @@ Writable tags use "xattr", "setfile" or "osascript" for writing.
|
|
737
737
|
|
738
738
|
=head1 AUTHOR
|
739
739
|
|
740
|
-
Copyright 2003-
|
740
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
741
741
|
|
742
742
|
This library is free software; you can redistribute it and/or modify it
|
743
743
|
under the same terms as Perl itself.
|
@@ -1831,7 +1831,7 @@ maker notes in EXIF information.
|
|
1831
1831
|
|
1832
1832
|
=head1 AUTHOR
|
1833
1833
|
|
1834
|
-
Copyright 2003-
|
1834
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
1835
1835
|
|
1836
1836
|
This library is free software; you can redistribute it and/or modify it
|
1837
1837
|
under the same terms as Perl itself.
|