exiftool-vendored.exe 12.99.0 → 13.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/bin/exiftool.exe +0 -0
  2. package/bin/exiftool_files/exiftool.pl +183 -70
  3. package/bin/exiftool_files/lib/File/RandomAccess.pm +1 -1
  4. package/bin/exiftool_files/lib/File/RandomAccess.pod +2 -2
  5. package/bin/exiftool_files/lib/Image/ExifTool/AAC.pm +1 -1
  6. package/bin/exiftool_files/lib/Image/ExifTool/AES.pm +1 -1
  7. package/bin/exiftool_files/lib/Image/ExifTool/AFCP.pm +6 -6
  8. package/bin/exiftool_files/lib/Image/ExifTool/AIFF.pm +2 -2
  9. package/bin/exiftool_files/lib/Image/ExifTool/APE.pm +2 -2
  10. package/bin/exiftool_files/lib/Image/ExifTool/APP12.pm +1 -1
  11. package/bin/exiftool_files/lib/Image/ExifTool/ASF.pm +2 -2
  12. package/bin/exiftool_files/lib/Image/ExifTool/Apple.pm +11 -9
  13. package/bin/exiftool_files/lib/Image/ExifTool/Audible.pm +1 -1
  14. package/bin/exiftool_files/lib/Image/ExifTool/BMP.pm +1 -1
  15. package/bin/exiftool_files/lib/Image/ExifTool/BPG.pm +1 -1
  16. package/bin/exiftool_files/lib/Image/ExifTool/BZZ.pm +1 -1
  17. package/bin/exiftool_files/lib/Image/ExifTool/BigTIFF.pm +1 -1
  18. package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +36 -22
  19. package/bin/exiftool_files/lib/Image/ExifTool/CBOR.pm +5 -2
  20. package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +66 -27
  21. package/bin/exiftool_files/lib/Image/ExifTool/CanonCustom.pm +1 -1
  22. package/bin/exiftool_files/lib/Image/ExifTool/CanonRaw.pm +1 -1
  23. package/bin/exiftool_files/lib/Image/ExifTool/CanonVRD.pm +1 -1
  24. package/bin/exiftool_files/lib/Image/ExifTool/CaptureOne.pm +1 -1
  25. package/bin/exiftool_files/lib/Image/ExifTool/Casio.pm +1 -1
  26. package/bin/exiftool_files/lib/Image/ExifTool/Charset.pm +1 -1
  27. package/bin/exiftool_files/lib/Image/ExifTool/DICOM.pm +1 -1
  28. package/bin/exiftool_files/lib/Image/ExifTool/DJI.pm +196 -30
  29. package/bin/exiftool_files/lib/Image/ExifTool/DNG.pm +1 -1
  30. package/bin/exiftool_files/lib/Image/ExifTool/DPX.pm +1 -1
  31. package/bin/exiftool_files/lib/Image/ExifTool/DV.pm +1 -1
  32. package/bin/exiftool_files/lib/Image/ExifTool/DarwinCore.pm +1 -1
  33. package/bin/exiftool_files/lib/Image/ExifTool/DjVu.pm +1 -1
  34. package/bin/exiftool_files/lib/Image/ExifTool/EXE.pm +138 -33
  35. package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +30 -17
  36. package/bin/exiftool_files/lib/Image/ExifTool/FITS.pm +3 -3
  37. package/bin/exiftool_files/lib/Image/ExifTool/FLAC.pm +1 -1
  38. package/bin/exiftool_files/lib/Image/ExifTool/FLIF.pm +3 -3
  39. package/bin/exiftool_files/lib/Image/ExifTool/FLIR.pm +1 -1
  40. package/bin/exiftool_files/lib/Image/ExifTool/Fixup.pm +1 -1
  41. package/bin/exiftool_files/lib/Image/ExifTool/Flash.pm +1 -1
  42. package/bin/exiftool_files/lib/Image/ExifTool/FlashPix.pm +17 -21
  43. package/bin/exiftool_files/lib/Image/ExifTool/Font.pm +2 -2
  44. package/bin/exiftool_files/lib/Image/ExifTool/FotoStation.pm +1 -1
  45. package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +1 -1
  46. package/bin/exiftool_files/lib/Image/ExifTool/GE.pm +1 -1
  47. package/bin/exiftool_files/lib/Image/ExifTool/GIF.pm +144 -93
  48. package/bin/exiftool_files/lib/Image/ExifTool/GIMP.pm +1 -1
  49. package/bin/exiftool_files/lib/Image/ExifTool/GM.pm +1 -1
  50. package/bin/exiftool_files/lib/Image/ExifTool/GPS.pm +34 -30
  51. package/bin/exiftool_files/lib/Image/ExifTool/GeoTiff.pm +1 -1
  52. package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.dat +0 -0
  53. package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.pm +19 -9
  54. package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +49 -14
  55. package/bin/exiftool_files/lib/Image/ExifTool/GoPro.pm +120 -8
  56. package/bin/exiftool_files/lib/Image/ExifTool/H264.pm +1 -1
  57. package/bin/exiftool_files/lib/Image/ExifTool/HP.pm +2 -2
  58. package/bin/exiftool_files/lib/Image/ExifTool/HTML.pm +1 -1
  59. package/bin/exiftool_files/lib/Image/ExifTool/HtmlDump.pm +1 -1
  60. package/bin/exiftool_files/lib/Image/ExifTool/ICC_Profile.pm +81 -2
  61. package/bin/exiftool_files/lib/Image/ExifTool/ICO.pm +1 -1
  62. package/bin/exiftool_files/lib/Image/ExifTool/ID3.pm +8 -8
  63. package/bin/exiftool_files/lib/Image/ExifTool/IPTC.pm +10 -7
  64. package/bin/exiftool_files/lib/Image/ExifTool/ISO.pm +1 -1
  65. package/bin/exiftool_files/lib/Image/ExifTool/ITC.pm +1 -1
  66. package/bin/exiftool_files/lib/Image/ExifTool/Import.pm +5 -4
  67. package/bin/exiftool_files/lib/Image/ExifTool/InDesign.pm +2 -2
  68. package/bin/exiftool_files/lib/Image/ExifTool/InfiRay.pm +1 -1
  69. package/bin/exiftool_files/lib/Image/ExifTool/JPEG.pm +32 -5
  70. package/bin/exiftool_files/lib/Image/ExifTool/JPEGDigest.pm +1 -1
  71. package/bin/exiftool_files/lib/Image/ExifTool/JSON.pm +1 -1
  72. package/bin/exiftool_files/lib/Image/ExifTool/JVC.pm +1 -1
  73. package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +10 -9
  74. package/bin/exiftool_files/lib/Image/ExifTool/Kodak.pm +1 -1
  75. package/bin/exiftool_files/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
  76. package/bin/exiftool_files/lib/Image/ExifTool/LIF.pm +1 -1
  77. package/bin/exiftool_files/lib/Image/ExifTool/LNK.pm +2 -2
  78. package/bin/exiftool_files/lib/Image/ExifTool/Lang/cs.pm +1 -1
  79. package/bin/exiftool_files/lib/Image/ExifTool/Lang/de.pm +1 -1
  80. package/bin/exiftool_files/lib/Image/ExifTool/Lang/en_ca.pm +1 -1
  81. package/bin/exiftool_files/lib/Image/ExifTool/Lang/en_gb.pm +1 -1
  82. package/bin/exiftool_files/lib/Image/ExifTool/Lang/es.pm +1 -1
  83. package/bin/exiftool_files/lib/Image/ExifTool/Lang/fi.pm +1 -1
  84. package/bin/exiftool_files/lib/Image/ExifTool/Lang/fr.pm +1 -1
  85. package/bin/exiftool_files/lib/Image/ExifTool/Lang/it.pm +1 -1
  86. package/bin/exiftool_files/lib/Image/ExifTool/Lang/ja.pm +1 -1
  87. package/bin/exiftool_files/lib/Image/ExifTool/Lang/ko.pm +1 -1
  88. package/bin/exiftool_files/lib/Image/ExifTool/Lang/nl.pm +1 -1
  89. package/bin/exiftool_files/lib/Image/ExifTool/Lang/pl.pm +1 -1
  90. package/bin/exiftool_files/lib/Image/ExifTool/Lang/ru.pm +1 -1
  91. package/bin/exiftool_files/lib/Image/ExifTool/Lang/sk.pm +1 -1
  92. package/bin/exiftool_files/lib/Image/ExifTool/Lang/sv.pm +1 -1
  93. package/bin/exiftool_files/lib/Image/ExifTool/Lang/tr.pm +1 -1
  94. package/bin/exiftool_files/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
  95. package/bin/exiftool_files/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
  96. package/bin/exiftool_files/lib/Image/ExifTool/Leaf.pm +1 -1
  97. package/bin/exiftool_files/lib/Image/ExifTool/LigoGPS.pm +409 -0
  98. package/bin/exiftool_files/lib/Image/ExifTool/Lytro.pm +1 -1
  99. package/bin/exiftool_files/lib/Image/ExifTool/M2TS.pm +58 -19
  100. package/bin/exiftool_files/lib/Image/ExifTool/MIE.pm +15 -6
  101. package/bin/exiftool_files/lib/Image/ExifTool/MIEUnits.pod +1 -1
  102. package/bin/exiftool_files/lib/Image/ExifTool/MIFF.pm +1 -1
  103. package/bin/exiftool_files/lib/Image/ExifTool/MISB.pm +1 -1
  104. package/bin/exiftool_files/lib/Image/ExifTool/MNG.pm +1 -1
  105. package/bin/exiftool_files/lib/Image/ExifTool/MOI.pm +1 -1
  106. package/bin/exiftool_files/lib/Image/ExifTool/MPC.pm +1 -1
  107. package/bin/exiftool_files/lib/Image/ExifTool/MPEG.pm +1 -1
  108. package/bin/exiftool_files/lib/Image/ExifTool/MPF.pm +1 -1
  109. package/bin/exiftool_files/lib/Image/ExifTool/MRC.pm +1 -1
  110. package/bin/exiftool_files/lib/Image/ExifTool/MWG.pm +1 -1
  111. package/bin/exiftool_files/lib/Image/ExifTool/MXF.pm +3 -3
  112. package/bin/exiftool_files/lib/Image/ExifTool/MacOS.pm +3 -2
  113. package/bin/exiftool_files/lib/Image/ExifTool/MakerNotes.pm +1 -1
  114. package/bin/exiftool_files/lib/Image/ExifTool/Matroska.pm +22 -6
  115. package/bin/exiftool_files/lib/Image/ExifTool/Microsoft.pm +2 -2
  116. package/bin/exiftool_files/lib/Image/ExifTool/Minolta.pm +1 -1
  117. package/bin/exiftool_files/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
  118. package/bin/exiftool_files/lib/Image/ExifTool/Motorola.pm +1 -1
  119. package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +495 -39
  120. package/bin/exiftool_files/lib/Image/ExifTool/NikonCapture.pm +1 -1
  121. package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +2 -2
  122. package/bin/exiftool_files/lib/Image/ExifTool/NikonSettings.pm +1 -1
  123. package/bin/exiftool_files/lib/Image/ExifTool/Nintendo.pm +1 -1
  124. package/bin/exiftool_files/lib/Image/ExifTool/OOXML.pm +8 -8
  125. package/bin/exiftool_files/lib/Image/ExifTool/Ogg.pm +1 -1
  126. package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +1 -1
  127. package/bin/exiftool_files/lib/Image/ExifTool/OpenEXR.pm +1 -1
  128. package/bin/exiftool_files/lib/Image/ExifTool/Opus.pm +1 -1
  129. package/bin/exiftool_files/lib/Image/ExifTool/Other.pm +1 -1
  130. package/bin/exiftool_files/lib/Image/ExifTool/PCX.pm +1 -1
  131. package/bin/exiftool_files/lib/Image/ExifTool/PDF.pm +49 -18
  132. package/bin/exiftool_files/lib/Image/ExifTool/PGF.pm +1 -1
  133. package/bin/exiftool_files/lib/Image/ExifTool/PICT.pm +1 -1
  134. package/bin/exiftool_files/lib/Image/ExifTool/PLIST.pm +4 -4
  135. package/bin/exiftool_files/lib/Image/ExifTool/PLUS.pm +1 -1
  136. package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +20 -8
  137. package/bin/exiftool_files/lib/Image/ExifTool/PPM.pm +12 -3
  138. package/bin/exiftool_files/lib/Image/ExifTool/PSP.pm +1 -1
  139. package/bin/exiftool_files/lib/Image/ExifTool/Palm.pm +1 -1
  140. package/bin/exiftool_files/lib/Image/ExifTool/Panasonic.pm +27 -3
  141. package/bin/exiftool_files/lib/Image/ExifTool/PanasonicRaw.pm +1 -1
  142. package/bin/exiftool_files/lib/Image/ExifTool/Parrot.pm +1 -1
  143. package/bin/exiftool_files/lib/Image/ExifTool/Pentax.pm +1 -1
  144. package/bin/exiftool_files/lib/Image/ExifTool/PhaseOne.pm +6 -5
  145. package/bin/exiftool_files/lib/Image/ExifTool/PhotoCD.pm +1 -1
  146. package/bin/exiftool_files/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
  147. package/bin/exiftool_files/lib/Image/ExifTool/Photoshop.pm +65 -4
  148. package/bin/exiftool_files/lib/Image/ExifTool/PostScript.pm +1 -1
  149. package/bin/exiftool_files/lib/Image/ExifTool/PrintIM.pm +1 -1
  150. package/bin/exiftool_files/lib/Image/ExifTool/Protobuf.pm +270 -0
  151. package/bin/exiftool_files/lib/Image/ExifTool/Qualcomm.pm +1 -1
  152. package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +326 -88
  153. package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +266 -200
  154. package/bin/exiftool_files/lib/Image/ExifTool/README +12 -2
  155. package/bin/exiftool_files/lib/Image/ExifTool/RIFF.pm +21 -6
  156. package/bin/exiftool_files/lib/Image/ExifTool/RSRC.pm +1 -1
  157. package/bin/exiftool_files/lib/Image/ExifTool/RTF.pm +2 -2
  158. package/bin/exiftool_files/lib/Image/ExifTool/Radiance.pm +1 -1
  159. package/bin/exiftool_files/lib/Image/ExifTool/Rawzor.pm +1 -1
  160. package/bin/exiftool_files/lib/Image/ExifTool/Real.pm +1 -1
  161. package/bin/exiftool_files/lib/Image/ExifTool/Reconyx.pm +1 -1
  162. package/bin/exiftool_files/lib/Image/ExifTool/Red.pm +1 -1
  163. package/bin/exiftool_files/lib/Image/ExifTool/Ricoh.pm +4 -4
  164. package/bin/exiftool_files/lib/Image/ExifTool/Samsung.pm +2 -2
  165. package/bin/exiftool_files/lib/Image/ExifTool/Sanyo.pm +1 -1
  166. package/bin/exiftool_files/lib/Image/ExifTool/Scalado.pm +1 -1
  167. package/bin/exiftool_files/lib/Image/ExifTool/Shift.pl +1 -1
  168. package/bin/exiftool_files/lib/Image/ExifTool/Shortcuts.pm +1 -1
  169. package/bin/exiftool_files/lib/Image/ExifTool/Sigma.pm +1 -1
  170. package/bin/exiftool_files/lib/Image/ExifTool/SigmaRaw.pm +1 -1
  171. package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +5 -4
  172. package/bin/exiftool_files/lib/Image/ExifTool/SonyIDC.pm +1 -1
  173. package/bin/exiftool_files/lib/Image/ExifTool/Stim.pm +1 -1
  174. package/bin/exiftool_files/lib/Image/ExifTool/TagInfoXML.pm +6 -5
  175. package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +7025 -6967
  176. package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +477 -46
  177. package/bin/exiftool_files/lib/Image/ExifTool/Text.pm +4 -3
  178. package/bin/exiftool_files/lib/Image/ExifTool/Theora.pm +1 -1
  179. package/bin/exiftool_files/lib/Image/ExifTool/Torrent.pm +3 -3
  180. package/bin/exiftool_files/lib/Image/ExifTool/Unknown.pm +1 -1
  181. package/bin/exiftool_files/lib/Image/ExifTool/VCard.pm +3 -3
  182. package/bin/exiftool_files/lib/Image/ExifTool/Validate.pm +6 -6
  183. package/bin/exiftool_files/lib/Image/ExifTool/Vivo.pm +124 -0
  184. package/bin/exiftool_files/lib/Image/ExifTool/Vorbis.pm +1 -1
  185. package/bin/exiftool_files/lib/Image/ExifTool/WPG.pm +1 -1
  186. package/bin/exiftool_files/lib/Image/ExifTool/WTV.pm +1 -1
  187. package/bin/exiftool_files/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
  188. package/bin/exiftool_files/lib/Image/ExifTool/WriteExif.pl +3 -3
  189. package/bin/exiftool_files/lib/Image/ExifTool/WriteIPTC.pl +1 -1
  190. package/bin/exiftool_files/lib/Image/ExifTool/WritePDF.pl +1 -1
  191. package/bin/exiftool_files/lib/Image/ExifTool/WritePNG.pl +1 -1
  192. package/bin/exiftool_files/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
  193. package/bin/exiftool_files/lib/Image/ExifTool/WritePostScript.pl +1 -1
  194. package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +166 -79
  195. package/bin/exiftool_files/lib/Image/ExifTool/WriteRIFF.pl +17 -6
  196. package/bin/exiftool_files/lib/Image/ExifTool/WriteXMP.pl +3 -3
  197. package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +89 -96
  198. package/bin/exiftool_files/lib/Image/ExifTool/XISF.pm +1 -1
  199. package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +39 -14
  200. package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +103 -1
  201. package/bin/exiftool_files/lib/Image/ExifTool/XMPStruct.pl +2 -3
  202. package/bin/exiftool_files/lib/Image/ExifTool/ZIP.pm +2 -2
  203. package/bin/exiftool_files/lib/Image/ExifTool/ZISRAW.pm +1 -1
  204. package/bin/exiftool_files/lib/Image/ExifTool/iWork.pm +1 -1
  205. package/bin/exiftool_files/lib/Image/ExifTool.pm +338 -166
  206. package/bin/exiftool_files/lib/Image/ExifTool.pod +119 -73
  207. package/bin/exiftool_files/readme_windows.txt +8 -13
  208. package/bin/exiftool_files/windows_exiftool.txt +102 -53
  209. package/package.json +11 -11
@@ -5,21 +5,29 @@
5
5
  #
6
6
  # Revisions: 2016-07-25 - P. Harvey Created
7
7
  # 2017-06-23 - PH Added XMP tags
8
+ # 2024-12-04 - PH Added protobuf tags
8
9
  #------------------------------------------------------------------------------
9
10
 
10
11
  package Image::ExifTool::DJI;
11
12
 
12
13
  use strict;
13
- use vars qw($VERSION);
14
+ use vars qw($VERSION %knownProtocol);
14
15
  use Image::ExifTool qw(:DataAccess :Utils);
15
16
  use Image::ExifTool::Exif;
16
17
  use Image::ExifTool::XMP;
17
18
  use Image::ExifTool::GPS;
19
+ use Image::ExifTool::Protobuf;
18
20
 
19
- $VERSION = '1.09';
21
+ $VERSION = '1.12';
20
22
 
21
23
  sub ProcessDJIInfo($$$);
22
- sub Process_djmd($$$);
24
+
25
+ %knownProtocol = (
26
+ 'dvtm_ac203.proto' => 1, # Osmo Action 4
27
+ 'dvtm_ac204.proto' => 1, # Osmo Action 5
28
+ 'dvtm_AVATA2.proto' => 1, # Avanta 2
29
+ 'dvtm_wm265e.proto' => 1, # Mavic 3
30
+ );
23
31
 
24
32
  my %convFloat2 = (
25
33
  PrintConv => 'sprintf("%+.2f", $val)',
@@ -187,33 +195,191 @@ my %convFloat2 = (
187
195
  },
188
196
  );
189
197
 
190
- # TODO - eventually add ability to decode this?
191
- %Image::ExifTool::DJI::djmd = (
192
- PROCESS_PROC => \&Process_djmd,
198
+ # metadata in protobuf format (djmd and dbgi meta types, ref PH)
199
+ %Image::ExifTool::DJI::Protobuf = (
200
+ GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Camera' },
201
+ TAG_PREFIX => '',
202
+ PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
203
+ NOTES => q{
204
+ Tags found in protobuf-format DJI djmd and dbgi timed metadata. The known
205
+ tags listed below are extracted by default, but unknown djmd tags may be
206
+ extracted as well by setting the Unknown option to 1, or 2 to also extract
207
+ unknown dbgi debug tags. Tag ID's are composed of the corresponding .proto
208
+ file name combined with the hierarchical protobuf field numbers.
209
+
210
+ ExifTool currently extracts timed GPS plus a few other tags from DJI devices
211
+ which use the following protocols: dvtm_AVATA2.proto (Avanta 2),
212
+ dvtm_ac203.proto (Osmo Action 4), dvtm_ac204.proto (Osmo Action 5) and
213
+ dvtm_wm265e.proto (Mavic 3).
214
+
215
+ Note that with the protobuf format, numerical tags missing from the output
216
+ for a given protocol should be considered to have the default value of 0.
217
+ },
218
+ Protocol => {
219
+ RawConv => q{
220
+ unless ($Image::ExifTool::DJI::knownProtocol{$val}) {
221
+ $self->Warn("Unknown protocol $val (please submit sample for testing)");
222
+ }
223
+ return $val;
224
+ },
225
+ },
226
+ #
227
+ # Osmo Action 4
228
+ #
229
+ 'dvtm_ac203_1-1-5' => 'SerialNumber', # (NC)
230
+ # dvtm_ac203_1-1-6 - some version number
231
+ 'dvtm_ac203_1-1-10' => 'Model',
232
+ 'dvtm_ac203_2-3' => {
233
+ Name => 'FrameInfo',
234
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
235
+ },
236
+ # dvtm_ac203_3-4-1-4 - model code?
237
+ 'dvtm_ac203_3-4-2-1' => {
238
+ Name => 'GPSInfo',
239
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
240
+ },
241
+ 'dvtm_ac203_3-4-2-2' => {
242
+ Name => 'GPSAltitude',
243
+ Groups => { 2 => 'Location' },
244
+ Format => 'unsigned',
245
+ ValueConv => '$val / 1000',
246
+ },
247
+ 'dvtm_ac203_3-4-2-6-1' => {
248
+ Name => 'GPSDateTime',
249
+ Format => 'string',
250
+ Groups => { 2 => 'Time' },
251
+ RawConv => '$$self{GPSDateTime} = $val',
252
+ ValueConv => '$val =~ tr/-/:/; $val',
253
+ PrintConv => '$self->ConvertDateTime($val)',
254
+ },
255
+ #
256
+ # Osmo Action 5
257
+ #
258
+ 'dvtm_ac204_1-1-5' => 'SerialNumber', # (NC)
259
+ # dvtm_ac204_1-1-6 - some version number
260
+ 'dvtm_ac204_1-1-10' => 'Model',
261
+ 'dvtm_ac204_2-3' => {
262
+ Name => 'FrameInfo',
263
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
264
+ },
265
+ # dvtm_ac204_3-4-1-4 - model code?
266
+ 'dvtm_ac204_3-4-2-1' => {
267
+ Name => 'GPSInfo',
268
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
269
+ },
270
+ # dvtm_ac204_3-2-4-1 - shutter speed? (rational)
271
+ 'dvtm_ac204_3-4-2-2' => {
272
+ Name => 'GPSAltitude',
273
+ Groups => { 2 => 'Location' },
274
+ Format => 'unsigned',
275
+ ValueConv => '$val / 1000',
276
+ },
277
+ 'dvtm_ac204_3-4-2-6-1' => {
278
+ Name => 'GPSDateTime',
279
+ Format => 'string',
280
+ Groups => { 2 => 'Time' },
281
+ RawConv => '$$self{GPSDateTime} = $val',
282
+ ValueConv => '$val =~ tr/-/:/; $val',
283
+ PrintConv => '$self->ConvertDateTime($val)',
284
+ },
285
+ #
286
+ # Avanta 2
287
+ #
288
+ # dvtm_AVATA2_1-1-2 - some version number
289
+ # dvtm_AVATA2_1-1-3 - some version number
290
+ 'dvtm_AVATA2_1-1-5' => 'SerialNumber', # (NC)
291
+ 'dvtm_AVATA2_1-1-10' => 'Model',
292
+ # dvtm_AVATA2_2-2-1-4 - model code?
293
+ 'dvtm_AVATA2_2-2-3-1' => 'SerialNumber2', # (NC)
294
+ 'dvtm_AVATA2_2-3' => {
295
+ Name => 'FrameInfo',
296
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
297
+ },
298
+ # dvtm_AVATA2_3-1-1 - frame number (starting at 1)
299
+ 'dvtm_AVATA2_3-1-2' => { # (also 3-2-1-6 and 3-4-1-6)
300
+ Name => 'TimeStamp',
301
+ Groups => { 2 => 'Time' },
302
+ Format => 'unsigned',
303
+ # milliseconds, but I don't know what the zero is
304
+ ValueConv => '$val / 1e6',
305
+ },
306
+ # dvtm_AVATA2_3-2-1-4 - model code?
307
+ # dvtm_AVATA2_3-2-1-5 - frame rate?
308
+ # dvtm_AVATA2_3-2-4-1 - shutter speed? (rational)
309
+ # dvtm_AVATA2_3-4-1-4 - model code?
310
+ # dvtm_AVATA2_3-4-3-1,2,3 - YPR? (int64s)
311
+ 'dvtm_AVATA2_3-4-4-1' => {
312
+ Name => 'GPSInfo',
313
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
314
+ },
315
+ #
316
+ # Mavic 3
317
+ #
318
+ 'dvtm_wm265e_1-1-5' => 'SerialNumber', # (confirmed)
319
+ 'dvtm_wm265e_1-1-10' => 'Model',
320
+ 'dvtm_wm265e_2-2' => {
321
+ Name => 'FrameInfo',
322
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
323
+ },
324
+ # dvtm_wm265e_3-2-1-4 - model code?
325
+ 'dvtm_wm265e_3-2-2-1' => { Name => 'ISO', Format => 'float' },
326
+ 'dvtm_wm265e_3-2-3-1' => {
327
+ Name => 'ShutterSpeed',
328
+ Format => 'rational',
329
+ ValueConv => '$val =~ m{(.*)/(.*)} ? $1 / $2 : $val',
330
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
331
+ },
332
+ # dvtm_wm265e_3-2-5-1 - unknown rational (xxxx / 1000)
333
+ 'dvtm_wm265e_3-2-6-1' => { Name => 'DigitalZoom', Format => 'float' },
334
+ 'dvtm_wm265e_3-3-4-1' => {
335
+ Name => 'GPSInfo',
336
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
337
+ },
338
+ 'dvtm_wm265e_3-3-3-1' => { Name => 'DroneRoll', Format => 'int64s', ValueConv => '$val/10' },
339
+ 'dvtm_wm265e_3-3-3-2' => { Name => 'DronePitch', Format => 'int64s', ValueConv => '$val/10' },
340
+ 'dvtm_wm265e_3-3-3-3' => { Name => 'DroneYaw', Format => 'int64s', ValueConv => '$val/10' },
341
+ 'dvtm_wm265e_3-3-4-2' => { Name => 'AbsoluteAltitude', ValueConv => '$val / 1000' },
342
+ 'dvtm_wm265e_3-3-5-1' => { Name => 'RelativeAltitude', Format => 'float', ValueConv => '$val / 1000' },
343
+ 'dvtm_wm265e_3-4-3-1' => { Name => 'GimbalPitch',Format => 'int64s', ValueConv => '$val / 10' },
344
+ 'dvtm_wm265e_3-4-3-2' => { Name => 'GimbalRoll', Format => 'int64s', ValueConv => '$val / 10' },
345
+ 'dvtm_wm265e_3-4-3-3' => { Name => 'GimbalYaw', Format => 'int64s', ValueConv => '$val / 10' },
346
+ );
347
+
348
+ %Image::ExifTool::DJI::FrameInfo = (
349
+ GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Video' },
350
+ PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
351
+ VARS => { HEX_ID => 0 },
352
+ 1 => { Name => 'FrameWidth', Format => 'unsigned' },
353
+ 2 => { Name => 'FrameHeight', Format => 'unsigned' },
354
+ 3 => { Name => 'FrameRate', Format => 'float' },
193
355
  );
194
356
 
195
- #------------------------------------------------------------------------------
196
- # Process DJI djmd timed data from Action4 videos (ref PH)
197
- # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
198
- # Returns: 1 on success
199
- # TODO: work in progress
200
- sub Process_djmd($$$)
201
- {
202
- my ($et, $dirInfo, $tagTbl) = @_;
203
- my $dataPt = $$dirInfo{DataPt};
204
- my ($pos, $bit, $val) = (6, 0, 0);
205
- for (;;) {
206
- my $v = Get8u($dataPt, $pos);
207
- $val += ($v & 0x7f) << $bit;
208
- last unless $v & 0x80;
209
- ++$pos;
210
- $bit += 7;
211
- }
212
- $pos += 49;
213
- my @a = unpack("x${pos}fxfxfxfx3fxfxf", $$dataPt);
214
- print "$val @a\n";
215
- return 1;
216
- }
357
+ %Image::ExifTool::DJI::GPSInfo = (
358
+ GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Location' },
359
+ PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
360
+ VARS => { HEX_ID => 0 },
361
+ 1 => {
362
+ Name => 'CoordinateUnits',
363
+ Format => 'unsigned',
364
+ Notes => 'not extracted, but used internally to convert coordinates to degrees',
365
+ # don't extract this -- just convert to degrees
366
+ RawConv => '$$self{CoordUnits} = $val; undef',
367
+ # PrintConv => { 0 => 'Radians', 1 => 'Degrees' },
368
+ },
369
+ 2 => {
370
+ Name => 'GPSLatitude',
371
+ Format => 'double',
372
+ # set ExifTool GPSLatitude/GPSLongitude members so GPSDateTime will be generated if necessary
373
+ RawConv => '$$self{GPSLatitude} = $$self{CoordUnits} ? $val : $val * 180 / 3.141592653589793', # (NC)
374
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
375
+ },
376
+ 3 => {
377
+ Name => 'GPSLongitude',
378
+ Format => 'double',
379
+ RawConv => '$$self{GPSLongitude} = $$self{CoordUnits} ? $val : $val * 180 / 3.141592653589793', # (NC)
380
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
381
+ },
382
+ );
217
383
 
218
384
  #------------------------------------------------------------------------------
219
385
  # Process DJI info (ref PH)
@@ -233,7 +399,7 @@ sub ProcessDJIInfo($$$)
233
399
  while ($$dataPt =~ /\G\[(.*?)\](?=(\[|$))/sg) {
234
400
  my ($tag, $val) = split /:/, $1, 2;
235
401
  next unless defined $tag and defined $val;
236
- if ($val =~ /^([\x20-\x7f]+)\0*$/) {
402
+ if ($val =~ /^([\x20-\x7e]+)\0*$/) {
237
403
  $val = $1;
238
404
  } else {
239
405
  my $buff = $val;
@@ -266,7 +432,7 @@ the maker notes in images from some DJI Phantom drones.
266
432
 
267
433
  =head1 AUTHOR
268
434
 
269
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
435
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
270
436
 
271
437
  This library is free software; you can redistribute it and/or modify it
272
438
  under the same terms as Perl itself.
@@ -849,7 +849,7 @@ information in DNG (Digital Negative) images.
849
849
 
850
850
  =head1 AUTHOR
851
851
 
852
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
852
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
853
853
 
854
854
  This library is free software; you can redistribute it and/or modify it
855
855
  under the same terms as Perl itself.
@@ -225,7 +225,7 @@ metadata from DPX (Digital Picture Exchange) images.
225
225
 
226
226
  =head1 AUTHOR
227
227
 
228
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
228
+ Copyright 2003-2025, 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.
@@ -291,7 +291,7 @@ information from DV (raw Digital Video) files.
291
291
 
292
292
  =head1 AUTHOR
293
293
 
294
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
294
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
295
295
 
296
296
  This library is free software; you can redistribute it and/or modify it
297
297
  under the same terms as Perl itself.
@@ -372,7 +372,7 @@ This file contains tag definitions for the Darwin Core XMP namespace.
372
372
 
373
373
  =head1 AUTHOR
374
374
 
375
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
375
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
376
376
 
377
377
  This library is free software; you can redistribute it and/or modify it
378
378
  under the same terms as Perl itself.
@@ -353,7 +353,7 @@ Image::ExifTool::AIFF.
353
353
 
354
354
  =head1 AUTHOR
355
355
 
356
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
356
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
357
357
 
358
358
  This library is free software; you can redistribute it and/or modify it
359
359
  under the same terms as Perl itself.
@@ -13,6 +13,7 @@
13
13
  # 5) http://msdn.microsoft.com/en-us/library/ms809762.aspx
14
14
  # 6) http://code.google.com/p/pefile/
15
15
  # 7) http://www.codeproject.com/KB/DLL/showver.aspx
16
+ # 8) https://learn.microsoft.com/en-us/windows/win32/debug/pe-format
16
17
  #------------------------------------------------------------------------------
17
18
 
18
19
  package Image::ExifTool::EXE;
@@ -21,7 +22,7 @@ use strict;
21
22
  use vars qw($VERSION);
22
23
  use Image::ExifTool qw(:DataAccess :Utils);
23
24
 
24
- $VERSION = '1.19';
25
+ $VERSION = '1.22';
25
26
 
26
27
  sub ProcessPEResources($$);
27
28
  sub ProcessPEVersion($$);
@@ -171,6 +172,13 @@ my %languageCode = (
171
172
  '100C' => 'French (Swiss)',
172
173
  );
173
174
 
175
+ my %int32uTime = (
176
+ Format => 'int32u',
177
+ Groups => { 0 => 'EXE', 1 => 'EXE', 2 => 'Time' },
178
+ ValueConv => 'ConvertUnixTime($val,1)',
179
+ PrintConv => '$self->ConvertDateTime($val)',
180
+ );
181
+
174
182
  # Information extracted from PE COFF (Windows EXE) file header
175
183
  %Image::ExifTool::EXE::Main = (
176
184
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
@@ -186,6 +194,8 @@ my %languageCode = (
186
194
  Name => 'MachineType',
187
195
  PrintHex => 1,
188
196
  PrintConv => {
197
+ 0x0 => 'Unknown',
198
+ 0x01 => 'Target host',
189
199
  0x014c => 'Intel 386 or later, and compatibles',
190
200
  0x014d => 'Intel i860', #5
191
201
  0x0162 => 'MIPS R3000',
@@ -196,10 +206,12 @@ my %languageCode = (
196
206
  0x0184 => 'Alpha AXP',
197
207
  0x01a2 => 'Hitachi SH3',
198
208
  0x01a3 => 'Hitachi SH3 DSP',
209
+ 0x01a4 => 'Hitachi SH3E',
199
210
  0x01a6 => 'Hitachi SH4',
200
211
  0x01a8 => 'Hitachi SH5',
201
212
  0x01c0 => 'ARM little endian',
202
213
  0x01c2 => 'Thumb',
214
+ 0x01c4 => 'Thumb 2 little endian',
203
215
  0x01d3 => 'Matsushita AM33',
204
216
  0x01f0 => 'PowerPC little endian',
205
217
  0x01f1 => 'PowerPC with floating point support',
@@ -209,22 +221,26 @@ my %languageCode = (
209
221
  0x0284 => 'Alpha AXP 64-bit',
210
222
  0x0366 => 'MIPS with FPU',
211
223
  0x0466 => 'MIPS16 with FPU',
224
+ 0x0520 => 'Infineon Tricore',
212
225
  0x0ebc => 'EFI Byte Code',
226
+ 0x3a64 => 'Compiled Hybrid PE',
227
+ 0x5032 => 'RISC-V 32-bit',
228
+ 0x5064 => 'RISC-V 64-bit',
229
+ 0x5128 => 'RISC-V 128-bit',
230
+ 0x6232 => 'LoongArch 32-bit',
231
+ 0x6264 => 'LoongArch 64-bit',
213
232
  0x8664 => 'AMD AMD64',
214
233
  0x9041 => 'Mitsubishi M32R little endian',
234
+ 0xaa64 => 'ARM64 little endian',
215
235
  0xc0ee => 'clr pure MSIL',
236
+ 0x0cef => 'CEF',
237
+ 0xec20 => 'Dotnet 0xEC20'
216
238
  },
217
239
  },
218
- 2 => {
219
- Name => 'TimeStamp',
220
- Format => 'int32u',
221
- Groups => { 2 => 'Time' },
222
- ValueConv => 'ConvertUnixTime($val,1)',
223
- PrintConv => '$self->ConvertDateTime($val)',
224
- },
240
+ 2 => { Name => 'TimeStamp', %int32uTime },
225
241
  9 => {
226
242
  Name => 'ImageFileCharacteristics',
227
- # ref https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_image_file_header
243
+ # ref https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-image_file_header
228
244
  PrintConv => { BITMASK => {
229
245
  0 => 'No relocs',
230
246
  1 => 'Executable',
@@ -243,6 +259,10 @@ my %languageCode = (
243
259
  15 => 'Bytes reversed hi',
244
260
  }},
245
261
  },
262
+ #
263
+ # optional header starts at index 10
264
+ # (note: all extracted tags are the same for 32 and 64-bit versions of the optional header)
265
+ #
246
266
  10 => {
247
267
  Name => 'PEType',
248
268
  PrintHex => 1,
@@ -308,6 +328,42 @@ my %languageCode = (
308
328
  },
309
329
  );
310
330
 
331
+ # information extracted from newer CodeView PDB70 ("RSDS") debug entry
332
+ %Image::ExifTool::EXE::DebugRSDS = (
333
+ GROUPS => { 2 => 'Other' },
334
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
335
+ NOTES => 'CodeView RSDS debug information found in some Windows EXE files.',
336
+ 0 => {
337
+ Name => 'PDBModifyDate',
338
+ Notes => 'Taken from debug directory entry pointing to RSDS record.',
339
+ %int32uTime,
340
+ },
341
+ 20 => { Name => 'PDBAge', Format => 'int32u' },
342
+ 24 => { Name => 'PDBFileName', Format => 'string' },
343
+ );
344
+
345
+ # information extracted from older CodeView PDB20 ("NB10") debug entry
346
+ %Image::ExifTool::EXE::DebugNB10 = (
347
+ GROUPS => { 2 => 'Other' },
348
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
349
+ NOTES => 'CodeView NB10 debug information found in some Windows EXE files.',
350
+ 0 => {
351
+ Name => 'PDBModifyDate',
352
+ Notes => 'Taken from debug directory entry pointing to NB10 record.',
353
+ %int32uTime,
354
+ },
355
+ 8 => { Name => 'PDBCreateDate',%int32uTime },
356
+ 12 => { Name => 'PDBAge', Format => 'int32u' },
357
+ 16 => { Name => 'PDBFileName', Format => 'string' },
358
+ );
359
+
360
+ %Image::ExifTool::EXE::Misc = (
361
+ GROUPS => { 2 => 'Other' },
362
+ VARS => { ID_LABEL => 'Index1' },
363
+ NOTES => 'Miscellaneous CodeView debug information in Windows EXE files.',
364
+ 12 => 'EXEFileName',
365
+ );
366
+
311
367
  # PE file version information (ref 6)
312
368
  %Image::ExifTool::EXE::PEVersion = (
313
369
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
@@ -974,6 +1030,22 @@ sub ProcessPEVersion($$)
974
1030
  return 1;
975
1031
  }
976
1032
 
1033
+ #------------------------------------------------------------------------------
1034
+ # Get actual file offset given a virtual address in a PE file
1035
+ # Inputs: 0) virtual address, 1) section list ref
1036
+ # Returns: absolute file offset or undef on error
1037
+ sub GetFileOffset($$)
1038
+ {
1039
+ my ($addr, $sections) = @_;
1040
+ my $section;
1041
+ foreach $section (@$sections) {
1042
+ next unless $addr >= $$section{VirtualAddress} and
1043
+ $addr < $$section{VirtualAddress} + $$section{Size};
1044
+ return $addr + $$section{Base} - $$section{VirtualAddress};
1045
+ }
1046
+ return undef;
1047
+ }
1048
+
977
1049
  #------------------------------------------------------------------------------
978
1050
  # Process Windows PE Resources
979
1051
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref
@@ -994,6 +1066,7 @@ sub ProcessPEResources($$)
994
1066
  my $nameEntries = Get16u(\$buff, 12);
995
1067
  my $idEntries = Get16u(\$buff, 14);
996
1068
  my $count = $nameEntries + $idEntries;
1069
+ return 0 if $count > 10000;
997
1070
  $raf->Read($buff, $count * 8) == $count * 8 or return 0;
998
1071
  # loop through all resource entries
999
1072
  for ($item=0; $item<$count; ++$item) {
@@ -1023,18 +1096,12 @@ sub ProcessPEResources($$)
1023
1096
  # get position of this resource in the file
1024
1097
  my $buf2;
1025
1098
  $raf->Seek($entryPos + $base, 0) and $raf->Read($buf2, 16) == 16 or return 0;
1026
- my $off = Get32u(\$buf2, 0);
1099
+ my $addr = Get32u(\$buf2, 0);
1027
1100
  my $len = Get32u(\$buf2, 4);
1028
1101
  # determine which section this is in so we can convert the virtual address
1029
- my ($section, $filePos);
1030
- foreach $section (@{$$dirInfo{Sections}}) {
1031
- next unless $off >= $$section{VirtualAddress} and
1032
- $off < $$section{VirtualAddress} + $$section{Size};
1033
- $filePos = $off + $$section{Base} - $$section{VirtualAddress};
1034
- last;
1035
- }
1036
- return 0 unless $filePos;
1037
- $raf->Seek($filePos, 0) and $raf->Read($buf2, $len) == $len or return 0;
1102
+ my $fileOff = GetFileOffset($addr, $$dirInfo{Sections});
1103
+ return 0 unless $fileOff;
1104
+ $raf->Seek($fileOff, 0) and $raf->Read($buf2, $len) == $len or return 0;
1038
1105
  ProcessPEVersion($et, {
1039
1106
  DataPt => \$buf2,
1040
1107
  DataLen => $len,
@@ -1050,7 +1117,8 @@ sub ProcessPEResources($$)
1050
1117
  #------------------------------------------------------------------------------
1051
1118
  # Process Windows PE file data dictionary
1052
1119
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref
1053
- # Returns: true on success
1120
+ # Returns: true on success or if the PE resources didn't exist, or false on error
1121
+ # processing the PE resources
1054
1122
  sub ProcessPEDict($$)
1055
1123
  {
1056
1124
  my ($et, $dirInfo) = @_;
@@ -1078,6 +1146,7 @@ sub ProcessPEDict($$)
1078
1146
  Sections => \@sections,
1079
1147
  );
1080
1148
  }
1149
+ $$dirInfo{Sections} = \@sections; # return section information
1081
1150
  # process the first resource section
1082
1151
  ProcessPEResources($et, \%dirInfo) or return 0 if %dirInfo;
1083
1152
  return 1;
@@ -1228,11 +1297,12 @@ sub ProcessEXE($$)
1228
1297
  # read the rest of the optional header if necessary
1229
1298
  my $optSize = Get16u(\$buff, 20);
1230
1299
  my $more = $optSize + 24 - $size;
1300
+ my $magic = 0;
1231
1301
  if ($more > 0) {
1232
1302
  if ($raf->Read($buf2, $more) == $more) {
1233
1303
  $buff .= $buf2;
1234
1304
  $size += $more;
1235
- my $magic = Get16u(\$buff, 24);
1305
+ $magic = Get16u(\$buff, 24);
1236
1306
  # verify PE magic number
1237
1307
  unless ($magic == 0x107 or $magic == 0x10b or $magic == 0x20b) {
1238
1308
  $et->Warn('Unknown PE magic number');
@@ -1246,21 +1316,54 @@ sub ProcessEXE($$)
1246
1316
  # process PE COFF file header
1247
1317
  $tagTablePtr = GetTagTable('Image::ExifTool::EXE::Main');
1248
1318
  %dirInfo = (
1249
- DataPt => \$buff,
1250
- DataPos => $raf->Tell() - $size,
1251
- DataLen => $size,
1319
+ DataPt => \$buff,
1320
+ DataPos => $raf->Tell() - $size,
1321
+ DataLen => $size,
1252
1322
  DirStart => 4,
1253
- DirLen => $size - 4,
1323
+ DirLen => $size - 4,
1254
1324
  );
1255
1325
  $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
1256
- # process data dictionary
1257
1326
  my $num = Get16u(\$buff, 6); # NumberOfSections
1258
- if ($raf->Read($buff, 40 * $num) == 40 * $num) {
1259
- %dirInfo = (
1260
- RAF => $raf,
1261
- DataPt => \$buff,
1262
- );
1263
- ProcessPEDict($et, \%dirInfo) or $et->Warn('Error processing PE data dictionary');
1327
+ # image data directory entry for debug info is index 6,
1328
+ # so offset is 4 bytes + 20 byte header + 96 bytes into PE32 optional
1329
+ # header (or 112 bytes for PE32+) + 6 * 8 bytes into data directory
1330
+ my $dirEntry = $magic == 0x20b ? 184 : 168;
1331
+ my ($addr, $len, $pos, $buf2); # virtual address/size of debug section
1332
+ if (length($buff) >= $dirEntry + 8) {
1333
+ $addr = Get32u(\$buff, $dirEntry);
1334
+ $len = Get32u(\$buff, $dirEntry+4);
1335
+ }
1336
+ # process data dictionary
1337
+ # (ref https://www.debuginfo.com/articles/debuginfomatch.html)
1338
+ return 1 unless $raf->Read($buff, 40 * $num) == 40 * $num;
1339
+ %dirInfo = ( RAF => $raf, DataPt => \$buff );
1340
+ ProcessPEDict($et, \%dirInfo) or $et->Warn('Error processing PE resources');
1341
+ # dive into debug section to extract pdb info if available
1342
+ return 1 unless $addr and $len < 2800 and $dirInfo{Sections} and
1343
+ ($magic == 0x10b or $magic == 0x20b);
1344
+ # get file offset for debug section
1345
+ my $off = GetFileOffset($addr, $dirInfo{Sections});
1346
+ return 1 unless $off and $raf->Seek($off,0) and
1347
+ $raf->Read($buff,$len) == $len;
1348
+ for ($pos=0; $pos+28<=$len; $pos+=28) {
1349
+ my $type = Get32u(\$buff,$pos+12);
1350
+ next unless $type == 2 or $type == 4; # (CodeView debug data)
1351
+ my ($n, $of) = (Get32u(\$buff,$pos+16), Get32u(\$buff,$pos+24));
1352
+ next unless $n < 1e4 and $raf->Seek($of,0) and $raf->Read($buf2,$n) == $n;
1353
+ if ($type == 2) { # CodeView debug info
1354
+ next unless $buf2 =~ /^(RSDS|NB10)/;
1355
+ $tagTablePtr = GetTagTable("Image::ExifTool::EXE::Debug$1");
1356
+ substr($buf2,0,4) = substr($buff,$pos+4,4); # use timestamp from debug dir
1357
+ %dirInfo = ( DataPt => \$buf2, DataPos => $of );
1358
+ $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
1359
+ } else { # misc debug info
1360
+ next unless $n > 12;
1361
+ my $exe = substr($buf2,12);
1362
+ $exe = $et->Decode($exe, 'UCS2') if Get32u(\$buf2,8);
1363
+ $exe =~ s/\0.*//; # truncate at null
1364
+ $tagTablePtr = GetTagTable('Image::ExifTool::EXE::Misc');
1365
+ $et->HandleTag($tagTablePtr, 12, $exe, DataPt => \$buf2, DataPos => $of);
1366
+ }
1264
1367
  }
1265
1368
  return 1;
1266
1369
  }
@@ -1454,7 +1557,7 @@ library files.
1454
1557
 
1455
1558
  =head1 AUTHOR
1456
1559
 
1457
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
1560
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
1458
1561
 
1459
1562
  This library is free software; you can redistribute it and/or modify it
1460
1563
  under the same terms as Perl itself.
@@ -1477,6 +1580,8 @@ under the same terms as Perl itself.
1477
1580
 
1478
1581
  =item L<http://www.codeproject.com/KB/DLL/showver.aspx>
1479
1582
 
1583
+ =item L<https://learn.microsoft.com/en-us/windows/win32/debug/pe-format>
1584
+
1480
1585
  =back
1481
1586
 
1482
1587
  =head1 SEE ALSO