exiftool-vendored.pl 12.50.0 → 12.55.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.
Files changed (204) hide show
  1. package/bin/Changes +81 -3
  2. package/bin/MANIFEST +2 -0
  3. package/bin/META.json +1 -1
  4. package/bin/META.yml +1 -1
  5. package/bin/README +3 -3
  6. package/bin/exiftool +15 -12
  7. package/bin/fmt_files/kml_track.fmt +3 -3
  8. package/bin/lib/File/RandomAccess.pm +1 -1
  9. package/bin/lib/File/RandomAccess.pod +2 -2
  10. package/bin/lib/Image/ExifTool/AES.pm +1 -1
  11. package/bin/lib/Image/ExifTool/AFCP.pm +1 -1
  12. package/bin/lib/Image/ExifTool/AIFF.pm +1 -1
  13. package/bin/lib/Image/ExifTool/APE.pm +1 -1
  14. package/bin/lib/Image/ExifTool/APP12.pm +1 -1
  15. package/bin/lib/Image/ExifTool/ASF.pm +1 -1
  16. package/bin/lib/Image/ExifTool/Apple.pm +197 -27
  17. package/bin/lib/Image/ExifTool/Audible.pm +1 -1
  18. package/bin/lib/Image/ExifTool/BMP.pm +1 -1
  19. package/bin/lib/Image/ExifTool/BPG.pm +1 -1
  20. package/bin/lib/Image/ExifTool/BZZ.pm +1 -1
  21. package/bin/lib/Image/ExifTool/BigTIFF.pm +1 -1
  22. package/bin/lib/Image/ExifTool/BuildTagLookup.pm +4 -4
  23. package/bin/lib/Image/ExifTool/CBOR.pm +1 -1
  24. package/bin/lib/Image/ExifTool/Canon.pm +14 -2
  25. package/bin/lib/Image/ExifTool/CanonCustom.pm +1 -1
  26. package/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
  27. package/bin/lib/Image/ExifTool/CanonVRD.pm +9 -9
  28. package/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
  29. package/bin/lib/Image/ExifTool/Casio.pm +4 -4
  30. package/bin/lib/Image/ExifTool/Charset.pm +1 -1
  31. package/bin/lib/Image/ExifTool/DICOM.pm +1 -1
  32. package/bin/lib/Image/ExifTool/DJI.pm +1 -1
  33. package/bin/lib/Image/ExifTool/DNG.pm +1 -1
  34. package/bin/lib/Image/ExifTool/DPX.pm +1 -1
  35. package/bin/lib/Image/ExifTool/DV.pm +1 -1
  36. package/bin/lib/Image/ExifTool/DarwinCore.pm +1 -1
  37. package/bin/lib/Image/ExifTool/DjVu.pm +1 -1
  38. package/bin/lib/Image/ExifTool/EXE.pm +1 -1
  39. package/bin/lib/Image/ExifTool/Exif.pm +5 -16
  40. package/bin/lib/Image/ExifTool/FITS.pm +1 -1
  41. package/bin/lib/Image/ExifTool/FLAC.pm +1 -1
  42. package/bin/lib/Image/ExifTool/FLIF.pm +1 -1
  43. package/bin/lib/Image/ExifTool/FLIR.pm +7 -6
  44. package/bin/lib/Image/ExifTool/Fixup.pm +1 -1
  45. package/bin/lib/Image/ExifTool/Flash.pm +1 -1
  46. package/bin/lib/Image/ExifTool/FlashPix.pm +1 -1
  47. package/bin/lib/Image/ExifTool/Font.pm +1 -1
  48. package/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
  49. package/bin/lib/Image/ExifTool/FujiFilm.pm +21 -13
  50. package/bin/lib/Image/ExifTool/GE.pm +1 -1
  51. package/bin/lib/Image/ExifTool/GIF.pm +1 -1
  52. package/bin/lib/Image/ExifTool/GIMP.pm +1 -1
  53. package/bin/lib/Image/ExifTool/GPS.pm +12 -6
  54. package/bin/lib/Image/ExifTool/GeoTiff.pm +1 -1
  55. package/bin/lib/Image/ExifTool/Geotag.pm +25 -8
  56. package/bin/lib/Image/ExifTool/GoPro.pm +1 -1
  57. package/bin/lib/Image/ExifTool/H264.pm +1 -1
  58. package/bin/lib/Image/ExifTool/HP.pm +1 -1
  59. package/bin/lib/Image/ExifTool/HTML.pm +1 -1
  60. package/bin/lib/Image/ExifTool/HtmlDump.pm +1 -1
  61. package/bin/lib/Image/ExifTool/ICC_Profile.pm +1 -1
  62. package/bin/lib/Image/ExifTool/ICO.pm +1 -1
  63. package/bin/lib/Image/ExifTool/ID3.pm +1 -1
  64. package/bin/lib/Image/ExifTool/IPTC.pm +1 -1
  65. package/bin/lib/Image/ExifTool/ISO.pm +1 -1
  66. package/bin/lib/Image/ExifTool/ITC.pm +1 -1
  67. package/bin/lib/Image/ExifTool/Import.pm +1 -1
  68. package/bin/lib/Image/ExifTool/InDesign.pm +1 -1
  69. package/bin/lib/Image/ExifTool/JPEG.pm +2 -1
  70. package/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
  71. package/bin/lib/Image/ExifTool/JSON.pm +1 -1
  72. package/bin/lib/Image/ExifTool/JVC.pm +1 -1
  73. package/bin/lib/Image/ExifTool/Jpeg2000.pm +35 -8
  74. package/bin/lib/Image/ExifTool/Kodak.pm +1 -1
  75. package/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
  76. package/bin/lib/Image/ExifTool/LIF.pm +1 -1
  77. package/bin/lib/Image/ExifTool/LNK.pm +1 -1
  78. package/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
  79. package/bin/lib/Image/ExifTool/Lang/de.pm +2 -2
  80. package/bin/lib/Image/ExifTool/Lang/en_ca.pm +1 -1
  81. package/bin/lib/Image/ExifTool/Lang/en_gb.pm +1 -1
  82. package/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
  83. package/bin/lib/Image/ExifTool/Lang/fi.pm +1 -1
  84. package/bin/lib/Image/ExifTool/Lang/fr.pm +6016 -760
  85. package/bin/lib/Image/ExifTool/Lang/it.pm +1 -1
  86. package/bin/lib/Image/ExifTool/Lang/ja.pm +1 -1
  87. package/bin/lib/Image/ExifTool/Lang/ko.pm +1 -1
  88. package/bin/lib/Image/ExifTool/Lang/nl.pm +1 -1
  89. package/bin/lib/Image/ExifTool/Lang/pl.pm +1 -1
  90. package/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
  91. package/bin/lib/Image/ExifTool/Lang/sk.pm +1806 -0
  92. package/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
  93. package/bin/lib/Image/ExifTool/Lang/tr.pm +1 -1
  94. package/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
  95. package/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
  96. package/bin/lib/Image/ExifTool/Leaf.pm +1 -1
  97. package/bin/lib/Image/ExifTool/Lytro.pm +1 -1
  98. package/bin/lib/Image/ExifTool/M2TS.pm +1 -1
  99. package/bin/lib/Image/ExifTool/MIE.pm +1 -1
  100. package/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
  101. package/bin/lib/Image/ExifTool/MIFF.pm +1 -1
  102. package/bin/lib/Image/ExifTool/MISB.pm +1 -1
  103. package/bin/lib/Image/ExifTool/MNG.pm +1 -1
  104. package/bin/lib/Image/ExifTool/MOI.pm +1 -1
  105. package/bin/lib/Image/ExifTool/MPC.pm +1 -1
  106. package/bin/lib/Image/ExifTool/MPEG.pm +1 -1
  107. package/bin/lib/Image/ExifTool/MPF.pm +1 -1
  108. package/bin/lib/Image/ExifTool/MRC.pm +1 -1
  109. package/bin/lib/Image/ExifTool/MWG.pm +1 -1
  110. package/bin/lib/Image/ExifTool/MXF.pm +1 -1
  111. package/bin/lib/Image/ExifTool/MacOS.pm +1 -1
  112. package/bin/lib/Image/ExifTool/MakerNotes.pm +1 -1
  113. package/bin/lib/Image/ExifTool/Matroska.pm +262 -46
  114. package/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
  115. package/bin/lib/Image/ExifTool/Minolta.pm +1 -1
  116. package/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
  117. package/bin/lib/Image/ExifTool/Motorola.pm +1 -1
  118. package/bin/lib/Image/ExifTool/Nikon.pm +687 -280
  119. package/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
  120. package/bin/lib/Image/ExifTool/NikonCustom.pm +140 -107
  121. package/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
  122. package/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
  123. package/bin/lib/Image/ExifTool/OOXML.pm +1 -1
  124. package/bin/lib/Image/ExifTool/Ogg.pm +1 -1
  125. package/bin/lib/Image/ExifTool/Olympus.pm +4 -3
  126. package/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
  127. package/bin/lib/Image/ExifTool/Opus.pm +1 -1
  128. package/bin/lib/Image/ExifTool/Other.pm +1 -1
  129. package/bin/lib/Image/ExifTool/PCX.pm +1 -1
  130. package/bin/lib/Image/ExifTool/PDF.pm +1 -1
  131. package/bin/lib/Image/ExifTool/PGF.pm +1 -1
  132. package/bin/lib/Image/ExifTool/PICT.pm +1 -1
  133. package/bin/lib/Image/ExifTool/PLIST.pm +12 -7
  134. package/bin/lib/Image/ExifTool/PLUS.pm +1 -1
  135. package/bin/lib/Image/ExifTool/PNG.pm +9 -2
  136. package/bin/lib/Image/ExifTool/PPM.pm +1 -1
  137. package/bin/lib/Image/ExifTool/PSP.pm +1 -1
  138. package/bin/lib/Image/ExifTool/Palm.pm +1 -1
  139. package/bin/lib/Image/ExifTool/Panasonic.pm +1 -1
  140. package/bin/lib/Image/ExifTool/PanasonicRaw.pm +1 -1
  141. package/bin/lib/Image/ExifTool/Parrot.pm +1 -1
  142. package/bin/lib/Image/ExifTool/Pentax.pm +1 -1
  143. package/bin/lib/Image/ExifTool/PhaseOne.pm +1 -1
  144. package/bin/lib/Image/ExifTool/PhotoCD.pm +1 -1
  145. package/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
  146. package/bin/lib/Image/ExifTool/Photoshop.pm +1 -1
  147. package/bin/lib/Image/ExifTool/PostScript.pm +1 -1
  148. package/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
  149. package/bin/lib/Image/ExifTool/Qualcomm.pm +1 -1
  150. package/bin/lib/Image/ExifTool/QuickTime.pm +26 -7
  151. package/bin/lib/Image/ExifTool/QuickTimeStream.pl +166 -39
  152. package/bin/lib/Image/ExifTool/README +5 -1
  153. package/bin/lib/Image/ExifTool/RIFF.pm +1 -1
  154. package/bin/lib/Image/ExifTool/RSRC.pm +1 -1
  155. package/bin/lib/Image/ExifTool/RTF.pm +1 -1
  156. package/bin/lib/Image/ExifTool/Radiance.pm +1 -1
  157. package/bin/lib/Image/ExifTool/Rawzor.pm +1 -1
  158. package/bin/lib/Image/ExifTool/Real.pm +1 -1
  159. package/bin/lib/Image/ExifTool/Reconyx.pm +1 -1
  160. package/bin/lib/Image/ExifTool/Red.pm +1 -1
  161. package/bin/lib/Image/ExifTool/Ricoh.pm +1 -1
  162. package/bin/lib/Image/ExifTool/Samsung.pm +3 -1
  163. package/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
  164. package/bin/lib/Image/ExifTool/Scalado.pm +1 -1
  165. package/bin/lib/Image/ExifTool/Shift.pl +1 -1
  166. package/bin/lib/Image/ExifTool/Shortcuts.pm +1 -1
  167. package/bin/lib/Image/ExifTool/Sigma.pm +1 -1
  168. package/bin/lib/Image/ExifTool/SigmaRaw.pm +1 -1
  169. package/bin/lib/Image/ExifTool/Sony.pm +7 -7
  170. package/bin/lib/Image/ExifTool/SonyIDC.pm +1 -1
  171. package/bin/lib/Image/ExifTool/Stim.pm +1 -1
  172. package/bin/lib/Image/ExifTool/TagInfoXML.pm +13 -8
  173. package/bin/lib/Image/ExifTool/TagLookup.pm +4608 -4512
  174. package/bin/lib/Image/ExifTool/TagNames.pod +323 -43
  175. package/bin/lib/Image/ExifTool/Text.pm +1 -1
  176. package/bin/lib/Image/ExifTool/Theora.pm +1 -1
  177. package/bin/lib/Image/ExifTool/Torrent.pm +1 -1
  178. package/bin/lib/Image/ExifTool/Unknown.pm +1 -1
  179. package/bin/lib/Image/ExifTool/VCard.pm +1 -1
  180. package/bin/lib/Image/ExifTool/Validate.pm +1 -1
  181. package/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
  182. package/bin/lib/Image/ExifTool/WTV.pm +1 -1
  183. package/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
  184. package/bin/lib/Image/ExifTool/WriteExif.pl +14 -1
  185. package/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
  186. package/bin/lib/Image/ExifTool/WritePDF.pl +5 -1
  187. package/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
  188. package/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
  189. package/bin/lib/Image/ExifTool/WritePostScript.pl +1 -1
  190. package/bin/lib/Image/ExifTool/WriteQuickTime.pl +30 -14
  191. package/bin/lib/Image/ExifTool/WriteRIFF.pl +1 -1
  192. package/bin/lib/Image/ExifTool/WriteXMP.pl +16 -2
  193. package/bin/lib/Image/ExifTool/Writer.pl +35 -15
  194. package/bin/lib/Image/ExifTool/XMP.pm +23 -3
  195. package/bin/lib/Image/ExifTool/XMP2.pl +20 -1
  196. package/bin/lib/Image/ExifTool/XMPStruct.pl +1 -1
  197. package/bin/lib/Image/ExifTool/ZIP.pm +20 -8
  198. package/bin/lib/Image/ExifTool/ZISRAW.pm +1 -1
  199. package/bin/lib/Image/ExifTool/iWork.pm +1 -1
  200. package/bin/lib/Image/ExifTool.pm +38 -16
  201. package/bin/lib/Image/ExifTool.pod +39 -38
  202. package/bin/perl-Image-ExifTool.spec +1 -1
  203. package/bin/pp_build_exe.args +6 -5
  204. package/package.json +4 -4
@@ -26,6 +26,7 @@ sub ProcessFreeGPS($$$);
26
26
  sub ProcessFreeGPS2($$$);
27
27
  sub Process360Fly($$$);
28
28
  sub ProcessFMAS($$$);
29
+ sub ProcessCAMM($$$);
29
30
 
30
31
  my $debug; # set to 1 for extra debugging messages
31
32
 
@@ -101,7 +102,7 @@ my %insvLimit = (
101
102
  The tags below are extracted from timed metadata in QuickTime and other
102
103
  formats of video files when the ExtractEmbedded option is used. Although
103
104
  most of these tags are combined into the single table below, ExifTool
104
- currently reads 62 different formats of timed GPS metadata from video files.
105
+ currently reads 66 different formats of timed GPS metadata from video files.
105
106
  },
106
107
  VARS => { NO_ID => 1 },
107
108
  GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
@@ -236,7 +237,7 @@ my %insvLimit = (
236
237
  camm => [{
237
238
  Name => 'camm0',
238
239
  # (according to the spec. the first 2 bytes are reserved and should be zero,
239
- # but I have a sample where these bytes are non-zero, so allow anything here)
240
+ # but I have samples where these bytes are non-zero, so allow anything here)
240
241
  Condition => '$$valPt =~ /^..\0\0/s',
241
242
  SubDirectory => {
242
243
  TagTable => 'Image::ExifTool::QuickTime::camm0',
@@ -318,7 +319,7 @@ my %insvLimit = (
318
319
 
319
320
  # tags found in 'camm' type 0 timed metadata (ref 4)
320
321
  %Image::ExifTool::QuickTime::camm0 = (
321
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
322
+ PROCESS_PROC => \&ProcessCAMM,
322
323
  GROUPS => { 2 => 'Location' },
323
324
  FIRST_ENTRY => 0,
324
325
  NOTES => q{
@@ -336,7 +337,7 @@ my %insvLimit = (
336
337
 
337
338
  # tags found in 'camm' type 1 timed metadata (ref 4)
338
339
  %Image::ExifTool::QuickTime::camm1 = (
339
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
340
+ PROCESS_PROC => \&ProcessCAMM,
340
341
  GROUPS => { 2 => 'Camera' },
341
342
  FIRST_ENTRY => 0,
342
343
  4 => {
@@ -355,7 +356,7 @@ my %insvLimit = (
355
356
 
356
357
  # tags found in 'camm' type 2 timed metadata (ref PH, Insta360Pro)
357
358
  %Image::ExifTool::QuickTime::camm2 = (
358
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
359
+ PROCESS_PROC => \&ProcessCAMM,
359
360
  GROUPS => { 2 => 'Location' },
360
361
  FIRST_ENTRY => 0,
361
362
  4 => {
@@ -367,7 +368,7 @@ my %insvLimit = (
367
368
 
368
369
  # tags found in 'camm' type 3 timed metadata (ref PH, Insta360Pro)
369
370
  %Image::ExifTool::QuickTime::camm3 = (
370
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
371
+ PROCESS_PROC => \&ProcessCAMM,
371
372
  GROUPS => { 2 => 'Location' },
372
373
  FIRST_ENTRY => 0,
373
374
  4 => {
@@ -379,7 +380,7 @@ my %insvLimit = (
379
380
 
380
381
  # tags found in 'camm' type 4 timed metadata (ref 4)
381
382
  %Image::ExifTool::QuickTime::camm4 = (
382
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
383
+ PROCESS_PROC => \&ProcessCAMM,
383
384
  GROUPS => { 2 => 'Location' },
384
385
  FIRST_ENTRY => 0,
385
386
  4 => {
@@ -391,7 +392,7 @@ my %insvLimit = (
391
392
 
392
393
  # tags found in 'camm' type 5 timed metadata (ref 4)
393
394
  %Image::ExifTool::QuickTime::camm5 = (
394
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
395
+ PROCESS_PROC => \&ProcessCAMM,
395
396
  GROUPS => { 2 => 'Location' },
396
397
  FIRST_ENTRY => 0,
397
398
  4 => {
@@ -416,7 +417,7 @@ my %insvLimit = (
416
417
 
417
418
  # tags found in 'camm' type 6 timed metadata (ref PH/4, Insta360)
418
419
  %Image::ExifTool::QuickTime::camm6 = (
419
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
420
+ PROCESS_PROC => \&ProcessCAMM,
420
421
  GROUPS => { 2 => 'Location' },
421
422
  FIRST_ENTRY => 0,
422
423
  0x04 => {
@@ -482,7 +483,7 @@ my %insvLimit = (
482
483
 
483
484
  # tags found in 'camm' type 7 timed metadata (ref 4)
484
485
  %Image::ExifTool::QuickTime::camm7 = (
485
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
486
+ PROCESS_PROC => \&ProcessCAMM,
486
487
  GROUPS => { 2 => 'Location' },
487
488
  FIRST_ENTRY => 0,
488
489
  4 => {
@@ -879,9 +880,10 @@ sub HandleTextTags($$$)
879
880
  #------------------------------------------------------------------------------
880
881
  # Process subtitle 'text'
881
882
  # Inputs: 0) ExifTool ref, 1) data ref or dirInfo ref, 2) tag table ref
882
- sub Process_text($$$)
883
+ # 3) flag set if text was already stored
884
+ sub Process_text($$$;$)
883
885
  {
884
- my ($et, $dataPt, $tagTbl) = @_;
886
+ my ($et, $dataPt, $tagTbl, $handled) = @_;
885
887
  my %tags;
886
888
 
887
889
  return if $$et{NoMoreTextDecoding};
@@ -937,6 +939,16 @@ sub Process_text($$$)
937
939
  $tags{GPSSatellites} = $10 if defined $10;
938
940
  $tags{GPSDOP} = $11 if defined $11;
939
941
  $tags{GPSAltitude} = $12 if defined $12;
942
+ # ($G and $GS are ref https://exiftool.org/forum/index.php?topic=13115.msg71743#msg71743)
943
+ } elsif ($tag eq 'G' and $dat =~ /:(\d{4})-(\d{2})-(\d{2}) (\d{2}:\d{2}:\d{2})-([NS])(\d+\.\d+)-([EW])(\d+\.\d+)-S(\d+)/) {
944
+ $tags{GPSDateTime} = "$1:$2:$3 $4";
945
+ $tags{GPSLatitude} = $6 * ($5 eq 'S' ? -1 : 1);
946
+ $tags{GPSLongitude} = $8 * ($7 eq 'W' ? -1 : 1);
947
+ $tags{GPSSpeed} = $9;
948
+ } elsif ($tag eq 'GS' and $dat =~ /:([-+]?\d+),([-+]?\d+),([-+]?\d+)/) {
949
+ # scale and re-arrange to match gsensor output from Win app (forum11665)
950
+ my @acc = ( ($2+2432)/1000, ($3 + 361)/1000, ($1-3708)/1000 );
951
+ $tags{Accelerometer} = "@acc";
940
952
  } elsif ($tag eq 'BEGINGSENSOR' and $dat =~ /^:([-+]\d+\.\d+):([-+]\d+\.\d+):([-+]\d+\.\d+)/) {
941
953
  $tags{Accelerometer} = "$1 $2 $3";
942
954
  } elsif ($tag eq 'TIME' and $dat =~ /^:(\d+)/) {
@@ -945,7 +957,7 @@ sub Process_text($$$)
945
957
  $tags{Text} = $dat if length $dat;
946
958
  $tags{done} = 1;
947
959
  } elsif ($tag ne 'END') {
948
- $tags{Text} = "\$$tag$dat";
960
+ $tags{Text} = "\$$tag$dat" unless $handled;
949
961
  }
950
962
  }
951
963
  %tags and HandleTextTags($et, $tagTbl, \%tags), return;
@@ -1233,6 +1245,7 @@ Sample: for ($i=0; ; ) {
1233
1245
  ($type eq 'sbtl' and $metaFormat eq 'tx3g' and $buff =~ /^..PNDM/s))
1234
1246
  {
1235
1247
 
1248
+ my $handled;
1236
1249
  FoundSomething($et, $tagTbl, $time[$i], $dur[$i]);
1237
1250
  unless ($buff =~ /^\$BEGIN/) {
1238
1251
  # remove ending "encd" box if it exists
@@ -1272,9 +1285,10 @@ Sample: for ($i=0; ; ) {
1272
1285
  }
1273
1286
  unless (defined $val) {
1274
1287
  $et->HandleTag($tagTbl, Text => $buff); # just store any other text
1288
+ $handled = 1;
1275
1289
  }
1276
1290
  }
1277
- Process_text($et, \$buff, $tagTbl);
1291
+ Process_text($et, \$buff, $tagTbl, $handled);
1278
1292
 
1279
1293
  } elsif ($processByMetaFormat{$type}) {
1280
1294
 
@@ -1370,6 +1384,7 @@ sub ProcessFreeGPS($$$)
1370
1384
 
1371
1385
  if (substr($$dataPt,18,8) eq "\xaa\xaa\xf2\xe1\xf0\xee\x54\x54") {
1372
1386
 
1387
+ $debug and $et->FoundTag(GPSType => '1A');
1373
1388
  # (this is very similar to the encrypted text format)
1374
1389
  # decode encrypted ASCII-based GPS (DashCam Azdome GS63H, ref 5)
1375
1390
  # header looks like this in my sample:
@@ -1424,10 +1439,10 @@ sub ProcessFreeGPS($$$)
1424
1439
  } elsif ($buf2 =~ /^.{173}([-+]\d{3})([-+]\d{3})([-+]\d{3})/s) { # (Azdome)
1425
1440
  @acc = ($1/100, $2/100, $3/100);
1426
1441
  }
1427
- $debug and $et->FoundTag(GPSType => '1A');
1428
1442
 
1429
1443
  } elsif ($$dataPt =~ /^.{52}(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/s) {
1430
1444
 
1445
+ $debug and $et->FoundTag(GPSType => '1B');
1431
1446
  # decode NMEA-format GPS data (NextBase 512GW dashcam, ref PH)
1432
1447
  # header looks like this in my sample:
1433
1448
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 40 01 00 00 [....freeGPS @...]
@@ -1453,10 +1468,10 @@ sub ProcessFreeGPS($$$)
1453
1468
  # change to signed integer and divide by 256
1454
1469
  map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
1455
1470
  }
1456
- $debug and $et->FoundTag(GPSType => '1B');
1457
1471
 
1458
1472
  } elsif ($$dataPt =~ /^.{37}\0\0\0A([NS])([EW])/s) {
1459
1473
 
1474
+ $debug and $et->FoundTag(GPSType => '1C');
1460
1475
  # decode freeGPS from ViofoA119v3 dashcam (similar to Novatek GPS format)
1461
1476
  # 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ....]
1462
1477
  # 0010: 05 00 00 00 2f 00 00 00 03 00 00 00 13 00 00 00 [..../...........]
@@ -1481,13 +1496,17 @@ sub ProcessFreeGPS($$$)
1481
1496
  $lon = GetFloat($dataPt, 0x30);
1482
1497
  $spd = GetFloat($dataPt, 0x34) * $knotsToKph; # (convert knots to km/h)
1483
1498
  $trk = GetFloat($dataPt, 0x38);
1484
- @acc = unpack('x60V3', $$dataPt); # (may be all zeros if not valid)
1485
- map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
1499
+ # (may be all zeros or int16u counting from 1 to 6 if not valid)
1500
+ my $tmp = substr($$dataPt, 60, 12);
1501
+ if ($tmp ne "\0\0\0\0\0\0\0\0\0\0\0\0" and $tmp ne "\x01\0\x02\0\x03\0\x04\0\x05\0\x06\0") {
1502
+ @acc = unpack('V3', $tmp);
1503
+ map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
1504
+ }
1486
1505
  SetByteOrder('MM');
1487
- $debug and $et->FoundTag(GPSType => '1C');
1488
1506
 
1489
1507
  } elsif ($$dataPt =~ /^.{21}\0\0\0A([NS])([EW])/s) {
1490
1508
 
1509
+ $debug and $et->FoundTag(GPSType => '1D');
1491
1510
  # also decode 'gpmd' chunk from Kingslim D4 dashcam videos
1492
1511
  # 0000: 0a 00 00 00 0b 00 00 00 07 00 00 00 e5 07 00 00 [................]
1493
1512
  # 0010: 06 00 00 00 03 00 00 00 41 4e 57 31 91 52 83 45 [........ANW1.R.E]
@@ -1513,10 +1532,10 @@ sub ProcessFreeGPS($$$)
1513
1532
  $acc[1] = GetFloat($dataPt, 0x30);
1514
1533
  $acc[2] = GetFloat($dataPt, 0x34);
1515
1534
  SetByteOrder('MM');
1516
- $debug and $et->FoundTag(GPSType => '1D');
1517
1535
 
1518
1536
  } elsif ($$dataPt =~ /^.{60}A\0{3}.{4}([NS])\0{3}.{4}([EW])\0{3}/s) {
1519
1537
 
1538
+ $debug and $et->FoundTag(GPSType => '1E');
1520
1539
  # decode freeGPS from Akaso dashcam
1521
1540
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 60 00 00 00 [....freeGPS `...]
1522
1541
  # 0010: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx............]
@@ -1534,10 +1553,10 @@ sub ProcessFreeGPS($$$)
1534
1553
  $trk = GetFloat($dataPt, 0x54) + 180; # (why is this off by 180?)
1535
1554
  $trk -= 360 if $trk >= 360;
1536
1555
  SetByteOrder('MM');
1537
- $debug and $et->FoundTag(GPSType => '1E');
1538
1556
 
1539
1557
  } elsif ($$dataPt =~ /^.{60}4W`b]S</s and length($$dataPt) >= 140) {
1540
1558
 
1559
+ $debug and $et->FoundTag(GPSType => '1F');
1541
1560
  # 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 01 00 00 [..@.freeGPS ....]
1542
1561
  # 0010: 5a 58 53 42 4e 58 59 53 00 00 00 00 00 00 00 00 [ZXSBNXYS........]
1543
1562
  # 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
@@ -1552,10 +1571,10 @@ sub ProcessFreeGPS($$$)
1552
1571
  $yr += ($yr >= 70 ? 1900 : 2000);
1553
1572
  $spd = $9 * $knotsToKph if length $9;
1554
1573
  $trk = $10 if length $10;
1555
- $debug and $et->FoundTag(GPSType => '1F');
1556
1574
 
1557
1575
  } elsif ($$dataPt =~ /^.{64}[\x01-\x0c]\0{3}[\x01-\x1f]\0{3}A[NS][EW]\0{5}/s) {
1558
1576
 
1577
+ $debug and $et->FoundTag(GPSType => '1G');
1559
1578
  # Akaso V1 dascham
1560
1579
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 00 00 00 [....freeGPS x...]
1561
1580
  # 0010: 59 6e 64 41 6b 61 73 6f 43 61 72 00 00 00 00 00 [YndAkasoCar.....]
@@ -1596,10 +1615,10 @@ sub ProcessFreeGPS($$$)
1596
1615
 
1597
1616
  SetByteOrder('MM');
1598
1617
  #my $serialNum = substr($$dataPt, 0x68, 20);
1599
- $debug and $et->FoundTag(GPSType => '1G');
1600
1618
 
1601
1619
  } elsif ($$dataPt =~ /^.{12}\xac\0\0\0.{44}(.{72})/s) {
1602
1620
 
1621
+ $debug and $et->FoundTag(GPSType => '1H');
1603
1622
  # EACHPAI dash cam
1604
1623
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 ac 00 00 00 [....freeGPS ....]
1605
1624
  # 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
@@ -1619,10 +1638,10 @@ sub ProcessFreeGPS($$$)
1619
1638
  # bytes 7-12 are the timestamp in ASCII HHMMSS after xor-ing with 0x70
1620
1639
  substr($time,7,6) = pack 'C*', map { $_ ^= 0x70 } unpack 'C*', substr($time,7,6);
1621
1640
  # (other values are currently unknown)
1622
- $debug and $et->FoundTag(GPSType => '1H');
1623
1641
 
1624
1642
  } elsif ($$dataPt =~ /^.{64}A([NS])([EW])\0/s) {
1625
1643
 
1644
+ $debug and $et->FoundTag(GPSType => '1I');
1626
1645
  # Vantrue S1 dashcam
1627
1646
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 00 00 00 [....freeGPS x...]
1628
1647
  # 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
@@ -1645,10 +1664,10 @@ sub ProcessFreeGPS($$$)
1645
1664
  $trk = GetFloat($dataPt, 0x68);
1646
1665
  $alt = GetFloat($dataPt, 0x6c);
1647
1666
  SetByteOrder('MM');
1648
- $debug and $et->FoundTag(GPSType => '1I');
1649
1667
 
1650
1668
  } else {
1651
1669
 
1670
+ $debug and $et->FoundTag(GPSType => '1J');
1652
1671
  # decode binary GPS format (Viofo A119S, ref 2)
1653
1672
  # header looks like this in my sample:
1654
1673
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 4c 00 00 00 [....freeGPS L...]
@@ -1682,7 +1701,6 @@ sub ProcessFreeGPS($$$)
1682
1701
  $yr += 2000 if $yr < 2000;
1683
1702
  $spd *= $knotsToKph; # convert speed to km/h
1684
1703
  # ($trk is not confirmed; may be GPSImageDirection, ref PH)
1685
- $debug and $et->FoundTag(GPSType => '1J');
1686
1704
  }
1687
1705
  #
1688
1706
  # save tag values extracted by above code
@@ -1729,6 +1747,7 @@ sub ProcessFreeGPS2($$$)
1729
1747
 
1730
1748
  if (substr($$dataPt,0x45,3) eq 'ATC') {
1731
1749
 
1750
+ $debug and $et->FoundTag(GPSType => '2A');
1732
1751
  # header looks like this: (sample 1)
1733
1752
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 38 06 00 00 [....freeGPS 8...]
1734
1753
  # 0010: 49 51 53 32 30 31 33 30 33 30 36 42 00 00 00 00 [IQS20130306B....]
@@ -1836,11 +1855,11 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1836
1855
  }
1837
1856
  # save position of most recent record (needed when parsing the next freeGPS block)
1838
1857
  $$et{FreeGPS2}{RecentRecPos} = $lastRecPos;
1839
- $debug and $et->FoundTag(GPSType => '2A');
1840
1858
  return 1;
1841
1859
 
1842
1860
  } elsif ($$dataPt =~ /^.{60}A\0.{10}([NS])\0.{14}([EW])\0/s) {
1843
1861
 
1862
+ $debug and $et->FoundTag(GPSType => '2B');
1844
1863
  # header looks like this in my sample:
1845
1864
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 08 01 00 00 [....freeGPS ....]
1846
1865
  # 0010: 32 30 31 33 30 38 31 35 2e 30 31 00 00 00 00 00 [20130815.01.....]
@@ -1868,7 +1887,6 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1868
1887
  $lon = GetDouble($dataPt, 0x50);
1869
1888
  $spd = GetDouble($dataPt, 0x60) * $knotsToKph;
1870
1889
  $trk = GetDouble($dataPt, 0x68);
1871
- $debug and $et->FoundTag(GPSType => '2B');
1872
1890
 
1873
1891
  } elsif ($$dataPt =~ /^.{72}A([NS])([EW])/s) {
1874
1892
 
@@ -1895,6 +1913,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1895
1913
  ($latRef, $lonRef) = ($1, $2);
1896
1914
  ($hr,$min,$sec,$yr,$mon,$day) = unpack('x48V6', $$dataPt);
1897
1915
  if (substr($$dataPt, 16, 3) eq 'IQS') {
1916
+ $debug and $et->FoundTag(GPSType => '2C');
1898
1917
  # Type 3b (ref PH)
1899
1918
  # header looks like this in my sample:
1900
1919
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 4c 00 00 00 [....freeGPS L...]
@@ -1905,20 +1924,20 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1905
1924
  $lon = abs Get32s($dataPt, 0x50) / 1e7;
1906
1925
  $spd = Get32s($dataPt, 0x54) / 100 * $mpsToKph;
1907
1926
  $alt = GetFloat($dataPt, 0x58) / 1000; # (NC)
1908
- $debug and $et->FoundTag(GPSType => '2C');
1909
1927
 
1910
1928
  } else {
1929
+ $debug and $et->FoundTag(GPSType => '2D');
1911
1930
  # Type 3 (ref 2)
1912
1931
  # (no sample with this format)
1913
1932
  $lat = GetFloat($dataPt, 0x4c);
1914
1933
  $lon = GetFloat($dataPt, 0x50);
1915
1934
  $spd = GetFloat($dataPt, 0x54) * $knotsToKph;
1916
1935
  $trk = GetFloat($dataPt, 0x58);
1917
- $debug and $et->FoundTag(GPSType => '2D');
1918
1936
  }
1919
1937
 
1920
1938
  } elsif ($$dataPt =~ /^.{60}A\0.{6}([NS])\0.{6}([EW])\0/s and $dirLen >= 112) {
1921
1939
 
1940
+ $debug and $et->FoundTag(GPSType => '2E');
1922
1941
  # header looks like this in my sample (unknown dashcam, "Anticlock 2 2020_1125_1455_007.MOV"):
1923
1942
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 68 00 00 00 [....freeGPS h...]
1924
1943
  # 0010: 32 30 31 33 30 33 32 35 41 00 00 00 00 00 00 00 [20130325A.......]
@@ -1935,10 +1954,10 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1935
1954
  $lon = GetFloat($dataPt, 0x48);
1936
1955
  $spd = GetFloat($dataPt, 0x50);
1937
1956
  $trk = GetFloat($dataPt, 0x54);
1938
- $debug and $et->FoundTag(GPSType => '2E');
1939
1957
 
1940
1958
  } elsif ($$dataPt =~ /^.{16}A([NS])([EW])\0/s) {
1941
1959
 
1960
+ $debug and $et->FoundTag(GPSType => '2F');
1942
1961
  # INNOVV MP4 video (same format as INNOVV TS)
1943
1962
  while ($$dataPt =~ /(A[NS][EW]\0.{28})/g) {
1944
1963
  my $dat = $1;
@@ -1956,11 +1975,36 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1956
1975
  $et->HandleTag($tagTbl, GPSTrack => $trk);
1957
1976
  $et->HandleTag($tagTbl, Accelerometer => "@acc");
1958
1977
  }
1959
- $debug and $et->FoundTag(GPSType => '2F');
1960
1978
  return 1;
1961
1979
 
1980
+ } elsif ($$dataPt =~ /^.{28}A.{11}([NS]).{15}([EW])/s) {
1981
+
1982
+ $debug and $et->FoundTag(GPSType => '2G');
1983
+ # Vantrue N4 dashcam
1984
+ # 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ....]
1985
+ # 0010: 0d 00 00 00 16 00 00 00 1e 00 00 00 41 00 00 00 [............A...]
1986
+ # 0020: 2c b7 b4 1a 5a 71 b2 40 4e 00 00 00 00 00 00 00 [,...Zq.@N.......]
1987
+ # 0030: fb ae 08 fe 77 f6 89 40 45 00 00 00 00 00 00 00 [....w..@E.......]
1988
+ # 0040: be 9f 1a 2f dd 84 36 40 5c 8f c2 f5 28 fc 68 40 [.../..6@\...(.h@]
1989
+ # 0050: 16 00 00 00 0c 00 00 00 0e 00 00 00 f2 fb ff ff [................]
1990
+ # 0060: 42 00 00 00 02 00 00 00 20 24 47 4e 52 4d 43 2c [B....... $GNRMC,]
1991
+ # 0070: 31 33 32 32 33 30 2e 30 30 30 2c 41 2c 34 37 32 [132230.000,A,472]
1992
+ # 0080: 31 2e 33 35 31 39 37 2c 4e 2c 30 30 38 33 30 2e [1.35197,N,00830.]
1993
+ # 0090: 38 30 38 35 39 2c 45 2c 32 32 2e 35 31 39 2c 31 [80859,E,22.519,1]
1994
+ # 00a0: 39 39 2e 38 38 2c 31 34 31 32 32 32 2c 2c 2c 41 [99.88,141222,,,A]
1995
+ # 00b0: 2a 37 35 0d 0a 00 00 00 00 00 00 00 00 00 00 00 [*75.............]
1996
+ ($latRef, $lonRef) = ($1, $2);
1997
+ ($hr,$min,$sec,$yr,$mon,$day,@acc) = unpack('x16V3x52V3V3',$$dataPt);
1998
+ $lat = abs(GetDouble($dataPt, 32)); # (abs just to be safe)
1999
+ $lon = abs(GetDouble($dataPt, 48)); # (abs just to be safe)
2000
+ $spd = GetDouble($dataPt, 64) * $knotsToKph;
2001
+ $trk = GetDouble($dataPt, 72);
2002
+ map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1000 } @acc; # (NC)
2003
+ # (not necessary to read RMC sentence because we already have it all)
2004
+
1962
2005
  } else {
1963
2006
 
2007
+ $debug and $et->FoundTag(GPSType => '2H');
1964
2008
  # (look for binary GPS as stored by NextBase 512G, ref PH)
1965
2009
  # header looks like this in my sample:
1966
2010
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 01 00 00 [....freeGPS x...]
@@ -2003,7 +2047,6 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
2003
2047
  $et->HandleTag($tagTbl, GPSTrack => $trk);
2004
2048
  last if $pos += 0x20 > length($$dataPt) - 0x1e;
2005
2049
  }
2006
- $debug and $et->FoundTag(GPSType => '2G');
2007
2050
  return $$et{DOC_NUM} ? 1 : 0; # return 0 if nothing extracted
2008
2051
  }
2009
2052
  #
@@ -2020,9 +2063,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
2020
2063
  $et->HandleTag($tagTbl, GPSLongitude => $lon * ($lonRef eq 'W' ? -1 : 1));
2021
2064
  $et->HandleTag($tagTbl, GPSSpeed => $spd) if defined $spd; # (now in km/h)
2022
2065
  $et->HandleTag($tagTbl, GPSTrack => $trk) if defined $trk;
2023
- if (defined $alt) {
2024
- $et->HandleTag($tagTbl, GPSAltitude => $alt);
2025
- }
2066
+ $et->HandleTag($tagTbl, GPSAltitude => $alt) if defined $alt;
2026
2067
  $et->HandleTag($tagTbl, Accelerometer => "@acc") if @acc;
2027
2068
  return 1;
2028
2069
  }
@@ -2238,6 +2279,7 @@ sub Process_3gf($$$)
2238
2279
 
2239
2280
  #------------------------------------------------------------------------------
2240
2281
  # Process DuDuBell M1 dashcam / VSYS M6L 'gps0' atom (ref PH)
2282
+ # (Lamax S9 dual dashcam also uses 'gps0' atom, but encrypted text format)
2241
2283
  # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
2242
2284
  # Returns: 1 on success
2243
2285
  sub Process_gps0($$$)
@@ -2245,14 +2287,28 @@ sub Process_gps0($$$)
2245
2287
  my ($et, $dirInfo, $tagTbl) = @_;
2246
2288
  my $dataPt = $$dirInfo{DataPt};
2247
2289
  my $dirLen = $$dirInfo{DirLen};
2248
- my $recLen = 32; # 32-byte record length
2290
+ my ($pos, $recLen);
2249
2291
  $et->VerboseDir('gps0', undef, $dirLen);
2292
+ # check for encrypted format written by Lamax S9 dual dashcam
2293
+ # (similar to Ambarella A12, but in multiple 311-byte records)
2294
+ if ($$dataPt =~ /^.{2}\xf2\xe1\xf0\xeeTT\x98/s) {
2295
+ $recLen = 311;
2296
+ for ($pos=0; $pos+$recLen<=$dirLen; $pos+=$recLen) {
2297
+ my $dat = substr($$dataPt, $pos, $recLen);
2298
+ last unless $dat =~ /^.{2}\xf2\xe1\xf0\xeeTT\x98/s;
2299
+ $$et{DOC_NUM} = ++$$et{DOC_COUNT};
2300
+ Process_text($et, \$dat, $tagTbl);
2301
+ $pos += $recLen;
2302
+ }
2303
+ delete $$et{DOC_NUM};
2304
+ return 1;
2305
+ }
2306
+ $recLen = 32; # 32-byte record length
2250
2307
  SetByteOrder('II');
2251
2308
  if ($dirLen > $recLen and not $et->Options('ExtractEmbedded')) {
2252
2309
  $dirLen = $recLen;
2253
2310
  EEWarn($et);
2254
2311
  }
2255
- my $pos;
2256
2312
  for ($pos=0; $pos+$recLen<=$dirLen; $pos+=$recLen) {
2257
2313
  $$et{DOC_NUM} = ++$$et{DOC_COUNT};
2258
2314
  # lat/long are in DDDMM.MMMM format
@@ -2302,6 +2358,49 @@ sub Process_gsen($$$)
2302
2358
  return 1;
2303
2359
  }
2304
2360
 
2361
+ #------------------------------------------------------------------------------
2362
+ # Process Kenwood drv-a301w dashcam 'udta' atom (ref PH)
2363
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
2364
+ # Returns: 1 on success
2365
+ # Sample data:
2366
+ # 0000: 56 49 44 45 4f 55 55 55 55 55 55 55 55 55 55 55 [VIDEOUUUUUUUUUUU]
2367
+ # 0010: 55 55 55 55 55 55 55 55 55 55 55 fe fe 32 30 32 [UUUUUUUUUUU..202]
2368
+ # 0020: 33 30 31 30 37 31 31 31 39 31 34 2e 32 30 32 33 [30107111914.2023]
2369
+ # 0030: 30 31 30 37 31 31 31 39 31 35 03 4e 34 37 33 37 [0107111915.N4737]
2370
+ # 0040: 37 30 35 33 57 31 32 32 30 39 39 30 31 34 2b 30 [7053W122099014+0]
2371
+ # 0050: 30 35 38 30 30 30 2b 30 30 36 2b 30 30 39 2b 30 [058000+006+009+0]
2372
+ # 0060: 30 34 2b 30 30 32 2b 30 30 39 2b 30 30 35 2b 30 [04+002+009+005+0]
2373
+ sub ProcessKenwood($$$)
2374
+ {
2375
+ my ($et, $dirInfo, $tagTbl) = @_;
2376
+ my $dataPt = $$dirInfo{DataPt};
2377
+ my $dirLen = $$dirInfo{DirLen};
2378
+ while ($$dataPt =~ /\xfe\xfe([^\xfe]+)/g) {
2379
+ my $dat = $1;
2380
+ next unless $dat =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})./gs;
2381
+ my $time = "$1:$2:$3 $4:$5:$6"; # (likely local time zone, but not confirmed)
2382
+ # ignore second date (what is this for?)
2383
+ next unless $dat =~ /\G(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})./gs;
2384
+ next unless $dat =~ /\G([NS])(\d+)([EW])(\d+)/g;
2385
+ my ($lat, $lon) = ($2/1e4, $4/1e4);
2386
+ ConvertLatLon($lat, $lon);
2387
+ $$et{DOC_NUM} = ++$$et{DOC_COUNT};
2388
+ $et->HandleTag($tagTbl, GPSDateTime => $time);
2389
+ $et->HandleTag($tagTbl, GPSLatitude => $lat * ($1 eq 'S' ? -1 : 1));
2390
+ $et->HandleTag($tagTbl, GPSLongitude => $lon * ($3 eq 'W' ? -1 : 1));
2391
+ next unless $dat =~ /\G([-+]\d{4})(\d+)/g;
2392
+ $et->HandleTag($tagTbl, GPSAltitude => $1 + 0); # (NC, educated guess)
2393
+ $et->HandleTag($tagTbl, GPSSpeed => $2); # (km/h)
2394
+ my @acc;
2395
+ while ($dat =~ /\G([-+]\d+)([-+]\d+)([-+]\d+)/g) {
2396
+ push @acc, $1/1000, $2/1000, $3/1000;
2397
+ }
2398
+ $et->HandleTag($tagTbl, Accelerometer => "@acc") if @acc;
2399
+ }
2400
+ delete $$et{DOC_NUM};
2401
+ return 1;
2402
+ }
2403
+
2305
2404
  #------------------------------------------------------------------------------
2306
2405
  # Process RIFF-format trailer written by Auto-Vox dashcam (ref PH)
2307
2406
  # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
@@ -2773,6 +2872,34 @@ sub ProcessInsta360($;$)
2773
2872
  return 1;
2774
2873
  }
2775
2874
 
2875
+ #------------------------------------------------------------------------------
2876
+ # Process CAMM metadata (ref PH)
2877
+ # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
2878
+ # Returns: 1 on success
2879
+ sub ProcessCAMM($$$)
2880
+ {
2881
+ my ($et, $dirInfo, $tagTbl) = @_;
2882
+ my $dataPt = $$dirInfo{DataPt};
2883
+ my $pos = $$dirInfo{DirStart} || 0;
2884
+ my $end = $pos + ($$dirInfo{DirLen} || length($$dataPt) - $pos);
2885
+ # camm record size for each type, including 4-byte header
2886
+ my %size = ( 1 => 12, 2 => 16, 3 => 16, 4 => 16, 5 => 28, 6 => 60, 7 => 16 );
2887
+ my $rtnVal = 0;
2888
+ while ($pos + 4 < $end) {
2889
+ my $type = Get16u($dataPt, $pos + 2);
2890
+ my $size = $size{$type} or $et->WarnOnce("Unknown camm record type $type"), last;
2891
+ $pos + $size > $end and $et->WarnOnce("Truncated camm record $type"), last;
2892
+ my $tagTbl = GetTagTable("Image::ExifTool::QuickTime::camm$type");
2893
+ $$dirInfo{DirStart} = $pos;
2894
+ $$dirInfo{DirLen} = $size;
2895
+ $et->ProcessBinaryData($dirInfo, $tagTbl) and $rtnVal = 1;
2896
+ # not sure if this is according to specification, but I have seen multiple
2897
+ # camm records all in a single sample, so step forward to process the next one
2898
+ $pos += $size;
2899
+ }
2900
+ return $rtnVal;
2901
+ }
2902
+
2776
2903
  #------------------------------------------------------------------------------
2777
2904
  # Process Garmin GPS 'uuid' atom (ref PH)
2778
2905
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
@@ -2972,7 +3099,7 @@ information like GPS tracks from MOV, MP4 and INSV media data.
2972
3099
 
2973
3100
  =head1 AUTHOR
2974
3101
 
2975
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
3102
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
2976
3103
 
2977
3104
  This library is free software; you can redistribute it and/or modify it
2978
3105
  under the same terms as Perl itself.
@@ -3,6 +3,9 @@ File: Image/ExifTool/README
3
3
 
4
4
  Description: ExifTool support modules documentation
5
5
 
6
+ Note: This documentation is a reference to be used by developers when
7
+ adding new tags to ExifTool.
8
+
6
9
  The ExifTool support modules are loaded by ExifTool to allow processing of
7
10
  various meta information formats.
8
11
 
@@ -641,7 +644,8 @@ numerical, and generated automatically otherwise.
641
644
  expression, a code reference or a list reference. In this
642
645
  expression, $self, $val and $tag may be used as with
643
646
  ValueConv, but if ValueConv was defined then $val is the
644
- ValueConv value instead of the Raw value. The returned value
647
+ ValueConv value instead of the Raw value. Composite tags
648
+ may also use the @val, @prt and @raw lists. The returned value
645
649
  should always be defined. Note that the print conversion is
646
650
  only done if the PrintConv option is enabled (which it is by
647
651
  default), and if the result of the ValueConv is not a scalar
@@ -2126,7 +2126,7 @@ including AVI videos, WAV audio files and WEBP images.
2126
2126
 
2127
2127
  =head1 AUTHOR
2128
2128
 
2129
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
2129
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
2130
2130
 
2131
2131
  This library is free software; you can redistribute it and/or modify it
2132
2132
  under the same terms as Perl itself.
@@ -225,7 +225,7 @@ resource files.
225
225
 
226
226
  =head1 AUTHOR
227
227
 
228
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
228
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
229
229
 
230
230
  This library is free software; you can redistribute it and/or modify it
231
231
  under the same terms as Perl itself.
@@ -366,7 +366,7 @@ information from RTF (Rich Text Format) documents.
366
366
 
367
367
  =head1 AUTHOR
368
368
 
369
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
369
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
370
370
 
371
371
  This library is free software; you can redistribute it and/or modify it
372
372
  under the same terms as Perl itself.
@@ -125,7 +125,7 @@ images are a type of high dynamic-range image.
125
125
 
126
126
  =head1 AUTHOR
127
127
 
128
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
128
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
129
129
 
130
130
  This library is free software; you can redistribute it and/or modify it
131
131
  under the same terms as Perl itself.
@@ -168,7 +168,7 @@ information from Rawzor compressed images.
168
168
 
169
169
  =head1 AUTHOR
170
170
 
171
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
171
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
172
172
 
173
173
  This library is free software; you can redistribute it and/or modify it
174
174
  under the same terms as Perl itself.
@@ -715,7 +715,7 @@ little-endian, but the Real format is big-endian.
715
715
 
716
716
  =head1 AUTHOR
717
717
 
718
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
718
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
719
719
 
720
720
  This library is free software; you can redistribute it and/or modify it
721
721
  under the same terms as Perl itself.
@@ -431,7 +431,7 @@ maker notes in images from Reconyx cameras.
431
431
 
432
432
  =head1 AUTHOR
433
433
 
434
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
434
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
435
435
 
436
436
  This library is free software; you can redistribute it and/or modify it
437
437
  under the same terms as Perl itself.
@@ -303,7 +303,7 @@ from Redcode R3D version 1 and 2 video files.
303
303
 
304
304
  =head1 AUTHOR
305
305
 
306
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
306
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
307
307
 
308
308
  This library is free software; you can redistribute it and/or modify it
309
309
  under the same terms as Perl itself.
@@ -1143,7 +1143,7 @@ interpret Ricoh maker notes EXIF meta information.
1143
1143
 
1144
1144
  =head1 AUTHOR
1145
1145
 
1146
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
1146
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
1147
1147
 
1148
1148
  This library is free software; you can redistribute it and/or modify it
1149
1149
  under the same terms as Perl itself.
@@ -1261,8 +1261,10 @@ my %formatMinMax = (
1261
1261
  },
1262
1262
  # 0x0b41-name - seen 'SingeShot_DepthMap_1' (Yes, "Singe") (SM-N975X front camera)
1263
1263
  '0x0b41' => { Name => 'SingleShotDepthMap', Binary => 1 },
1264
+ # 0x0ba1-name - seen 'Original_Path_Hash_Key', 'PhotoEditor_Re_Edit_Data'
1264
1265
  # 0xa050-name - seen 'Jpeg360_2D_Info' (Samsung Gear 360)
1265
1266
  # 0xa050 - seen 'Jpeg3602D' (Samsung Gear 360)
1267
+ # 0x0c81-name - seen 'Watermark_Info'
1266
1268
  );
1267
1269
 
1268
1270
  # DualShot Extra Info (ref PH)
@@ -1720,7 +1722,7 @@ Samsung maker notes in EXIF information.
1720
1722
 
1721
1723
  =head1 AUTHOR
1722
1724
 
1723
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
1725
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
1724
1726
 
1725
1727
  This library is free software; you can redistribute it and/or modify it
1726
1728
  under the same terms as Perl itself.