exiftool-vendored.pl 13.0.1 → 13.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/bin/Changes +254 -20
  2. package/bin/MANIFEST +10 -0
  3. package/bin/META.json +1 -1
  4. package/bin/META.yml +1 -1
  5. package/bin/README +3 -3
  6. package/bin/arg_files/exif2xmp.args +4 -0
  7. package/bin/arg_files/xmp2exif.args +2 -1
  8. package/bin/build_geolocation +1 -1
  9. package/bin/exiftool +356 -213
  10. package/bin/lib/File/RandomAccess.pm +1 -1
  11. package/bin/lib/File/RandomAccess.pod +2 -2
  12. package/bin/lib/Image/ExifTool/AAC.pm +1 -1
  13. package/bin/lib/Image/ExifTool/AES.pm +1 -1
  14. package/bin/lib/Image/ExifTool/AFCP.pm +6 -6
  15. package/bin/lib/Image/ExifTool/AIFF.pm +2 -2
  16. package/bin/lib/Image/ExifTool/APE.pm +2 -2
  17. package/bin/lib/Image/ExifTool/APP12.pm +1 -1
  18. package/bin/lib/Image/ExifTool/ASF.pm +2 -2
  19. package/bin/lib/Image/ExifTool/Apple.pm +11 -9
  20. package/bin/lib/Image/ExifTool/Audible.pm +1 -1
  21. package/bin/lib/Image/ExifTool/BMP.pm +1 -1
  22. package/bin/lib/Image/ExifTool/BPG.pm +1 -1
  23. package/bin/lib/Image/ExifTool/BZZ.pm +1 -1
  24. package/bin/lib/Image/ExifTool/BigTIFF.pm +1 -1
  25. package/bin/lib/Image/ExifTool/BuildTagLookup.pm +36 -22
  26. package/bin/lib/Image/ExifTool/CBOR.pm +5 -2
  27. package/bin/lib/Image/ExifTool/Canon.pm +66 -27
  28. package/bin/lib/Image/ExifTool/CanonCustom.pm +1 -1
  29. package/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
  30. package/bin/lib/Image/ExifTool/CanonVRD.pm +1 -1
  31. package/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
  32. package/bin/lib/Image/ExifTool/Casio.pm +1 -1
  33. package/bin/lib/Image/ExifTool/Charset.pm +1 -1
  34. package/bin/lib/Image/ExifTool/DICOM.pm +1 -1
  35. package/bin/lib/Image/ExifTool/DJI.pm +196 -30
  36. package/bin/lib/Image/ExifTool/DNG.pm +1 -1
  37. package/bin/lib/Image/ExifTool/DPX.pm +1 -1
  38. package/bin/lib/Image/ExifTool/DV.pm +1 -1
  39. package/bin/lib/Image/ExifTool/DarwinCore.pm +1 -1
  40. package/bin/lib/Image/ExifTool/DjVu.pm +1 -1
  41. package/bin/lib/Image/ExifTool/EXE.pm +138 -33
  42. package/bin/lib/Image/ExifTool/Exif.pm +29 -16
  43. package/bin/lib/Image/ExifTool/FITS.pm +3 -3
  44. package/bin/lib/Image/ExifTool/FLAC.pm +1 -1
  45. package/bin/lib/Image/ExifTool/FLIF.pm +3 -3
  46. package/bin/lib/Image/ExifTool/FLIR.pm +1 -1
  47. package/bin/lib/Image/ExifTool/Fixup.pm +1 -1
  48. package/bin/lib/Image/ExifTool/Flash.pm +1 -1
  49. package/bin/lib/Image/ExifTool/FlashPix.pm +17 -21
  50. package/bin/lib/Image/ExifTool/Font.pm +2 -2
  51. package/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
  52. package/bin/lib/Image/ExifTool/FujiFilm.pm +1 -1
  53. package/bin/lib/Image/ExifTool/GE.pm +1 -1
  54. package/bin/lib/Image/ExifTool/GIF.pm +144 -93
  55. package/bin/lib/Image/ExifTool/GIMP.pm +1 -1
  56. package/bin/lib/Image/ExifTool/GM.pm +1 -1
  57. package/bin/lib/Image/ExifTool/GPS.pm +34 -30
  58. package/bin/lib/Image/ExifTool/GeoTiff.pm +1 -1
  59. package/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
  60. package/bin/lib/Image/ExifTool/Geolocation.pm +19 -9
  61. package/bin/lib/Image/ExifTool/Geotag.pm +46 -12
  62. package/bin/lib/Image/ExifTool/GoPro.pm +120 -8
  63. package/bin/lib/Image/ExifTool/H264.pm +1 -1
  64. package/bin/lib/Image/ExifTool/HP.pm +2 -2
  65. package/bin/lib/Image/ExifTool/HTML.pm +1 -1
  66. package/bin/lib/Image/ExifTool/HtmlDump.pm +1 -1
  67. package/bin/lib/Image/ExifTool/ICC_Profile.pm +81 -2
  68. package/bin/lib/Image/ExifTool/ICO.pm +1 -1
  69. package/bin/lib/Image/ExifTool/ID3.pm +8 -8
  70. package/bin/lib/Image/ExifTool/IPTC.pm +10 -7
  71. package/bin/lib/Image/ExifTool/ISO.pm +1 -1
  72. package/bin/lib/Image/ExifTool/ITC.pm +1 -1
  73. package/bin/lib/Image/ExifTool/Import.pm +5 -4
  74. package/bin/lib/Image/ExifTool/InDesign.pm +2 -2
  75. package/bin/lib/Image/ExifTool/InfiRay.pm +1 -1
  76. package/bin/lib/Image/ExifTool/JPEG.pm +32 -5
  77. package/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
  78. package/bin/lib/Image/ExifTool/JSON.pm +1 -1
  79. package/bin/lib/Image/ExifTool/JVC.pm +1 -1
  80. package/bin/lib/Image/ExifTool/Jpeg2000.pm +10 -9
  81. package/bin/lib/Image/ExifTool/Kodak.pm +1 -1
  82. package/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
  83. package/bin/lib/Image/ExifTool/LIF.pm +1 -1
  84. package/bin/lib/Image/ExifTool/LNK.pm +2 -2
  85. package/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
  86. package/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
  87. package/bin/lib/Image/ExifTool/Lang/en_ca.pm +1 -1
  88. package/bin/lib/Image/ExifTool/Lang/en_gb.pm +1 -1
  89. package/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
  90. package/bin/lib/Image/ExifTool/Lang/fi.pm +1 -1
  91. package/bin/lib/Image/ExifTool/Lang/fr.pm +1 -1
  92. package/bin/lib/Image/ExifTool/Lang/it.pm +1 -1
  93. package/bin/lib/Image/ExifTool/Lang/ja.pm +1 -1
  94. package/bin/lib/Image/ExifTool/Lang/ko.pm +1 -1
  95. package/bin/lib/Image/ExifTool/Lang/nl.pm +1 -1
  96. package/bin/lib/Image/ExifTool/Lang/pl.pm +1 -1
  97. package/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
  98. package/bin/lib/Image/ExifTool/Lang/sk.pm +1 -1
  99. package/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
  100. package/bin/lib/Image/ExifTool/Lang/tr.pm +1 -1
  101. package/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
  102. package/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
  103. package/bin/lib/Image/ExifTool/Leaf.pm +1 -1
  104. package/bin/lib/Image/ExifTool/LigoGPS.pm +409 -0
  105. package/bin/lib/Image/ExifTool/Lytro.pm +1 -1
  106. package/bin/lib/Image/ExifTool/M2TS.pm +57 -18
  107. package/bin/lib/Image/ExifTool/MIE.pm +15 -6
  108. package/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
  109. package/bin/lib/Image/ExifTool/MIFF.pm +1 -1
  110. package/bin/lib/Image/ExifTool/MISB.pm +1 -1
  111. package/bin/lib/Image/ExifTool/MNG.pm +1 -1
  112. package/bin/lib/Image/ExifTool/MOI.pm +1 -1
  113. package/bin/lib/Image/ExifTool/MPC.pm +1 -1
  114. package/bin/lib/Image/ExifTool/MPEG.pm +1 -1
  115. package/bin/lib/Image/ExifTool/MPF.pm +1 -1
  116. package/bin/lib/Image/ExifTool/MRC.pm +1 -1
  117. package/bin/lib/Image/ExifTool/MWG.pm +1 -1
  118. package/bin/lib/Image/ExifTool/MXF.pm +3 -3
  119. package/bin/lib/Image/ExifTool/MacOS.pm +3 -2
  120. package/bin/lib/Image/ExifTool/MakerNotes.pm +1 -1
  121. package/bin/lib/Image/ExifTool/Matroska.pm +22 -6
  122. package/bin/lib/Image/ExifTool/Microsoft.pm +2 -2
  123. package/bin/lib/Image/ExifTool/Minolta.pm +1 -1
  124. package/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
  125. package/bin/lib/Image/ExifTool/Motorola.pm +1 -1
  126. package/bin/lib/Image/ExifTool/Nikon.pm +495 -39
  127. package/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
  128. package/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
  129. package/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
  130. package/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
  131. package/bin/lib/Image/ExifTool/OOXML.pm +8 -8
  132. package/bin/lib/Image/ExifTool/Ogg.pm +1 -1
  133. package/bin/lib/Image/ExifTool/Olympus.pm +1 -1
  134. package/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
  135. package/bin/lib/Image/ExifTool/Opus.pm +1 -1
  136. package/bin/lib/Image/ExifTool/Other.pm +1 -1
  137. package/bin/lib/Image/ExifTool/PCX.pm +1 -1
  138. package/bin/lib/Image/ExifTool/PDF.pm +49 -18
  139. package/bin/lib/Image/ExifTool/PGF.pm +1 -1
  140. package/bin/lib/Image/ExifTool/PICT.pm +1 -1
  141. package/bin/lib/Image/ExifTool/PLIST.pm +4 -4
  142. package/bin/lib/Image/ExifTool/PLUS.pm +1 -1
  143. package/bin/lib/Image/ExifTool/PNG.pm +20 -8
  144. package/bin/lib/Image/ExifTool/PPM.pm +12 -3
  145. package/bin/lib/Image/ExifTool/PSP.pm +1 -1
  146. package/bin/lib/Image/ExifTool/Palm.pm +1 -1
  147. package/bin/lib/Image/ExifTool/Panasonic.pm +27 -3
  148. package/bin/lib/Image/ExifTool/PanasonicRaw.pm +1 -1
  149. package/bin/lib/Image/ExifTool/Parrot.pm +1 -1
  150. package/bin/lib/Image/ExifTool/Pentax.pm +1 -1
  151. package/bin/lib/Image/ExifTool/PhaseOne.pm +4 -4
  152. package/bin/lib/Image/ExifTool/PhotoCD.pm +1 -1
  153. package/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
  154. package/bin/lib/Image/ExifTool/Photoshop.pm +65 -4
  155. package/bin/lib/Image/ExifTool/PostScript.pm +1 -1
  156. package/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
  157. package/bin/lib/Image/ExifTool/Protobuf.pm +270 -0
  158. package/bin/lib/Image/ExifTool/Qualcomm.pm +1 -1
  159. package/bin/lib/Image/ExifTool/QuickTime.pm +326 -88
  160. package/bin/lib/Image/ExifTool/QuickTimeStream.pl +199 -195
  161. package/bin/lib/Image/ExifTool/README +12 -2
  162. package/bin/lib/Image/ExifTool/RIFF.pm +21 -6
  163. package/bin/lib/Image/ExifTool/RSRC.pm +1 -1
  164. package/bin/lib/Image/ExifTool/RTF.pm +2 -2
  165. package/bin/lib/Image/ExifTool/Radiance.pm +1 -1
  166. package/bin/lib/Image/ExifTool/Rawzor.pm +1 -1
  167. package/bin/lib/Image/ExifTool/Real.pm +1 -1
  168. package/bin/lib/Image/ExifTool/Reconyx.pm +1 -1
  169. package/bin/lib/Image/ExifTool/Red.pm +1 -1
  170. package/bin/lib/Image/ExifTool/Ricoh.pm +4 -4
  171. package/bin/lib/Image/ExifTool/Samsung.pm +2 -2
  172. package/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
  173. package/bin/lib/Image/ExifTool/Scalado.pm +1 -1
  174. package/bin/lib/Image/ExifTool/Shift.pl +1 -1
  175. package/bin/lib/Image/ExifTool/Shortcuts.pm +1 -1
  176. package/bin/lib/Image/ExifTool/Sigma.pm +1 -1
  177. package/bin/lib/Image/ExifTool/SigmaRaw.pm +1 -1
  178. package/bin/lib/Image/ExifTool/Sony.pm +5 -4
  179. package/bin/lib/Image/ExifTool/SonyIDC.pm +1 -1
  180. package/bin/lib/Image/ExifTool/Stim.pm +1 -1
  181. package/bin/lib/Image/ExifTool/TagInfoXML.pm +6 -5
  182. package/bin/lib/Image/ExifTool/TagLookup.pm +7023 -6968
  183. package/bin/lib/Image/ExifTool/TagNames.pod +445 -29
  184. package/bin/lib/Image/ExifTool/Text.pm +4 -3
  185. package/bin/lib/Image/ExifTool/Theora.pm +1 -1
  186. package/bin/lib/Image/ExifTool/Torrent.pm +3 -3
  187. package/bin/lib/Image/ExifTool/Unknown.pm +1 -1
  188. package/bin/lib/Image/ExifTool/VCard.pm +3 -3
  189. package/bin/lib/Image/ExifTool/Validate.pm +6 -6
  190. package/bin/lib/Image/ExifTool/Vivo.pm +124 -0
  191. package/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
  192. package/bin/lib/Image/ExifTool/WPG.pm +1 -1
  193. package/bin/lib/Image/ExifTool/WTV.pm +1 -1
  194. package/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
  195. package/bin/lib/Image/ExifTool/WriteExif.pl +3 -3
  196. package/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
  197. package/bin/lib/Image/ExifTool/WritePDF.pl +1 -1
  198. package/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
  199. package/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
  200. package/bin/lib/Image/ExifTool/WritePostScript.pl +1 -1
  201. package/bin/lib/Image/ExifTool/WriteQuickTime.pl +166 -79
  202. package/bin/lib/Image/ExifTool/WriteRIFF.pl +17 -6
  203. package/bin/lib/Image/ExifTool/WriteXMP.pl +3 -3
  204. package/bin/lib/Image/ExifTool/Writer.pl +89 -96
  205. package/bin/lib/Image/ExifTool/XISF.pm +1 -1
  206. package/bin/lib/Image/ExifTool/XMP.pm +28 -13
  207. package/bin/lib/Image/ExifTool/XMP2.pl +103 -1
  208. package/bin/lib/Image/ExifTool/XMPStruct.pl +2 -3
  209. package/bin/lib/Image/ExifTool/ZIP.pm +2 -2
  210. package/bin/lib/Image/ExifTool/ZISRAW.pm +1 -1
  211. package/bin/lib/Image/ExifTool/iWork.pm +1 -1
  212. package/bin/lib/Image/ExifTool.pm +335 -163
  213. package/bin/lib/Image/ExifTool.pod +119 -73
  214. package/bin/perl-Image-ExifTool.spec +1 -1
  215. package/bin/windows_exiftool.txt +96 -51
  216. package/package.json +6 -6
@@ -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
@@ -57,7 +57,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
57
57
  use Image::ExifTool qw(:DataAccess :Utils);
58
58
  use Image::ExifTool::MakerNotes;
59
59
 
60
- $VERSION = '4.52';
60
+ $VERSION = '4.56';
61
61
 
62
62
  sub ProcessExif($$$);
63
63
  sub WriteExif($$$);
@@ -246,10 +246,13 @@ $formatName[129] = 'utf8'; # (Exif 3.0)
246
246
  # 34888,34889 - ESRI reserved
247
247
  34892 => 'Lossy JPEG', # (DNG 1.4)
248
248
  34925 => 'LZMA2', #LibTiff
249
- 34926 => 'Zstd', #LibTiff
250
- 34927 => 'WebP', #LibTiff
249
+ 34926 => 'Zstd (old)', #LibTiff
250
+ 34927 => 'WebP (old)', #LibTiff
251
251
  34933 => 'PNG', # (TIFF mail list)
252
252
  34934 => 'JPEG XR', # (TIFF mail list)
253
+ 50000 => 'Zstd', #LibTiff 4.7
254
+ 50001 => 'WebP', #LibTiff 4.7
255
+ 50002 => 'JPEG XL (old)', #LibTiff 4.7
253
256
  52546 => 'JPEG XL', # (DNG 1.7)
254
257
  65000 => 'Kodak DCR Compressed', #PH
255
258
  65535 => 'Pentax PEF Compressed', #Jens
@@ -4421,6 +4424,13 @@ my %opcodeInfo = (
4421
4424
  Writable => 'int32u',
4422
4425
  WriteGroup => 'IFD0',
4423
4426
  },
4427
+ 0xcea1 => {
4428
+ Name => 'SEAL', # (writable directory!)
4429
+ Writable => 'string',
4430
+ WriteGroup => 'IFD0',
4431
+ SubDirectory => { TagTable => 'Image::ExifTool::XMP::SEAL' },
4432
+ WriteCheck => 'return "Can only delete"', # (don't allow writing)
4433
+ },
4424
4434
  0xea1c => { #13
4425
4435
  Name => 'Padding',
4426
4436
  Binary => 1,
@@ -5346,10 +5356,7 @@ sub CalcScaleFactor35efl
5346
5356
  # calculate Canon sensor size using a dedicated algorithm
5347
5357
  if ($$et{Make} eq 'Canon') {
5348
5358
  require Image::ExifTool::Canon;
5349
- my $canonDiag = Image::ExifTool::Canon::CalcSensorDiag(
5350
- $$et{RATIONAL}{FocalPlaneXResolution},
5351
- $$et{RATIONAL}{FocalPlaneYResolution},
5352
- );
5359
+ my $canonDiag = Image::ExifTool::Canon::CalcSensorDiag($et);
5353
5360
  $diag = $canonDiag if $canonDiag;
5354
5361
  }
5355
5362
  unless ($diag and Image::ExifTool::IsFloat($diag)) {
@@ -6171,7 +6178,7 @@ sub ProcessExif($$$)
6171
6178
  my $base = $$dirInfo{Base} || 0;
6172
6179
  my $firstBase = $base;
6173
6180
  my $raf = $$dirInfo{RAF};
6174
- my ($verbose,$validate,$saveFormat) = @{$$et{OPTIONS}}{qw(Verbose Validate SaveFormat)};
6181
+ my ($verbose,$validate,$saveFormat,$saveBin) = @{$$et{OPTIONS}}{qw(Verbose Validate SaveFormat SaveBin)};
6175
6182
  my $htmlDump = $$et{HTML_DUMP};
6176
6183
  my $success = 1;
6177
6184
  my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffName, $doHash);
@@ -6182,7 +6189,7 @@ sub ProcessExif($$$)
6182
6189
  if ($$dirInfo{DirName} eq 'MakerNotes' and $$et{FileType} eq 'CR3' and
6183
6190
  $$dirInfo{Parent} and $$dirInfo{Parent} eq 'ExifIFD')
6184
6191
  {
6185
- $et->WarnOnce("MakerNotes shouldn't exist ExifIFD of CR3 image", 1);
6192
+ $et->Warn("MakerNotes shouldn't exist ExifIFD of CR3 image", 1);
6186
6193
  }
6187
6194
  # set flag to calculate image data hash if requested
6188
6195
  $doHash = 1 if $$et{ImageDataHash} and (($$et{FILE_TYPE} eq 'TIFF' and not $base and not $inMakerNotes) or
@@ -6361,7 +6368,7 @@ sub ProcessExif($$$)
6361
6368
  my $valueDataLen = $dataLen;
6362
6369
  my $valuePtr = $entry + 8; # pointer to value within $$dataPt
6363
6370
  my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID);
6364
- my ($origFormStr, $bad, $rational, $subOffName);
6371
+ my ($origFormStr, $bad, $rational, $binVal, $subOffName);
6365
6372
  # save the EXIF format codes if requested
6366
6373
  $$et{SaveFormat}{$saveFormat = $formatStr} = 1 if $saveFormat;
6367
6374
  # hack to patch incorrect count in Kodak SubIFD3 tags
@@ -6652,12 +6659,13 @@ sub ProcessExif($$$)
6652
6659
  if ($count > 500 and $formatStr !~ /^(undef|string|binary)$/ and
6653
6660
  (not $tagInfo or $$tagInfo{LongBinary} or $warned) and not $$et{OPTIONS}{IgnoreMinorErrors})
6654
6661
  {
6655
- $et->WarnOnce('Not decoding some large array(s). Ignore minor errors to decode', 2) unless $warned;
6662
+ $et->Warn('Not decoding some large array(s). Ignore minor errors to decode', 2) unless $warned;
6656
6663
  next if $$et{TAGS_FROM_FILE}; # don't generate bogus value when copying tags
6657
6664
  $val = "(large array of $count $formatStr values)";
6658
6665
  } else {
6659
6666
  # convert according to specified format
6660
6667
  $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$readSize,\$rational);
6668
+ $binVal = substr($$valueDataPt,$valuePtr,$readSize) if $saveBin;
6661
6669
  # re-code if necessary
6662
6670
  if (defined $val) {
6663
6671
  if ($formatStr eq 'utf8') {
@@ -6692,8 +6700,9 @@ sub ProcessExif($$$)
6692
6700
  "Format: $fstr\nSize: $size bytes\n";
6693
6701
  if ($size > 4) {
6694
6702
  my $offPt = Get32u($dataPt,$entry+8);
6695
- # (test this with ../pics/{CanonEOS-1D_XMarkIII.hif,PanasonicDC-G9.rw2})
6696
- my $actPt = $valuePtr + $valueDataPos + $base - ($$et{EXIF_POS} || 0) + ($$et{BASE_FUDGE} || 0);
6703
+ # (test this with ../pics/{CanonEOS-1D_XMarkIII.hif,PanasonicDC-G9.rw2,*.raf})
6704
+ my $actPt = $valuePtr + $valueDataPos + $base - ($$et{EXIF_POS} || 0) +
6705
+ ($$et{BASE_FUDGE} || $$et{BASE} || 0);
6697
6706
  $tip .= sprintf("Value offset: 0x%.4x\n", $offPt);
6698
6707
  # highlight tag name (red for bad size)
6699
6708
  my $style = ($bad or not defined $tval) ? 'V' : 'H';
@@ -6724,12 +6733,15 @@ sub ProcessExif($$$)
6724
6733
  } elsif ($tagInfo and Image::ExifTool::IsInt($tval)) {
6725
6734
  if ($$tagInfo{IsOffset} or $$tagInfo{SubIFD}) {
6726
6735
  $tval = sprintf('0x%.4x', $tval);
6727
- my $actPt = $val + $base - ($$et{EXIF_POS} || 0) + ($$et{BASE_FUDGE} || 0);
6736
+ my $actPt = $val + $base - ($$et{EXIF_POS} || 0) + ($$et{BASE_FUDGE} || $$et{BASE} || 0);
6728
6737
  if ($actPt != $val) {
6729
6738
  $tval .= sprintf("\nActual offset: 0x%.4x", $actPt);
6730
6739
  my $sign = $actPt < $val ? '-' : '';
6731
6740
  $tval .= sprintf("\nOffset base: ${sign}0x%.4x", abs($actPt - $val));
6732
6741
  }
6742
+ if ($$et{EXIF_POS} and not $$et{BASE_FUDGE}) {
6743
+ $tip .= sprintf("File offset: 0x%.4x\n", $actPt + $$et{EXIF_POS})
6744
+ }
6733
6745
  } elsif ($$tagInfo{PrintHex}) {
6734
6746
  $tval = sprintf('0x%x', $tval);
6735
6747
  }
@@ -7055,7 +7067,8 @@ sub ProcessExif($$$)
7055
7067
  # set the group 1 name for tags in specified tables
7056
7068
  $et->SetGroup($tagKey, $dirName) if $$tagTablePtr{SET_GROUP1};
7057
7069
  # save original components of rational numbers (used when copying)
7058
- $$et{RATIONAL}{$tagKey} = $rational if defined $rational;
7070
+ $$et{TAG_EXTRA}{$tagKey}{Rational} = $rational if defined $rational;
7071
+ $$et{TAG_EXTRA}{$tagKey}{BinVal} = $binVal if defined $binVal;
7059
7072
  $$et{TAG_EXTRA}{$tagKey}{G6} = $saveFormat if $saveFormat;
7060
7073
  if ($$et{MAKER_NOTE_FIXUP}) {
7061
7074
  $$et{TAG_EXTRA}{$tagKey}{Fixup} = $$et{MAKER_NOTE_FIXUP};
@@ -7130,7 +7143,7 @@ EXIF and TIFF meta information.
7130
7143
 
7131
7144
  =head1 AUTHOR
7132
7145
 
7133
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
7146
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
7134
7147
 
7135
7148
  This library is free software; you can redistribute it and/or modify it
7136
7149
  under the same terms as Perl itself.
@@ -61,7 +61,7 @@ sub ProcessFITS($$)
61
61
  my $key = substr($buff, 0, 8);
62
62
  $key =~ s/ +$//; # remove trailing space from key
63
63
  if ($key eq 'CONTINUE') {
64
- defined $continue or $et->WarnOnce('Unexpected FITS CONTINUE keyword'), next;
64
+ defined $continue or $et->Warn('Unexpected FITS CONTINUE keyword'), next;
65
65
  } else {
66
66
  if (defined $continue) {
67
67
  # the previous value wasn't continued, so store with the trailing '&'
@@ -104,7 +104,7 @@ sub ProcessFITS($$)
104
104
  # check for possible continuation, removing trailing '&'
105
105
  $val =~ s/\&$// and $continue = $val, next;
106
106
  } elsif (defined $continue) {
107
- $et->WarnOnce('Invalid FITS CONTINUE value');
107
+ $et->Warn('Invalid FITS CONTINUE value');
108
108
  next;
109
109
  } else {
110
110
  $val =~ s/ *(\/.*)?$//; # remove trailing spaces and comment
@@ -137,7 +137,7 @@ information from FITS (Flexible Image Transport System) images.
137
137
 
138
138
  =head1 AUTHOR
139
139
 
140
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
140
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
141
141
 
142
142
  This library is free software; you can redistribute it and/or modify it
143
143
  under the same terms as Perl itself.
@@ -298,7 +298,7 @@ information from Free Lossless Audio Codec (FLAC) audio files.
298
298
 
299
299
  =head1 AUTHOR
300
300
 
301
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
301
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
302
302
 
303
303
  This library is free software; you can redistribute it and/or modify it
304
304
  under the same terms as Perl itself.
@@ -244,7 +244,7 @@ sub WriteFLIF($$)
244
244
  }
245
245
  }
246
246
  } else {
247
- $et->WarnOnce('Install IO::Compress::RawDeflate to write FLIF metadata');
247
+ $et->Warn('Install IO::Compress::RawDeflate to write FLIF metadata');
248
248
  }
249
249
  Write($outfile, $tag, SetVarInt(length $buff), $buff) or return -1;
250
250
  } elsif (not defined $soi) {
@@ -301,7 +301,7 @@ sub ProcessFLIF($$)
301
301
  $et->Warn("Error inflating FLIF $tag chunk");
302
302
  }
303
303
  } else {
304
- $et->WarnOnce('Install IO::Uncompress::RawInflate to decode FLIF metadata');
304
+ $et->Warn('Install IO::Uncompress::RawInflate to decode FLIF metadata');
305
305
  }
306
306
  } else {
307
307
  $raf->Seek($size, 1) or $et->Warn('Seek error'), last;
@@ -329,7 +329,7 @@ meta information in FLIF (Free Lossless Image Format) images.
329
329
 
330
330
  =head1 AUTHOR
331
331
 
332
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
332
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
333
333
 
334
334
  This library is free software; you can redistribute it and/or modify it
335
335
  under the same terms as Perl itself.
@@ -1633,7 +1633,7 @@ Systems Inc. thermal image files (FFF, FPF and JPEG format).
1633
1633
 
1634
1634
  =head1 AUTHOR
1635
1635
 
1636
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
1636
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
1637
1637
 
1638
1638
  This library is free software; you can redistribute it and/or modify it
1639
1639
  under the same terms as Perl itself.
@@ -354,7 +354,7 @@ linear list when ApplyFixups() is called.
354
354
 
355
355
  =head1 AUTHOR
356
356
 
357
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
357
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
358
358
 
359
359
  This library is free software; you can redistribute it and/or modify it
360
360
  under the same terms as Perl itself.
@@ -721,7 +721,7 @@ will add AMF3 support.
721
721
 
722
722
  =head1 AUTHOR
723
723
 
724
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
724
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
725
725
 
726
726
  This library is free software; you can redistribute it and/or modify it
727
727
  under the same terms as Perl itself.