exiftool_vendored 10.65.0 → 11.41.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of exiftool_vendored might be problematic. Click here for more details.

Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +818 -19
  3. data/bin/MANIFEST +38 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +48 -44
  7. data/bin/arg_files/exif2xmp.args +4 -1
  8. data/bin/arg_files/gps2xmp.args +4 -1
  9. data/bin/arg_files/iptcCore.args +8 -0
  10. data/bin/arg_files/xmp2exif.args +4 -1
  11. data/bin/arg_files/xmp2gps.args +4 -1
  12. data/bin/config_files/dji.config +131 -0
  13. data/bin/config_files/example.config +6 -2
  14. data/bin/config_files/gps2utm.config +256 -256
  15. data/bin/config_files/nksc.config +146 -0
  16. data/bin/config_files/picasa_faces.config +382 -382
  17. data/bin/exiftool +688 -408
  18. data/bin/fmt_files/gpx.fmt +10 -6
  19. data/bin/fmt_files/gpx_wpt.fmt +10 -6
  20. data/bin/fmt_files/kml.fmt +8 -5
  21. data/bin/lib/File/RandomAccess.pm +48 -8
  22. data/bin/lib/File/RandomAccess.pod +21 -2
  23. data/bin/lib/Image/ExifTool.pm +645 -256
  24. data/bin/lib/Image/ExifTool.pod +219 -164
  25. data/bin/lib/Image/ExifTool/AES.pm +1 -1
  26. data/bin/lib/Image/ExifTool/AFCP.pm +3 -8
  27. data/bin/lib/Image/ExifTool/AIFF.pm +12 -4
  28. data/bin/lib/Image/ExifTool/APE.pm +1 -1
  29. data/bin/lib/Image/ExifTool/APP12.pm +1 -1
  30. data/bin/lib/Image/ExifTool/ASF.pm +19 -6
  31. data/bin/lib/Image/ExifTool/Apple.pm +13 -5
  32. data/bin/lib/Image/ExifTool/Audible.pm +1 -1
  33. data/bin/lib/Image/ExifTool/BMP.pm +1 -1
  34. data/bin/lib/Image/ExifTool/BPG.pm +17 -15
  35. data/bin/lib/Image/ExifTool/BZZ.pm +1 -1
  36. data/bin/lib/Image/ExifTool/BigTIFF.pm +30 -15
  37. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +103 -52
  38. data/bin/lib/Image/ExifTool/Canon.pm +684 -112
  39. data/bin/lib/Image/ExifTool/CanonCustom.pm +119 -9
  40. data/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
  41. data/bin/lib/Image/ExifTool/CanonVRD.pm +13 -26
  42. data/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
  43. data/bin/lib/Image/ExifTool/Casio.pm +1 -1
  44. data/bin/lib/Image/ExifTool/Charset.pm +1 -1
  45. data/bin/lib/Image/ExifTool/DICOM.pm +12 -5
  46. data/bin/lib/Image/ExifTool/DJI.pm +51 -3
  47. data/bin/lib/Image/ExifTool/DNG.pm +15 -8
  48. data/bin/lib/Image/ExifTool/DPX.pm +1 -1
  49. data/bin/lib/Image/ExifTool/DV.pm +1 -1
  50. data/bin/lib/Image/ExifTool/DarwinCore.pm +63 -23
  51. data/bin/lib/Image/ExifTool/DjVu.pm +4 -2
  52. data/bin/lib/Image/ExifTool/EXE.pm +30 -6
  53. data/bin/lib/Image/ExifTool/Exif.pm +351 -109
  54. data/bin/lib/Image/ExifTool/FITS.pm +148 -0
  55. data/bin/lib/Image/ExifTool/FLAC.pm +2 -2
  56. data/bin/lib/Image/ExifTool/FLIF.pm +1 -1
  57. data/bin/lib/Image/ExifTool/FLIR.pm +109 -13
  58. data/bin/lib/Image/ExifTool/Fixup.pm +1 -1
  59. data/bin/lib/Image/ExifTool/Flash.pm +3 -3
  60. data/bin/lib/Image/ExifTool/FlashPix.pm +433 -9
  61. data/bin/lib/Image/ExifTool/Font.pm +2 -2
  62. data/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
  63. data/bin/lib/Image/ExifTool/FujiFilm.pm +336 -16
  64. data/bin/lib/Image/ExifTool/GE.pm +1 -1
  65. data/bin/lib/Image/ExifTool/GIF.pm +5 -7
  66. data/bin/lib/Image/ExifTool/GIMP.pm +39 -3
  67. data/bin/lib/Image/ExifTool/GPS.pm +48 -22
  68. data/bin/lib/Image/ExifTool/GeoTiff.pm +23 -23
  69. data/bin/lib/Image/ExifTool/Geotag.pm +80 -45
  70. data/bin/lib/Image/ExifTool/GoPro.pm +709 -0
  71. data/bin/lib/Image/ExifTool/H264.pm +40 -18
  72. data/bin/lib/Image/ExifTool/HP.pm +1 -1
  73. data/bin/lib/Image/ExifTool/HTML.pm +19 -12
  74. data/bin/lib/Image/ExifTool/HtmlDump.pm +37 -26
  75. data/bin/lib/Image/ExifTool/ICC_Profile.pm +297 -23
  76. data/bin/lib/Image/ExifTool/ID3.pm +12 -7
  77. data/bin/lib/Image/ExifTool/IPTC.pm +48 -19
  78. data/bin/lib/Image/ExifTool/ISO.pm +1 -1
  79. data/bin/lib/Image/ExifTool/ITC.pm +1 -1
  80. data/bin/lib/Image/ExifTool/Import.pm +13 -9
  81. data/bin/lib/Image/ExifTool/InDesign.pm +3 -5
  82. data/bin/lib/Image/ExifTool/JPEG.pm +22 -11
  83. data/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
  84. data/bin/lib/Image/ExifTool/JSON.pm +3 -3
  85. data/bin/lib/Image/ExifTool/JVC.pm +1 -1
  86. data/bin/lib/Image/ExifTool/Jpeg2000.pm +2 -2
  87. data/bin/lib/Image/ExifTool/Kodak.pm +1233 -58
  88. data/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
  89. data/bin/lib/Image/ExifTool/LNK.pm +1 -1
  90. data/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
  91. data/bin/lib/Image/ExifTool/Lang/de.pm +33 -24
  92. data/bin/lib/Image/ExifTool/Lang/en_ca.pm +64 -2
  93. data/bin/lib/Image/ExifTool/Lang/en_gb.pm +64 -2
  94. data/bin/lib/Image/ExifTool/Lang/es.pm +8 -4
  95. data/bin/lib/Image/ExifTool/Lang/fi.pm +46 -4
  96. data/bin/lib/Image/ExifTool/Lang/fr.pm +5 -3
  97. data/bin/lib/Image/ExifTool/Lang/it.pm +6 -3
  98. data/bin/lib/Image/ExifTool/Lang/ja.pm +15 -3
  99. data/bin/lib/Image/ExifTool/Lang/ko.pm +5 -2
  100. data/bin/lib/Image/ExifTool/Lang/nl.pm +6 -3
  101. data/bin/lib/Image/ExifTool/Lang/pl.pm +2 -2
  102. data/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
  103. data/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
  104. data/bin/lib/Image/ExifTool/Lang/tr.pm +4 -2
  105. data/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
  106. data/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
  107. data/bin/lib/Image/ExifTool/Leaf.pm +1 -1
  108. data/bin/lib/Image/ExifTool/Lytro.pm +4 -8
  109. data/bin/lib/Image/ExifTool/M2TS.pm +10 -9
  110. data/bin/lib/Image/ExifTool/MIE.pm +12 -8
  111. data/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
  112. data/bin/lib/Image/ExifTool/MIFF.pm +1 -1
  113. data/bin/lib/Image/ExifTool/MNG.pm +1 -1
  114. data/bin/lib/Image/ExifTool/MOI.pm +1 -1
  115. data/bin/lib/Image/ExifTool/MPC.pm +1 -1
  116. data/bin/lib/Image/ExifTool/MPEG.pm +2 -3
  117. data/bin/lib/Image/ExifTool/MPF.pm +6 -6
  118. data/bin/lib/Image/ExifTool/MWG.pm +4 -4
  119. data/bin/lib/Image/ExifTool/MXF.pm +2 -2
  120. data/bin/lib/Image/ExifTool/MacOS.pm +184 -34
  121. data/bin/lib/Image/ExifTool/MakerNotes.pm +101 -18
  122. data/bin/lib/Image/ExifTool/Matroska.pm +1 -1
  123. data/bin/lib/Image/ExifTool/Microsoft.pm +5 -3
  124. data/bin/lib/Image/ExifTool/Minolta.pm +89 -62
  125. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
  126. data/bin/lib/Image/ExifTool/Motorola.pm +1 -1
  127. data/bin/lib/Image/ExifTool/Nikon.pm +1511 -380
  128. data/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
  129. data/bin/lib/Image/ExifTool/NikonCustom.pm +2758 -2935
  130. data/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
  131. data/bin/lib/Image/ExifTool/OOXML.pm +1 -1
  132. data/bin/lib/Image/ExifTool/Ogg.pm +1 -1
  133. data/bin/lib/Image/ExifTool/Olympus.pm +47 -8
  134. data/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
  135. data/bin/lib/Image/ExifTool/Opus.pm +1 -1
  136. data/bin/lib/Image/ExifTool/PCX.pm +138 -0
  137. data/bin/lib/Image/ExifTool/PDF.pm +58 -42
  138. data/bin/lib/Image/ExifTool/PGF.pm +1 -1
  139. data/bin/lib/Image/ExifTool/PICT.pm +1 -1
  140. data/bin/lib/Image/ExifTool/PLIST.pm +12 -5
  141. data/bin/lib/Image/ExifTool/PLUS.pm +1 -1
  142. data/bin/lib/Image/ExifTool/PNG.pm +108 -10
  143. data/bin/lib/Image/ExifTool/PPM.pm +3 -3
  144. data/bin/lib/Image/ExifTool/PSP.pm +1 -1
  145. data/bin/lib/Image/ExifTool/Palm.pm +1 -1
  146. data/bin/lib/Image/ExifTool/Panasonic.pm +299 -31
  147. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +201 -19
  148. data/bin/lib/Image/ExifTool/Pentax.pm +164 -143
  149. data/bin/lib/Image/ExifTool/PhaseOne.pm +12 -5
  150. data/bin/lib/Image/ExifTool/PhotoCD.pm +9 -10
  151. data/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
  152. data/bin/lib/Image/ExifTool/Photoshop.pm +230 -60
  153. data/bin/lib/Image/ExifTool/PostScript.pm +29 -4
  154. data/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
  155. data/bin/lib/Image/ExifTool/Qualcomm.pm +2 -2
  156. data/bin/lib/Image/ExifTool/QuickTime.pm +1539 -279
  157. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +1857 -0
  158. data/bin/lib/Image/ExifTool/README +84 -46
  159. data/bin/lib/Image/ExifTool/RIFF.pm +116 -23
  160. data/bin/lib/Image/ExifTool/RSRC.pm +1 -1
  161. data/bin/lib/Image/ExifTool/RTF.pm +6 -4
  162. data/bin/lib/Image/ExifTool/Radiance.pm +1 -1
  163. data/bin/lib/Image/ExifTool/Rawzor.pm +3 -2
  164. data/bin/lib/Image/ExifTool/Real.pm +1 -1
  165. data/bin/lib/Image/ExifTool/Reconyx.pm +261 -7
  166. data/bin/lib/Image/ExifTool/Red.pm +325 -0
  167. data/bin/lib/Image/ExifTool/Ricoh.pm +3 -7
  168. data/bin/lib/Image/ExifTool/Samsung.pm +95 -25
  169. data/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
  170. data/bin/lib/Image/ExifTool/Scalado.pm +1 -1
  171. data/bin/lib/Image/ExifTool/Shift.pl +26 -12
  172. data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -2
  173. data/bin/lib/Image/ExifTool/Sigma.pm +36 -30
  174. data/bin/lib/Image/ExifTool/SigmaRaw.pm +3 -8
  175. data/bin/lib/Image/ExifTool/Sony.pm +531 -177
  176. data/bin/lib/Image/ExifTool/SonyIDC.pm +63 -3
  177. data/bin/lib/Image/ExifTool/Stim.pm +2 -2
  178. data/bin/lib/Image/ExifTool/TagInfoXML.pm +23 -23
  179. data/bin/lib/Image/ExifTool/TagLookup.pm +6352 -5062
  180. data/bin/lib/Image/ExifTool/TagNames.pod +3024 -565
  181. data/bin/lib/Image/ExifTool/Theora.pm +1 -1
  182. data/bin/lib/Image/ExifTool/Torrent.pm +2 -2
  183. data/bin/lib/Image/ExifTool/Unknown.pm +1 -1
  184. data/bin/lib/Image/ExifTool/VCard.pm +47 -9
  185. data/bin/lib/Image/ExifTool/Validate.pm +391 -99
  186. data/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
  187. data/bin/lib/Image/ExifTool/WTV.pm +319 -0
  188. data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
  189. data/bin/lib/Image/ExifTool/WriteExif.pl +91 -18
  190. data/bin/lib/Image/ExifTool/WriteIPTC.pl +6 -6
  191. data/bin/lib/Image/ExifTool/WritePDF.pl +13 -12
  192. data/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
  193. data/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
  194. data/bin/lib/Image/ExifTool/WritePostScript.pl +2 -2
  195. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +764 -121
  196. data/bin/lib/Image/ExifTool/WriteXMP.pl +176 -67
  197. data/bin/lib/Image/ExifTool/Writer.pl +490 -246
  198. data/bin/lib/Image/ExifTool/XMP.pm +216 -76
  199. data/bin/lib/Image/ExifTool/XMP2.pl +54 -10
  200. data/bin/lib/Image/ExifTool/XMPStruct.pl +14 -11
  201. data/bin/lib/Image/ExifTool/ZIP.pm +60 -15
  202. data/bin/lib/Image/ExifTool/iWork.pm +12 -5
  203. data/bin/perl-Image-ExifTool.spec +46 -44
  204. data/lib/exiftool_vendored/version.rb +1 -1
  205. metadata +14 -4
@@ -68,7 +68,7 @@ General Imaging maker notes.
68
68
 
69
69
  =head1 AUTHOR
70
70
 
71
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
71
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
72
72
 
73
73
  This library is free software; you can redistribute it and/or modify it
74
74
  under the same terms as Perl itself.
@@ -20,7 +20,7 @@ use strict;
20
20
  use vars qw($VERSION);
21
21
  use Image::ExifTool qw(:DataAccess :Utils);
22
22
 
23
- $VERSION = '1.14';
23
+ $VERSION = '1.16';
24
24
 
25
25
  # road map of directory locations in GIF images
26
26
  my %gifMap = (
@@ -102,12 +102,12 @@ my %gifMap = (
102
102
  4.1 => {
103
103
  Name => 'HasColorMap',
104
104
  Mask => 0x80,
105
- PrintConv => { 0x00 => 'No', 0x80 => 'Yes' },
105
+ PrintConv => { 0 => 'No', 1 => 'Yes' },
106
106
  },
107
107
  4.2 => {
108
108
  Name => 'ColorResolutionDepth',
109
109
  Mask => 0x70,
110
- ValueConv => '($val >> 4) + 1',
110
+ ValueConv => '$val + 1',
111
111
  },
112
112
  4.3 => {
113
113
  Name => 'BitsPerPixel',
@@ -321,9 +321,7 @@ Block:
321
321
  my $comment = '';
322
322
  while ($length) {
323
323
  last unless $raf->Read($buff, $length) == $length;
324
- if ($verbose > 2 and not $outfile) {
325
- HexDump(\$buff, undef, Out => $out);
326
- }
324
+ $et->VerboseDump(\$buff) unless $outfile;
327
325
  # add buffer to comment string
328
326
  $comment .= $buff;
329
327
  last unless $raf->Read($ch, 1); # read next block header
@@ -534,7 +532,7 @@ write GIF meta information.
534
532
 
535
533
  =head1 AUTHOR
536
534
 
537
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
535
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
538
536
 
539
537
  This library is free software; you can redistribute it and/or modify it
540
538
  under the same terms as Perl itself.
@@ -4,9 +4,10 @@
4
4
  # Description: Read meta information from GIMP XCF images
5
5
  #
6
6
  # Revisions: 2010/10/05 - P. Harvey Created
7
+ # 2018/08/21 - PH Updated to current XCF specification (v013)
7
8
  #
8
9
  # References: 1) GIMP source code
9
- # 2) http://svn.gnome.org/viewvc/gimp/trunk/devel-docs/xcf.txt?view=markup
10
+ # 2) https://gitlab.gnome.org/GNOME/gimp/blob/master/devel-docs/xcf.txt
10
11
  #------------------------------------------------------------------------------
11
12
 
12
13
  package Image::ExifTool::GIMP;
@@ -15,7 +16,7 @@ use strict;
15
16
  use vars qw($VERSION);
16
17
  use Image::ExifTool qw(:DataAccess :Utils);
17
18
 
18
- $VERSION = '1.02';
19
+ $VERSION = '1.03';
19
20
 
20
21
  sub ProcessParasites($$$);
21
22
 
@@ -28,6 +29,9 @@ sub ProcessParasites($$$);
28
29
  XCF (eXperimental Computing Facilty) images.
29
30
  },
30
31
  header => { SubDirectory => { TagTable => 'Image::ExifTool::GIMP::Header' } },
32
+ # recognized properties
33
+ # 1 - ColorMap
34
+ # 17 - SamplePoints? (doc says 17 is also "PROP_SAMPLE_POINTS"??)
31
35
  17 => {
32
36
  Name => 'Compression',
33
37
  Format => 'int8u',
@@ -38,14 +42,32 @@ sub ProcessParasites($$$);
38
42
  3 => 'Fractal',
39
43
  },
40
44
  },
45
+ # 18 - Guides
41
46
  19 => {
42
47
  Name => 'Resolution',
43
48
  SubDirectory => { TagTable => 'Image::ExifTool::GIMP::Resolution' },
44
49
  },
50
+ 20 => {
51
+ Name => 'Tattoo',
52
+ Format => 'int32u',
53
+ },
45
54
  21 => {
46
55
  Name => 'Parasites',
47
56
  SubDirectory => { TagTable => 'Image::ExifTool::GIMP::Parasite' },
48
57
  },
58
+ 22 => {
59
+ Name => 'Units',
60
+ Format => 'int32u',
61
+ PrintConv => {
62
+ 1 => 'Inches',
63
+ 2 => 'mm',
64
+ 3 => 'Points',
65
+ 4 => 'Picas',
66
+ },
67
+ },
68
+ # 23 Paths
69
+ # 24 UserUnit
70
+ # 25 Vectors
49
71
  );
50
72
 
51
73
  # information extracted from the XCF file header (ref 2)
@@ -55,10 +77,13 @@ sub ProcessParasites($$$);
55
77
  9 => {
56
78
  Name => 'XCFVersion',
57
79
  Format => 'string[5]',
80
+ DataMember => 'XCFVersion',
81
+ RawConv => '$$self{XCFVersion} = $val',
58
82
  PrintConv => {
59
83
  'file' => '0',
60
84
  'v001' => '1',
61
85
  'v002' => '2',
86
+ OTHER => sub { my $val = shift; $val =~ s/^v0*//; return $val },
62
87
  },
63
88
  },
64
89
  14 => { Name => 'ImageWidth', Format => 'int32u' },
@@ -72,6 +97,7 @@ sub ProcessParasites($$$);
72
97
  2 => 'Indexed Color',
73
98
  },
74
99
  },
100
+ # 26 - [XCF 4 or later] Precision
75
101
  );
76
102
 
77
103
  # XCF resolution data (property type 19) (ref 2)
@@ -126,6 +152,13 @@ sub ProcessParasites($$$);
126
152
  Start => 10, # starts after "GIMP_XMP_1" header
127
153
  },
128
154
  },
155
+ 'gimp-image-metadata' => {
156
+ Name => 'XML',
157
+ SubDirectory => { TagTable => 'Image::ExifTool::XMP::XML' },
158
+ },
159
+ # Seen, but not yet decoded:
160
+ # gimp-image-grid
161
+ # jpeg-settings
129
162
  );
130
163
 
131
164
  #------------------------------------------------------------------------------
@@ -193,6 +226,9 @@ sub ProcessXCF($$)
193
226
  # process the XCF header
194
227
  $et->HandleTag($tagTablePtr, 'header', $buff);
195
228
 
229
+ # skip over precision for XCV version 4 or later
230
+ $raf->Seek(4, 1) if $$et{XCFVersion} =~ /^v0*(\d+)/ and $1 >= 4;
231
+
196
232
  # loop through image properties
197
233
  for (;;) {
198
234
  $raf->Read($buff, 8) == 8 or last;
@@ -234,7 +270,7 @@ GIMP software.
234
270
 
235
271
  =head1 AUTHOR
236
272
 
237
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
273
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
238
274
 
239
275
  This library is free software; you can redistribute it and/or modify it
240
276
  under the same terms as Perl itself.
@@ -12,7 +12,7 @@ use strict;
12
12
  use vars qw($VERSION);
13
13
  use Image::ExifTool::Exif;
14
14
 
15
- $VERSION = '1.47';
15
+ $VERSION = '1.50';
16
16
 
17
17
  my %coordConv = (
18
18
  ValueConv => 'Image::ExifTool::GPS::ToDegrees($val)',
@@ -133,7 +133,8 @@ my %coordConv = (
133
133
  # pull time out of any format date/time string
134
134
  # (converting to UTC if a timezone is given)
135
135
  PrintConvInv => sub {
136
- my $v = shift;
136
+ my ($v, $et) = @_;
137
+ $v = $et->TimeNow() if lc($v) eq 'now';
137
138
  my @tz;
138
139
  if ($v =~ s/([-+])(.*)//s) { # remove timezone
139
140
  my $s = $1 eq '-' ? 1 : -1; # opposite sign to convert back to UTC
@@ -230,10 +231,7 @@ my %coordConv = (
230
231
  Writable => 'string',
231
232
  Notes => 'tags 0x0013-0x001a used for subject location according to MWG 2.0',
232
233
  Count => 2,
233
- PrintConv => {
234
- N => 'North',
235
- S => 'South',
236
- },
234
+ PrintConv => { N => 'North', S => 'South' },
237
235
  },
238
236
  0x0014 => {
239
237
  Name => 'GPSDestLatitude',
@@ -245,10 +243,7 @@ my %coordConv = (
245
243
  Name => 'GPSDestLongitudeRef',
246
244
  Writable => 'string',
247
245
  Count => 2,
248
- PrintConv => {
249
- E => 'East',
250
- W => 'West',
251
- },
246
+ PrintConv => { E => 'East', W => 'West' },
252
247
  },
253
248
  0x0016 => {
254
249
  Name => 'GPSDestLongitude',
@@ -314,6 +309,7 @@ my %coordConv = (
314
309
  # (and adjust to UTC if this is a full date/time/timezone value)
315
310
  PrintConvInv => q{
316
311
  my $secs;
312
+ $val = $self->TimeNow() if lc($val) eq 'now';
317
313
  if ($val =~ /[-+]/ and ($secs = Image::ExifTool::GetUnixTime($val, 1))) {
318
314
  $val = Image::ExifTool::ConvertUnixTime($secs);
319
315
  }
@@ -374,7 +370,7 @@ my %coordConv = (
374
370
  PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
375
371
  },
376
372
  GPSAltitude => {
377
- SubDoc => 1, # generate for all sub-documents
373
+ SubDoc => [1,3], # generate for sub-documents if Desire 1 or 3 has a chance to exist
378
374
  Desire => {
379
375
  0 => 'GPS:GPSAltitude',
380
376
  1 => 'GPS:GPSAltitudeRef',
@@ -394,6 +390,23 @@ my %coordConv = (
394
390
  return ($val =~ s/^-// ? "$val m Below" : "$val m Above") . " Sea Level";
395
391
  },
396
392
  },
393
+ GPSDestLatitude => {
394
+ Require => {
395
+ 0 => 'GPS:GPSDestLatitude',
396
+ 1 => 'GPS:GPSDestLatitudeRef',
397
+ },
398
+ ValueConv => '$val[1] =~ /^S/i ? -$val[0] : $val[0]',
399
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
400
+ },
401
+ GPSDestLongitude => {
402
+ SubDoc => 1, # generate for all sub-documents
403
+ Require => {
404
+ 0 => 'GPS:GPSDestLongitude',
405
+ 1 => 'GPS:GPSDestLongitudeRef',
406
+ },
407
+ ValueConv => '$val[1] =~ /^W/i ? -$val[0] : $val[0]',
408
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
409
+ },
397
410
  );
398
411
 
399
412
  # add our composite tags
@@ -410,14 +423,14 @@ sub ConvertTimeStamp($)
410
423
  my $f = (($h || 0) * 60 + ($m || 0)) * 60 + ($s || 0);
411
424
  $h = int($f / 3600); $f -= $h * 3600;
412
425
  $m = int($f / 60); $f -= $m * 60;
413
- $s = int($f); $f -= $s;
414
- $f = int($f * 1000000000 + 0.5);
415
- if ($f) {
416
- ($f = sprintf(".%.9d", $f)) =~ s/0+$//;
426
+ my $ss = sprintf('%012.9f', $f);
427
+ if ($ss >= 60) {
428
+ $ss = '00';
429
+ ++$m >= 60 and $m -= 60, ++$h;
417
430
  } else {
418
- $f = ''
431
+ $ss =~ s/\.?0+$//; # trim trailing zeros + decimal
419
432
  }
420
- return sprintf("%.2d:%.2d:%.2d%s",$h,$m,$s,$f);
433
+ return sprintf("%.2d:%.2d:%s",$h,$m,$ss);
421
434
  }
422
435
 
423
436
  #------------------------------------------------------------------------------
@@ -442,8 +455,13 @@ sub PrintTimeStamp($)
442
455
  sub ToDMS($$;$$)
443
456
  {
444
457
  my ($et, $val, $doPrintConv, $ref) = @_;
445
- my ($fmt, @fmt, $num, $sign);
458
+ my ($fmt, @fmt, $num, $sign, $rtnVal);
446
459
 
460
+ unless (length $val) {
461
+ # don't convert an empty value
462
+ return $val if $doPrintConv and $doPrintConv eq 1; # avoid hiding existing tag when extracting
463
+ return undef; # avoid writing empty value
464
+ }
447
465
  if ($ref) {
448
466
  if ($val < 0) {
449
467
  $val = -$val;
@@ -469,7 +487,7 @@ sub ToDMS($$;$$)
469
487
  $fmt =~ s/%\+/%/g; # don't know sign, so don't print it
470
488
  }
471
489
  } else {
472
- $fmt = "%d,%.6f$ref"; # use XMP standard format
490
+ $fmt = "%d,%.8f$ref"; # use XMP format with 8 decimal minutes
473
491
  }
474
492
  # count (and capture) the format specifiers (max 3)
475
493
  while ($fmt =~ /(%(%|[^%]*?[diouxXDOUeEfFgGcs]))/g) {
@@ -498,7 +516,14 @@ sub ToDMS($$;$$)
498
516
  ($c[-2] += 1) >= 60 and $num > 2 and $c[-2] -= 60, $c[-3] += 1;
499
517
  }
500
518
  }
501
- return $doPrintConv ? sprintf($fmt, @c) : "@c$ref";
519
+ if ($doPrintConv) {
520
+ $rtnVal = sprintf($fmt, @c);
521
+ # trim trailing zeros in XMP
522
+ $rtnVal =~ s/(\d)0+$ref$/$1$ref/ if $doPrintConv eq '2';
523
+ } else {
524
+ $rtnVal = "@c$ref";
525
+ }
526
+ return $rtnVal;
502
527
  }
503
528
 
504
529
  #------------------------------------------------------------------------------
@@ -511,7 +536,8 @@ sub ToDegrees($;$)
511
536
  my ($val, $doSign) = @_;
512
537
  # extract decimal or floating point values out of any other garbage
513
538
  my ($d, $m, $s) = ($val =~ /((?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee][+-]\d+)?)/g);
514
- my $deg = ($d || 0) + (($m || 0) + ($s || 0)/60) / 60;
539
+ return '' unless defined $d;
540
+ my $deg = $d + (($m || 0) + ($s || 0)/60) / 60;
515
541
  # make negative if S or W coordinate
516
542
  $deg = -$deg if $doSign ? $val =~ /[^A-Z](S|W)$/i : $deg < 0;
517
543
  return $deg;
@@ -537,7 +563,7 @@ GPS (Global Positioning System) meta information in EXIF data.
537
563
 
538
564
  =head1 AUTHOR
539
565
 
540
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
566
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
541
567
 
542
568
  This library is free software; you can redistribute it and/or modify it
543
569
  under the same terms as Perl itself.
@@ -19,11 +19,12 @@ use strict;
19
19
  use vars qw($VERSION);
20
20
  use Image::ExifTool qw(:DataAccess :Utils);
21
21
 
22
- $VERSION = '1.11';
22
+ $VERSION = '1.12';
23
23
 
24
24
  # format codes for geoTiff directory entries
25
25
  my %geoTiffFormat = (
26
- 0 => 'int16u',
26
+ 0 => 'int16u', # (value is stored in offset, and count is 1)
27
+ 0x87af => 'int16u', # (value is stored after directory)
27
28
  0x87b0 => 'double',
28
29
  0x87b1 => 'string',
29
30
  );
@@ -2167,31 +2168,30 @@ sub ProcessGeoTiff($)
2167
2168
  my $offset = Get16u($dirData, $pt+6);
2168
2169
  my $format = $geoTiffFormat{$loc};
2169
2170
  my ($val, $dataPt);
2170
- if ($format eq 'double') { # in the double parms
2171
- if (not $doubleData or length($$doubleData) < 8*($offset+$count)) {
2172
- $et->Warn("Missing double data for $$tagInfo{Name}");
2173
- next;
2174
- }
2171
+ if (not $format) {
2172
+ $et->Warn("Unknown GeoTiff location ($loc) for $$tagInfo{Name}");
2173
+ next;
2174
+ } elsif ($format eq 'double') { # in the double parms
2175
2175
  $dataPt = $doubleData;
2176
- $offset *= 8;
2177
- $val = Image::ExifTool::ReadValue($dataPt, $offset, $format,
2178
- $count, length($$doubleData)-$offset);
2179
2176
  } elsif ($format eq 'string') { # in the ASCII parms
2180
- if (not $asciiData or length($$asciiData) < $offset+$count) {
2181
- $et->Warn("Missing string data for $$tagInfo{Name}");
2182
- next;
2183
- }
2184
2177
  $dataPt = $asciiData;
2185
- $val = substr($$dataPt, $offset, $count);
2186
- $val =~ s/(\0|\|)$//; # remove trailing terminator (NULL or '|')
2187
- } elsif ($format eq 'int16u') { # use the offset as the value
2178
+ } elsif ($format eq 'int16u') { # in the GeoTiffDirectory data
2188
2179
  $dataPt = $dirData;
2189
- $val = $offset;
2190
- $offset = $pt+6;
2191
- } else {
2192
- $et->Warn("Unknown GeoTiff location: $loc");
2180
+ unless ($loc) { # is value is stored in offset?
2181
+ $count = 1; # (implied by location of 0)
2182
+ $offset = ($pt + 6) / 2; # offset of the "offset" value
2183
+ }
2184
+ }
2185
+ my $size = Image::ExifTool::FormatSize($format);
2186
+ if (not $dataPt or length($$dataPt) < $size*($offset+$count)) {
2187
+ $et->Warn("Missing $format data for $$tagInfo{Name}");
2193
2188
  next;
2194
2189
  }
2190
+ $offset *= $size;
2191
+ $val = Image::ExifTool::ReadValue($dataPt, $offset, $format,
2192
+ $count, length($$dataPt)-$offset);
2193
+ # remove trailing terminator (NULL or '|') from string value
2194
+ $val =~ s/(\0|\|)$// if $format eq 'string';
2195
2195
  $verbose and $et->VerboseInfo($tag, $tagInfo,
2196
2196
  'Table' => $tagTable,
2197
2197
  'Index' => $i,
@@ -2200,7 +2200,7 @@ sub ProcessGeoTiff($)
2200
2200
  'Start' => $offset,
2201
2201
  'Format' => $format,
2202
2202
  'Count' => $count,
2203
- 'Size' => $count * Image::ExifTool::FormatSize($format),
2203
+ 'Size' => $count * $size,
2204
2204
  );
2205
2205
  $et->FoundTag($tagInfo, $val);
2206
2206
  }
@@ -2240,7 +2240,7 @@ coordinates.
2240
2240
 
2241
2241
  =head1 AUTHOR
2242
2242
 
2243
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
2243
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
2244
2244
 
2245
2245
  This library is free software; you can redistribute it and/or modify it
2246
2246
  under the same terms as Perl itself.
@@ -24,7 +24,7 @@ use strict;
24
24
  use vars qw($VERSION);
25
25
  use Image::ExifTool qw(:Public);
26
26
 
27
- $VERSION = '1.51';
27
+ $VERSION = '1.58';
28
28
 
29
29
  sub JITTER() { return 2 } # maximum time jitter
30
30
 
@@ -52,6 +52,7 @@ my %xmlTag = (
52
52
  vdop => 'vdop', # GPX
53
53
  pdop => 'pdop', # GPX
54
54
  sat => 'nsats', # GPX
55
+ atemp => 'atemp', # GPX (Garmin 550t)
55
56
  when => 'time', # KML
56
57
  coordinates => 'coords', # KML
57
58
  coord => 'coords', # KML, as written by Google Location History
@@ -77,10 +78,21 @@ my %fixInfoKeys = (
77
78
  track => [ 'track', 'speed' ],
78
79
  alt => [ 'alt' ],
79
80
  orient => [ 'dir', 'pitch', 'roll' ],
81
+ atemp => [ 'atemp' ],
80
82
  );
81
83
 
82
84
  my %isOrient = ( dir => 1, pitch => 1, roll => 1 ); # test for orientation key
83
85
 
86
+ # conversion factors for GPSSpeed
87
+ my %speedConv = (
88
+ 'K' => 1.852, # km/h per knot
89
+ 'M' => 1.150779448, # mph per knot
90
+ 'k' => 'K', # (allow lower case)
91
+ 'm' => 'M',
92
+ 'km/h' => 'K', # (allow other formats)
93
+ 'mph' => 'M',
94
+ );
95
+
84
96
  my $secPerDay = 24 * 3600; # a useful constant
85
97
 
86
98
  #------------------------------------------------------------------------------
@@ -147,7 +159,7 @@ sub LoadTrackLog($$;$)
147
159
  $raf = new File::RandomAccess(\*EXIFTOOL_TRKFILE);
148
160
  unless ($raf->Read($_, 256)) {
149
161
  close EXIFTOOL_TRKFILE;
150
- return "Empty track file '$val'";
162
+ return "Empty track file '${val}'";
151
163
  }
152
164
  # look for XML or GPX header (might as well allow UTF-8 BOM)
153
165
  if (/^(\xef\xbb\xbf)?<(\?xml|gpx)[\s>]/) {
@@ -157,17 +169,17 @@ sub LoadTrackLog($$;$)
157
169
  $/ = $1;
158
170
  } else {
159
171
  close EXIFTOOL_TRKFILE;
160
- return "Invalid track file '$val'";
172
+ return "Invalid track file '${val}'";
161
173
  }
162
174
  $raf->Seek(0,0);
163
- $from = "file '$val'";
175
+ $from = "file '${val}'";
164
176
  } elsif ($val eq 'DATETIMEONLY') {
165
177
  $$geotag{DateTimeOnly} = 1;
166
178
  $$geotag{IsDate} = 1;
167
179
  $et->VPrint(0, 'Geotagging date/time only');
168
180
  return $geotag;
169
181
  } else {
170
- return "Error opening GPS file '$val'";
182
+ return "Error opening GPS file '${val}'";
171
183
  }
172
184
  }
173
185
  unless ($from) {
@@ -195,7 +207,7 @@ sub LoadTrackLog($$;$)
195
207
  $format = 'XML';
196
208
  # check for NMEA sentence
197
209
  # (must ONLY start with ones that have timestamps! eg. not GSA or PTNTHPR!)
198
- } elsif (/^\$(GP(RMC|GGA|GLL|ZDA)|PMGNTRK),/) {
210
+ } elsif (/^.*\$([A-Z]{2}(RMC|GGA|GLL|ZDA)|PMGNTRK),/) {
199
211
  $format = 'NMEA';
200
212
  $nmeaStart = $2 || $1; # save type of first sentence
201
213
  } elsif (/^A(FLA|XSY|FIL)/) {
@@ -237,7 +249,15 @@ sub LoadTrackLog($$;$)
237
249
  my $tag = $xmlTag{lc $2};
238
250
  if ($tag) {
239
251
  $$fix{$tag} = $4;
240
- $$has{orient} = 1 if $isOrient{$tag};
252
+ if ($isOrient{$tag}) {
253
+ $$has{orient} = 1;
254
+ } elsif ($tag eq 'alt') {
255
+ # validate altitude
256
+ undef $$fix{alt} if defined $$fix{alt} and $$fix{alt} !~ /^[+-]?\d+\.?\d*/;
257
+ $$has{alt} = 1 if $$fix{alt}; # set "has altitude" flag if appropriate
258
+ } elsif ($tag eq 'atemp') {
259
+ $$has{atemp} = 1;
260
+ }
241
261
  }
242
262
  }
243
263
  # loop through XML elements
@@ -270,7 +290,15 @@ sub LoadTrackLog($$;$)
270
290
  @$fix{'lon','lat','alt'} = split ',', $1;
271
291
  } else {
272
292
  $$fix{$tag} = $1;
273
- $$has{orient} = 1 if $isOrient{$tag};
293
+ if ($isOrient{$tag}) {
294
+ $$has{orient} = 1;
295
+ } elsif ($tag eq 'alt') {
296
+ # validate altitude
297
+ undef $$fix{alt} if defined $$fix{alt} and $$fix{alt} !~ /^[+-]?\d+\.?\d*/;
298
+ $$has{alt} = 1 if $$fix{alt}; # set "has altitude" flag if appropriate
299
+ } elsif ($tag eq 'atemp') {
300
+ $$has{atemp} = 1;
301
+ }
274
302
  }
275
303
  }
276
304
  next;
@@ -287,11 +315,8 @@ sub LoadTrackLog($$;$)
287
315
  $e1 or $et->VPrint(0, "Timestamp format error in $from\n"), $e1 = 1;
288
316
  next;
289
317
  }
290
- # validate altitude
291
- undef $$fix{alt} if defined $$fix{alt} and $$fix{alt} !~ /^[+-]?\d+\.?\d*/;
292
318
  $isDate = 1;
293
319
  $canCut= 1 if defined $$fix{pdop} or defined $$fix{hdop} or defined $$fix{nsats};
294
- $$has{alt} = 1 if $$fix{alt}; # set "has altitude" flag if appropriate
295
320
  # generate extra fixes assuming an equally spaced track
296
321
  if ($$fix{begin}) {
297
322
  my $begin = GetTime($$fix{begin});
@@ -361,8 +386,10 @@ DoneFix: $isDate = 1;
361
386
  my (%fix, $secs, $date, $nmea);
362
387
  if ($format eq 'NMEA') {
363
388
  # ignore unrecognized NMEA sentences
364
- next unless /^\$(GP(RMC|GGA|GLL|GSA|ZDA)|PMGNTRK|PTNTHPR),/;
365
- $nmea = $2 || $1;
389
+ # (first 2 characters: GP=GPS, GL=GLONASS, GA=Gallileo, GN=combined, BD=Beidou)
390
+ next unless /^(.*)\$([A-Z]{2}(RMC|GGA|GLL|GSA|ZDA)|PMGNTRK|PTNTHPR),/;
391
+ $nmea = $3 || $2;
392
+ $_ = substr($_, length($1)) if length($1);
366
393
  }
367
394
  #
368
395
  # IGC (flarm) (ref 4)
@@ -390,7 +417,7 @@ DoneFix: $isDate = 1;
390
417
  # $GPRMC,092204.999,A,4250.5589,S,14718.5084,E,0.00,89.68,211200,,*25
391
418
  # $GPRMC,093657.007,,3652.835020,N,01053.104094,E,1.642,,290913,,,A*0F
392
419
  # $GPRMC,hhmmss.sss,A/V,ddmm.mmmm,N/S,ddmmm.mmmm,E/W,spd(knots),dir(deg),DDMMYY,,*cs
393
- /^\$GPRMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/ or next;
420
+ /^\$[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/ or next;
394
421
  next if $13 > 31 or $14 > 12 or $15 > 99; # validate day/month/year
395
422
  $fix{lat} = (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1);
396
423
  $fix{lon} = (($8 || 0) + $9/60) * ($10 eq 'E' ? 1 : -1);
@@ -406,7 +433,7 @@ DoneFix: $isDate = 1;
406
433
  # $GPGGA,092204.999,4250.5589,S,14718.5084,E,1,04,24.4,19.7,M,,,,0000*1F
407
434
  # $GPGGA,093657.000,3652.835020,N,01053.104094,E,,8,,166.924,M,40.9,M,,*77
408
435
  # $GPGGA,hhmmss.sss,ddmm.mmmm,N/S,dddmm.mmmm,E/W,0=invalid,sats,hdop,alt,M,...
409
- /^\$GPGGA,(\d{2})(\d{2})(\d+(\.\d*)?),(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),[1-6]?,(\d+)?,(\.\d+|\d+\.?\d*)?,(-?\d+\.?\d*)?,M?/ or next;
436
+ /^\$[A-Z]{2}GGA,(\d{2})(\d{2})(\d+(\.\d*)?),(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),[1-6]?,(\d+)?,(\.\d+|\d+\.?\d*)?,(-?\d+\.?\d*)?,M?/ or next;
410
437
  $fix{lat} = (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1);
411
438
  $fix{lon} = (($8 || 0) + $9/60) * ($10 eq 'E' ? 1 : -1);
412
439
  @fix{qw(nsats hdop alt)} = ($11,$12,$13);
@@ -418,7 +445,7 @@ DoneFix: $isDate = 1;
418
445
  } elsif ($nmea eq 'GLL') {
419
446
  # $GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D
420
447
  # $GPGLL,ddmm.mmmm,N/S,dddmm.mmmm,E/W,hhmmss.sss,A/V*cs
421
- /^\$GPGLL,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d{2})(\d{2})(\d+(\.\d*)?),A/ or next;
448
+ /^\$[A-Z]{2}GLL,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d{2})(\d{2})(\d+(\.\d*)?),A/ or next;
422
449
  $fix{lat} = (($1 || 0) + $2/60) * ($3 eq 'N' ? 1 : -1);
423
450
  $fix{lon} = (($4 || 0) + $5/60) * ($6 eq 'E' ? 1 : -1);
424
451
  $secs = (($7 * 60) + $8) * 60 + $9;
@@ -427,7 +454,7 @@ DoneFix: $isDate = 1;
427
454
  #
428
455
  } elsif ($nmea eq 'GSA') {
429
456
  # $GPGSA,A,3,04,05,,,,,,,,,,,pdop,hdop,vdop*HH
430
- /^\$GPGSA,[AM],([23]),((?:\d*,){11}(?:\d*)),(\d+\.?\d*|\.\d+)?,(\d+\.?\d*|\.\d+)?,(\d+\.?\d*|\.\d+)?\*/ or next;
457
+ /^\$[A-Z]{2}GSA,[AM],([23]),((?:\d*,){11}(?:\d*)),(\d+\.?\d*|\.\d+)?,(\d+\.?\d*|\.\d+)?,(\d+\.?\d*|\.\d+)?\*/ or next;
431
458
  @fix{qw(fixtype sats pdop hdop vdop)} = ($1.'d',$2,$3,$4,$5);
432
459
  # count the number of acquired satellites
433
460
  my @a = ($fix{sats} =~ /\d+/g);
@@ -439,7 +466,7 @@ DoneFix: $isDate = 1;
439
466
  } elsif ($nmea eq 'ZDA') {
440
467
  # $GPZDA,093655.000,29,09,2013,,*58
441
468
  # $GPZDA,hhmmss.ss,DD,MM,YYYY,tzh,tzm (hhmmss in UTC)
442
- /^\$GPZDA,(\d{2})(\d{2})(\d{2}(\.\d*)?),(\d+),(\d+),(\d+)/ or next;
469
+ /^\$[A-Z]{2}ZDA,(\d{2})(\d{2})(\d{2}(\.\d*)?),(\d+),(\d+),(\d+)/ or next;
443
470
  $secs = (($1 * 60) + $2) * 60 + $3;
444
471
  $date = Time::Local::timegm(0,0,0,$5,$6-1,$7-1900);
445
472
  #
@@ -469,7 +496,7 @@ DoneFix: $isDate = 1;
469
496
  # status: L=low alarm, M=low warning, N=normal, O=high warning
470
497
  # P=high alarm, C=tuning analog circuit
471
498
  # (ignore this information on any alarm status)
472
- /^\$PTNTHPR,(-?[\d.]+),[MNO],(-?[\d.]+),[MNO],(-?[\d.]+),[MNO],/ or next;
499
+ /^\$PTNTHPR,(-?[\d.]+),[MNO],(-?[\d.]+),[MNO],(-?[\d.]+),[MNO]/ or next;
473
500
  @fix{qw(dir pitch roll)} = ($1,$2,$3);
474
501
 
475
502
  } else {
@@ -675,11 +702,7 @@ sub ApplySyncCorr($$)
675
702
  my ($i0, $i1) = (0, scalar(@$syncTimes) - 1);
676
703
  while ($i1 > $i0 + 1) {
677
704
  my $pt = int(($i0 + $i1) / 2);
678
- if ($time < $$syncTimes[$pt]) {
679
- $i1 = $pt;
680
- } else {
681
- $i0 = $pt;
682
- }
705
+ ($time < $$syncTimes[$pt] ? $i1 : $i0) = $pt;
683
706
  }
684
707
  my ($t0, $t1) = ($$syncTimes[$i0], $$syncTimes[$i1]);
685
708
  # interpolate/extrapolate to account for linear camera clock drift
@@ -829,7 +852,8 @@ sub SetGeoValues($$;$)
829
852
  $time += $fs if $fs and $fs ne '.';
830
853
 
831
854
  # bring UTC time back to Jan. 1 if no date is given
832
- $time %= $secPerDay if $noDate;
855
+ # (don't use '%' operator here because it drops fractional seconds)
856
+ $time -= int($time / $secPerDay) * $secPerDay if $noDate;
833
857
 
834
858
  # apply time synchronization if available
835
859
  my $sync = ApplySyncCorr($et, $time);
@@ -877,11 +901,7 @@ sub SetGeoValues($$;$)
877
901
  my ($i0, $i1) = (0, scalar(@$times) - 1);
878
902
  while ($i1 > $i0 + 1) {
879
903
  my $pt = int(($i0 + $i1) / 2);
880
- if ($time < $$times[$pt]) {
881
- $i1 = $pt;
882
- } else {
883
- $i0 = $pt;
884
- }
904
+ ($time < $$times[$pt] ? $i1 : $i0) = $pt;
885
905
  }
886
906
  # do linear interpolation for position
887
907
  my $t0 = $$times[$i0];
@@ -921,7 +941,7 @@ sub SetGeoValues($$;$)
921
941
  # loop through available fix information categories
922
942
  # (pos, track, alt, orient)
923
943
  my ($category, $key);
924
- Category: foreach $category (qw{pos track alt orient}) {
944
+ Category: foreach $category (qw{pos track alt orient atemp}) {
925
945
  next unless $$has{$category};
926
946
  my ($f, $p0b, $p1b, $f0b);
927
947
  # loop through specific fix information keys
@@ -1021,8 +1041,18 @@ Category: foreach $category (qw{pos track alt orient}) {
1021
1041
  }
1022
1042
  @r = $et->SetNewValue(GPSTrack => $$tFix{track}, %opts);
1023
1043
  @r = $et->SetNewValue(GPSTrackRef => (defined $$tFix{track} ? 'T' : undef), %opts);
1024
- @r = $et->SetNewValue(GPSSpeed => $$tFix{speed}, %opts);
1025
- @r = $et->SetNewValue(GPSSpeedRef => (defined $$tFix{speed} ? 'N' : undef), %opts);
1044
+ my ($spd, $ref);
1045
+ if (defined($spd = $$tFix{speed})) {
1046
+ $ref = $$et{OPTIONS}{GeoSpeedRef};
1047
+ if ($ref and defined $speedConv{$ref}) {
1048
+ $ref = $speedConv{$ref} if $speedConv{$speedConv{$ref}};
1049
+ $spd *= $speedConv{$ref};
1050
+ } else {
1051
+ $ref = 'N'; # knots by default
1052
+ }
1053
+ }
1054
+ @r = $et->SetNewValue(GPSSpeed => $spd, %opts);
1055
+ @r = $et->SetNewValue(GPSSpeedRef => $ref, %opts);
1026
1056
  }
1027
1057
  if ($$has{orient}) {
1028
1058
  my $tFix = $fix;
@@ -1036,6 +1066,15 @@ Category: foreach $category (qw{pos track alt orient}) {
1036
1066
  @r = $et->SetNewValue(GPSPitch => $$tFix{pitch}, %opts);
1037
1067
  @r = $et->SetNewValue(GPSRoll => $$tFix{roll}, %opts);
1038
1068
  }
1069
+ if ($$has{atemp}) {
1070
+ my $tFix = $fix;
1071
+ if (not defined $$fix{atemp} and defined $iExt) {
1072
+ # (not all fixes have atemp, so try interpolating specifically for this)
1073
+ my $p = FindFix($et,'atemp',$times,$points,$iExt,$iDir,$geoMaxExtSecs);
1074
+ $tFix = $p if $p;
1075
+ }
1076
+ @r = $et->SetNewValue(AmbientTemperature => $$tFix{atemp}, %opts);
1077
+ }
1039
1078
  unless ($xmp) {
1040
1079
  my ($latRef, $lonRef);
1041
1080
  $latRef = ($$fix{lat} > 0 ? 'N' : 'S') if defined $$fix{lat};
@@ -1059,8 +1098,8 @@ Category: foreach $category (qw{pos track alt orient}) {
1059
1098
  # reset any GPS values we might have already set
1060
1099
  foreach (qw(GPSLatitude GPSLatitudeRef GPSLongitude GPSLongitudeRef
1061
1100
  GPSAltitude GPSAltitudeRef GPSDateStamp GPSTimeStamp GPSDateTime
1062
- GPSTrack GPSTrackRef GPSSpeed GPSSpeedRef
1063
- GPSImgDirection GPSImgDirectionRef GPSPitch GPSRoll))
1101
+ GPSTrack GPSTrackRef GPSSpeed GPSSpeedRef GPSImgDirection
1102
+ GPSImgDirectionRef GPSPitch GPSRoll AmbientTemperature))
1064
1103
  {
1065
1104
  my @r = $et->SetNewValue($_, undef, %opts);
1066
1105
  }
@@ -1087,11 +1126,7 @@ sub ConvertGeosync($$)
1087
1126
 
1088
1127
  if ($val =~ /(.*?)\@(.*)/) {
1089
1128
  $gpsTime = $1;
1090
- if (-f $2) {
1091
- $syncFile = $2;
1092
- } else {
1093
- $imgTime = $2;
1094
- }
1129
+ (-f $2 ? $syncFile : $imgTime) = $2;
1095
1130
  # (take care because "-f '1:30'" crashes ActivePerl 5.10)
1096
1131
  } elsif ($val !~ /^\d/ or $val !~ /:/) {
1097
1132
  $syncFile = $val if -f $val;
@@ -1114,11 +1149,11 @@ sub ConvertGeosync($$)
1114
1149
  foreach $tag (@timeTags) {
1115
1150
  if ($$info{$tag}) {
1116
1151
  $imgTime = $$info{$tag};
1117
- $et->VPrint(2, "Geosyncing with $tag from '$syncFile'\n");
1152
+ $et->VPrint(2, "Geosyncing with $tag from '${syncFile}'\n");
1118
1153
  last;
1119
1154
  }
1120
1155
  }
1121
- $imgTime or warn("No image timestamp in '$syncFile'\n"), return undef;
1156
+ $imgTime or warn("No image timestamp in '${syncFile}'\n"), return undef;
1122
1157
  }
1123
1158
  # add date to date-less timestamps
1124
1159
  my ($imgDateTime, $gpsDateTime, $noDate);
@@ -1143,9 +1178,9 @@ sub ConvertGeosync($$)
1143
1178
  }
1144
1179
  # calculate Unix seconds since the epoch
1145
1180
  my $imgSecs = Image::ExifTool::GetUnixTime($imgDateTime, 1);
1146
- defined $imgSecs or warn("Invalid image time '$imgTime'\n"), return undef;
1181
+ defined $imgSecs or warn("Invalid image time '${imgTime}'\n"), return undef;
1147
1182
  my $gpsSecs = Image::ExifTool::GetUnixTime($gpsDateTime, 1);
1148
- defined $gpsSecs or warn("Invalid GPS time '$gpsTime'\n"), return undef;
1183
+ defined $gpsSecs or warn("Invalid GPS time '${gpsTime}'\n"), return undef;
1149
1184
  # add fractional seconds
1150
1185
  $gpsSecs += $1 if $gpsTime =~ /(\.\d+)/;
1151
1186
  $imgSecs += $1 if $imgTime =~ /(\.\d+)/;
@@ -1262,7 +1297,7 @@ user-defined tags, GPSPitch and GPSRoll, must be active.
1262
1297
 
1263
1298
  =head1 AUTHOR
1264
1299
 
1265
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
1300
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
1266
1301
 
1267
1302
  This library is free software; you can redistribute it and/or modify it
1268
1303
  under the same terms as Perl itself.