exiftool-vendored.pl 13.0.1 → 13.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/Changes +254 -20
- package/bin/MANIFEST +10 -0
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +3 -3
- package/bin/arg_files/exif2xmp.args +4 -0
- package/bin/arg_files/xmp2exif.args +2 -1
- package/bin/build_geolocation +1 -1
- package/bin/exiftool +356 -213
- package/bin/lib/File/RandomAccess.pm +1 -1
- package/bin/lib/File/RandomAccess.pod +2 -2
- package/bin/lib/Image/ExifTool/AAC.pm +1 -1
- package/bin/lib/Image/ExifTool/AES.pm +1 -1
- package/bin/lib/Image/ExifTool/AFCP.pm +6 -6
- package/bin/lib/Image/ExifTool/AIFF.pm +2 -2
- package/bin/lib/Image/ExifTool/APE.pm +2 -2
- package/bin/lib/Image/ExifTool/APP12.pm +1 -1
- package/bin/lib/Image/ExifTool/ASF.pm +2 -2
- package/bin/lib/Image/ExifTool/Apple.pm +11 -9
- package/bin/lib/Image/ExifTool/Audible.pm +1 -1
- package/bin/lib/Image/ExifTool/BMP.pm +1 -1
- package/bin/lib/Image/ExifTool/BPG.pm +1 -1
- package/bin/lib/Image/ExifTool/BZZ.pm +1 -1
- package/bin/lib/Image/ExifTool/BigTIFF.pm +1 -1
- package/bin/lib/Image/ExifTool/BuildTagLookup.pm +36 -22
- package/bin/lib/Image/ExifTool/CBOR.pm +5 -2
- package/bin/lib/Image/ExifTool/Canon.pm +66 -27
- package/bin/lib/Image/ExifTool/CanonCustom.pm +1 -1
- package/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
- package/bin/lib/Image/ExifTool/CanonVRD.pm +1 -1
- package/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
- package/bin/lib/Image/ExifTool/Casio.pm +1 -1
- package/bin/lib/Image/ExifTool/Charset.pm +1 -1
- package/bin/lib/Image/ExifTool/DICOM.pm +1 -1
- package/bin/lib/Image/ExifTool/DJI.pm +196 -30
- package/bin/lib/Image/ExifTool/DNG.pm +1 -1
- package/bin/lib/Image/ExifTool/DPX.pm +1 -1
- package/bin/lib/Image/ExifTool/DV.pm +1 -1
- package/bin/lib/Image/ExifTool/DarwinCore.pm +1 -1
- package/bin/lib/Image/ExifTool/DjVu.pm +1 -1
- package/bin/lib/Image/ExifTool/EXE.pm +138 -33
- package/bin/lib/Image/ExifTool/Exif.pm +29 -16
- package/bin/lib/Image/ExifTool/FITS.pm +3 -3
- package/bin/lib/Image/ExifTool/FLAC.pm +1 -1
- package/bin/lib/Image/ExifTool/FLIF.pm +3 -3
- package/bin/lib/Image/ExifTool/FLIR.pm +1 -1
- package/bin/lib/Image/ExifTool/Fixup.pm +1 -1
- package/bin/lib/Image/ExifTool/Flash.pm +1 -1
- package/bin/lib/Image/ExifTool/FlashPix.pm +17 -21
- package/bin/lib/Image/ExifTool/Font.pm +2 -2
- package/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
- package/bin/lib/Image/ExifTool/FujiFilm.pm +1 -1
- package/bin/lib/Image/ExifTool/GE.pm +1 -1
- package/bin/lib/Image/ExifTool/GIF.pm +144 -93
- package/bin/lib/Image/ExifTool/GIMP.pm +1 -1
- package/bin/lib/Image/ExifTool/GM.pm +1 -1
- package/bin/lib/Image/ExifTool/GPS.pm +34 -30
- package/bin/lib/Image/ExifTool/GeoTiff.pm +1 -1
- package/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- package/bin/lib/Image/ExifTool/Geolocation.pm +19 -9
- package/bin/lib/Image/ExifTool/Geotag.pm +46 -12
- package/bin/lib/Image/ExifTool/GoPro.pm +120 -8
- package/bin/lib/Image/ExifTool/H264.pm +1 -1
- package/bin/lib/Image/ExifTool/HP.pm +2 -2
- package/bin/lib/Image/ExifTool/HTML.pm +1 -1
- package/bin/lib/Image/ExifTool/HtmlDump.pm +1 -1
- package/bin/lib/Image/ExifTool/ICC_Profile.pm +81 -2
- package/bin/lib/Image/ExifTool/ICO.pm +1 -1
- package/bin/lib/Image/ExifTool/ID3.pm +8 -8
- package/bin/lib/Image/ExifTool/IPTC.pm +10 -7
- package/bin/lib/Image/ExifTool/ISO.pm +1 -1
- package/bin/lib/Image/ExifTool/ITC.pm +1 -1
- package/bin/lib/Image/ExifTool/Import.pm +5 -4
- package/bin/lib/Image/ExifTool/InDesign.pm +2 -2
- package/bin/lib/Image/ExifTool/InfiRay.pm +1 -1
- package/bin/lib/Image/ExifTool/JPEG.pm +32 -5
- package/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
- package/bin/lib/Image/ExifTool/JSON.pm +1 -1
- package/bin/lib/Image/ExifTool/JVC.pm +1 -1
- package/bin/lib/Image/ExifTool/Jpeg2000.pm +10 -9
- package/bin/lib/Image/ExifTool/Kodak.pm +1 -1
- package/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
- package/bin/lib/Image/ExifTool/LIF.pm +1 -1
- package/bin/lib/Image/ExifTool/LNK.pm +2 -2
- package/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/en_ca.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/en_gb.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/fi.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/fr.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/it.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/ja.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/ko.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/nl.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/pl.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/sk.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/tr.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
- package/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
- package/bin/lib/Image/ExifTool/Leaf.pm +1 -1
- package/bin/lib/Image/ExifTool/LigoGPS.pm +409 -0
- package/bin/lib/Image/ExifTool/Lytro.pm +1 -1
- package/bin/lib/Image/ExifTool/M2TS.pm +57 -18
- package/bin/lib/Image/ExifTool/MIE.pm +15 -6
- package/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
- package/bin/lib/Image/ExifTool/MIFF.pm +1 -1
- package/bin/lib/Image/ExifTool/MISB.pm +1 -1
- package/bin/lib/Image/ExifTool/MNG.pm +1 -1
- package/bin/lib/Image/ExifTool/MOI.pm +1 -1
- package/bin/lib/Image/ExifTool/MPC.pm +1 -1
- package/bin/lib/Image/ExifTool/MPEG.pm +1 -1
- package/bin/lib/Image/ExifTool/MPF.pm +1 -1
- package/bin/lib/Image/ExifTool/MRC.pm +1 -1
- package/bin/lib/Image/ExifTool/MWG.pm +1 -1
- package/bin/lib/Image/ExifTool/MXF.pm +3 -3
- package/bin/lib/Image/ExifTool/MacOS.pm +3 -2
- package/bin/lib/Image/ExifTool/MakerNotes.pm +1 -1
- package/bin/lib/Image/ExifTool/Matroska.pm +22 -6
- package/bin/lib/Image/ExifTool/Microsoft.pm +2 -2
- package/bin/lib/Image/ExifTool/Minolta.pm +1 -1
- package/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
- package/bin/lib/Image/ExifTool/Motorola.pm +1 -1
- package/bin/lib/Image/ExifTool/Nikon.pm +495 -39
- package/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
- package/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
- package/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
- package/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
- package/bin/lib/Image/ExifTool/OOXML.pm +8 -8
- package/bin/lib/Image/ExifTool/Ogg.pm +1 -1
- package/bin/lib/Image/ExifTool/Olympus.pm +1 -1
- package/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
- package/bin/lib/Image/ExifTool/Opus.pm +1 -1
- package/bin/lib/Image/ExifTool/Other.pm +1 -1
- package/bin/lib/Image/ExifTool/PCX.pm +1 -1
- package/bin/lib/Image/ExifTool/PDF.pm +49 -18
- package/bin/lib/Image/ExifTool/PGF.pm +1 -1
- package/bin/lib/Image/ExifTool/PICT.pm +1 -1
- package/bin/lib/Image/ExifTool/PLIST.pm +4 -4
- package/bin/lib/Image/ExifTool/PLUS.pm +1 -1
- package/bin/lib/Image/ExifTool/PNG.pm +20 -8
- package/bin/lib/Image/ExifTool/PPM.pm +12 -3
- package/bin/lib/Image/ExifTool/PSP.pm +1 -1
- package/bin/lib/Image/ExifTool/Palm.pm +1 -1
- package/bin/lib/Image/ExifTool/Panasonic.pm +27 -3
- package/bin/lib/Image/ExifTool/PanasonicRaw.pm +1 -1
- package/bin/lib/Image/ExifTool/Parrot.pm +1 -1
- package/bin/lib/Image/ExifTool/Pentax.pm +1 -1
- package/bin/lib/Image/ExifTool/PhaseOne.pm +4 -4
- package/bin/lib/Image/ExifTool/PhotoCD.pm +1 -1
- package/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
- package/bin/lib/Image/ExifTool/Photoshop.pm +65 -4
- package/bin/lib/Image/ExifTool/PostScript.pm +1 -1
- package/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
- package/bin/lib/Image/ExifTool/Protobuf.pm +270 -0
- package/bin/lib/Image/ExifTool/Qualcomm.pm +1 -1
- package/bin/lib/Image/ExifTool/QuickTime.pm +326 -88
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +199 -195
- package/bin/lib/Image/ExifTool/README +12 -2
- package/bin/lib/Image/ExifTool/RIFF.pm +21 -6
- package/bin/lib/Image/ExifTool/RSRC.pm +1 -1
- package/bin/lib/Image/ExifTool/RTF.pm +2 -2
- package/bin/lib/Image/ExifTool/Radiance.pm +1 -1
- package/bin/lib/Image/ExifTool/Rawzor.pm +1 -1
- package/bin/lib/Image/ExifTool/Real.pm +1 -1
- package/bin/lib/Image/ExifTool/Reconyx.pm +1 -1
- package/bin/lib/Image/ExifTool/Red.pm +1 -1
- package/bin/lib/Image/ExifTool/Ricoh.pm +4 -4
- package/bin/lib/Image/ExifTool/Samsung.pm +2 -2
- package/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
- package/bin/lib/Image/ExifTool/Scalado.pm +1 -1
- package/bin/lib/Image/ExifTool/Shift.pl +1 -1
- package/bin/lib/Image/ExifTool/Shortcuts.pm +1 -1
- package/bin/lib/Image/ExifTool/Sigma.pm +1 -1
- package/bin/lib/Image/ExifTool/SigmaRaw.pm +1 -1
- package/bin/lib/Image/ExifTool/Sony.pm +5 -4
- package/bin/lib/Image/ExifTool/SonyIDC.pm +1 -1
- package/bin/lib/Image/ExifTool/Stim.pm +1 -1
- package/bin/lib/Image/ExifTool/TagInfoXML.pm +6 -5
- package/bin/lib/Image/ExifTool/TagLookup.pm +7023 -6968
- package/bin/lib/Image/ExifTool/TagNames.pod +445 -29
- package/bin/lib/Image/ExifTool/Text.pm +4 -3
- package/bin/lib/Image/ExifTool/Theora.pm +1 -1
- package/bin/lib/Image/ExifTool/Torrent.pm +3 -3
- package/bin/lib/Image/ExifTool/Unknown.pm +1 -1
- package/bin/lib/Image/ExifTool/VCard.pm +3 -3
- package/bin/lib/Image/ExifTool/Validate.pm +6 -6
- package/bin/lib/Image/ExifTool/Vivo.pm +124 -0
- package/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
- package/bin/lib/Image/ExifTool/WPG.pm +1 -1
- package/bin/lib/Image/ExifTool/WTV.pm +1 -1
- package/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
- package/bin/lib/Image/ExifTool/WriteExif.pl +3 -3
- package/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
- package/bin/lib/Image/ExifTool/WritePDF.pl +1 -1
- package/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
- package/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
- package/bin/lib/Image/ExifTool/WritePostScript.pl +1 -1
- package/bin/lib/Image/ExifTool/WriteQuickTime.pl +166 -79
- package/bin/lib/Image/ExifTool/WriteRIFF.pl +17 -6
- package/bin/lib/Image/ExifTool/WriteXMP.pl +3 -3
- package/bin/lib/Image/ExifTool/Writer.pl +89 -96
- package/bin/lib/Image/ExifTool/XISF.pm +1 -1
- package/bin/lib/Image/ExifTool/XMP.pm +28 -13
- package/bin/lib/Image/ExifTool/XMP2.pl +103 -1
- package/bin/lib/Image/ExifTool/XMPStruct.pl +2 -3
- package/bin/lib/Image/ExifTool/ZIP.pm +2 -2
- package/bin/lib/Image/ExifTool/ZISRAW.pm +1 -1
- package/bin/lib/Image/ExifTool/iWork.pm +1 -1
- package/bin/lib/Image/ExifTool.pm +335 -163
- package/bin/lib/Image/ExifTool.pod +119 -73
- package/bin/perl-Image-ExifTool.spec +1 -1
- package/bin/windows_exiftool.txt +96 -51
- package/package.json +6 -6
|
@@ -4005,7 +4005,7 @@ and values.
|
|
|
4005
4005
|
|
|
4006
4006
|
=head1 AUTHOR
|
|
4007
4007
|
|
|
4008
|
-
Copyright 2003-
|
|
4008
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
4009
4009
|
|
|
4010
4010
|
This library is free software; you can redistribute it and/or modify it
|
|
4011
4011
|
under the same terms as Perl itself.
|
|
@@ -2878,7 +2878,7 @@ and values.
|
|
|
2878
2878
|
|
|
2879
2879
|
=head1 AUTHOR
|
|
2880
2880
|
|
|
2881
|
-
Copyright 2003-
|
|
2881
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
2882
2882
|
|
|
2883
2883
|
This library is free software; you can redistribute it and/or modify it
|
|
2884
2884
|
under the same terms as Perl itself.
|
|
@@ -11270,7 +11270,7 @@ and values.
|
|
|
11270
11270
|
|
|
11271
11271
|
=head1 AUTHOR
|
|
11272
11272
|
|
|
11273
|
-
Copyright 2003-
|
|
11273
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
11274
11274
|
|
|
11275
11275
|
This library is free software; you can redistribute it and/or modify it
|
|
11276
11276
|
under the same terms as Perl itself.
|
|
@@ -7903,7 +7903,7 @@ and values.
|
|
|
7903
7903
|
|
|
7904
7904
|
=head1 AUTHOR
|
|
7905
7905
|
|
|
7906
|
-
Copyright 2003-
|
|
7906
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
7907
7907
|
|
|
7908
7908
|
This library is free software; you can redistribute it and/or modify it
|
|
7909
7909
|
under the same terms as Perl itself.
|
|
@@ -5841,7 +5841,7 @@ and values.
|
|
|
5841
5841
|
|
|
5842
5842
|
=head1 AUTHOR
|
|
5843
5843
|
|
|
5844
|
-
Copyright 2003-
|
|
5844
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
5845
5845
|
|
|
5846
5846
|
This library is free software; you can redistribute it and/or modify it
|
|
5847
5847
|
under the same terms as Perl itself.
|
|
@@ -2316,7 +2316,7 @@ and values.
|
|
|
2316
2316
|
|
|
2317
2317
|
=head1 AUTHOR
|
|
2318
2318
|
|
|
2319
|
-
Copyright 2003-
|
|
2319
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
2320
2320
|
|
|
2321
2321
|
This library is free software; you can redistribute it and/or modify it
|
|
2322
2322
|
under the same terms as Perl itself.
|
|
@@ -3208,7 +3208,7 @@ and values.
|
|
|
3208
3208
|
|
|
3209
3209
|
=head1 AUTHOR
|
|
3210
3210
|
|
|
3211
|
-
Copyright 2003-
|
|
3211
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
3212
3212
|
|
|
3213
3213
|
This library is free software; you can redistribute it and/or modify it
|
|
3214
3214
|
under the same terms as Perl itself.
|
|
@@ -1258,7 +1258,7 @@ and values.
|
|
|
1258
1258
|
|
|
1259
1259
|
=head1 AUTHOR
|
|
1260
1260
|
|
|
1261
|
-
Copyright 2003-
|
|
1261
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
1262
1262
|
|
|
1263
1263
|
This library is free software; you can redistribute it and/or modify it
|
|
1264
1264
|
under the same terms as Perl itself.
|
|
@@ -5718,7 +5718,7 @@ and values.
|
|
|
5718
5718
|
|
|
5719
5719
|
=head1 AUTHOR
|
|
5720
5720
|
|
|
5721
|
-
Copyright 2003-
|
|
5721
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
5722
5722
|
|
|
5723
5723
|
This library is free software; you can redistribute it and/or modify it
|
|
5724
5724
|
under the same terms as Perl itself.
|
|
@@ -1789,7 +1789,7 @@ and values.
|
|
|
1789
1789
|
|
|
1790
1790
|
=head1 AUTHOR
|
|
1791
1791
|
|
|
1792
|
-
Copyright 2003-
|
|
1792
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
1793
1793
|
|
|
1794
1794
|
This library is free software; you can redistribute it and/or modify it
|
|
1795
1795
|
under the same terms as Perl itself.
|
|
@@ -620,7 +620,7 @@ and values.
|
|
|
620
620
|
|
|
621
621
|
=head1 AUTHOR
|
|
622
622
|
|
|
623
|
-
Copyright 2003-
|
|
623
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
624
624
|
|
|
625
625
|
This library is free software; you can redistribute it and/or modify it
|
|
626
626
|
under the same terms as Perl itself.
|
|
@@ -528,7 +528,7 @@ and values.
|
|
|
528
528
|
|
|
529
529
|
=head1 AUTHOR
|
|
530
530
|
|
|
531
|
-
Copyright 2003-
|
|
531
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
532
532
|
|
|
533
533
|
This library is free software; you can redistribute it and/or modify it
|
|
534
534
|
under the same terms as Perl itself.
|
|
@@ -1313,7 +1313,7 @@ and values.
|
|
|
1313
1313
|
|
|
1314
1314
|
=head1 AUTHOR
|
|
1315
1315
|
|
|
1316
|
-
Copyright 2003-
|
|
1316
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
1317
1317
|
|
|
1318
1318
|
This library is free software; you can redistribute it and/or modify it
|
|
1319
1319
|
under the same terms as Perl itself.
|
|
@@ -784,7 +784,7 @@ and values.
|
|
|
784
784
|
|
|
785
785
|
=head1 AUTHOR
|
|
786
786
|
|
|
787
|
-
Copyright 2003-
|
|
787
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
788
788
|
|
|
789
789
|
This library is free software; you can redistribute it and/or modify it
|
|
790
790
|
under the same terms as Perl itself.
|
|
@@ -504,7 +504,7 @@ Capture.
|
|
|
504
504
|
|
|
505
505
|
=head1 AUTHOR
|
|
506
506
|
|
|
507
|
-
Copyright 2003-
|
|
507
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
508
508
|
|
|
509
509
|
This library is free software; you can redistribute it and/or modify it
|
|
510
510
|
under the same terms as Perl itself.
|
|
@@ -0,0 +1,409 @@
|
|
|
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
|
+
# Notes: The directory data should start with the string "LIGOGPSINFO\0"
|
|
273
|
+
sub ProcessLigoGPS($$$;$)
|
|
274
|
+
{
|
|
275
|
+
my ($et, $dirInfo, $tagTbl, $noFuzz) = @_;
|
|
276
|
+
my $dataPt = $$dirInfo{DataPt};
|
|
277
|
+
my $pos = ($$dirInfo{DirStart} || 0) + 0x14;
|
|
278
|
+
return undef if $pos > length $$dataPt;
|
|
279
|
+
my $cipherInfo = $$et{LigoCipher};
|
|
280
|
+
my $dirName = $$dirInfo{DirName} || 'LigoGPS';
|
|
281
|
+
push @{$$et{PATH}}, $dirName unless $$dirInfo{DirID};
|
|
282
|
+
# not fuzzed if header =~ /LIGOGPSINFO\0\0\0\0[\x01\x14]/ (\x01=BlueSkySeaDV688)
|
|
283
|
+
$noFuzz = 1 if substr($$dataPt, $pos-8, 4) =~ /^\0\0\0[\x01\x14]/;
|
|
284
|
+
$et->VerboseDir($dirName);
|
|
285
|
+
for (; $pos + 0x84 <= length($$dataPt); $pos+=0x84) {
|
|
286
|
+
my $dat = substr($$dataPt, $pos, 0x84);
|
|
287
|
+
$dat =~ /^####/ or next; # (have seen blank records filled with zeros, so keep trying)
|
|
288
|
+
# decipher if we already know the encryption
|
|
289
|
+
$cipherInfo and $$cipherInfo{decipher} and DecipherLigoGPS($et, $dat, $tagTbl, $noFuzz) and next;
|
|
290
|
+
my $str = DecryptLigoGPS($dat);
|
|
291
|
+
defined $str or DecipherLigoGPS($et, $dat, $tagTbl, $noFuzz), next; # try to decipher
|
|
292
|
+
$et->VPrint(1, "$$et{INDENT}\(Decrypted: ",unpack('V',$str),' ',substr($str,4),")\n") if $$et{OPTIONS}{Verbose} > 1;
|
|
293
|
+
ParseLigoGPS($et, $str, $tagTbl, $noFuzz);
|
|
294
|
+
}
|
|
295
|
+
pop @{$$et{PATH}} unless $$dirInfo{DirID};
|
|
296
|
+
delete $$et{DOC_NUM};
|
|
297
|
+
return 1;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
#------------------------------------------------------------------------------
|
|
301
|
+
# Process LIGOGPSINFO JSON-format GPS (Yada RoadCam Pro 4K BT58189)
|
|
302
|
+
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
|
|
303
|
+
# Returns: 1 on success
|
|
304
|
+
# Sample data (chained 512-byte records starting like this):
|
|
305
|
+
# 0000: 4c 49 47 4f 47 50 53 49 4e 46 4f 20 7b 22 48 6f [LIGOGPSINFO {"Ho]
|
|
306
|
+
# 0010: 75 72 22 3a 20 22 32 33 22 2c 20 22 4d 69 6e 75 [ur": "23", "Minu]
|
|
307
|
+
# 0020: 74 65 22 3a 20 22 31 30 22 2c 20 22 53 65 63 6f [te": "10", "Seco]
|
|
308
|
+
# 0030: 6e 64 22 3a 20 22 32 32 22 2c 20 22 59 65 61 72 [nd": "22", "Year]
|
|
309
|
+
# 0040: 22 3a 20 22 32 30 32 33 22 2c 20 22 4d 6f 6e 74 [": "2023", "Mont]
|
|
310
|
+
# 0050: 68 22 3a 20 22 31 32 22 2c 20 22 44 61 79 22 3a [h": "12", "Day":]
|
|
311
|
+
# 0060: 20 22 32 38 22 2c 20 22 73 74 61 74 75 73 22 3a [ "28", "status":]
|
|
312
|
+
sub ProcessLigoJSON($$$)
|
|
313
|
+
{
|
|
314
|
+
my ($et, $dirInfo, $tagTbl) = @_;
|
|
315
|
+
my $dataPt = $$dirInfo{DataPt};
|
|
316
|
+
my $dirLen = $$dirInfo{DirLen};
|
|
317
|
+
require Image::ExifTool::Import;
|
|
318
|
+
$et->VerboseDir('LIGO_JSON', undef, length($$dataPt));
|
|
319
|
+
$$et{SET_GROUP1} = 'LIGO';
|
|
320
|
+
while ($$dataPt =~ /LIGOGPSINFO (\{.*?\})/g) {
|
|
321
|
+
my $json = $1;
|
|
322
|
+
my %dbase;
|
|
323
|
+
Image::ExifTool::Import::ReadJSON(\$json, \%dbase);
|
|
324
|
+
my $info = $dbase{'*'} or next;
|
|
325
|
+
# my sample contains the following JSON fields (in this order):
|
|
326
|
+
# Hour Minute Second Year Month Day (GPS UTC time)
|
|
327
|
+
# status NS EW Latitude Longitude Speed (speed in knots)
|
|
328
|
+
# GsensorX GsensorY GsensorZ (units? - only seen "000" for all)
|
|
329
|
+
# MHour MMinute MSecond MYear MMonth MDay (local dashcam clock time)
|
|
330
|
+
# OLatitude OLongitude (? same values as Latitude/Longitude)
|
|
331
|
+
next unless defined $$info{status} and $$info{status} eq 'A'; # only read if GPS is active
|
|
332
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
|
333
|
+
my $num = 0;
|
|
334
|
+
defined $$info{$_} and ++$num foreach qw(Year Month Day Hour Minute Second);
|
|
335
|
+
if ($num == 6) {
|
|
336
|
+
# this is the GPS time in UTC
|
|
337
|
+
my $time = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ',@$info{qw{Year Month Day Hour Minute Second}});
|
|
338
|
+
$et->HandleTag($tagTbl, GPSDateTime => $time);
|
|
339
|
+
}
|
|
340
|
+
if ($$info{Latitude} and $$info{Longitude}) {
|
|
341
|
+
my $lat = $$info{Latitude};
|
|
342
|
+
$lat = -$lat if $$info{NS} and $$info{NS} eq 'S';
|
|
343
|
+
my $lon = $$info{Longitude};
|
|
344
|
+
$lon = -$lon if $$info{EW} and $$info{EW} eq 'W';
|
|
345
|
+
$et->HandleTag($tagTbl, GPSLatitude => $lat);
|
|
346
|
+
$et->HandleTag($tagTbl, GPSLongitude => $lon);
|
|
347
|
+
}
|
|
348
|
+
$et->HandleTag($tagTbl, GPSSpeed => $$info{Speed} * $knotsToKph) if defined $$info{Speed};
|
|
349
|
+
if (defined $$info{GsensorX} and defined $$info{GsensorY} and defined $$info{GsensorZ}) {
|
|
350
|
+
# (don't know conversion factor for accel data, so leave it raw for now)
|
|
351
|
+
$et->HandleTag($tagTbl, Accelerometer => "$$info{GsensorX} $$info{GsensorY} $$info{GsensorZ}");
|
|
352
|
+
}
|
|
353
|
+
$num = 0;
|
|
354
|
+
defined $$info{$_} and ++$num foreach qw(MYear MMonth MDay MHour MMinute MSecond);
|
|
355
|
+
if ($num == 6) {
|
|
356
|
+
# this is the dashcam clock time (local time zone)
|
|
357
|
+
my $time = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d',@$info{qw{MYear MMonth MDay MHour MMinute MSecond}});
|
|
358
|
+
$et->HandleTag($tagTbl, DateTimeOriginal => $time);
|
|
359
|
+
}
|
|
360
|
+
if (defined $$info{OLatitude} and defined $$info{OLongitude}) {
|
|
361
|
+
my $lat = $$info{OLatitude};
|
|
362
|
+
$lat = -$lat if $$info{NS} and $$info{NS} eq 'S';
|
|
363
|
+
my $lon = $$info{OLongitude};
|
|
364
|
+
$lon = -$lon if $$info{EW} and $$info{EW} eq 'W';
|
|
365
|
+
$et->HandleTag($tagTbl, GPSLatitude2 => $lat);
|
|
366
|
+
$et->HandleTag($tagTbl, GPSLongitude2 => $lon);
|
|
367
|
+
}
|
|
368
|
+
unless ($et->Options('ExtractEmbedded')) {
|
|
369
|
+
$et->Warn('Use the ExtractEmbedded option to extract all timed GPS',3);
|
|
370
|
+
last;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
delete $$et{DOC_NUM};
|
|
374
|
+
delete $$et{SET_GROUP1};
|
|
375
|
+
return 1;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
1; #end
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
__END__
|
|
382
|
+
|
|
383
|
+
=head1 NAME
|
|
384
|
+
|
|
385
|
+
Image::ExifTool::LigoGPS - Read LIGOGPSINFO timed GPS records
|
|
386
|
+
|
|
387
|
+
=head1 SYNOPSIS
|
|
388
|
+
|
|
389
|
+
This module is loaded automatically by Image::ExifTool when required.
|
|
390
|
+
|
|
391
|
+
=head1 DESCRIPTION
|
|
392
|
+
|
|
393
|
+
This module decrypts, deciphers and decodes timed GPS metadata from
|
|
394
|
+
LIGOGPSINFO records found in various locations of MP4 and M2TS videos from a
|
|
395
|
+
variety of dashcam makes and models.
|
|
396
|
+
|
|
397
|
+
=head1 AUTHOR
|
|
398
|
+
|
|
399
|
+
Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
|
|
400
|
+
|
|
401
|
+
This library is free software; you can redistribute it and/or modify it
|
|
402
|
+
under the same terms as Perl itself.
|
|
403
|
+
|
|
404
|
+
=head1 SEE ALSO
|
|
405
|
+
|
|
406
|
+
L<Image::ExifTool::TagNames/QuickTime Stream Tags>,
|
|
407
|
+
L<Image::ExifTool(3pm)|Image::ExifTool>
|
|
408
|
+
|
|
409
|
+
=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.
|