exiftool-vendored.pl 12.49.0 → 12.54.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 (203) hide show
  1. package/bin/Changes +107 -6
  2. package/bin/MANIFEST +5 -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 +39 -30
  7. package/bin/lib/File/RandomAccess.pm +1 -1
  8. package/bin/lib/File/RandomAccess.pod +2 -2
  9. package/bin/lib/Image/ExifTool/AES.pm +1 -1
  10. package/bin/lib/Image/ExifTool/AFCP.pm +1 -1
  11. package/bin/lib/Image/ExifTool/AIFF.pm +1 -1
  12. package/bin/lib/Image/ExifTool/APE.pm +1 -1
  13. package/bin/lib/Image/ExifTool/APP12.pm +1 -1
  14. package/bin/lib/Image/ExifTool/ASF.pm +1 -1
  15. package/bin/lib/Image/ExifTool/Apple.pm +197 -27
  16. package/bin/lib/Image/ExifTool/Audible.pm +1 -1
  17. package/bin/lib/Image/ExifTool/BMP.pm +1 -1
  18. package/bin/lib/Image/ExifTool/BPG.pm +1 -1
  19. package/bin/lib/Image/ExifTool/BZZ.pm +1 -1
  20. package/bin/lib/Image/ExifTool/BigTIFF.pm +1 -1
  21. package/bin/lib/Image/ExifTool/BuildTagLookup.pm +10 -7
  22. package/bin/lib/Image/ExifTool/CBOR.pm +1 -1
  23. package/bin/lib/Image/ExifTool/Canon.pm +26 -9
  24. package/bin/lib/Image/ExifTool/CanonCustom.pm +1 -1
  25. package/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
  26. package/bin/lib/Image/ExifTool/CanonVRD.pm +9 -9
  27. package/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
  28. package/bin/lib/Image/ExifTool/Casio.pm +4 -4
  29. package/bin/lib/Image/ExifTool/Charset.pm +1 -1
  30. package/bin/lib/Image/ExifTool/DICOM.pm +1 -1
  31. package/bin/lib/Image/ExifTool/DJI.pm +1 -1
  32. package/bin/lib/Image/ExifTool/DNG.pm +1 -1
  33. package/bin/lib/Image/ExifTool/DPX.pm +1 -1
  34. package/bin/lib/Image/ExifTool/DV.pm +1 -1
  35. package/bin/lib/Image/ExifTool/DarwinCore.pm +1 -1
  36. package/bin/lib/Image/ExifTool/DjVu.pm +1 -1
  37. package/bin/lib/Image/ExifTool/EXE.pm +1 -1
  38. package/bin/lib/Image/ExifTool/Exif.pm +11 -21
  39. package/bin/lib/Image/ExifTool/FITS.pm +1 -1
  40. package/bin/lib/Image/ExifTool/FLAC.pm +1 -1
  41. package/bin/lib/Image/ExifTool/FLIF.pm +1 -1
  42. package/bin/lib/Image/ExifTool/FLIR.pm +7 -6
  43. package/bin/lib/Image/ExifTool/Fixup.pm +1 -1
  44. package/bin/lib/Image/ExifTool/Flash.pm +1 -1
  45. package/bin/lib/Image/ExifTool/FlashPix.pm +1 -1
  46. package/bin/lib/Image/ExifTool/Font.pm +1 -1
  47. package/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
  48. package/bin/lib/Image/ExifTool/FujiFilm.pm +20 -13
  49. package/bin/lib/Image/ExifTool/GE.pm +1 -1
  50. package/bin/lib/Image/ExifTool/GIF.pm +1 -1
  51. package/bin/lib/Image/ExifTool/GIMP.pm +1 -1
  52. package/bin/lib/Image/ExifTool/GPS.pm +12 -6
  53. package/bin/lib/Image/ExifTool/GeoTiff.pm +1 -1
  54. package/bin/lib/Image/ExifTool/Geotag.pm +14 -6
  55. package/bin/lib/Image/ExifTool/GoPro.pm +1 -1
  56. package/bin/lib/Image/ExifTool/H264.pm +1 -1
  57. package/bin/lib/Image/ExifTool/HP.pm +1 -1
  58. package/bin/lib/Image/ExifTool/HTML.pm +1 -1
  59. package/bin/lib/Image/ExifTool/HtmlDump.pm +1 -1
  60. package/bin/lib/Image/ExifTool/ICC_Profile.pm +1 -1
  61. package/bin/lib/Image/ExifTool/ICO.pm +3 -1
  62. package/bin/lib/Image/ExifTool/ID3.pm +1 -1
  63. package/bin/lib/Image/ExifTool/IPTC.pm +6 -2
  64. package/bin/lib/Image/ExifTool/ISO.pm +1 -1
  65. package/bin/lib/Image/ExifTool/ITC.pm +1 -1
  66. package/bin/lib/Image/ExifTool/Import.pm +1 -1
  67. package/bin/lib/Image/ExifTool/InDesign.pm +1 -1
  68. package/bin/lib/Image/ExifTool/JPEG.pm +2 -1
  69. package/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
  70. package/bin/lib/Image/ExifTool/JSON.pm +1 -1
  71. package/bin/lib/Image/ExifTool/JVC.pm +1 -1
  72. package/bin/lib/Image/ExifTool/Jpeg2000.pm +35 -8
  73. package/bin/lib/Image/ExifTool/Kodak.pm +1 -1
  74. package/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
  75. package/bin/lib/Image/ExifTool/LIF.pm +1 -1
  76. package/bin/lib/Image/ExifTool/LNK.pm +1 -1
  77. package/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
  78. package/bin/lib/Image/ExifTool/Lang/de.pm +2 -2
  79. package/bin/lib/Image/ExifTool/Lang/en_ca.pm +1 -1
  80. package/bin/lib/Image/ExifTool/Lang/en_gb.pm +1 -1
  81. package/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
  82. package/bin/lib/Image/ExifTool/Lang/fi.pm +1 -1
  83. package/bin/lib/Image/ExifTool/Lang/fr.pm +6016 -760
  84. package/bin/lib/Image/ExifTool/Lang/it.pm +1 -1
  85. package/bin/lib/Image/ExifTool/Lang/ja.pm +1 -1
  86. package/bin/lib/Image/ExifTool/Lang/ko.pm +1 -1
  87. package/bin/lib/Image/ExifTool/Lang/nl.pm +1 -1
  88. package/bin/lib/Image/ExifTool/Lang/pl.pm +1 -1
  89. package/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
  90. package/bin/lib/Image/ExifTool/Lang/sk.pm +1806 -0
  91. package/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
  92. package/bin/lib/Image/ExifTool/Lang/tr.pm +1 -1
  93. package/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
  94. package/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
  95. package/bin/lib/Image/ExifTool/Leaf.pm +1 -1
  96. package/bin/lib/Image/ExifTool/Lytro.pm +1 -1
  97. package/bin/lib/Image/ExifTool/M2TS.pm +45 -2
  98. package/bin/lib/Image/ExifTool/MIE.pm +1 -1
  99. package/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
  100. package/bin/lib/Image/ExifTool/MIFF.pm +1 -1
  101. package/bin/lib/Image/ExifTool/MISB.pm +2 -2
  102. package/bin/lib/Image/ExifTool/MNG.pm +1 -1
  103. package/bin/lib/Image/ExifTool/MOI.pm +1 -1
  104. package/bin/lib/Image/ExifTool/MPC.pm +1 -1
  105. package/bin/lib/Image/ExifTool/MPEG.pm +1 -1
  106. package/bin/lib/Image/ExifTool/MPF.pm +1 -1
  107. package/bin/lib/Image/ExifTool/MRC.pm +1 -1
  108. package/bin/lib/Image/ExifTool/MWG.pm +1 -1
  109. package/bin/lib/Image/ExifTool/MXF.pm +1 -1
  110. package/bin/lib/Image/ExifTool/MacOS.pm +1 -1
  111. package/bin/lib/Image/ExifTool/MakerNotes.pm +1 -1
  112. package/bin/lib/Image/ExifTool/Matroska.pm +262 -46
  113. package/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
  114. package/bin/lib/Image/ExifTool/Minolta.pm +1 -1
  115. package/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
  116. package/bin/lib/Image/ExifTool/Motorola.pm +1 -1
  117. package/bin/lib/Image/ExifTool/Nikon.pm +845 -355
  118. package/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
  119. package/bin/lib/Image/ExifTool/NikonCustom.pm +140 -107
  120. package/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
  121. package/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
  122. package/bin/lib/Image/ExifTool/OOXML.pm +1 -1
  123. package/bin/lib/Image/ExifTool/Ogg.pm +1 -1
  124. package/bin/lib/Image/ExifTool/Olympus.pm +6 -4
  125. package/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
  126. package/bin/lib/Image/ExifTool/Opus.pm +1 -1
  127. package/bin/lib/Image/ExifTool/Other.pm +1 -1
  128. package/bin/lib/Image/ExifTool/PCX.pm +1 -1
  129. package/bin/lib/Image/ExifTool/PDF.pm +1 -1
  130. package/bin/lib/Image/ExifTool/PGF.pm +1 -1
  131. package/bin/lib/Image/ExifTool/PICT.pm +1 -1
  132. package/bin/lib/Image/ExifTool/PLIST.pm +12 -7
  133. package/bin/lib/Image/ExifTool/PLUS.pm +1 -1
  134. package/bin/lib/Image/ExifTool/PNG.pm +9 -2
  135. package/bin/lib/Image/ExifTool/PPM.pm +1 -1
  136. package/bin/lib/Image/ExifTool/PSP.pm +1 -1
  137. package/bin/lib/Image/ExifTool/Palm.pm +1 -1
  138. package/bin/lib/Image/ExifTool/Panasonic.pm +1 -1
  139. package/bin/lib/Image/ExifTool/PanasonicRaw.pm +1 -1
  140. package/bin/lib/Image/ExifTool/Parrot.pm +1 -1
  141. package/bin/lib/Image/ExifTool/Pentax.pm +8 -3
  142. package/bin/lib/Image/ExifTool/PhaseOne.pm +1 -1
  143. package/bin/lib/Image/ExifTool/PhotoCD.pm +1 -1
  144. package/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
  145. package/bin/lib/Image/ExifTool/Photoshop.pm +1 -1
  146. package/bin/lib/Image/ExifTool/PostScript.pm +1 -1
  147. package/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
  148. package/bin/lib/Image/ExifTool/Qualcomm.pm +1 -1
  149. package/bin/lib/Image/ExifTool/QuickTime.pm +52 -9
  150. package/bin/lib/Image/ExifTool/QuickTimeStream.pl +95 -14
  151. package/bin/lib/Image/ExifTool/README +6 -1
  152. package/bin/lib/Image/ExifTool/RIFF.pm +1 -1
  153. package/bin/lib/Image/ExifTool/RSRC.pm +1 -1
  154. package/bin/lib/Image/ExifTool/RTF.pm +1 -1
  155. package/bin/lib/Image/ExifTool/Radiance.pm +1 -1
  156. package/bin/lib/Image/ExifTool/Rawzor.pm +1 -1
  157. package/bin/lib/Image/ExifTool/Real.pm +1 -1
  158. package/bin/lib/Image/ExifTool/Reconyx.pm +1 -1
  159. package/bin/lib/Image/ExifTool/Red.pm +1 -1
  160. package/bin/lib/Image/ExifTool/Ricoh.pm +1 -1
  161. package/bin/lib/Image/ExifTool/Samsung.pm +3 -1
  162. package/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
  163. package/bin/lib/Image/ExifTool/Scalado.pm +1 -1
  164. package/bin/lib/Image/ExifTool/Shift.pl +1 -1
  165. package/bin/lib/Image/ExifTool/Shortcuts.pm +1 -1
  166. package/bin/lib/Image/ExifTool/Sigma.pm +1 -1
  167. package/bin/lib/Image/ExifTool/SigmaRaw.pm +1 -1
  168. package/bin/lib/Image/ExifTool/Sony.pm +35 -20
  169. package/bin/lib/Image/ExifTool/SonyIDC.pm +1 -1
  170. package/bin/lib/Image/ExifTool/Stim.pm +1 -1
  171. package/bin/lib/Image/ExifTool/TagInfoXML.pm +15 -8
  172. package/bin/lib/Image/ExifTool/TagLookup.pm +4672 -4568
  173. package/bin/lib/Image/ExifTool/TagNames.pod +357 -46
  174. package/bin/lib/Image/ExifTool/Text.pm +1 -1
  175. package/bin/lib/Image/ExifTool/Theora.pm +1 -1
  176. package/bin/lib/Image/ExifTool/Torrent.pm +1 -1
  177. package/bin/lib/Image/ExifTool/Unknown.pm +1 -1
  178. package/bin/lib/Image/ExifTool/VCard.pm +1 -1
  179. package/bin/lib/Image/ExifTool/Validate.pm +1 -1
  180. package/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
  181. package/bin/lib/Image/ExifTool/WTV.pm +1 -1
  182. package/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
  183. package/bin/lib/Image/ExifTool/WriteExif.pl +14 -1
  184. package/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
  185. package/bin/lib/Image/ExifTool/WritePDF.pl +5 -1
  186. package/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
  187. package/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
  188. package/bin/lib/Image/ExifTool/WritePostScript.pl +1 -1
  189. package/bin/lib/Image/ExifTool/WriteQuickTime.pl +30 -14
  190. package/bin/lib/Image/ExifTool/WriteRIFF.pl +1 -1
  191. package/bin/lib/Image/ExifTool/WriteXMP.pl +16 -2
  192. package/bin/lib/Image/ExifTool/Writer.pl +35 -15
  193. package/bin/lib/Image/ExifTool/XMP.pm +25 -4
  194. package/bin/lib/Image/ExifTool/XMP2.pl +29 -2
  195. package/bin/lib/Image/ExifTool/XMPStruct.pl +1 -1
  196. package/bin/lib/Image/ExifTool/ZIP.pm +20 -8
  197. package/bin/lib/Image/ExifTool/ZISRAW.pm +1 -1
  198. package/bin/lib/Image/ExifTool/iWork.pm +1 -1
  199. package/bin/lib/Image/ExifTool.pm +45 -20
  200. package/bin/lib/Image/ExifTool.pod +48 -46
  201. package/bin/perl-Image-ExifTool.spec +1 -1
  202. package/bin/pp_build_exe.args +6 -5
  203. package/package.json +3 -3
@@ -379,7 +379,7 @@ KF7 and KF8 books (AZW and AZW3).
379
379
 
380
380
  =head1 AUTHOR
381
381
 
382
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
382
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
383
383
 
384
384
  This library is free software; you can redistribute it and/or modify it
385
385
  under the same terms as Perl itself.
@@ -2863,7 +2863,7 @@ Panasonic and Leica maker notes in EXIF information.
2863
2863
 
2864
2864
  =head1 AUTHOR
2865
2865
 
2866
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
2866
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
2867
2867
 
2868
2868
  This library is free software; you can redistribute it and/or modify it
2869
2869
  under the same terms as Perl itself.
@@ -908,7 +908,7 @@ write meta information in Panasonic/Leica RAW, RW2 and RWL images.
908
908
 
909
909
  =head1 AUTHOR
910
910
 
911
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
911
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
912
912
 
913
913
  This library is free software; you can redistribute it and/or modify it
914
914
  under the same terms as Perl itself.
@@ -825,7 +825,7 @@ timed metadata from the 'mett' frame found in Parrot drone MP4 videos.
825
825
 
826
826
  =head1 AUTHOR
827
827
 
828
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
828
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
829
829
 
830
830
  This library is free software; you can redistribute it and/or modify it
831
831
  under the same terms as Perl itself.
@@ -58,7 +58,7 @@ use Image::ExifTool::Exif;
58
58
  use Image::ExifTool::GPS;
59
59
  use Image::ExifTool::HP;
60
60
 
61
- $VERSION = '3.40';
61
+ $VERSION = '3.41';
62
62
 
63
63
  sub CryptShutterCount($$);
64
64
  sub PrintFilter($$$);
@@ -365,10 +365,15 @@ sub DecodeAFPoints($$$$;$);
365
365
  '8 255.4' => 'Sigma 4.5mm F2.8 EX DC HSM Circular Fisheye', #PH
366
366
  '8 255.5' => 'Sigma 50-200mm F4-5.6 DC OS', #26
367
367
  '8 255.6' => 'Sigma 24-70mm F2.8 EX DG HSM', #29
368
+
369
+ '9 0' => '645 Manual Lens', #PH (NC)
370
+ '9 3' => 'HD PENTAX-FA 43mm F1.9 Limited', #IB
371
+ '9 24' => 'HD PENTAX-FA 77mm F1.8 Limited', #IB
372
+ '9 39' => 'HD PENTAX-FA 31mm F1.8 AL Limited', #IB
373
+ '9 247' => 'HD PENTAX-DA FISH-EYE 10-17mm F3.5-4.5 ED [IF]', #IB
368
374
  #
369
375
  # 645 lenses
370
376
  #
371
- '9 0' => '645 Manual Lens', #PH (NC)
372
377
  '10 0' => '645 A Series Lens', #PH
373
378
  '11 1' => 'smc PENTAX-FA 645 75mm F2.8', #PH
374
379
  '11 2' => 'smc PENTAX-FA 645 45mm F2.8', #PH
@@ -6315,7 +6320,7 @@ tags, and everyone who helped contribute to the LensType values.
6315
6320
 
6316
6321
  =head1 AUTHOR
6317
6322
 
6318
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
6323
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
6319
6324
 
6320
6325
  This library is free software; you can redistribute it and/or modify it
6321
6326
  under the same terms as Perl itself.
@@ -712,7 +712,7 @@ One maker notes.
712
712
 
713
713
  =head1 AUTHOR
714
714
 
715
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
715
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
716
716
 
717
717
  This library is free software; you can redistribute it and/or modify it
718
718
  under the same terms as Perl itself.
@@ -484,7 +484,7 @@ information from Kodak Photo CD Image Pac (PCD) files.
484
484
 
485
485
  =head1 AUTHOR
486
486
 
487
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
487
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
488
488
 
489
489
  This library is free software; you can redistribute it and/or modify it
490
490
  under the same terms as Perl itself.
@@ -236,7 +236,7 @@ write information written by the Camera Bits Photo Mechanic software.
236
236
 
237
237
  =head1 AUTHOR
238
238
 
239
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
239
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
240
240
 
241
241
  This library is free software; you can redistribute it and/or modify it
242
242
  under the same terms as Perl itself.
@@ -1170,7 +1170,7 @@ be preserved when copying Photoshop information via user-defined tags.
1170
1170
 
1171
1171
  =head1 AUTHOR
1172
1172
 
1173
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
1173
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
1174
1174
 
1175
1175
  This library is free software; you can redistribute it and/or modify it
1176
1176
  under the same terms as Perl itself.
@@ -777,7 +777,7 @@ This code reads meta information from EPS (Encapsulated PostScript), PS
777
777
 
778
778
  =head1 AUTHOR
779
779
 
780
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
780
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
781
781
 
782
782
  This library is free software; you can redistribute it and/or modify it
783
783
  under the same terms as Perl itself.
@@ -112,7 +112,7 @@ Print Image Matching meta information.
112
112
 
113
113
  =head1 AUTHOR
114
114
 
115
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
115
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
116
116
 
117
117
  This library is free software; you can redistribute it and/or modify it
118
118
  under the same terms as Perl itself.
@@ -1331,7 +1331,7 @@ information from the APP7 Qualcomm segment in JPEG images.
1331
1331
 
1332
1332
  =head1 AUTHOR
1333
1333
 
1334
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
1334
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
1335
1335
 
1336
1336
  This library is free software; you can redistribute it and/or modify it
1337
1337
  under the same terms as Perl itself.
@@ -47,7 +47,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
47
47
  use Image::ExifTool::Exif;
48
48
  use Image::ExifTool::GPS;
49
49
 
50
- $VERSION = '2.79';
50
+ $VERSION = '2.82';
51
51
 
52
52
  sub ProcessMOV($$;$);
53
53
  sub ProcessKeys($$$);
@@ -522,6 +522,12 @@ my %eeBox2 = (
522
522
  return substr($val, 12, $len);
523
523
  },
524
524
  },
525
+ {
526
+ Name => 'SkipInfo', # (found in 70mai Pro Plus+ MP4 videos)
527
+ # (look for something that looks like a QuickTime atom header)
528
+ Condition => '$$valPt =~ /^\0[\0-\x04]..[a-zA-Z ]{4}/s',
529
+ SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::SkipInfo' },
530
+ },
525
531
  { Name => 'Skip', Unknown => 1, Binary => 1 },
526
532
  ],
527
533
  wide => { Unknown => 1, Binary => 1 },
@@ -759,6 +765,19 @@ my %eeBox2 = (
759
765
  # 'samn'? - seen in Vantrue N2S sample video
760
766
  );
761
767
 
768
+ # stuff seen in 'skip' atom (70mai Pro Plus+ MP4 videos)
769
+ %Image::ExifTool::QuickTime::SkipInfo = (
770
+ PROCESS_PROC => \&ProcessMOV,
771
+ GROUPS => { 2 => 'Video' },
772
+ 'ver ' => 'Version',
773
+ # tima - int32u: seen 0x3c
774
+ thma => {
775
+ Name => 'ThumbnailImage',
776
+ Groups => { 2 => 'Preview' },
777
+ Binary => 1,
778
+ },
779
+ );
780
+
762
781
  # MPEG-4 'ftyp' atom
763
782
  # (ref http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html)
764
783
  %Image::ExifTool::QuickTime::FileType = (
@@ -1333,12 +1352,14 @@ my %eeBox2 = (
1333
1352
  },
1334
1353
  { #https://github.com/google/spatial-media/blob/master/docs/spherical-video-rfc.md
1335
1354
  Name => 'SphericalVideoXML',
1355
+ # (this tag is readable/writable as a block through the Extra SphericalVideoXML tags)
1336
1356
  Condition => '$$valPt=~/^\xff\xcc\x82\x63\xf8\x55\x4a\x93\x88\x14\x58\x7a\x02\x52\x1f\xdd/',
1337
1357
  WriteGroup => 'GSpherical', # write only GSpherical XMP tags here
1338
1358
  HandlerType => 'vide', # only write in video tracks
1339
1359
  SubDirectory => {
1340
1360
  TagTable => 'Image::ExifTool::XMP::Main',
1341
1361
  Start => 16,
1362
+ ProcessProc => 'Image::ExifTool::XMP::ProcessGSpherical',
1342
1363
  WriteProc => 'Image::ExifTool::XMP::WriteGSpherical',
1343
1364
  },
1344
1365
  },
@@ -6015,6 +6036,7 @@ my %eeBox2 = (
6015
6036
  plID => { #10 (or TV season)
6016
6037
  Name => 'PlayListID',
6017
6038
  Format => 'int8u', # actually int64u, but split it up
6039
+ Count => 8,
6018
6040
  Writable => 'int32s', #27
6019
6041
  },
6020
6042
  purd => 'PurchaseDate', #7
@@ -8691,7 +8713,7 @@ sub HandleItemInfo($)
8691
8713
  $et->VPrint(0, "$$et{INDENT}Item $id) '${type}' ($len bytes)\n");
8692
8714
  }
8693
8715
  # get ExifTool name for this item
8694
- my $name = { Exif => 'EXIF', 'application/rdf+xml' => 'XMP' }->{$type} || '';
8716
+ my $name = { Exif => 'EXIF', 'application/rdf+xml' => 'XMP', jpeg => 'PreviewImage' }->{$type} || '';
8695
8717
  my ($warn, $extent);
8696
8718
  $warn = "Can't currently decode encoded $type metadata" if $$item{ContentEncoding};
8697
8719
  $warn = "Can't currently decode protected $type metadata" if $$item{ProtectionIndex};
@@ -8768,6 +8790,21 @@ sub HandleItemInfo($)
8768
8790
  }
8769
8791
  $subTable = GetTagTable('Image::ExifTool::Exif::Main');
8770
8792
  $proc = \&Image::ExifTool::ProcessTIFF;
8793
+ } elsif ($name eq 'PreviewImage') {
8794
+ # take a quick stab at determining the size of the image
8795
+ # (based on JPEG previews found in Fuji X-H2S HIF images)
8796
+ my $type = 'PreviewImage';
8797
+ if ($buff =~ /^.{556}\xff\xc0\0\x11.(.{4})/s) {
8798
+ my ($h, $w) = unpack('n2', $1);
8799
+ # (not sure if $h is ever the long dimension, but test it just in case)
8800
+ if ($w == 160 or $h == 160) {
8801
+ $type = 'ThumbnailImage';
8802
+ } elsif ($w == 1920 or $h == 1920) {
8803
+ $type = 'OtherImage'; # (large preview)
8804
+ } # (PreviewImage is 640x480)
8805
+ }
8806
+ $et->FoundTag($type => $buff);
8807
+ next;
8771
8808
  } else {
8772
8809
  $start = 0;
8773
8810
  $subTable = GetTagTable('Image::ExifTool::XMP::Main');
@@ -9184,9 +9221,9 @@ sub ProcessMOV($$;$)
9184
9221
  } else {
9185
9222
  # check on file type if called with a RAF
9186
9223
  $$tagTablePtr{$tag} or return 0;
9224
+ my $fileType;
9187
9225
  if ($tag eq 'ftyp' and $size >= 12) {
9188
9226
  # read ftyp atom to see what type of file this is
9189
- my $fileType;
9190
9227
  if ($raf->Read($buff, $size-8) == $size-8) {
9191
9228
  $raf->Seek(-($size-8), 1);
9192
9229
  my $type = substr($buff, 0, 4);
@@ -9208,12 +9245,14 @@ sub ProcessMOV($$;$)
9208
9245
  # temporarily set ExtractEmbedded option for CRX files
9209
9246
  $saveOptions{ExtractEmbedded} = $et->Options(ExtractEmbedded => 1) if $fileType eq 'CRX';
9210
9247
  } else {
9211
- $et->SetFileType(); # MOV
9248
+ $et->SetFileType(); # MOV
9212
9249
  }
9213
9250
  SetByteOrder('MM');
9214
- $$et{PRIORITY_DIR} = 'XMP'; # have XMP take priority
9251
+ # have XMP take priority except for HEIC
9252
+ $$et{PRIORITY_DIR} = 'XMP' unless $fileType and $fileType eq 'HEIC';
9215
9253
  }
9216
- $$raf{NoBuffer} = 1 if $et->Options('FastScan'); # disable buffering in FastScan mode
9254
+ my $fast = $$et{OPTIONS}{FastScan} || 0;
9255
+ $$raf{NoBuffer} = 1 if $fast; # disable buffering in FastScan mode
9217
9256
 
9218
9257
  my $ee = $$et{OPTIONS}{ExtractEmbedded};
9219
9258
  if ($ee) {
@@ -9241,8 +9280,10 @@ sub ProcessMOV($$;$)
9241
9280
  $et->VPrint(0,"$$et{INDENT}Tag '${t}' extends to end of file");
9242
9281
  if ($$tagTablePtr{"$tag-size"}) {
9243
9282
  my $pos = $raf->Tell();
9244
- $raf->Seek(0, 2);
9245
- $et->HandleTag($tagTablePtr, "$tag-size", $raf->Tell() - $pos);
9283
+ unless ($fast) {
9284
+ $raf->Seek(0, 2);
9285
+ $et->HandleTag($tagTablePtr, "$tag-size", $raf->Tell() - $pos);
9286
+ }
9246
9287
  $et->HandleTag($tagTablePtr, "$tag-offset", $pos) if $$tagTablePtr{"$tag-offset"};
9247
9288
  }
9248
9289
  }
@@ -9345,6 +9386,8 @@ sub ProcessMOV($$;$)
9345
9386
  $et->HandleTag($tagTablePtr, "$tag-size", $size);
9346
9387
  $et->HandleTag($tagTablePtr, "$tag-offset", $raf->Tell()) if $$tagTablePtr{"$tag-offset"};
9347
9388
  }
9389
+ # stop processing at mdat/idat if -fast2 is used
9390
+ last if $fast > 1 and ($tag eq 'mdat' or $tag eq 'idat');
9348
9391
  # load values only if associated with a tag (or verbose) and not too big
9349
9392
  if ($size > 0x2000000) { # start to get worried above 32 MB
9350
9393
  # check for RIFF trailer (written by Auto-Vox dashcam)
@@ -9800,7 +9843,7 @@ information from QuickTime and MP4 video, M4A audio, and HEIC image files.
9800
9843
 
9801
9844
  =head1 AUTHOR
9802
9845
 
9803
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
9846
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
9804
9847
 
9805
9848
  This library is free software; you can redistribute it and/or modify it
9806
9849
  under the same terms as Perl itself.
@@ -26,6 +26,9 @@ sub ProcessFreeGPS($$$);
26
26
  sub ProcessFreeGPS2($$$);
27
27
  sub Process360Fly($$$);
28
28
  sub ProcessFMAS($$$);
29
+ sub ProcessCAMM($$$);
30
+
31
+ my $debug; # set to 1 for extra debugging messages
29
32
 
30
33
  # QuickTime data types that have ExifTool equivalents
31
34
  # (ref https://developer.apple.com/library/content/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW35)
@@ -99,7 +102,7 @@ my %insvLimit = (
99
102
  The tags below are extracted from timed metadata in QuickTime and other
100
103
  formats of video files when the ExtractEmbedded option is used. Although
101
104
  most of these tags are combined into the single table below, ExifTool
102
- currently reads 61 different formats of timed GPS metadata from video files.
105
+ currently reads 63 different formats of timed GPS metadata from video files.
103
106
  },
104
107
  VARS => { NO_ID => 1 },
105
108
  GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
@@ -234,7 +237,7 @@ my %insvLimit = (
234
237
  camm => [{
235
238
  Name => 'camm0',
236
239
  # (according to the spec. the first 2 bytes are reserved and should be zero,
237
- # 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)
238
241
  Condition => '$$valPt =~ /^..\0\0/s',
239
242
  SubDirectory => {
240
243
  TagTable => 'Image::ExifTool::QuickTime::camm0',
@@ -316,7 +319,7 @@ my %insvLimit = (
316
319
 
317
320
  # tags found in 'camm' type 0 timed metadata (ref 4)
318
321
  %Image::ExifTool::QuickTime::camm0 = (
319
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
322
+ PROCESS_PROC => \&ProcessCAMM,
320
323
  GROUPS => { 2 => 'Location' },
321
324
  FIRST_ENTRY => 0,
322
325
  NOTES => q{
@@ -334,7 +337,7 @@ my %insvLimit = (
334
337
 
335
338
  # tags found in 'camm' type 1 timed metadata (ref 4)
336
339
  %Image::ExifTool::QuickTime::camm1 = (
337
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
340
+ PROCESS_PROC => \&ProcessCAMM,
338
341
  GROUPS => { 2 => 'Camera' },
339
342
  FIRST_ENTRY => 0,
340
343
  4 => {
@@ -353,7 +356,7 @@ my %insvLimit = (
353
356
 
354
357
  # tags found in 'camm' type 2 timed metadata (ref PH, Insta360Pro)
355
358
  %Image::ExifTool::QuickTime::camm2 = (
356
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
359
+ PROCESS_PROC => \&ProcessCAMM,
357
360
  GROUPS => { 2 => 'Location' },
358
361
  FIRST_ENTRY => 0,
359
362
  4 => {
@@ -365,7 +368,7 @@ my %insvLimit = (
365
368
 
366
369
  # tags found in 'camm' type 3 timed metadata (ref PH, Insta360Pro)
367
370
  %Image::ExifTool::QuickTime::camm3 = (
368
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
371
+ PROCESS_PROC => \&ProcessCAMM,
369
372
  GROUPS => { 2 => 'Location' },
370
373
  FIRST_ENTRY => 0,
371
374
  4 => {
@@ -377,7 +380,7 @@ my %insvLimit = (
377
380
 
378
381
  # tags found in 'camm' type 4 timed metadata (ref 4)
379
382
  %Image::ExifTool::QuickTime::camm4 = (
380
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
383
+ PROCESS_PROC => \&ProcessCAMM,
381
384
  GROUPS => { 2 => 'Location' },
382
385
  FIRST_ENTRY => 0,
383
386
  4 => {
@@ -389,7 +392,7 @@ my %insvLimit = (
389
392
 
390
393
  # tags found in 'camm' type 5 timed metadata (ref 4)
391
394
  %Image::ExifTool::QuickTime::camm5 = (
392
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
395
+ PROCESS_PROC => \&ProcessCAMM,
393
396
  GROUPS => { 2 => 'Location' },
394
397
  FIRST_ENTRY => 0,
395
398
  4 => {
@@ -414,7 +417,7 @@ my %insvLimit = (
414
417
 
415
418
  # tags found in 'camm' type 6 timed metadata (ref PH/4, Insta360)
416
419
  %Image::ExifTool::QuickTime::camm6 = (
417
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
420
+ PROCESS_PROC => \&ProcessCAMM,
418
421
  GROUPS => { 2 => 'Location' },
419
422
  FIRST_ENTRY => 0,
420
423
  0x04 => {
@@ -480,7 +483,7 @@ my %insvLimit = (
480
483
 
481
484
  # tags found in 'camm' type 7 timed metadata (ref 4)
482
485
  %Image::ExifTool::QuickTime::camm7 = (
483
- PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
486
+ PROCESS_PROC => \&ProcessCAMM,
484
487
  GROUPS => { 2 => 'Location' },
485
488
  FIRST_ENTRY => 0,
486
489
  4 => {
@@ -1422,6 +1425,7 @@ sub ProcessFreeGPS($$$)
1422
1425
  } elsif ($buf2 =~ /^.{173}([-+]\d{3})([-+]\d{3})([-+]\d{3})/s) { # (Azdome)
1423
1426
  @acc = ($1/100, $2/100, $3/100);
1424
1427
  }
1428
+ $debug and $et->FoundTag(GPSType => '1A');
1425
1429
 
1426
1430
  } elsif ($$dataPt =~ /^.{52}(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/s) {
1427
1431
 
@@ -1450,6 +1454,7 @@ sub ProcessFreeGPS($$$)
1450
1454
  # change to signed integer and divide by 256
1451
1455
  map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
1452
1456
  }
1457
+ $debug and $et->FoundTag(GPSType => '1B');
1453
1458
 
1454
1459
  } elsif ($$dataPt =~ /^.{37}\0\0\0A([NS])([EW])/s) {
1455
1460
 
@@ -1460,13 +1465,31 @@ sub ProcessFreeGPS($$$)
1460
1465
  # 0030: f1 47 40 46 66 66 d2 41 85 eb 83 41 00 00 00 00 [.G@Fff.A...A....]
1461
1466
  ($latRef, $lonRef) = ($1, $2);
1462
1467
  ($hr,$min,$sec,$yr,$mon,$day) = unpack('x16V6', $$dataPt);
1463
- $yr += 2000;
1468
+ if ($yr < 2000) {
1469
+ $yr += 2000;
1470
+ } else {
1471
+ # Kenwood dashcam sometimes stores absolute year and local time
1472
+ # (but sometimes year since 2000 and UTC time in same video!)
1473
+ require Time::Local;
1474
+ my $time = Image::ExifTool::TimeLocal($sec,$min,$hr,$day,$mon-1,$yr-1900);
1475
+ ($sec,$min,$hr,$day,$mon,$yr) = gmtime($time);
1476
+ $yr += 1900;
1477
+ ++$mon;
1478
+ $et->WarnOnce('Converting GPSDateTime to UTC based on local time zone',1);
1479
+ }
1464
1480
  SetByteOrder('II');
1465
1481
  $lat = GetFloat($dataPt, 0x2c);
1466
1482
  $lon = GetFloat($dataPt, 0x30);
1467
1483
  $spd = GetFloat($dataPt, 0x34) * $knotsToKph; # (convert knots to km/h)
1468
1484
  $trk = GetFloat($dataPt, 0x38);
1485
+ # (may be all zeros or int16u counting from 1 to 6 if not valid)
1486
+ my $tmp = substr($$dataPt, 60, 12);
1487
+ 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") {
1488
+ @acc = unpack('V3', $tmp);
1489
+ map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
1490
+ }
1469
1491
  SetByteOrder('MM');
1492
+ $debug and $et->FoundTag(GPSType => '1C');
1470
1493
 
1471
1494
  } elsif ($$dataPt =~ /^.{21}\0\0\0A([NS])([EW])/s) {
1472
1495
 
@@ -1495,6 +1518,7 @@ sub ProcessFreeGPS($$$)
1495
1518
  $acc[1] = GetFloat($dataPt, 0x30);
1496
1519
  $acc[2] = GetFloat($dataPt, 0x34);
1497
1520
  SetByteOrder('MM');
1521
+ $debug and $et->FoundTag(GPSType => '1D');
1498
1522
 
1499
1523
  } elsif ($$dataPt =~ /^.{60}A\0{3}.{4}([NS])\0{3}.{4}([EW])\0{3}/s) {
1500
1524
 
@@ -1515,6 +1539,7 @@ sub ProcessFreeGPS($$$)
1515
1539
  $trk = GetFloat($dataPt, 0x54) + 180; # (why is this off by 180?)
1516
1540
  $trk -= 360 if $trk >= 360;
1517
1541
  SetByteOrder('MM');
1542
+ $debug and $et->FoundTag(GPSType => '1E');
1518
1543
 
1519
1544
  } elsif ($$dataPt =~ /^.{60}4W`b]S</s and length($$dataPt) >= 140) {
1520
1545
 
@@ -1532,6 +1557,7 @@ sub ProcessFreeGPS($$$)
1532
1557
  $yr += ($yr >= 70 ? 1900 : 2000);
1533
1558
  $spd = $9 * $knotsToKph if length $9;
1534
1559
  $trk = $10 if length $10;
1560
+ $debug and $et->FoundTag(GPSType => '1F');
1535
1561
 
1536
1562
  } elsif ($$dataPt =~ /^.{64}[\x01-\x0c]\0{3}[\x01-\x1f]\0{3}A[NS][EW]\0{5}/s) {
1537
1563
 
@@ -1575,6 +1601,7 @@ sub ProcessFreeGPS($$$)
1575
1601
 
1576
1602
  SetByteOrder('MM');
1577
1603
  #my $serialNum = substr($$dataPt, 0x68, 20);
1604
+ $debug and $et->FoundTag(GPSType => '1G');
1578
1605
 
1579
1606
  } elsif ($$dataPt =~ /^.{12}\xac\0\0\0.{44}(.{72})/s) {
1580
1607
 
@@ -1597,6 +1624,7 @@ sub ProcessFreeGPS($$$)
1597
1624
  # bytes 7-12 are the timestamp in ASCII HHMMSS after xor-ing with 0x70
1598
1625
  substr($time,7,6) = pack 'C*', map { $_ ^= 0x70 } unpack 'C*', substr($time,7,6);
1599
1626
  # (other values are currently unknown)
1627
+ $debug and $et->FoundTag(GPSType => '1H');
1600
1628
 
1601
1629
  } elsif ($$dataPt =~ /^.{64}A([NS])([EW])\0/s) {
1602
1630
 
@@ -1622,6 +1650,7 @@ sub ProcessFreeGPS($$$)
1622
1650
  $trk = GetFloat($dataPt, 0x68);
1623
1651
  $alt = GetFloat($dataPt, 0x6c);
1624
1652
  SetByteOrder('MM');
1653
+ $debug and $et->FoundTag(GPSType => '1I');
1625
1654
 
1626
1655
  } else {
1627
1656
 
@@ -1658,6 +1687,7 @@ sub ProcessFreeGPS($$$)
1658
1687
  $yr += 2000 if $yr < 2000;
1659
1688
  $spd *= $knotsToKph; # convert speed to km/h
1660
1689
  # ($trk is not confirmed; may be GPSImageDirection, ref PH)
1690
+ $debug and $et->FoundTag(GPSType => '1J');
1661
1691
  }
1662
1692
  #
1663
1693
  # save tag values extracted by above code
@@ -1811,6 +1841,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1811
1841
  }
1812
1842
  # save position of most recent record (needed when parsing the next freeGPS block)
1813
1843
  $$et{FreeGPS2}{RecentRecPos} = $lastRecPos;
1844
+ $debug and $et->FoundTag(GPSType => '2A');
1814
1845
  return 1;
1815
1846
 
1816
1847
  } elsif ($$dataPt =~ /^.{60}A\0.{10}([NS])\0.{14}([EW])\0/s) {
@@ -1842,6 +1873,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1842
1873
  $lon = GetDouble($dataPt, 0x50);
1843
1874
  $spd = GetDouble($dataPt, 0x60) * $knotsToKph;
1844
1875
  $trk = GetDouble($dataPt, 0x68);
1876
+ $debug and $et->FoundTag(GPSType => '2B');
1845
1877
 
1846
1878
  } elsif ($$dataPt =~ /^.{72}A([NS])([EW])/s) {
1847
1879
 
@@ -1878,6 +1910,8 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1878
1910
  $lon = abs Get32s($dataPt, 0x50) / 1e7;
1879
1911
  $spd = Get32s($dataPt, 0x54) / 100 * $mpsToKph;
1880
1912
  $alt = GetFloat($dataPt, 0x58) / 1000; # (NC)
1913
+ $debug and $et->FoundTag(GPSType => '2C');
1914
+
1881
1915
  } else {
1882
1916
  # Type 3 (ref 2)
1883
1917
  # (no sample with this format)
@@ -1885,6 +1919,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1885
1919
  $lon = GetFloat($dataPt, 0x50);
1886
1920
  $spd = GetFloat($dataPt, 0x54) * $knotsToKph;
1887
1921
  $trk = GetFloat($dataPt, 0x58);
1922
+ $debug and $et->FoundTag(GPSType => '2D');
1888
1923
  }
1889
1924
 
1890
1925
  } elsif ($$dataPt =~ /^.{60}A\0.{6}([NS])\0.{6}([EW])\0/s and $dirLen >= 112) {
@@ -1905,6 +1940,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1905
1940
  $lon = GetFloat($dataPt, 0x48);
1906
1941
  $spd = GetFloat($dataPt, 0x50);
1907
1942
  $trk = GetFloat($dataPt, 0x54);
1943
+ $debug and $et->FoundTag(GPSType => '2E');
1908
1944
 
1909
1945
  } elsif ($$dataPt =~ /^.{16}A([NS])([EW])\0/s) {
1910
1946
 
@@ -1925,6 +1961,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1925
1961
  $et->HandleTag($tagTbl, GPSTrack => $trk);
1926
1962
  $et->HandleTag($tagTbl, Accelerometer => "@acc");
1927
1963
  }
1964
+ $debug and $et->FoundTag(GPSType => '2F');
1928
1965
  return 1;
1929
1966
 
1930
1967
  } else {
@@ -1971,6 +2008,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1971
2008
  $et->HandleTag($tagTbl, GPSTrack => $trk);
1972
2009
  last if $pos += 0x20 > length($$dataPt) - 0x1e;
1973
2010
  }
2011
+ $debug and $et->FoundTag(GPSType => '2G');
1974
2012
  return $$et{DOC_NUM} ? 1 : 0; # return 0 if nothing extracted
1975
2013
  }
1976
2014
  #
@@ -2205,6 +2243,7 @@ sub Process_3gf($$$)
2205
2243
 
2206
2244
  #------------------------------------------------------------------------------
2207
2245
  # Process DuDuBell M1 dashcam / VSYS M6L 'gps0' atom (ref PH)
2246
+ # (Lamax S9 dual dashcam also uses 'gps0' atom, but encrypted text format)
2208
2247
  # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
2209
2248
  # Returns: 1 on success
2210
2249
  sub Process_gps0($$$)
@@ -2212,14 +2251,28 @@ sub Process_gps0($$$)
2212
2251
  my ($et, $dirInfo, $tagTbl) = @_;
2213
2252
  my $dataPt = $$dirInfo{DataPt};
2214
2253
  my $dirLen = $$dirInfo{DirLen};
2215
- my $recLen = 32; # 32-byte record length
2254
+ my ($pos, $recLen);
2216
2255
  $et->VerboseDir('gps0', undef, $dirLen);
2256
+ # check for encrypted format written by Lamax S9 dual dashcam
2257
+ # (similar to Ambarella A12, but in multiple 311-byte records)
2258
+ if ($$dataPt =~ /^.{2}\xf2\xe1\xf0\xeeTT\x98/s) {
2259
+ $recLen = 311;
2260
+ for ($pos=0; $pos+$recLen<=$dirLen; $pos+=$recLen) {
2261
+ my $dat = substr($$dataPt, $pos, $recLen);
2262
+ last unless $dat =~ /^.{2}\xf2\xe1\xf0\xeeTT\x98/s;
2263
+ $$et{DOC_NUM} = ++$$et{DOC_COUNT};
2264
+ Process_text($et, \$dat, $tagTbl);
2265
+ $pos += $recLen;
2266
+ }
2267
+ delete $$et{DOC_NUM};
2268
+ return 1;
2269
+ }
2270
+ $recLen = 32; # 32-byte record length
2217
2271
  SetByteOrder('II');
2218
2272
  if ($dirLen > $recLen and not $et->Options('ExtractEmbedded')) {
2219
2273
  $dirLen = $recLen;
2220
2274
  EEWarn($et);
2221
2275
  }
2222
- my $pos;
2223
2276
  for ($pos=0; $pos+$recLen<=$dirLen; $pos+=$recLen) {
2224
2277
  $$et{DOC_NUM} = ++$$et{DOC_COUNT};
2225
2278
  # lat/long are in DDDMM.MMMM format
@@ -2740,6 +2793,34 @@ sub ProcessInsta360($;$)
2740
2793
  return 1;
2741
2794
  }
2742
2795
 
2796
+ #------------------------------------------------------------------------------
2797
+ # Process CAMM metadata (ref PH)
2798
+ # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
2799
+ # Returns: 1 on success
2800
+ sub ProcessCAMM($$$)
2801
+ {
2802
+ my ($et, $dirInfo, $tagTbl) = @_;
2803
+ my $dataPt = $$dirInfo{DataPt};
2804
+ my $pos = $$dirInfo{DirStart} || 0;
2805
+ my $end = $pos + ($$dirInfo{DirLen} || length($$dataPt) - $pos);
2806
+ # camm record size for each type, including 4-byte header
2807
+ my %size = ( 1 => 12, 2 => 16, 3 => 16, 4 => 16, 5 => 28, 6 => 60, 7 => 16 );
2808
+ my $rtnVal = 0;
2809
+ while ($pos + 4 < $end) {
2810
+ my $type = Get16u($dataPt, $pos + 2);
2811
+ my $size = $size{$type} or $et->WarnOnce("Unknown camm record type $type"), last;
2812
+ $pos + $size > $end and $et->WarnOnce("Truncated camm record $type"), last;
2813
+ my $tagTbl = GetTagTable("Image::ExifTool::QuickTime::camm$type");
2814
+ $$dirInfo{DirStart} = $pos;
2815
+ $$dirInfo{DirLen} = $size;
2816
+ $et->ProcessBinaryData($dirInfo, $tagTbl) and $rtnVal = 1;
2817
+ # not sure if this is according to specification, but I have seen multiple
2818
+ # camm records all in a single sample, so step forward to process the next one
2819
+ $pos += $size;
2820
+ }
2821
+ return $rtnVal;
2822
+ }
2823
+
2743
2824
  #------------------------------------------------------------------------------
2744
2825
  # Process Garmin GPS 'uuid' atom (ref PH)
2745
2826
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
@@ -2939,7 +3020,7 @@ information like GPS tracks from MOV, MP4 and INSV media data.
2939
3020
 
2940
3021
  =head1 AUTHOR
2941
3022
 
2942
- Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
3023
+ Copyright 2003-2023, Phil Harvey (philharvey66 at gmail.com)
2943
3024
 
2944
3025
  This library is free software; you can redistribute it and/or modify it
2945
3026
  under the same terms as Perl itself.
@@ -641,7 +641,8 @@ numerical, and generated automatically otherwise.
641
641
  expression, a code reference or a list reference. In this
642
642
  expression, $self, $val and $tag may be used as with
643
643
  ValueConv, but if ValueConv was defined then $val is the
644
- ValueConv value instead of the Raw value. The returned value
644
+ ValueConv value instead of the Raw value. Composite tags
645
+ may also use the @val, @prt and @raw lists. The returned value
645
646
  should always be defined. Note that the print conversion is
646
647
  only done if the PrintConv option is enabled (which it is by
647
648
  default), and if the result of the ValueConv is not a scalar
@@ -967,6 +968,10 @@ numerical, and generated automatically otherwise.
967
968
  OtherLang : [reserved] Used internally by QuickTime module to store a list
968
969
  of tag ID's for alternate-language tags based on this one.
969
970
 
971
+ ParentTagInfo : [reserved] Used internally to store a reference to the tag
972
+ information hash of the parent structure for flattened
973
+ structure tags.
974
+
970
975
  RootTagInfo : [reserved] Used internally to store a reference to the tag
971
976
  information hash of the top-level structure for flattened
972
977
  structure tags.
@@ -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.