exiftool_vendored 9.33.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 (864) hide show
  1. checksums.yaml +15 -0
  2. data/bin/Image-ExifTool-9.33/Changes +6241 -0
  3. data/bin/Image-ExifTool-9.33/MANIFEST +859 -0
  4. data/bin/Image-ExifTool-9.33/META.yml +27 -0
  5. data/bin/Image-ExifTool-9.33/Makefile.PL +41 -0
  6. data/bin/Image-ExifTool-9.33/README +227 -0
  7. data/bin/Image-ExifTool-9.33/arg_files/exif2iptc.args +24 -0
  8. data/bin/Image-ExifTool-9.33/arg_files/exif2xmp.args +38 -0
  9. data/bin/Image-ExifTool-9.33/arg_files/gps2xmp.args +20 -0
  10. data/bin/Image-ExifTool-9.33/arg_files/iptc2exif.args +17 -0
  11. data/bin/Image-ExifTool-9.33/arg_files/iptc2xmp.args +53 -0
  12. data/bin/Image-ExifTool-9.33/arg_files/iptcCore.args +172 -0
  13. data/bin/Image-ExifTool-9.33/arg_files/pdf2xmp.args +23 -0
  14. data/bin/Image-ExifTool-9.33/arg_files/xmp2exif.args +39 -0
  15. data/bin/Image-ExifTool-9.33/arg_files/xmp2gps.args +24 -0
  16. data/bin/Image-ExifTool-9.33/arg_files/xmp2iptc.args +62 -0
  17. data/bin/Image-ExifTool-9.33/arg_files/xmp2pdf.args +23 -0
  18. data/bin/Image-ExifTool-9.33/config_files/ExifTool_config +299 -0
  19. data/bin/Image-ExifTool-9.33/config_files/convert_regions.config +81 -0
  20. data/bin/Image-ExifTool-9.33/exiftool +5715 -0
  21. data/bin/Image-ExifTool-9.33/fmt_files/gpx.fmt +29 -0
  22. data/bin/Image-ExifTool-9.33/fmt_files/gpx_wpt.fmt +33 -0
  23. data/bin/Image-ExifTool-9.33/fmt_files/kml.fmt +53 -0
  24. data/bin/Image-ExifTool-9.33/html/ExifTool.html +1959 -0
  25. data/bin/Image-ExifTool-9.33/html/MIE1.1-20070121.pdf +0 -0
  26. data/bin/Image-ExifTool-9.33/html/Shift.html +173 -0
  27. data/bin/Image-ExifTool-9.33/html/TagNames/AFCP.html +53 -0
  28. data/bin/Image-ExifTool-9.33/html/TagNames/AIFF.html +146 -0
  29. data/bin/Image-ExifTool-9.33/html/TagNames/APE.html +149 -0
  30. data/bin/Image-ExifTool-9.33/html/TagNames/APP12.html +188 -0
  31. data/bin/Image-ExifTool-9.33/html/TagNames/ASF.html +1066 -0
  32. data/bin/Image-ExifTool-9.33/html/TagNames/BMP.html +110 -0
  33. data/bin/Image-ExifTool-9.33/html/TagNames/Canon.html +8062 -0
  34. data/bin/Image-ExifTool-9.33/html/TagNames/CanonCustom.html +2044 -0
  35. data/bin/Image-ExifTool-9.33/html/TagNames/CanonRaw.html +561 -0
  36. data/bin/Image-ExifTool-9.33/html/TagNames/CanonVRD.html +1222 -0
  37. data/bin/Image-ExifTool-9.33/html/TagNames/Casio.html +1569 -0
  38. data/bin/Image-ExifTool-9.33/html/TagNames/Composite.html +665 -0
  39. data/bin/Image-ExifTool-9.33/html/TagNames/DICOM.html +15762 -0
  40. data/bin/Image-ExifTool-9.33/html/TagNames/DNG.html +273 -0
  41. data/bin/Image-ExifTool-9.33/html/TagNames/DV.html +75 -0
  42. data/bin/Image-ExifTool-9.33/html/TagNames/DarwinCore.html +1445 -0
  43. data/bin/Image-ExifTool-9.33/html/TagNames/DjVu.html +313 -0
  44. data/bin/Image-ExifTool-9.33/html/TagNames/EXE.html +697 -0
  45. data/bin/Image-ExifTool-9.33/html/TagNames/EXIF.html +3244 -0
  46. data/bin/Image-ExifTool-9.33/html/TagNames/Extra.html +301 -0
  47. data/bin/Image-ExifTool-9.33/html/TagNames/FLAC.html +183 -0
  48. data/bin/Image-ExifTool-9.33/html/TagNames/FLIR.html +931 -0
  49. data/bin/Image-ExifTool-9.33/html/TagNames/Flash.html +419 -0
  50. data/bin/Image-ExifTool-9.33/html/TagNames/FlashPix.html +1435 -0
  51. data/bin/Image-ExifTool-9.33/html/TagNames/Font.html +485 -0
  52. data/bin/Image-ExifTool-9.33/html/TagNames/FotoStation.html +103 -0
  53. data/bin/Image-ExifTool-9.33/html/TagNames/FujiFilm.html +637 -0
  54. data/bin/Image-ExifTool-9.33/html/TagNames/GE.html +40 -0
  55. data/bin/Image-ExifTool-9.33/html/TagNames/GIF.html +116 -0
  56. data/bin/Image-ExifTool-9.33/html/TagNames/GIMP.html +140 -0
  57. data/bin/Image-ExifTool-9.33/html/TagNames/GPS.html +222 -0
  58. data/bin/Image-ExifTool-9.33/html/TagNames/GeoTiff.html +2177 -0
  59. data/bin/Image-ExifTool-9.33/html/TagNames/H264.html +393 -0
  60. data/bin/Image-ExifTool-9.33/html/TagNames/HP.html +155 -0
  61. data/bin/Image-ExifTool-9.33/html/TagNames/HTML.html +666 -0
  62. data/bin/Image-ExifTool-9.33/html/TagNames/ICC_Profile.html +710 -0
  63. data/bin/Image-ExifTool-9.33/html/TagNames/ID3.html +1473 -0
  64. data/bin/Image-ExifTool-9.33/html/TagNames/IPTC.html +895 -0
  65. data/bin/Image-ExifTool-9.33/html/TagNames/ITC.html +90 -0
  66. data/bin/Image-ExifTool-9.33/html/TagNames/JFIF.html +61 -0
  67. data/bin/Image-ExifTool-9.33/html/TagNames/JPEG.html +523 -0
  68. data/bin/Image-ExifTool-9.33/html/TagNames/JVC.html +56 -0
  69. data/bin/Image-ExifTool-9.33/html/TagNames/Jpeg2000.html +464 -0
  70. data/bin/Image-ExifTool-9.33/html/TagNames/Kodak.html +1759 -0
  71. data/bin/Image-ExifTool-9.33/html/TagNames/KyoceraRaw.html +92 -0
  72. data/bin/Image-ExifTool-9.33/html/TagNames/LNK.html +478 -0
  73. data/bin/Image-ExifTool-9.33/html/TagNames/Leaf.html +870 -0
  74. data/bin/Image-ExifTool-9.33/html/TagNames/M2TS.html +133 -0
  75. data/bin/Image-ExifTool-9.33/html/TagNames/MIE.html +1026 -0
  76. data/bin/Image-ExifTool-9.33/html/TagNames/MIFF.html +196 -0
  77. data/bin/Image-ExifTool-9.33/html/TagNames/MNG.html +847 -0
  78. data/bin/Image-ExifTool-9.33/html/TagNames/MPC.html +97 -0
  79. data/bin/Image-ExifTool-9.33/html/TagNames/MPEG.html +249 -0
  80. data/bin/Image-ExifTool-9.33/html/TagNames/MPF.html +199 -0
  81. data/bin/Image-ExifTool-9.33/html/TagNames/MWG.html +563 -0
  82. data/bin/Image-ExifTool-9.33/html/TagNames/MXF.html +6673 -0
  83. data/bin/Image-ExifTool-9.33/html/TagNames/Matroska.html +1069 -0
  84. data/bin/Image-ExifTool-9.33/html/TagNames/Microsoft.html +2066 -0
  85. data/bin/Image-ExifTool-9.33/html/TagNames/Minolta.html +2555 -0
  86. data/bin/Image-ExifTool-9.33/html/TagNames/MinoltaRaw.html +326 -0
  87. data/bin/Image-ExifTool-9.33/html/TagNames/Nikon.html +4467 -0
  88. data/bin/Image-ExifTool-9.33/html/TagNames/NikonCapture.html +776 -0
  89. data/bin/Image-ExifTool-9.33/html/TagNames/NikonCustom.html +3835 -0
  90. data/bin/Image-ExifTool-9.33/html/TagNames/OOXML.html +280 -0
  91. data/bin/Image-ExifTool-9.33/html/TagNames/Ogg.html +44 -0
  92. data/bin/Image-ExifTool-9.33/html/TagNames/Olympus.html +3386 -0
  93. data/bin/Image-ExifTool-9.33/html/TagNames/OpenEXR.html +222 -0
  94. data/bin/Image-ExifTool-9.33/html/TagNames/PDF.html +745 -0
  95. data/bin/Image-ExifTool-9.33/html/TagNames/PGF.html +80 -0
  96. data/bin/Image-ExifTool-9.33/html/TagNames/PICT.html +753 -0
  97. data/bin/Image-ExifTool-9.33/html/TagNames/PLIST.html +86 -0
  98. data/bin/Image-ExifTool-9.33/html/TagNames/PNG.html +515 -0
  99. data/bin/Image-ExifTool-9.33/html/TagNames/PSP.html +160 -0
  100. data/bin/Image-ExifTool-9.33/html/TagNames/Panasonic.html +1452 -0
  101. data/bin/Image-ExifTool-9.33/html/TagNames/PanasonicRaw.html +214 -0
  102. data/bin/Image-ExifTool-9.33/html/TagNames/Pentax.html +4332 -0
  103. data/bin/Image-ExifTool-9.33/html/TagNames/PhaseOne.html +258 -0
  104. data/bin/Image-ExifTool-9.33/html/TagNames/PhotoCD.html +402 -0
  105. data/bin/Image-ExifTool-9.33/html/TagNames/PhotoMechanic.html +196 -0
  106. data/bin/Image-ExifTool-9.33/html/TagNames/Photoshop.html +555 -0
  107. data/bin/Image-ExifTool-9.33/html/TagNames/PostScript.html +125 -0
  108. data/bin/Image-ExifTool-9.33/html/TagNames/PrintIM.html +31 -0
  109. data/bin/Image-ExifTool-9.33/html/TagNames/Qualcomm.html +4778 -0
  110. data/bin/Image-ExifTool-9.33/html/TagNames/QuickTime.html +3104 -0
  111. data/bin/Image-ExifTool-9.33/html/TagNames/RIFF.html +1164 -0
  112. data/bin/Image-ExifTool-9.33/html/TagNames/RSRC.html +74 -0
  113. data/bin/Image-ExifTool-9.33/html/TagNames/RTF.html +150 -0
  114. data/bin/Image-ExifTool-9.33/html/TagNames/Radiance.html +87 -0
  115. data/bin/Image-ExifTool-9.33/html/TagNames/Rawzor.html +45 -0
  116. data/bin/Image-ExifTool-9.33/html/TagNames/Real.html +780 -0
  117. data/bin/Image-ExifTool-9.33/html/TagNames/Reconyx.html +132 -0
  118. data/bin/Image-ExifTool-9.33/html/TagNames/Ricoh.html +456 -0
  119. data/bin/Image-ExifTool-9.33/html/TagNames/Samsung.html +419 -0
  120. data/bin/Image-ExifTool-9.33/html/TagNames/Sanyo.html +366 -0
  121. data/bin/Image-ExifTool-9.33/html/TagNames/Shortcuts.html +237 -0
  122. data/bin/Image-ExifTool-9.33/html/TagNames/Sigma.html +372 -0
  123. data/bin/Image-ExifTool-9.33/html/TagNames/SigmaRaw.html +403 -0
  124. data/bin/Image-ExifTool-9.33/html/TagNames/Sony.html +4279 -0
  125. data/bin/Image-ExifTool-9.33/html/TagNames/SonyIDC.html +267 -0
  126. data/bin/Image-ExifTool-9.33/html/TagNames/Stim.html +200 -0
  127. data/bin/Image-ExifTool-9.33/html/TagNames/Theora.html +102 -0
  128. data/bin/Image-ExifTool-9.33/html/TagNames/Unknown.html +31 -0
  129. data/bin/Image-ExifTool-9.33/html/TagNames/Vorbis.html +228 -0
  130. data/bin/Image-ExifTool-9.33/html/TagNames/XMP.html +7234 -0
  131. data/bin/Image-ExifTool-9.33/html/TagNames/ZIP.html +204 -0
  132. data/bin/Image-ExifTool-9.33/html/TagNames/iWork.html +49 -0
  133. data/bin/Image-ExifTool-9.33/html/TagNames/index.html +192 -0
  134. data/bin/Image-ExifTool-9.33/html/TagNames/style.css +31 -0
  135. data/bin/Image-ExifTool-9.33/html/ancient_history.html +6727 -0
  136. data/bin/Image-ExifTool-9.33/html/canon_raw.html +366 -0
  137. data/bin/Image-ExifTool-9.33/html/commentary.html +319 -0
  138. data/bin/Image-ExifTool-9.33/html/config.html +312 -0
  139. data/bin/Image-ExifTool-9.33/html/data_members.html +265 -0
  140. data/bin/Image-ExifTool-9.33/html/exiftool_pod.html +2338 -0
  141. data/bin/Image-ExifTool-9.33/html/faq.html +1434 -0
  142. data/bin/Image-ExifTool-9.33/html/filename.html +281 -0
  143. data/bin/Image-ExifTool-9.33/html/geotag.html +642 -0
  144. data/bin/Image-ExifTool-9.33/html/history.html +358 -0
  145. data/bin/Image-ExifTool-9.33/html/htmldump.html +732 -0
  146. data/bin/Image-ExifTool-9.33/html/idiosyncracies.html +251 -0
  147. data/bin/Image-ExifTool-9.33/html/index.html +1271 -0
  148. data/bin/Image-ExifTool-9.33/html/install.html +239 -0
  149. data/bin/Image-ExifTool-9.33/html/metafiles.html +266 -0
  150. data/bin/Image-ExifTool-9.33/html/overview.png +0 -0
  151. data/bin/Image-ExifTool-9.33/html/standards.html +277 -0
  152. data/bin/Image-ExifTool-9.33/html/struct.html +342 -0
  153. data/bin/Image-ExifTool-9.33/html/style.css +31 -0
  154. data/bin/Image-ExifTool-9.33/html/under.html +124 -0
  155. data/bin/Image-ExifTool-9.33/html/verbose.html +195 -0
  156. data/bin/Image-ExifTool-9.33/html/writing.html +239 -0
  157. data/bin/Image-ExifTool-9.33/lib/File/RandomAccess.pm +378 -0
  158. data/bin/Image-ExifTool-9.33/lib/File/RandomAccess.pod +231 -0
  159. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool.pm +6815 -0
  160. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool.pod +2385 -0
  161. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/AES.pm +501 -0
  162. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/AFCP.pm +284 -0
  163. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/AIFF.pm +271 -0
  164. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/APE.pm +262 -0
  165. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/APP12.pm +322 -0
  166. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/ASF.pm +884 -0
  167. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/BMP.pm +179 -0
  168. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/BZZ.pm +472 -0
  169. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/BigTIFF.pm +282 -0
  170. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/BuildTagLookup.pm +2400 -0
  171. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Canon.pm +7794 -0
  172. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/CanonCustom.pm +2523 -0
  173. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/CanonRaw.pm +931 -0
  174. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/CanonVRD.pm +1481 -0
  175. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/CaptureOne.pm +235 -0
  176. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Casio.pm +2013 -0
  177. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset.pm +396 -0
  178. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/Arabic.pm +39 -0
  179. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/Baltic.pm +35 -0
  180. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/Cyrillic.pm +45 -0
  181. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/Greek.pm +40 -0
  182. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/Hebrew.pm +36 -0
  183. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/JIS.pm +1735 -0
  184. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/Latin.pm +24 -0
  185. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/Latin2.pm +36 -0
  186. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacArabic.pm +47 -0
  187. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacChineseCN.pm +2088 -0
  188. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacChineseTW.pm +3623 -0
  189. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacCroatian.pm +43 -0
  190. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacCyrillic.pm +47 -0
  191. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacGreek.pm +45 -0
  192. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacHebrew.pm +47 -0
  193. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacIceland.pm +42 -0
  194. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacJapanese.pm +1933 -0
  195. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacKorean.pm +2720 -0
  196. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacLatin2.pm +44 -0
  197. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacRSymbol.pm +2087 -0
  198. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacRoman.pm +42 -0
  199. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacRomanian.pm +42 -0
  200. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacThai.pm +49 -0
  201. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/MacTurkish.pm +42 -0
  202. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/PDFDoc.pm +28 -0
  203. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/ShiftJIS.pm +1835 -0
  204. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/Symbol.pm +54 -0
  205. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/Thai.pm +41 -0
  206. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/Turkish.pm +25 -0
  207. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Charset/Vietnam.pm +27 -0
  208. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/DICOM.pm +3835 -0
  209. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/DNG.pm +835 -0
  210. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/DV.pm +319 -0
  211. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/DarwinCore.pm +317 -0
  212. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/DjVu.pm +376 -0
  213. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/EXE.pm +1228 -0
  214. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Exif.pm +4542 -0
  215. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/FLAC.pm +296 -0
  216. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/FLIR.pm +972 -0
  217. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Fixup.pm +354 -0
  218. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Flash.pm +755 -0
  219. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/FlashPix.pm +1882 -0
  220. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Font.pm +643 -0
  221. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/FotoStation.pm +258 -0
  222. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/FujiFilm.pm +1020 -0
  223. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/GE.pm +80 -0
  224. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/GIF.pm +542 -0
  225. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/GIMP.pm +258 -0
  226. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/GPS.pm +511 -0
  227. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/GeoTiff.pm +2187 -0
  228. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Geotag.pm +1173 -0
  229. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/H264.pm +1102 -0
  230. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/HP.pm +262 -0
  231. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/HTML.pm +576 -0
  232. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/HtmlDump.pm +895 -0
  233. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/ICC_Profile.pm +999 -0
  234. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/ID3.pm +1532 -0
  235. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/IPTC.pm +1244 -0
  236. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/ITC.pm +215 -0
  237. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Import.pm +308 -0
  238. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/InDesign.pm +277 -0
  239. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/JPEG.pm +588 -0
  240. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/JPEGDigest.pm +2511 -0
  241. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/JVC.pm +130 -0
  242. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Jpeg2000.pm +881 -0
  243. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Kodak.pm +2014 -0
  244. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/KyoceraRaw.pm +173 -0
  245. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/LNK.pm +723 -0
  246. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/cs.pm +1586 -0
  247. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/de.pm +7356 -0
  248. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/en_ca.pm +557 -0
  249. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/en_gb.pm +572 -0
  250. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/es.pm +4016 -0
  251. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/fi.pm +2856 -0
  252. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/fr.pm +4720 -0
  253. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/it.pm +7917 -0
  254. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/ja.pm +5815 -0
  255. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/ko.pm +2332 -0
  256. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/nl.pm +3220 -0
  257. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/pl.pm +1140 -0
  258. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/ru.pm +769 -0
  259. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/sv.pm +639 -0
  260. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/tr.pm +544 -0
  261. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/zh_cn.pm +1329 -0
  262. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Lang/zh_tw.pm +802 -0
  263. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Leaf.pm +515 -0
  264. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/M2TS.pm +729 -0
  265. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/MIE.pm +2561 -0
  266. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/MIEUnits.pod +377 -0
  267. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/MIFF.pm +279 -0
  268. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/MNG.pm +684 -0
  269. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/MPC.pm +156 -0
  270. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/MPEG.pm +736 -0
  271. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/MPF.pm +289 -0
  272. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/MWG.pm +736 -0
  273. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/MXF.pm +3032 -0
  274. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/MakerNotes.pm +1573 -0
  275. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Matroska.pm +891 -0
  276. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Microsoft.pm +879 -0
  277. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Minolta.pm +2833 -0
  278. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/MinoltaRaw.pm +534 -0
  279. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Nikon.pm +6116 -0
  280. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/NikonCapture.pm +911 -0
  281. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/NikonCustom.pm +4405 -0
  282. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/OOXML.pm +409 -0
  283. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Ogg.pm +237 -0
  284. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Olympus.pm +3582 -0
  285. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/OpenEXR.pm +324 -0
  286. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PDF.pm +2327 -0
  287. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PGF.pm +143 -0
  288. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PICT.pm +1260 -0
  289. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PLIST.pm +449 -0
  290. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PNG.pm +1100 -0
  291. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PPM.pm +169 -0
  292. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PSP.pm +305 -0
  293. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Panasonic.pm +1995 -0
  294. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PanasonicRaw.pm +535 -0
  295. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Pentax.pm +5489 -0
  296. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PhaseOne.pm +557 -0
  297. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PhotoCD.pm +507 -0
  298. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PhotoMechanic.pm +256 -0
  299. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Photoshop.pm +629 -0
  300. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PostScript.pm +693 -0
  301. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/PrintIM.pm +125 -0
  302. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Qualcomm.pm +1344 -0
  303. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/QuickTime.pm +3519 -0
  304. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/README +944 -0
  305. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/RIFF.pm +1322 -0
  306. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/RSRC.pm +241 -0
  307. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/RTF.pm +383 -0
  308. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Radiance.pm +144 -0
  309. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Rawzor.pm +190 -0
  310. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Real.pm +736 -0
  311. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Reconyx.pm +190 -0
  312. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Ricoh.pm +741 -0
  313. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Samsung.pm +820 -0
  314. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Sanyo.pm +439 -0
  315. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Shift.pl +594 -0
  316. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Shortcuts.pm +291 -0
  317. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Sigma.pm +574 -0
  318. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/SigmaRaw.pm +649 -0
  319. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Sony.pm +5722 -0
  320. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/SonyIDC.pm +330 -0
  321. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Stim.pm +196 -0
  322. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/TagInfoXML.pm +792 -0
  323. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/TagLookup.pm +8005 -0
  324. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/TagNames.pod +25950 -0
  325. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Theora.pm +145 -0
  326. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Unknown.pm +66 -0
  327. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Vorbis.pm +237 -0
  328. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/WriteCanonRaw.pl +637 -0
  329. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/WriteExif.pl +3674 -0
  330. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/WriteIPTC.pl +702 -0
  331. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/WritePDF.pl +759 -0
  332. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/WritePNG.pl +330 -0
  333. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/WritePhotoshop.pl +266 -0
  334. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/WritePostScript.pl +777 -0
  335. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/WriteXMP.pl +1318 -0
  336. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/Writer.pl +5779 -0
  337. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/XMP.pm +3634 -0
  338. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/XMP2.pl +1298 -0
  339. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/XMPStruct.pl +813 -0
  340. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/ZIP.pm +623 -0
  341. data/bin/Image-ExifTool-9.33/lib/Image/ExifTool/iWork.pm +223 -0
  342. data/bin/Image-ExifTool-9.33/perl-Image-ExifTool.spec +104 -0
  343. data/bin/Image-ExifTool-9.33/t/AFCP.t +44 -0
  344. data/bin/Image-ExifTool-9.33/t/AFCP_2.out +37 -0
  345. data/bin/Image-ExifTool-9.33/t/AFCP_3.out +20 -0
  346. data/bin/Image-ExifTool-9.33/t/AIFF.t +28 -0
  347. data/bin/Image-ExifTool-9.33/t/AIFF_2.out +31 -0
  348. data/bin/Image-ExifTool-9.33/t/APE.t +38 -0
  349. data/bin/Image-ExifTool-9.33/t/APE_2.out +28 -0
  350. data/bin/Image-ExifTool-9.33/t/APE_3.out +57 -0
  351. data/bin/Image-ExifTool-9.33/t/ASF.t +28 -0
  352. data/bin/Image-ExifTool-9.33/t/ASF_2.out +54 -0
  353. data/bin/Image-ExifTool-9.33/t/BMP.t +28 -0
  354. data/bin/Image-ExifTool-9.33/t/BMP_2.out +21 -0
  355. data/bin/Image-ExifTool-9.33/t/BigTIFF.t +28 -0
  356. data/bin/Image-ExifTool-9.33/t/BigTIFF_2.out +19 -0
  357. data/bin/Image-ExifTool-9.33/t/Canon.t +41 -0
  358. data/bin/Image-ExifTool-9.33/t/CanonRaw.t +126 -0
  359. data/bin/Image-ExifTool-9.33/t/CanonRaw_2.out +165 -0
  360. data/bin/Image-ExifTool-9.33/t/CanonRaw_4.out +217 -0
  361. data/bin/Image-ExifTool-9.33/t/CanonRaw_5.out +207 -0
  362. data/bin/Image-ExifTool-9.33/t/CanonRaw_6.out +231 -0
  363. data/bin/Image-ExifTool-9.33/t/CanonRaw_7.out +247 -0
  364. data/bin/Image-ExifTool-9.33/t/CanonVRD.t +129 -0
  365. data/bin/Image-ExifTool-9.33/t/CanonVRD_11.out +118 -0
  366. data/bin/Image-ExifTool-9.33/t/CanonVRD_12.out +12 -0
  367. data/bin/Image-ExifTool-9.33/t/CanonVRD_2.out +116 -0
  368. data/bin/Image-ExifTool-9.33/t/CanonVRD_3.out +116 -0
  369. data/bin/Image-ExifTool-9.33/t/CanonVRD_4.out +2 -0
  370. data/bin/Image-ExifTool-9.33/t/CanonVRD_5.out +3 -0
  371. data/bin/Image-ExifTool-9.33/t/CanonVRD_6.out +3 -0
  372. data/bin/Image-ExifTool-9.33/t/CanonVRD_7.out +2 -0
  373. data/bin/Image-ExifTool-9.33/t/CanonVRD_8.out +2 -0
  374. data/bin/Image-ExifTool-9.33/t/CanonVRD_9.out +1 -0
  375. data/bin/Image-ExifTool-9.33/t/Canon_2.out +350 -0
  376. data/bin/Image-ExifTool-9.33/t/Canon_3.out +3 -0
  377. data/bin/Image-ExifTool-9.33/t/Casio.t +54 -0
  378. data/bin/Image-ExifTool-9.33/t/Casio_2.out +70 -0
  379. data/bin/Image-ExifTool-9.33/t/Casio_3.out +100 -0
  380. data/bin/Image-ExifTool-9.33/t/Casio_4.out +26 -0
  381. data/bin/Image-ExifTool-9.33/t/Casio_5.out +78 -0
  382. data/bin/Image-ExifTool-9.33/t/Casio_6.out +115 -0
  383. data/bin/Image-ExifTool-9.33/t/DICOM.t +28 -0
  384. data/bin/Image-ExifTool-9.33/t/DICOM_2.out +108 -0
  385. data/bin/Image-ExifTool-9.33/t/DNG.t +39 -0
  386. data/bin/Image-ExifTool-9.33/t/DNG_2.out +326 -0
  387. data/bin/Image-ExifTool-9.33/t/DNG_3.out +4 -0
  388. data/bin/Image-ExifTool-9.33/t/DV.t +27 -0
  389. data/bin/Image-ExifTool-9.33/t/DV_2.out +24 -0
  390. data/bin/Image-ExifTool-9.33/t/DjVu.t +28 -0
  391. data/bin/Image-ExifTool-9.33/t/DjVu_2.out +44 -0
  392. data/bin/Image-ExifTool-9.33/t/EXE.t +31 -0
  393. data/bin/Image-ExifTool-9.33/t/EXE_2.out +40 -0
  394. data/bin/Image-ExifTool-9.33/t/EXE_3.out +15 -0
  395. data/bin/Image-ExifTool-9.33/t/EXE_4.out +14 -0
  396. data/bin/Image-ExifTool-9.33/t/ExifTool.t +284 -0
  397. data/bin/Image-ExifTool-9.33/t/ExifTool_16.out +180 -0
  398. data/bin/Image-ExifTool-9.33/t/ExifTool_17.out +594 -0
  399. data/bin/Image-ExifTool-9.33/t/ExifTool_2.out +399 -0
  400. data/bin/Image-ExifTool-9.33/t/ExifTool_20.out +1 -0
  401. data/bin/Image-ExifTool-9.33/t/ExifTool_21.out +1 -0
  402. data/bin/Image-ExifTool-9.33/t/ExifTool_22.out +1 -0
  403. data/bin/Image-ExifTool-9.33/t/ExifTool_23.out +6 -0
  404. data/bin/Image-ExifTool-9.33/t/ExifTool_24.out +3 -0
  405. data/bin/Image-ExifTool-9.33/t/ExifTool_25.out +13 -0
  406. data/bin/Image-ExifTool-9.33/t/ExifTool_26.out +12 -0
  407. data/bin/Image-ExifTool-9.33/t/ExifTool_3.out +87 -0
  408. data/bin/Image-ExifTool-9.33/t/ExifTool_4.out +41 -0
  409. data/bin/Image-ExifTool-9.33/t/ExifTool_5.out +6 -0
  410. data/bin/Image-ExifTool-9.33/t/ExifTool_6.out +68 -0
  411. data/bin/Image-ExifTool-9.33/t/ExifTool_7.out +125 -0
  412. data/bin/Image-ExifTool-9.33/t/ExifTool_8.out +125 -0
  413. data/bin/Image-ExifTool-9.33/t/ExifTool_9.out +33 -0
  414. data/bin/Image-ExifTool-9.33/t/FLAC.t +37 -0
  415. data/bin/Image-ExifTool-9.33/t/FLAC_2.out +25 -0
  416. data/bin/Image-ExifTool-9.33/t/FLAC_3.out +19 -0
  417. data/bin/Image-ExifTool-9.33/t/FLIR.t +30 -0
  418. data/bin/Image-ExifTool-9.33/t/FLIR_2.out +104 -0
  419. data/bin/Image-ExifTool-9.33/t/FLIR_3.out +47 -0
  420. data/bin/Image-ExifTool-9.33/t/Flash.t +37 -0
  421. data/bin/Image-ExifTool-9.33/t/FlashPix.t +30 -0
  422. data/bin/Image-ExifTool-9.33/t/FlashPix_2.out +48 -0
  423. data/bin/Image-ExifTool-9.33/t/Flash_2.out +20 -0
  424. data/bin/Image-ExifTool-9.33/t/Flash_3.out +53 -0
  425. data/bin/Image-ExifTool-9.33/t/Font.t +30 -0
  426. data/bin/Image-ExifTool-9.33/t/Font_2.out +23 -0
  427. data/bin/Image-ExifTool-9.33/t/Font_3.out +35 -0
  428. data/bin/Image-ExifTool-9.33/t/Font_4.out +26 -0
  429. data/bin/Image-ExifTool-9.33/t/Font_5.out +26 -0
  430. data/bin/Image-ExifTool-9.33/t/Font_6.out +36 -0
  431. data/bin/Image-ExifTool-9.33/t/Font_7.out +36 -0
  432. data/bin/Image-ExifTool-9.33/t/FotoStation.t +38 -0
  433. data/bin/Image-ExifTool-9.33/t/FotoStation_2.out +39 -0
  434. data/bin/Image-ExifTool-9.33/t/FotoStation_3.out +3 -0
  435. data/bin/Image-ExifTool-9.33/t/FujiFilm.t +78 -0
  436. data/bin/Image-ExifTool-9.33/t/FujiFilm_2.out +87 -0
  437. data/bin/Image-ExifTool-9.33/t/FujiFilm_3.out +88 -0
  438. data/bin/Image-ExifTool-9.33/t/FujiFilm_4.out +117 -0
  439. data/bin/Image-ExifTool-9.33/t/FujiFilm_5.out +1 -0
  440. data/bin/Image-ExifTool-9.33/t/GE.t +46 -0
  441. data/bin/Image-ExifTool-9.33/t/GE_2.out +84 -0
  442. data/bin/Image-ExifTool-9.33/t/GE_3.out +84 -0
  443. data/bin/Image-ExifTool-9.33/t/GIF.t +83 -0
  444. data/bin/Image-ExifTool-9.33/t/GIF_2.out +40 -0
  445. data/bin/Image-ExifTool-9.33/t/GIF_3.out +41 -0
  446. data/bin/Image-ExifTool-9.33/t/GIF_4.out +16 -0
  447. data/bin/Image-ExifTool-9.33/t/GIMP.t +27 -0
  448. data/bin/Image-ExifTool-9.33/t/GIMP_2.out +63 -0
  449. data/bin/Image-ExifTool-9.33/t/GPS.t +42 -0
  450. data/bin/Image-ExifTool-9.33/t/GPS_2.out +94 -0
  451. data/bin/Image-ExifTool-9.33/t/GPS_3.out +96 -0
  452. data/bin/Image-ExifTool-9.33/t/GeoTiff.t +36 -0
  453. data/bin/Image-ExifTool-9.33/t/GeoTiff_2.out +36 -0
  454. data/bin/Image-ExifTool-9.33/t/GeoTiff_3.out +36 -0
  455. data/bin/Image-ExifTool-9.33/t/Geotag.t +164 -0
  456. data/bin/Image-ExifTool-9.33/t/Geotag_2.out +9 -0
  457. data/bin/Image-ExifTool-9.33/t/Geotag_3.out +6 -0
  458. data/bin/Image-ExifTool-9.33/t/Geotag_5.out +1 -0
  459. data/bin/Image-ExifTool-9.33/t/Geotag_6.out +9 -0
  460. data/bin/Image-ExifTool-9.33/t/Geotag_7.out +53 -0
  461. data/bin/Image-ExifTool-9.33/t/Geotag_8.out +15 -0
  462. data/bin/Image-ExifTool-9.33/t/HTML.t +28 -0
  463. data/bin/Image-ExifTool-9.33/t/HTML_2.out +68 -0
  464. data/bin/Image-ExifTool-9.33/t/IPTC.t +157 -0
  465. data/bin/Image-ExifTool-9.33/t/IPTC_2.out +58 -0
  466. data/bin/Image-ExifTool-9.33/t/IPTC_4.out +56 -0
  467. data/bin/Image-ExifTool-9.33/t/IPTC_5.out +1 -0
  468. data/bin/Image-ExifTool-9.33/t/IPTC_6.out +2 -0
  469. data/bin/Image-ExifTool-9.33/t/IPTC_7.out +1 -0
  470. data/bin/Image-ExifTool-9.33/t/IPTC_8.out +20 -0
  471. data/bin/Image-ExifTool-9.33/t/ITC.t +28 -0
  472. data/bin/Image-ExifTool-9.33/t/ITC_2.out +19 -0
  473. data/bin/Image-ExifTool-9.33/t/InDesign.t +61 -0
  474. data/bin/Image-ExifTool-9.33/t/InDesign_2.out +19 -0
  475. data/bin/Image-ExifTool-9.33/t/InDesign_3.out +21 -0
  476. data/bin/Image-ExifTool-9.33/t/InDesign_4.out +11 -0
  477. data/bin/Image-ExifTool-9.33/t/JVC.t +36 -0
  478. data/bin/Image-ExifTool-9.33/t/JVC_2.out +3 -0
  479. data/bin/Image-ExifTool-9.33/t/JVC_3.out +3 -0
  480. data/bin/Image-ExifTool-9.33/t/Jpeg2000.t +49 -0
  481. data/bin/Image-ExifTool-9.33/t/Jpeg2000_2.out +63 -0
  482. data/bin/Image-ExifTool-9.33/t/Jpeg2000_3.out +51 -0
  483. data/bin/Image-ExifTool-9.33/t/Jpeg2000_4.out +15 -0
  484. data/bin/Image-ExifTool-9.33/t/Kodak.t +40 -0
  485. data/bin/Image-ExifTool-9.33/t/Kodak_2.out +109 -0
  486. data/bin/Image-ExifTool-9.33/t/Kodak_3.out +119 -0
  487. data/bin/Image-ExifTool-9.33/t/KyoceraRaw.t +28 -0
  488. data/bin/Image-ExifTool-9.33/t/KyoceraRaw_2.out +27 -0
  489. data/bin/Image-ExifTool-9.33/t/LNK.t +28 -0
  490. data/bin/Image-ExifTool-9.33/t/LNK_2.out +45 -0
  491. data/bin/Image-ExifTool-9.33/t/Lang.t +40 -0
  492. data/bin/Image-ExifTool-9.33/t/Lang_1.out +1 -0
  493. data/bin/Image-ExifTool-9.33/t/Lang_10.out +46 -0
  494. data/bin/Image-ExifTool-9.33/t/Lang_11.out +46 -0
  495. data/bin/Image-ExifTool-9.33/t/Lang_12.out +46 -0
  496. data/bin/Image-ExifTool-9.33/t/Lang_13.out +46 -0
  497. data/bin/Image-ExifTool-9.33/t/Lang_14.out +46 -0
  498. data/bin/Image-ExifTool-9.33/t/Lang_15.out +46 -0
  499. data/bin/Image-ExifTool-9.33/t/Lang_16.out +46 -0
  500. data/bin/Image-ExifTool-9.33/t/Lang_17.out +46 -0
  501. data/bin/Image-ExifTool-9.33/t/Lang_18.out +46 -0
  502. data/bin/Image-ExifTool-9.33/t/Lang_2.out +46 -0
  503. data/bin/Image-ExifTool-9.33/t/Lang_3.out +46 -0
  504. data/bin/Image-ExifTool-9.33/t/Lang_4.out +46 -0
  505. data/bin/Image-ExifTool-9.33/t/Lang_5.out +46 -0
  506. data/bin/Image-ExifTool-9.33/t/Lang_6.out +46 -0
  507. data/bin/Image-ExifTool-9.33/t/Lang_7.out +46 -0
  508. data/bin/Image-ExifTool-9.33/t/Lang_8.out +46 -0
  509. data/bin/Image-ExifTool-9.33/t/Lang_9.out +46 -0
  510. data/bin/Image-ExifTool-9.33/t/M2TS.t +29 -0
  511. data/bin/Image-ExifTool-9.33/t/M2TS_2.out +27 -0
  512. data/bin/Image-ExifTool-9.33/t/MIE.t +82 -0
  513. data/bin/Image-ExifTool-9.33/t/MIE_2.out +67 -0
  514. data/bin/Image-ExifTool-9.33/t/MIE_3.out +134 -0
  515. data/bin/Image-ExifTool-9.33/t/MIE_5.out +1 -0
  516. data/bin/Image-ExifTool-9.33/t/MIE_6.out +1 -0
  517. data/bin/Image-ExifTool-9.33/t/MIFF.t +28 -0
  518. data/bin/Image-ExifTool-9.33/t/MIFF_2.out +108 -0
  519. data/bin/Image-ExifTool-9.33/t/MP3.t +29 -0
  520. data/bin/Image-ExifTool-9.33/t/MP3_2.out +45 -0
  521. data/bin/Image-ExifTool-9.33/t/MWG.t +72 -0
  522. data/bin/Image-ExifTool-9.33/t/MWG_2.out +13 -0
  523. data/bin/Image-ExifTool-9.33/t/MWG_3.out +8 -0
  524. data/bin/Image-ExifTool-9.33/t/MWG_4.out +5 -0
  525. data/bin/Image-ExifTool-9.33/t/MWG_5.out +22 -0
  526. data/bin/Image-ExifTool-9.33/t/MXF.t +27 -0
  527. data/bin/Image-ExifTool-9.33/t/MXF_2.out +78 -0
  528. data/bin/Image-ExifTool-9.33/t/Matroska.t +29 -0
  529. data/bin/Image-ExifTool-9.33/t/Matroska_2.out +64 -0
  530. data/bin/Image-ExifTool-9.33/t/Minolta.t +50 -0
  531. data/bin/Image-ExifTool-9.33/t/Minolta_2.out +133 -0
  532. data/bin/Image-ExifTool-9.33/t/Minolta_3.out +146 -0
  533. data/bin/Image-ExifTool-9.33/t/Minolta_4.out +148 -0
  534. data/bin/Image-ExifTool-9.33/t/Nikon.t +114 -0
  535. data/bin/Image-ExifTool-9.33/t/Nikon_2.out +82 -0
  536. data/bin/Image-ExifTool-9.33/t/Nikon_3.out +98 -0
  537. data/bin/Image-ExifTool-9.33/t/Nikon_4.out +174 -0
  538. data/bin/Image-ExifTool-9.33/t/Nikon_5.out +167 -0
  539. data/bin/Image-ExifTool-9.33/t/Nikon_7.out +260 -0
  540. data/bin/Image-ExifTool-9.33/t/Nikon_8.out +4 -0
  541. data/bin/Image-ExifTool-9.33/t/Olympus.t +85 -0
  542. data/bin/Image-ExifTool-9.33/t/Olympus_2.out +79 -0
  543. data/bin/Image-ExifTool-9.33/t/Olympus_3.out +81 -0
  544. data/bin/Image-ExifTool-9.33/t/Olympus_4.out +192 -0
  545. data/bin/Image-ExifTool-9.33/t/Olympus_5.out +264 -0
  546. data/bin/Image-ExifTool-9.33/t/Olympus_6.out +151 -0
  547. data/bin/Image-ExifTool-9.33/t/Olympus_7.out +482 -0
  548. data/bin/Image-ExifTool-9.33/t/OpenEXR.t +28 -0
  549. data/bin/Image-ExifTool-9.33/t/OpenEXR_2.out +23 -0
  550. data/bin/Image-ExifTool-9.33/t/PDF.t +295 -0
  551. data/bin/Image-ExifTool-9.33/t/PDF_10.out +10 -0
  552. data/bin/Image-ExifTool-9.33/t/PDF_11.out +10 -0
  553. data/bin/Image-ExifTool-9.33/t/PDF_12.out +9 -0
  554. data/bin/Image-ExifTool-9.33/t/PDF_14.out +5 -0
  555. data/bin/Image-ExifTool-9.33/t/PDF_15.out +6 -0
  556. data/bin/Image-ExifTool-9.33/t/PDF_16.out +4 -0
  557. data/bin/Image-ExifTool-9.33/t/PDF_17.out +4 -0
  558. data/bin/Image-ExifTool-9.33/t/PDF_18.out +5 -0
  559. data/bin/Image-ExifTool-9.33/t/PDF_19.out +6 -0
  560. data/bin/Image-ExifTool-9.33/t/PDF_2.out +117 -0
  561. data/bin/Image-ExifTool-9.33/t/PDF_20.out +4 -0
  562. data/bin/Image-ExifTool-9.33/t/PDF_22.out +3 -0
  563. data/bin/Image-ExifTool-9.33/t/PDF_4.out +12 -0
  564. data/bin/Image-ExifTool-9.33/t/PDF_5.out +8 -0
  565. data/bin/Image-ExifTool-9.33/t/PDF_6.out +9 -0
  566. data/bin/Image-ExifTool-9.33/t/PDF_7.out +11 -0
  567. data/bin/Image-ExifTool-9.33/t/PDF_8.out +9 -0
  568. data/bin/Image-ExifTool-9.33/t/PDF_9.out +9 -0
  569. data/bin/Image-ExifTool-9.33/t/PGF.t +28 -0
  570. data/bin/Image-ExifTool-9.33/t/PGF_2.out +32 -0
  571. data/bin/Image-ExifTool-9.33/t/PICT.t +28 -0
  572. data/bin/Image-ExifTool-9.33/t/PICT_2.out +15 -0
  573. data/bin/Image-ExifTool-9.33/t/PLIST.t +31 -0
  574. data/bin/Image-ExifTool-9.33/t/PLIST_2.out +20 -0
  575. data/bin/Image-ExifTool-9.33/t/PLIST_3.out +20 -0
  576. data/bin/Image-ExifTool-9.33/t/PNG.t +75 -0
  577. data/bin/Image-ExifTool-9.33/t/PNG_2.out +22 -0
  578. data/bin/Image-ExifTool-9.33/t/PNG_3.out +118 -0
  579. data/bin/Image-ExifTool-9.33/t/PNG_4.out +12 -0
  580. data/bin/Image-ExifTool-9.33/t/PPM.t +40 -0
  581. data/bin/Image-ExifTool-9.33/t/PPM_2.out +15 -0
  582. data/bin/Image-ExifTool-9.33/t/PPM_3.out +9 -0
  583. data/bin/Image-ExifTool-9.33/t/PSP.t +28 -0
  584. data/bin/Image-ExifTool-9.33/t/PSP_2.out +32 -0
  585. data/bin/Image-ExifTool-9.33/t/Panasonic.t +60 -0
  586. data/bin/Image-ExifTool-9.33/t/Panasonic_2.out +99 -0
  587. data/bin/Image-ExifTool-9.33/t/Panasonic_3.out +119 -0
  588. data/bin/Image-ExifTool-9.33/t/Panasonic_4.out +177 -0
  589. data/bin/Image-ExifTool-9.33/t/Panasonic_5.out +228 -0
  590. data/bin/Image-ExifTool-9.33/t/Pentax.t +50 -0
  591. data/bin/Image-ExifTool-9.33/t/Pentax_2.out +219 -0
  592. data/bin/Image-ExifTool-9.33/t/Pentax_3.out +262 -0
  593. data/bin/Image-ExifTool-9.33/t/Pentax_4.out +123 -0
  594. data/bin/Image-ExifTool-9.33/t/PhotoCD.t +28 -0
  595. data/bin/Image-ExifTool-9.33/t/PhotoCD_2.out +35 -0
  596. data/bin/Image-ExifTool-9.33/t/PhotoMechanic.t +38 -0
  597. data/bin/Image-ExifTool-9.33/t/PhotoMechanic_2.out +81 -0
  598. data/bin/Image-ExifTool-9.33/t/PhotoMechanic_3.out +2 -0
  599. data/bin/Image-ExifTool-9.33/t/Photoshop.t +42 -0
  600. data/bin/Image-ExifTool-9.33/t/Photoshop_2.out +96 -0
  601. data/bin/Image-ExifTool-9.33/t/Photoshop_3.out +108 -0
  602. data/bin/Image-ExifTool-9.33/t/PostScript.t +49 -0
  603. data/bin/Image-ExifTool-9.33/t/PostScript_2.out +64 -0
  604. data/bin/Image-ExifTool-9.33/t/PostScript_3.out +132 -0
  605. data/bin/Image-ExifTool-9.33/t/QuickTime.t +31 -0
  606. data/bin/Image-ExifTool-9.33/t/QuickTime_2.out +128 -0
  607. data/bin/Image-ExifTool-9.33/t/QuickTime_3.out +69 -0
  608. data/bin/Image-ExifTool-9.33/t/RIFF.t +31 -0
  609. data/bin/Image-ExifTool-9.33/t/RIFF_2.out +24 -0
  610. data/bin/Image-ExifTool-9.33/t/RIFF_3.out +52 -0
  611. data/bin/Image-ExifTool-9.33/t/RIFF_4.out +16 -0
  612. data/bin/Image-ExifTool-9.33/t/RTF.t +27 -0
  613. data/bin/Image-ExifTool-9.33/t/RTF_2.out +20 -0
  614. data/bin/Image-ExifTool-9.33/t/Radiance.t +28 -0
  615. data/bin/Image-ExifTool-9.33/t/Radiance_2.out +22 -0
  616. data/bin/Image-ExifTool-9.33/t/Real.t +46 -0
  617. data/bin/Image-ExifTool-9.33/t/Real_2.out +68 -0
  618. data/bin/Image-ExifTool-9.33/t/Real_3.out +18 -0
  619. data/bin/Image-ExifTool-9.33/t/Real_4.out +11 -0
  620. data/bin/Image-ExifTool-9.33/t/Ricoh.t +47 -0
  621. data/bin/Image-ExifTool-9.33/t/Ricoh_2.out +70 -0
  622. data/bin/Image-ExifTool-9.33/t/Ricoh_3.out +98 -0
  623. data/bin/Image-ExifTool-9.33/t/Ricoh_4.out +112 -0
  624. data/bin/Image-ExifTool-9.33/t/Sanyo.t +39 -0
  625. data/bin/Image-ExifTool-9.33/t/Sanyo_2.out +101 -0
  626. data/bin/Image-ExifTool-9.33/t/Sanyo_3.out +111 -0
  627. data/bin/Image-ExifTool-9.33/t/Sigma.t +60 -0
  628. data/bin/Image-ExifTool-9.33/t/Sigma_2.out +91 -0
  629. data/bin/Image-ExifTool-9.33/t/Sigma_3.out +94 -0
  630. data/bin/Image-ExifTool-9.33/t/Sigma_4.out +63 -0
  631. data/bin/Image-ExifTool-9.33/t/Sigma_5.out +192 -0
  632. data/bin/Image-ExifTool-9.33/t/Sony.t +62 -0
  633. data/bin/Image-ExifTool-9.33/t/Sony_2.out +84 -0
  634. data/bin/Image-ExifTool-9.33/t/Sony_3.out +85 -0
  635. data/bin/Image-ExifTool-9.33/t/Sony_5.out +32 -0
  636. data/bin/Image-ExifTool-9.33/t/TestLib.pm +417 -0
  637. data/bin/Image-ExifTool-9.33/t/Unknown.t +36 -0
  638. data/bin/Image-ExifTool-9.33/t/Unknown_2.out +90 -0
  639. data/bin/Image-ExifTool-9.33/t/Unknown_3.out +90 -0
  640. data/bin/Image-ExifTool-9.33/t/Vorbis.t +28 -0
  641. data/bin/Image-ExifTool-9.33/t/Vorbis_2.out +28 -0
  642. data/bin/Image-ExifTool-9.33/t/Writer.t +913 -0
  643. data/bin/Image-ExifTool-9.33/t/Writer_10.out +240 -0
  644. data/bin/Image-ExifTool-9.33/t/Writer_11.out +37 -0
  645. data/bin/Image-ExifTool-9.33/t/Writer_13.out +160 -0
  646. data/bin/Image-ExifTool-9.33/t/Writer_14.out +67 -0
  647. data/bin/Image-ExifTool-9.33/t/Writer_15.out +171 -0
  648. data/bin/Image-ExifTool-9.33/t/Writer_16.out +1 -0
  649. data/bin/Image-ExifTool-9.33/t/Writer_17.out +1 -0
  650. data/bin/Image-ExifTool-9.33/t/Writer_18.out +3 -0
  651. data/bin/Image-ExifTool-9.33/t/Writer_19.out +34 -0
  652. data/bin/Image-ExifTool-9.33/t/Writer_2.out +168 -0
  653. data/bin/Image-ExifTool-9.33/t/Writer_22.out +4 -0
  654. data/bin/Image-ExifTool-9.33/t/Writer_24.out +1 -0
  655. data/bin/Image-ExifTool-9.33/t/Writer_25.out +38 -0
  656. data/bin/Image-ExifTool-9.33/t/Writer_26.out +32 -0
  657. data/bin/Image-ExifTool-9.33/t/Writer_27.out +14 -0
  658. data/bin/Image-ExifTool-9.33/t/Writer_28.out +1 -0
  659. data/bin/Image-ExifTool-9.33/t/Writer_29.out +2 -0
  660. data/bin/Image-ExifTool-9.33/t/Writer_30.out +2 -0
  661. data/bin/Image-ExifTool-9.33/t/Writer_31.out +97 -0
  662. data/bin/Image-ExifTool-9.33/t/Writer_32.out +3 -0
  663. data/bin/Image-ExifTool-9.33/t/Writer_33.out +3 -0
  664. data/bin/Image-ExifTool-9.33/t/Writer_34.out +3 -0
  665. data/bin/Image-ExifTool-9.33/t/Writer_35.out +187 -0
  666. data/bin/Image-ExifTool-9.33/t/Writer_36.out +2 -0
  667. data/bin/Image-ExifTool-9.33/t/Writer_37.out +2 -0
  668. data/bin/Image-ExifTool-9.33/t/Writer_38.out +62 -0
  669. data/bin/Image-ExifTool-9.33/t/Writer_39.out +4 -0
  670. data/bin/Image-ExifTool-9.33/t/Writer_4.out +85 -0
  671. data/bin/Image-ExifTool-9.33/t/Writer_40.out +4 -0
  672. data/bin/Image-ExifTool-9.33/t/Writer_41.out +3 -0
  673. data/bin/Image-ExifTool-9.33/t/Writer_42.out +5 -0
  674. data/bin/Image-ExifTool-9.33/t/Writer_43.out +5 -0
  675. data/bin/Image-ExifTool-9.33/t/Writer_44.out +2 -0
  676. data/bin/Image-ExifTool-9.33/t/Writer_45.out +1 -0
  677. data/bin/Image-ExifTool-9.33/t/Writer_46.out +77 -0
  678. data/bin/Image-ExifTool-9.33/t/Writer_47.out +56 -0
  679. data/bin/Image-ExifTool-9.33/t/Writer_48.out +29 -0
  680. data/bin/Image-ExifTool-9.33/t/Writer_50.out +3 -0
  681. data/bin/Image-ExifTool-9.33/t/Writer_51.out +386 -0
  682. data/bin/Image-ExifTool-9.33/t/Writer_6.out +182 -0
  683. data/bin/Image-ExifTool-9.33/t/Writer_7.out +149 -0
  684. data/bin/Image-ExifTool-9.33/t/Writer_9.out +237 -0
  685. data/bin/Image-ExifTool-9.33/t/XMP.t +521 -0
  686. data/bin/Image-ExifTool-9.33/t/XMP_10.out +33 -0
  687. data/bin/Image-ExifTool-9.33/t/XMP_11.out +59 -0
  688. data/bin/Image-ExifTool-9.33/t/XMP_12.out +4 -0
  689. data/bin/Image-ExifTool-9.33/t/XMP_13.out +5 -0
  690. data/bin/Image-ExifTool-9.33/t/XMP_14.out +3 -0
  691. data/bin/Image-ExifTool-9.33/t/XMP_15.out +3 -0
  692. data/bin/Image-ExifTool-9.33/t/XMP_16.out +5 -0
  693. data/bin/Image-ExifTool-9.33/t/XMP_17.out +6 -0
  694. data/bin/Image-ExifTool-9.33/t/XMP_18.out +10 -0
  695. data/bin/Image-ExifTool-9.33/t/XMP_19.out +35 -0
  696. data/bin/Image-ExifTool-9.33/t/XMP_2.out +138 -0
  697. data/bin/Image-ExifTool-9.33/t/XMP_20.out +35 -0
  698. data/bin/Image-ExifTool-9.33/t/XMP_21.out +38 -0
  699. data/bin/Image-ExifTool-9.33/t/XMP_22.out +38 -0
  700. data/bin/Image-ExifTool-9.33/t/XMP_23.out +9 -0
  701. data/bin/Image-ExifTool-9.33/t/XMP_24.out +31 -0
  702. data/bin/Image-ExifTool-9.33/t/XMP_25.out +28 -0
  703. data/bin/Image-ExifTool-9.33/t/XMP_26.out +52 -0
  704. data/bin/Image-ExifTool-9.33/t/XMP_27.out +93 -0
  705. data/bin/Image-ExifTool-9.33/t/XMP_28.out +44 -0
  706. data/bin/Image-ExifTool-9.33/t/XMP_29.out +24 -0
  707. data/bin/Image-ExifTool-9.33/t/XMP_3.out +136 -0
  708. data/bin/Image-ExifTool-9.33/t/XMP_30.out +90 -0
  709. data/bin/Image-ExifTool-9.33/t/XMP_31.out +19 -0
  710. data/bin/Image-ExifTool-9.33/t/XMP_32.out +2 -0
  711. data/bin/Image-ExifTool-9.33/t/XMP_34.out +2 -0
  712. data/bin/Image-ExifTool-9.33/t/XMP_36.out +18 -0
  713. data/bin/Image-ExifTool-9.33/t/XMP_37.out +35 -0
  714. data/bin/Image-ExifTool-9.33/t/XMP_39.out +44 -0
  715. data/bin/Image-ExifTool-9.33/t/XMP_40.out +3 -0
  716. data/bin/Image-ExifTool-9.33/t/XMP_41.out +175 -0
  717. data/bin/Image-ExifTool-9.33/t/XMP_5.out +29 -0
  718. data/bin/Image-ExifTool-9.33/t/XMP_6.out +87 -0
  719. data/bin/Image-ExifTool-9.33/t/XMP_7.out +118 -0
  720. data/bin/Image-ExifTool-9.33/t/XMP_8.out +17 -0
  721. data/bin/Image-ExifTool-9.33/t/XMP_9.out +36 -0
  722. data/bin/Image-ExifTool-9.33/t/ZIP.t +69 -0
  723. data/bin/Image-ExifTool-9.33/t/ZIP_2.out +18 -0
  724. data/bin/Image-ExifTool-9.33/t/ZIP_3.out +17 -0
  725. data/bin/Image-ExifTool-9.33/t/ZIP_4.out +213 -0
  726. data/bin/Image-ExifTool-9.33/t/ZIP_5.out +134 -0
  727. data/bin/Image-ExifTool-9.33/t/ZIP_6.out +49 -0
  728. data/bin/Image-ExifTool-9.33/t/ZIP_7.out +28 -0
  729. data/bin/Image-ExifTool-9.33/t/images/AFCP.jpg +0 -0
  730. data/bin/Image-ExifTool-9.33/t/images/AIFF.aif +0 -0
  731. data/bin/Image-ExifTool-9.33/t/images/APE.ape +0 -0
  732. data/bin/Image-ExifTool-9.33/t/images/APE.mpc +0 -0
  733. data/bin/Image-ExifTool-9.33/t/images/ASF.wmv +0 -0
  734. data/bin/Image-ExifTool-9.33/t/images/BMP.bmp +0 -0
  735. data/bin/Image-ExifTool-9.33/t/images/BigTIFF.btf +0 -0
  736. data/bin/Image-ExifTool-9.33/t/images/Canon.jpg +0 -0
  737. data/bin/Image-ExifTool-9.33/t/images/Canon1DmkIII.jpg +0 -0
  738. data/bin/Image-ExifTool-9.33/t/images/CanonRaw.cr2 +0 -0
  739. data/bin/Image-ExifTool-9.33/t/images/CanonRaw.crw +0 -0
  740. data/bin/Image-ExifTool-9.33/t/images/CanonVRD.vrd +0 -0
  741. data/bin/Image-ExifTool-9.33/t/images/CaptureOne.eip +0 -0
  742. data/bin/Image-ExifTool-9.33/t/images/Casio.jpg +0 -0
  743. data/bin/Image-ExifTool-9.33/t/images/Casio2.jpg +0 -0
  744. data/bin/Image-ExifTool-9.33/t/images/CasioQVCI.jpg +0 -0
  745. data/bin/Image-ExifTool-9.33/t/images/DICOM.dcm +0 -0
  746. data/bin/Image-ExifTool-9.33/t/images/DNG.dng +0 -0
  747. data/bin/Image-ExifTool-9.33/t/images/DV.dv +0 -0
  748. data/bin/Image-ExifTool-9.33/t/images/DjVu.djvu +0 -0
  749. data/bin/Image-ExifTool-9.33/t/images/EXE.elf +0 -0
  750. data/bin/Image-ExifTool-9.33/t/images/EXE.exe +0 -0
  751. data/bin/Image-ExifTool-9.33/t/images/EXE.macho +0 -0
  752. data/bin/Image-ExifTool-9.33/t/images/ExifTool.jpg +0 -0
  753. data/bin/Image-ExifTool-9.33/t/images/ExifTool.tif +0 -0
  754. data/bin/Image-ExifTool-9.33/t/images/ExtendedXMP.jpg +0 -0
  755. data/bin/Image-ExifTool-9.33/t/images/FLAC.flac +0 -0
  756. data/bin/Image-ExifTool-9.33/t/images/FLAC.ogg +0 -0
  757. data/bin/Image-ExifTool-9.33/t/images/FLIR.fpf +0 -0
  758. data/bin/Image-ExifTool-9.33/t/images/FLIR.jpg +0 -0
  759. data/bin/Image-ExifTool-9.33/t/images/Flash.flv +0 -0
  760. data/bin/Image-ExifTool-9.33/t/images/Flash.swf +0 -0
  761. data/bin/Image-ExifTool-9.33/t/images/FlashPix.ppt +0 -0
  762. data/bin/Image-ExifTool-9.33/t/images/Font.afm +28 -0
  763. data/bin/Image-ExifTool-9.33/t/images/Font.dfont +0 -0
  764. data/bin/Image-ExifTool-9.33/t/images/Font.pfa +38 -0
  765. data/bin/Image-ExifTool-9.33/t/images/Font.pfb +0 -0
  766. data/bin/Image-ExifTool-9.33/t/images/Font.pfm +0 -0
  767. data/bin/Image-ExifTool-9.33/t/images/Font.ttf +0 -0
  768. data/bin/Image-ExifTool-9.33/t/images/FotoStation.jpg +0 -0
  769. data/bin/Image-ExifTool-9.33/t/images/FujiFilm.jpg +0 -0
  770. data/bin/Image-ExifTool-9.33/t/images/FujiFilm.raf +0 -0
  771. data/bin/Image-ExifTool-9.33/t/images/GE.jpg +0 -0
  772. data/bin/Image-ExifTool-9.33/t/images/GIF.gif +0 -0
  773. data/bin/Image-ExifTool-9.33/t/images/GIMP.xcf +0 -0
  774. data/bin/Image-ExifTool-9.33/t/images/GPS.jpg +0 -0
  775. data/bin/Image-ExifTool-9.33/t/images/GeoTiff.tif +0 -0
  776. data/bin/Image-ExifTool-9.33/t/images/Geotag.gpx +23 -0
  777. data/bin/Image-ExifTool-9.33/t/images/Geotag.igc +24 -0
  778. data/bin/Image-ExifTool-9.33/t/images/Geotag.log +13 -0
  779. data/bin/Image-ExifTool-9.33/t/images/Geotag.xml +23 -0
  780. data/bin/Image-ExifTool-9.33/t/images/Geotag2.log +7 -0
  781. data/bin/Image-ExifTool-9.33/t/images/HTML.html +77 -0
  782. data/bin/Image-ExifTool-9.33/t/images/IPTC.jpg +0 -0
  783. data/bin/Image-ExifTool-9.33/t/images/ITC.itc +0 -0
  784. data/bin/Image-ExifTool-9.33/t/images/InDesign.indd +0 -0
  785. data/bin/Image-ExifTool-9.33/t/images/JVC.jpg +0 -0
  786. data/bin/Image-ExifTool-9.33/t/images/JVC2.jpg +0 -0
  787. data/bin/Image-ExifTool-9.33/t/images/Jpeg2000.j2c +0 -0
  788. data/bin/Image-ExifTool-9.33/t/images/Jpeg2000.jp2 +0 -0
  789. data/bin/Image-ExifTool-9.33/t/images/Kodak.jpg +0 -0
  790. data/bin/Image-ExifTool-9.33/t/images/KyoceraRaw.raw +0 -0
  791. data/bin/Image-ExifTool-9.33/t/images/LNK.lnk +0 -0
  792. data/bin/Image-ExifTool-9.33/t/images/M2TS.mts +0 -0
  793. data/bin/Image-ExifTool-9.33/t/images/MIE.mie +0 -0
  794. data/bin/Image-ExifTool-9.33/t/images/MIFF.miff +0 -0
  795. data/bin/Image-ExifTool-9.33/t/images/MP3.mp3 +0 -0
  796. data/bin/Image-ExifTool-9.33/t/images/MWG.jpg +0 -0
  797. data/bin/Image-ExifTool-9.33/t/images/MXF.mxf +0 -0
  798. data/bin/Image-ExifTool-9.33/t/images/Matroska.mkv +0 -0
  799. data/bin/Image-ExifTool-9.33/t/images/Minolta.jpg +0 -0
  800. data/bin/Image-ExifTool-9.33/t/images/Minolta.mrw +0 -0
  801. data/bin/Image-ExifTool-9.33/t/images/Nikon.jpg +0 -0
  802. data/bin/Image-ExifTool-9.33/t/images/Nikon.nef +0 -0
  803. data/bin/Image-ExifTool-9.33/t/images/NikonD2Hs.jpg +0 -0
  804. data/bin/Image-ExifTool-9.33/t/images/NikonD70.jpg +0 -0
  805. data/bin/Image-ExifTool-9.33/t/images/OOXML.docx +0 -0
  806. data/bin/Image-ExifTool-9.33/t/images/Olympus.jpg +0 -0
  807. data/bin/Image-ExifTool-9.33/t/images/Olympus2.jpg +0 -0
  808. data/bin/Image-ExifTool-9.33/t/images/OlympusE1.jpg +0 -0
  809. data/bin/Image-ExifTool-9.33/t/images/OpenDoc.ods +0 -0
  810. data/bin/Image-ExifTool-9.33/t/images/OpenEXR.exr +0 -0
  811. data/bin/Image-ExifTool-9.33/t/images/PDF.pdf +0 -0
  812. data/bin/Image-ExifTool-9.33/t/images/PDF2.pdf +0 -0
  813. data/bin/Image-ExifTool-9.33/t/images/PGF.pgf +0 -0
  814. data/bin/Image-ExifTool-9.33/t/images/PICT.pict +0 -0
  815. data/bin/Image-ExifTool-9.33/t/images/PLIST-bin.plist +0 -0
  816. data/bin/Image-ExifTool-9.33/t/images/PLIST-xml.plist +35 -0
  817. data/bin/Image-ExifTool-9.33/t/images/PNG.png +0 -0
  818. data/bin/Image-ExifTool-9.33/t/images/PPM.ppm +5 -0
  819. data/bin/Image-ExifTool-9.33/t/images/PSP.psp +0 -0
  820. data/bin/Image-ExifTool-9.33/t/images/Panasonic.jpg +0 -0
  821. data/bin/Image-ExifTool-9.33/t/images/Panasonic.rw2 +0 -0
  822. data/bin/Image-ExifTool-9.33/t/images/Pentax.avi +0 -0
  823. data/bin/Image-ExifTool-9.33/t/images/Pentax.jpg +0 -0
  824. data/bin/Image-ExifTool-9.33/t/images/PhotoCD.pcd +0 -0
  825. data/bin/Image-ExifTool-9.33/t/images/PhotoMechanic.jpg +0 -0
  826. data/bin/Image-ExifTool-9.33/t/images/Photoshop.psd +0 -0
  827. data/bin/Image-ExifTool-9.33/t/images/PostScript.eps +108 -0
  828. data/bin/Image-ExifTool-9.33/t/images/QuickTime.m4a +0 -0
  829. data/bin/Image-ExifTool-9.33/t/images/QuickTime.mov +0 -0
  830. data/bin/Image-ExifTool-9.33/t/images/RIFF.avi +0 -0
  831. data/bin/Image-ExifTool-9.33/t/images/RIFF.wav +0 -0
  832. data/bin/Image-ExifTool-9.33/t/images/RIFF.webp +0 -0
  833. data/bin/Image-ExifTool-9.33/t/images/RTF.rtf +25 -0
  834. data/bin/Image-ExifTool-9.33/t/images/Radiance.hdr +0 -0
  835. data/bin/Image-ExifTool-9.33/t/images/Real.ra +0 -0
  836. data/bin/Image-ExifTool-9.33/t/images/Real.ram +1 -0
  837. data/bin/Image-ExifTool-9.33/t/images/Real.rm +0 -0
  838. data/bin/Image-ExifTool-9.33/t/images/Ricoh.jpg +0 -0
  839. data/bin/Image-ExifTool-9.33/t/images/Ricoh2.jpg +0 -0
  840. data/bin/Image-ExifTool-9.33/t/images/Sanyo.jpg +0 -0
  841. data/bin/Image-ExifTool-9.33/t/images/Sigma.jpg +0 -0
  842. data/bin/Image-ExifTool-9.33/t/images/Sigma.x3f +0 -0
  843. data/bin/Image-ExifTool-9.33/t/images/SigmaDP2.x3f +0 -0
  844. data/bin/Image-ExifTool-9.33/t/images/Sony.jpg +0 -0
  845. data/bin/Image-ExifTool-9.33/t/images/Sony.pmp +0 -0
  846. data/bin/Image-ExifTool-9.33/t/images/Unknown.jpg +0 -0
  847. data/bin/Image-ExifTool-9.33/t/images/Vorbis.ogg +0 -0
  848. data/bin/Image-ExifTool-9.33/t/images/Writer.jpg +0 -0
  849. data/bin/Image-ExifTool-9.33/t/images/XMP.inx +108 -0
  850. data/bin/Image-ExifTool-9.33/t/images/XMP.jpg +0 -0
  851. data/bin/Image-ExifTool-9.33/t/images/XMP.svg +33 -0
  852. data/bin/Image-ExifTool-9.33/t/images/XMP.xml +98 -0
  853. data/bin/Image-ExifTool-9.33/t/images/XMP.xmp +99 -0
  854. data/bin/Image-ExifTool-9.33/t/images/XMP2.xmp +25 -0
  855. data/bin/Image-ExifTool-9.33/t/images/XMP3.xmp +43 -0
  856. data/bin/Image-ExifTool-9.33/t/images/XMP4.xmp +93 -0
  857. data/bin/Image-ExifTool-9.33/t/images/XMP5.xmp +158 -0
  858. data/bin/Image-ExifTool-9.33/t/images/ZIP.gz +0 -0
  859. data/bin/Image-ExifTool-9.33/t/images/ZIP.zip +0 -0
  860. data/bin/Image-ExifTool-9.33/t/images/iWork.numbers +0 -0
  861. data/lib/exiftool_vendored.rb +10 -0
  862. data/lib/exiftool_vendored/version.rb +3 -0
  863. data/lib/exiftool_vendored/version_extractor.rb +17 -0
  864. metadata +977 -0
@@ -0,0 +1,324 @@
1
+ #------------------------------------------------------------------------------
2
+ # File: OpenEXR.pm
3
+ #
4
+ # Description: Read OpenEXR meta information
5
+ #
6
+ # Revisions: 2011/12/10 - P. Harvey Created
7
+ #
8
+ # References: 1) http://www.openexr.com/
9
+ #------------------------------------------------------------------------------
10
+
11
+ package Image::ExifTool::OpenEXR;
12
+
13
+ use strict;
14
+ use vars qw($VERSION);
15
+ use Image::ExifTool qw(:DataAccess :Utils);
16
+
17
+ $VERSION = '1.00';
18
+
19
+ # supported EXR value format types (other types are extracted as undef binary data)
20
+ my %formatType = (
21
+ box2f => 'float[4]',
22
+ box2i => 'int32s[4]',
23
+ chlist => 1,
24
+ chromaticities => 'float[8]',
25
+ compression => 'int8u',
26
+ double => 'double',
27
+ envmap => 'int8u',
28
+ float => 'float',
29
+ 'int' => 'int32s',
30
+ keycode => 'int32s[7]',
31
+ lineOrder => 'int8u',
32
+ m33f => 'float[9]',
33
+ m44f => 'float[16]',
34
+ rational => 'rational64s',
35
+ string => 'string', # incorrect in specification! (no leading int)
36
+ stringvector => 1,
37
+ tiledesc => 1,
38
+ timecode => 'int32u[2]',
39
+ v2f => 'float[2]',
40
+ v2i => 'int32s[2]',
41
+ v3f => 'float[3]',
42
+ v3i => 'int32s[3]',
43
+ );
44
+
45
+ # OpenEXR tags
46
+ %Image::ExifTool::OpenEXR::Main = (
47
+ GROUPS => { 2 => 'Image' },
48
+ NOTES => q{
49
+ Information extracted from EXR images. See L<http://www.openexr.com/> for
50
+ the official specification.
51
+ },
52
+ _ver => { Name => 'EXRVersion' },
53
+ _lay => {
54
+ Name => 'Layout',
55
+ PrintHex => 1,
56
+ PrintConv => { 0 => 'Scan Lines', 0x200 => 'Tiles' },
57
+ },
58
+ adoptedNeutral => { },
59
+ altitude => {
60
+ Name => 'GPSAltitude',
61
+ Groups => { 2 => 'Location' },
62
+ PrintConv => q{
63
+ $val = int($val * 10) / 10;
64
+ return ($val =~ s/^-// ? "$val m Below" : "$val m Above") . " Sea Level";
65
+ },
66
+ },
67
+ aperture => { PrintConv => 'sprintf("%.1f",$val)' },
68
+ channels => { },
69
+ chromaticities => { },
70
+ capDate => {
71
+ Name => 'DateTimeOriginal',
72
+ Groups => { 2 => 'Time' },
73
+ PrintConv => '$self->ConvertDateTime($val)',
74
+ },
75
+ comments => { },
76
+ compression => {
77
+ PrintConvColumns => 2,
78
+ PrintConv => {
79
+ 0 => 'None',
80
+ 1 => 'RLE',
81
+ 2 => 'ZIPS',
82
+ 3 => 'ZIP',
83
+ 4 => 'PIZ',
84
+ 5 => 'PXR24',
85
+ 6 => 'B44',
86
+ 7 => 'B44A',
87
+ },
88
+ },
89
+ dataWindow => { },
90
+ displayWindow => { },
91
+ envmap => {
92
+ Name => 'EnvironmentMap',
93
+ PrintConv => {
94
+ 0 => 'Latitude/Longitude',
95
+ 1 => 'Cube',
96
+ },
97
+ },
98
+ expTime => {
99
+ Name => 'ExposureTime',
100
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
101
+ },
102
+ focus => {
103
+ Name => 'FocusDistance',
104
+ PrintConv => '"$val m"',
105
+ },
106
+ framesPerSecond => { },
107
+ keyCode => { },
108
+ isoSpeed => { Name => 'ISO' },
109
+ latitude => {
110
+ Name => 'GPSLatitude',
111
+ Groups => { 2 => 'Location' },
112
+ RawConv => 'require Image::ExifTool::GPS; $val', # to load Composite tags and routines
113
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
114
+ },
115
+ lineOrder => {
116
+ PrintConv => {
117
+ 0 => 'Increasing Y',
118
+ 1 => 'Decreasing Y',
119
+ 2 => 'Random Y',
120
+ },
121
+ },
122
+ longitude => {
123
+ Name => 'GPSLongitude',
124
+ Groups => { 2 => 'Location' },
125
+ RawConv => 'require Image::ExifTool::GPS; $val', # to load Composite tags and routines
126
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
127
+ },
128
+ lookModTransform => { },
129
+ multiView => { },
130
+ owner => { Groups => { 2 => 'Author' } },
131
+ pixelAspectRatio => { },
132
+ preview => { },
133
+ renderingTransform => { },
134
+ screenWindowCenter => { },
135
+ screenWindowWidth => { },
136
+ tiles => { },
137
+ timeCode => { },
138
+ utcOffset => {
139
+ Name => 'TimeZone',
140
+ Groups => { 2 => 'Time' },
141
+ PrintConv => 'TimeZoneString($val / 60)',
142
+ },
143
+ whiteLuminance => { },
144
+ worldToCamera => { },
145
+ worldToNDC => { },
146
+ wrapmodes => { Name => 'WrapModes' },
147
+ xDensity => { Name => 'XResolution' },
148
+ # also observed:
149
+ # ilut
150
+ );
151
+
152
+ #------------------------------------------------------------------------------
153
+ # Extract information from an OpenEXR file
154
+ # Inputs: 0) ExifTool object reference, 1) DirInfo reference
155
+ # Returns: 1 on success, 0 if this wasn't a valid OpenEXR file
156
+ sub ProcessEXR($$)
157
+ {
158
+ my ($exifTool, $dirInfo) = @_;
159
+ my $raf = $$dirInfo{RAF};
160
+ my $verbose = $exifTool->Options('Verbose');
161
+ my $binary = $exifTool->Options('Binary') || $verbose;
162
+ my ($buff, $buf2, $dim);
163
+
164
+ # verify this is a valid RIFF file
165
+ return 0 unless $raf->Read($buff, 8) == 8;
166
+ return 0 unless $buff =~ /^\x76\x2f\x31\x01/s;
167
+ $exifTool->SetFileType();
168
+ SetByteOrder('II');
169
+ my $tagTablePtr = GetTagTable('Image::ExifTool::OpenEXR::Main');
170
+
171
+ # extract information from header
172
+ my $ver = unpack('x4V', $buff);
173
+ $exifTool->HandleTag($tagTablePtr, '_ver', $ver & 0xff);
174
+ $exifTool->HandleTag($tagTablePtr, '_lay', $ver & 0x200);
175
+
176
+ # extract attributes
177
+ for (;;) {
178
+ $raf->Read($buff, 68) or last;
179
+ last if $buff =~ /^\0/;
180
+ unless ($buff =~ /^([^\0]{1,31})\0([^\0]{1,31})\0(.{4})/sg) {
181
+ $exifTool->Warn('EXR format error');
182
+ last;
183
+ }
184
+ my ($tag, $type, $size) = ($1, $2, unpack('V', $3));
185
+ unless ($raf->Seek(pos($buff) - length($buff), 1)) {
186
+ $exifTool->Warn('Seek error');
187
+ last;
188
+ }
189
+ my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
190
+ unless ($tagInfo) {
191
+ my $name = ucfirst $tag;
192
+ $name =~ tr/-_a-zA-Z0-9//dc;
193
+ if (length $name <= 1) {
194
+ if (length $name) {
195
+ $name = "Tag$name";
196
+ } else {
197
+ $name = 'Invalid';
198
+ }
199
+ }
200
+ $tagInfo = { Name => $name, WasAdded => 1 };
201
+ AddTagToTable($tagTablePtr, $tag, $tagInfo);
202
+ $exifTool->VPrint(0, $exifTool->{INDENT}, "[adding $tag]\n");
203
+ }
204
+ my ($val, $success);
205
+ my $format = $formatType{$type};
206
+ if ($format or $binary) {
207
+ $raf->Read($buff, $size) == $size and $success = 1;
208
+ if (not $format) {
209
+ $val = \$buff; # treat as undef binary data
210
+ } elsif ($format ne '1') {
211
+ # handle formats which map nicely into ExifTool format codes
212
+ if ($format =~ /^(\w+)\[?(\d*)/) {
213
+ my ($fmt, $cnt) = ($1, $2);
214
+ $cnt = $fmt eq 'string' ? $size : 1 unless $cnt;
215
+ $val = ReadValue(\$buff, 0, $fmt, $cnt, $size);
216
+ }
217
+ # handle other format types
218
+ } elsif ($type eq 'tiledesc') {
219
+ if ($size >= 9) {
220
+ my $x = Get32u(\$buff, 0);
221
+ my $y = Get32u(\$buff, 4);
222
+ my $mode = Get8u(\$buff, 8);
223
+ my $lvl = { 0 => 'One Level', 1 => 'MIMAP Levels', 2 => 'RIPMAP Levels' }->{$mode & 0x0f};
224
+ $lvl or $lvl = 'Unknown Levels (' . ($mode & 0xf) . ')';
225
+ my $rnd = { 0 => 'Round Down', 1 => 'Round Up' }->{$mode >> 4};
226
+ $rnd or $rnd = 'Unknown Rounding (' . ($mode >> 4) . ')';
227
+ $val = "${x}x$y; $lvl; $rnd";
228
+ }
229
+ } elsif ($type eq 'chlist') {
230
+ $val = [ ];
231
+ while ($buff =~ /\G([^\0]{1,31})\0(.{16})/sg) {
232
+ my ($str, $dat) = ($1, $2);
233
+ my ($pix,$lin,$x,$y) = unpack('VCx3VV', $dat);
234
+ $pix = { 0 => 'int8u', 1 => 'half', 2 => 'float' }->{$pix} || "unknown($pix)";
235
+ push @$val, "$str $pix" . ($lin ? ' linear' : '') . " $x $y";
236
+ }
237
+ } elsif ($type eq 'stringvector') {
238
+ $val = [ ];
239
+ my $pos = 0;
240
+ while ($pos + 4 <= length($buff)) {
241
+ my $len = Get32u(\$buff, $pos);
242
+ last if $pos + 4 + $len > length($buff);
243
+ push @$val, substr($buff, $pos + 4, $len);
244
+ $pos += 4 + $len;
245
+ }
246
+ } else {
247
+ $val = \$buff; # (shouldn't happen)
248
+ }
249
+ } else {
250
+ # avoid loading binary data
251
+ $val = \ "Binary data $size bytes";
252
+ $success = $raf->Seek($size, 1);
253
+ }
254
+ unless ($success) {
255
+ $exifTool->Warn('Truncated or corrupted EXR file');
256
+ last;
257
+ }
258
+ $val = '<bad>' unless defined $val;
259
+
260
+ # take image dimensions from dataWindow (with displayWindow as backup)
261
+ if (($tag eq 'dataWindow' or (not $dim and $tag eq 'displayWindow')) and
262
+ $val =~ /^(-?\d+) (-?\d+) (-?\d+) (-?\d+)$/)
263
+ {
264
+ $dim = [$3 - $1 + 1, $4 - $2 + 1];
265
+ }
266
+ if ($verbose) {
267
+ my $dataPt = ref $val ? $val : \$val,
268
+ $exifTool->VerboseInfo($tag, $tagInfo,
269
+ Table => $tagTablePtr,
270
+ Value => $val,
271
+ Size => $size,
272
+ Format => $type,
273
+ DataPt => \$buff,
274
+ Addr => $raf->Tell() - $size,
275
+ );
276
+ }
277
+ $exifTool->FoundTag($tagInfo, $val);
278
+ }
279
+ if ($dim) {
280
+ $exifTool->FoundTag('ImageWidth', $$dim[0]);
281
+ $exifTool->FoundTag('ImageHeight', $$dim[1]);
282
+ }
283
+ return 1;
284
+ }
285
+
286
+ 1; # end
287
+
288
+ __END__
289
+
290
+ =head1 NAME
291
+
292
+ Image::ExifTool::OpenEXR - Read OpenEXR meta information
293
+
294
+ =head1 SYNOPSIS
295
+
296
+ This module is used by Image::ExifTool
297
+
298
+ =head1 DESCRIPTION
299
+
300
+ This module contains definitions required by Image::ExifTool to extract meta
301
+ information from OpenEXR images.
302
+
303
+ =head1 AUTHOR
304
+
305
+ Copyright 2003-2013, Phil Harvey (phil at owl.phy.queensu.ca)
306
+
307
+ This library is free software; you can redistribute it and/or modify it
308
+ under the same terms as Perl itself.
309
+
310
+ =head1 REFERENCES
311
+
312
+ =over 4
313
+
314
+ =item L<http://www.openexr.com/documentation.html>
315
+
316
+ =back
317
+
318
+ =head1 SEE ALSO
319
+
320
+ L<Image::ExifTool::TagNames/OpenEXR Tags>,
321
+ L<Image::ExifTool(3pm)|Image::ExifTool>
322
+
323
+ =cut
324
+
@@ -0,0 +1,2327 @@
1
+ #------------------------------------------------------------------------------
2
+ # File: PDF.pm
3
+ #
4
+ # Description: Read PDF meta information
5
+ #
6
+ # Revisions: 07/11/2005 - P. Harvey Created
7
+ # 07/25/2005 - P. Harvey Add support for encrypted documents
8
+ #
9
+ # References: 1) http://www.adobe.com/devnet/pdf/pdf_reference.html
10
+ # 2) http://search.cpan.org/dist/Crypt-RC4/
11
+ # 3) http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf
12
+ # 4) http://www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000.pdf
13
+ # 5) http://tools.ietf.org/search/rfc3454
14
+ # 6) http://www.armware.dk/RFC/rfc/rfc4013.html
15
+ #------------------------------------------------------------------------------
16
+
17
+ package Image::ExifTool::PDF;
18
+
19
+ use strict;
20
+ use vars qw($VERSION $AUTOLOAD $lastFetched);
21
+ use Image::ExifTool qw(:DataAccess :Utils);
22
+ require Exporter;
23
+
24
+ $VERSION = '1.35';
25
+
26
+ sub FetchObject($$$$);
27
+ sub ExtractObject($$;$$);
28
+ sub ReadToNested($;$);
29
+ sub ProcessDict($$$$;$$);
30
+ sub ProcessAcroForm($$$$;$$);
31
+ sub ReadPDFValue($);
32
+ sub CheckPDF($$$);
33
+
34
+ # $lastFetched - last fetched object reference (used for decryption)
35
+ # (undefined if fetched object was already decrypted, ie. object from stream)
36
+
37
+ my $cryptInfo; # encryption object reference (plus additional information)
38
+ my $cryptString; # flag that strings are encrypted
39
+ my $cryptStream; # flag that streams are encrypted
40
+ my $lastOffset; # last fetched object offset
41
+ my %streamObjs; # hash of stream objects
42
+ my %fetched; # dicts fetched in verbose mode (to avoid cyclical recursion)
43
+ my $pdfVer; # version of PDF file being processed
44
+
45
+ # filters supported in DecodeStream()
46
+ my %supportedFilter = (
47
+ '/FlateDecode' => 1,
48
+ '/Crypt' => 1,
49
+ '/Identity' => 1, # (not filtered)
50
+ '/DCTDecode' => 1, # (JPEG image - not filtered)
51
+ '/JPXDecode' => 1, # (Jpeg2000 image - not filtered)
52
+ '/LZWDecode' => 1, # (usually a bitmapped image)
53
+ '/ASCIIHexDecode' => 1,
54
+ # other standard filters that we currently don't support
55
+ #'/JBIG2Decode' => 0, # (JBIG2 image format not supported)
56
+ #'/CCITTFaxDecode' => 0,
57
+ #'/RunLengthDecode' => 0,
58
+ #'/ASCII85Decode' => 0,
59
+ );
60
+
61
+ # tags in main PDF directories
62
+ %Image::ExifTool::PDF::Main = (
63
+ GROUPS => { 2 => 'Document' },
64
+ VARS => { CAPTURE => ['Main','Prev'] },
65
+ Info => {
66
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Info' },
67
+ # Adobe Acrobat 10.1.5 will create a duplicate Info dictionary with
68
+ # a different object number when metadata is edited. This flag
69
+ # is part of a patch to ignore this duplicate information (unless
70
+ # the IgnoreMinorErrors option is used)
71
+ IgnoreDuplicates => 1,
72
+ },
73
+ Root => {
74
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Root' },
75
+ },
76
+ Encrypt => {
77
+ NoProcess => 1, # don't process normally (processed in advance)
78
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Encrypt' },
79
+ },
80
+ _linearized => {
81
+ Name => 'Linearized',
82
+ Notes => 'flag set if document is linearized for fast web display; not a real Tag ID',
83
+ PrintConv => { 'true' => 'Yes', 'false' => 'No' },
84
+ },
85
+ );
86
+
87
+ # tags in PDF Info dictionary
88
+ %Image::ExifTool::PDF::Info = (
89
+ GROUPS => { 2 => 'Document' },
90
+ VARS => { CAPTURE => ['Info'] },
91
+ EXTRACT_UNKNOWN => 1, # extract all unknown tags in this directory
92
+ WRITE_PROC => \&Image::ExifTool::DummyWriteProc,
93
+ CHECK_PROC => \&CheckPDF,
94
+ WRITABLE => 'string',
95
+ # set PRIORITY to 0 so most recent Info dictionary takes precedence
96
+ # (Acrobat Pro bug? doesn't use same object/generation number for
97
+ # new Info dictionary when doing incrmental update)
98
+ PRIORITY => 0,
99
+ NOTES => q{
100
+ As well as the tags listed below, the PDF specification allows for
101
+ user-defined tags to exist in the Info dictionary. These tags, which should
102
+ have corresponding XMP-pdfx entries in the XMP of the PDF XML Metadata
103
+ object, are also extracted by ExifTool.
104
+
105
+ B<Writable> specifies the value format, and may be C<string>, C<date>,
106
+ C<integer>, C<real>, C<boolean> or C<name> for PDF tags.
107
+ },
108
+ Title => { },
109
+ Author => { Groups => { 2 => 'Author' } },
110
+ Subject => { },
111
+ Keywords => { List => 'string' }, # this is a string list
112
+ Creator => { },
113
+ Producer => { },
114
+ CreationDate => {
115
+ Name => 'CreateDate',
116
+ Writable => 'date',
117
+ Groups => { 2 => 'Time' },
118
+ Shift => 'Time',
119
+ PrintConv => '$self->ConvertDateTime($val)',
120
+ PrintConvInv => '$self->InverseDateTime($val)',
121
+ },
122
+ ModDate => {
123
+ Name => 'ModifyDate',
124
+ Writable => 'date',
125
+ Groups => { 2 => 'Time' },
126
+ Shift => 'Time',
127
+ PrintConv => '$self->ConvertDateTime($val)',
128
+ PrintConvInv => '$self->InverseDateTime($val)',
129
+ },
130
+ Trapped => {
131
+ Protected => 1,
132
+ # remove leading '/' from '/True' or '/False'
133
+ ValueConv => '$val=~s{^/}{}; $val',
134
+ ValueConvInv => '"/$val"',
135
+ },
136
+ 'AAPL:Keywords' => { #PH
137
+ Name => 'AppleKeywords',
138
+ List => 'array', # this is an array of values
139
+ Notes => q{
140
+ keywords written by Apple utilities, although they seem to use PDF:Keywords
141
+ when reading
142
+ },
143
+ },
144
+ );
145
+
146
+ # tags in the PDF Root document catalog
147
+ %Image::ExifTool::PDF::Root = (
148
+ GROUPS => { 2 => 'Document' },
149
+ # note: can't capture previous versions of Root since they are not parsed
150
+ VARS => { CAPTURE => ['Root'] },
151
+ NOTES => 'This is the PDF document catalog.',
152
+ MarkInfo => {
153
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::MarkInfo' },
154
+ },
155
+ Metadata => {
156
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Metadata' },
157
+ },
158
+ Pages => {
159
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Pages' },
160
+ },
161
+ Perms => {
162
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Perms' },
163
+ },
164
+ AcroForm => {
165
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::AcroForm' },
166
+ },
167
+ Lang => 'Language',
168
+ PageLayout => { },
169
+ PageMode => { },
170
+ Version => 'PDFVersion',
171
+ );
172
+
173
+ # tags extracted from the PDF Encrypt dictionary
174
+ %Image::ExifTool::PDF::Encrypt = (
175
+ GROUPS => { 2 => 'Document' },
176
+ NOTES => 'Tags extracted from the document Encrypt dictionary.',
177
+ Filter => {
178
+ Name => 'Encryption',
179
+ Notes => q{
180
+ extracted value is actually a combination of the Filter, SubFilter, V, R and
181
+ Length information from the Encrypt dictionary
182
+ },
183
+ },
184
+ P => {
185
+ Name => 'UserAccess',
186
+ ValueConv => '$val & 0x0f3c', # ignore reserved bits
187
+ PrintConvColumns => 2,
188
+ PrintConv => { BITMASK => {
189
+ 2 => 'Print',
190
+ 3 => 'Modify',
191
+ 4 => 'Copy',
192
+ 5 => 'Annotate',
193
+ 8 => 'Fill forms',
194
+ 9 => 'Extract',
195
+ 10 => 'Assemble',
196
+ 11 => 'Print high-res',
197
+ }},
198
+ },
199
+ );
200
+
201
+ # tags in PDF Pages dictionary
202
+ %Image::ExifTool::PDF::Pages = (
203
+ GROUPS => { 2 => 'Document' },
204
+ Count => 'PageCount',
205
+ Kids => {
206
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Kids' },
207
+ },
208
+ );
209
+
210
+ # tags in PDF Perms dictionary
211
+ %Image::ExifTool::PDF::Perms = (
212
+ NOTES => 'Additional document permissions imposed by digital signatures.',
213
+ DocMDP => {
214
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Signature' },
215
+ },
216
+ FieldMDP => {
217
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Signature' },
218
+ },
219
+ UR3 => {
220
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Signature' },
221
+ },
222
+ );
223
+
224
+ # tags in PDF Perms dictionary
225
+ %Image::ExifTool::PDF::AcroForm = (
226
+ PROCESS_PROC => \&ProcessAcroForm,
227
+ _has_xfa => {
228
+ Name => 'HasXFA',
229
+ Notes => q{
230
+ this tag is defined if a document contains form fields, and is true if it
231
+ uses XML Forms Architecture; not a real Tag ID
232
+ },
233
+ PrintConv => { 'true' => 'Yes', 'false' => 'No' },
234
+ },
235
+ );
236
+
237
+ # tags in PDF Kids dictionary
238
+ %Image::ExifTool::PDF::Kids = (
239
+ Metadata => {
240
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Metadata' },
241
+ },
242
+ PieceInfo => {
243
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::PieceInfo' },
244
+ },
245
+ Resources => {
246
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Resources' },
247
+ },
248
+ Kids => {
249
+ Condition => '$self->Options("ExtractEmbedded")',
250
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Kids' },
251
+ },
252
+ );
253
+
254
+ # tags in PDF Resources dictionary
255
+ %Image::ExifTool::PDF::Resources = (
256
+ ColorSpace => {
257
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::ColorSpace' },
258
+ },
259
+ XObject => {
260
+ Condition => '$self->Options("ExtractEmbedded")',
261
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::XObject' },
262
+ },
263
+ Properties => {
264
+ Condition => '$self->Options("ExtractEmbedded")',
265
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Properties' },
266
+ },
267
+ );
268
+
269
+ # tags in PDF ColorSpace dictionary
270
+ %Image::ExifTool::PDF::ColorSpace = (
271
+ DefaultRGB => {
272
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::DefaultRGB' },
273
+ },
274
+ Cs1 => {
275
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Cs1' },
276
+ },
277
+ );
278
+
279
+ # tags in PDF DefaultRGB dictionary
280
+ %Image::ExifTool::PDF::DefaultRGB = (
281
+ ICCBased => {
282
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::ICCBased' },
283
+ },
284
+ );
285
+
286
+ # tags in PDF Cs1 dictionary
287
+ %Image::ExifTool::PDF::Cs1 = (
288
+ _stream => {
289
+ SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' },
290
+ },
291
+ );
292
+
293
+ # tags in PDF ICCBased dictionary
294
+ %Image::ExifTool::PDF::ICCBased = (
295
+ _stream => {
296
+ SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' },
297
+ },
298
+ );
299
+
300
+ # tags in PDF XObject dictionary (parsed only if ExtractEmbedded is enabled)
301
+ %Image::ExifTool::PDF::XObject = (
302
+ EXTRACT_UNKNOWN => 0, # extract known but numbered tags (Im1, Im2, etc)
303
+ Im => {
304
+ Notes => q{
305
+ the ExtractEmbedded option enables information to be extracted from these
306
+ embedded images
307
+ },
308
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Im' },
309
+ },
310
+ );
311
+
312
+ # tags in PDF Im# dictionary
313
+ %Image::ExifTool::PDF::Im = (
314
+ NOTES => q{
315
+ Information extracted from embedded images with the ExtractEmbedded option.
316
+ The EmbeddedImage and its metadata are extracted only for JPEG and Jpeg2000
317
+ image formats.
318
+ },
319
+ Width => 'EmbeddedImageWidth',
320
+ Height => 'EmbeddedImageHeight',
321
+ Filter => { Name => 'EmbeddedImageFilter', List => 1 },
322
+ ColorSpace => {
323
+ Name => 'EmbeddedImageColorSpace',
324
+ List => 1,
325
+ RawConv => 'ref $val ? undef : $val', # (ignore color space data)
326
+ },
327
+ Image_stream => {
328
+ Name => 'EmbeddedImage',
329
+ Binary => 1,
330
+ },
331
+ );
332
+
333
+ # tags in PDF Properties dictionary
334
+ %Image::ExifTool::PDF::Properties = (
335
+ EXTRACT_UNKNOWN => 0, # extract known but numbered tags (MC0, MC1, etc)
336
+ MC => {
337
+ Notes => q{
338
+ the ExtractEmbedded option enables information to be extracted from these
339
+ embedded metadata dictionaries
340
+ },
341
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::MC' },
342
+ }
343
+ );
344
+
345
+ # tags in PDF MC# dictionary
346
+ %Image::ExifTool::PDF::MC = (
347
+ Metadata => {
348
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Metadata' },
349
+ }
350
+ );
351
+
352
+ # tags in PDF PieceInfo dictionary
353
+ %Image::ExifTool::PDF::PieceInfo = (
354
+ AdobePhotoshop => {
355
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::AdobePhotoshop' },
356
+ },
357
+ Illustrator => {
358
+ # assume this is an illustrator file if it contains this directory
359
+ # and doesn't have a ".PDF" extension
360
+ Condition => q{
361
+ $self->OverrideFileType("AI") unless $$self{FILE_EXT} and $$self{FILE_EXT} eq 'PDF';
362
+ return 1;
363
+ },
364
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Illustrator' },
365
+ },
366
+ );
367
+
368
+ # tags in PDF AdobePhotoshop dictionary
369
+ %Image::ExifTool::PDF::AdobePhotoshop = (
370
+ Private => {
371
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Private' },
372
+ },
373
+ );
374
+
375
+ # tags in PDF Illustrator dictionary
376
+ %Image::ExifTool::PDF::Illustrator = (
377
+ Private => {
378
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::AIPrivate' },
379
+ },
380
+ );
381
+
382
+ # tags in PDF Private dictionary
383
+ %Image::ExifTool::PDF::Private = (
384
+ ImageResources => {
385
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::ImageResources' },
386
+ },
387
+ );
388
+
389
+ # tags in PDF AI Private dictionary
390
+ %Image::ExifTool::PDF::AIPrivate = (
391
+ GROUPS => { 2 => 'Document' },
392
+ EXTRACT_UNKNOWN => 0, # extract known but numbered tags
393
+ AIMetaData => {
394
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::AIMetaData' },
395
+ },
396
+ AIPrivateData => {
397
+ Notes => q{
398
+ the ExtractEmbedded option enables information to be extracted from embedded
399
+ PostScript documents in the AIPrivateData# and AIPDFPrivateData# streams
400
+ },
401
+ JoinStreams => 1, # join streams from numbered tags and process as one
402
+ SubDirectory => { TagTable => 'Image::ExifTool::PostScript::Main' },
403
+ },
404
+ AIPDFPrivateData => {
405
+ JoinStreams => 1, # join streams from numbered tags and process as one
406
+ SubDirectory => { TagTable => 'Image::ExifTool::PostScript::Main' },
407
+ },
408
+ RoundTripVersion => { },
409
+ ContainerVersion => { },
410
+ CreatorVersion => { },
411
+ );
412
+
413
+ # tags in PDF AIMetaData dictionary
414
+ %Image::ExifTool::PDF::AIMetaData = (
415
+ _stream => {
416
+ SubDirectory => { TagTable => 'Image::ExifTool::PostScript::Main' },
417
+ },
418
+ );
419
+
420
+ # tags in PDF ImageResources dictionary
421
+ %Image::ExifTool::PDF::ImageResources = (
422
+ _stream => {
423
+ SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::Main' },
424
+ },
425
+ );
426
+
427
+ # tags in PDF MarkInfo dictionary
428
+ %Image::ExifTool::PDF::MarkInfo = (
429
+ GROUPS => { 2 => 'Document' },
430
+ Marked => {
431
+ Name => 'TaggedPDF',
432
+ Notes => "not a Tagged PDF if this tag is missing",
433
+ PrintConv => { 'true' => 'Yes', 'false' => 'No' },
434
+ },
435
+ );
436
+
437
+ # tags in PDF Metadata dictionary
438
+ %Image::ExifTool::PDF::Metadata = (
439
+ GROUPS => { 2 => 'Document' },
440
+ XML_stream => { # this is the stream for a Subtype /XML dictionary (not a real tag)
441
+ Name => 'XMP',
442
+ SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
443
+ },
444
+ );
445
+
446
+ # tags in PDF signature directories (DocMDP, FieldMDP or UR3)
447
+ %Image::ExifTool::PDF::Signature = (
448
+ GROUPS => { 2 => 'Document' },
449
+ ContactInfo => 'SignerContactInfo',
450
+ Location => 'SigningLocation',
451
+ M => {
452
+ Name => 'SigningDate',
453
+ Format => 'date',
454
+ Groups => { 2 => 'Time' },
455
+ PrintConv => '$self->ConvertDateTime($val)',
456
+ },
457
+ Name => 'SigningAuthority',
458
+ Reason => 'SigningReason',
459
+ Reference => {
460
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Reference' },
461
+ },
462
+ Prop_AuthTime => {
463
+ Name => 'AuthenticationTime',
464
+ PrintConv => 'ConvertTimeSpan($val) . " ago"',
465
+ },
466
+ Prop_AuthType => 'AuthenticationType',
467
+ );
468
+
469
+ # tags in PDF Reference dictionary
470
+ %Image::ExifTool::PDF::Reference = (
471
+ TransformParams => {
472
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::TransformParams' },
473
+ },
474
+ );
475
+
476
+ # tags in PDF TransformParams dictionary
477
+ %Image::ExifTool::PDF::TransformParams = (
478
+ GROUPS => { 2 => 'Document' },
479
+ Annots => {
480
+ Name => 'AnnotationUsageRights',
481
+ Notes => q{
482
+ possible values are Create, Delete, Modify, Copy, Import and Export;
483
+ additional values for UR3 signatures are Online and SummaryView
484
+ },
485
+ List => 1,
486
+ },
487
+ Document => {
488
+ Name => 'DocumentUsageRights',
489
+ Notes => 'only possible value is FullSave',
490
+ List => 1,
491
+ },
492
+ Form => {
493
+ Name => 'FormUsageRights',
494
+ Notes => q{
495
+ possible values are FillIn, Import, Export, SubmitStandalone and
496
+ SpawnTemplate; additional values for UR3 signatures are BarcodePlaintext and
497
+ Online
498
+ },
499
+ List => 1,
500
+ },
501
+ FormEX => {
502
+ Name => 'FormExtraUsageRights',
503
+ Notes => 'UR signatures only; only possible value is BarcodePlaintext',
504
+ List => 1,
505
+ },
506
+ Signature => {
507
+ Name => 'SignatureUsageRights',
508
+ Notes => 'only possible value is Modify',
509
+ List => 1,
510
+ },
511
+ EF => {
512
+ Name => 'EmbeddedFileUsageRights',
513
+ Notes => 'possible values are Create, Delete, Modify and Import',
514
+ List => 1,
515
+ },
516
+ Msg => 'UsageRightsMessage',
517
+ P => {
518
+ Name => 'ModificationPermissions',
519
+ Notes => q{
520
+ 1-3 for DocMDP signatures, default 2; true/false for UR3 signatures, default
521
+ false
522
+ },
523
+ PrintConv => {
524
+ 1 => 'No changes permitted',
525
+ 2 => 'Fill forms, Create page templates, Sign',
526
+ 3 => 'Fill forms, Create page templates, Sign, Create/Delete/Edit annotations',
527
+ 'true' => 'Restrict all applications to reader permissions',
528
+ 'false' => 'Do not restrict applications to reader permissions',
529
+ },
530
+ },
531
+ Action => {
532
+ Name => 'FieldPermissions',
533
+ Notes => 'FieldMDP signatures only',
534
+ PrintConv => {
535
+ 'All' => 'Disallow changes to all form fields',
536
+ 'Include' => 'Disallow changes to specified form fields',
537
+ 'Exclude' => 'Allow changes to specified form fields',
538
+ },
539
+ },
540
+ Fields => {
541
+ Notes => 'FieldMDP signatures only',
542
+ Name => 'FormFields',
543
+ List => 1,
544
+ },
545
+ );
546
+
547
+ # unknown tags for use in verbose option
548
+ %Image::ExifTool::PDF::Unknown = (
549
+ GROUPS => { 2 => 'Unknown' },
550
+ );
551
+
552
+ #------------------------------------------------------------------------------
553
+ # AutoLoad our writer routines when necessary
554
+ #
555
+ sub AUTOLOAD
556
+ {
557
+ return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
558
+ }
559
+
560
+ #------------------------------------------------------------------------------
561
+ # Convert from PDF to EXIF-style date/time
562
+ # Inputs: 0) PDF date/time string (D:YYYYmmddHHMMSS+HH'MM')
563
+ # Returns: EXIF date string (YYYY:mm:dd HH:MM:SS+HH:MM)
564
+ sub ConvertPDFDate($)
565
+ {
566
+ my $date = shift;
567
+ # remove optional 'D:' prefix
568
+ $date =~ s/^D://;
569
+ # fill in default values if necessary
570
+ # YYYYmmddHHMMSS
571
+ my $default = '00000101000000';
572
+ if (length $date < length $default) {
573
+ $date .= substr($default, length $date);
574
+ }
575
+ $date =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(.*)/ or return $date;
576
+ $date = "$1:$2:$3 $4:$5:$6";
577
+ if ($7) {
578
+ my $tz = $7;
579
+ if ($tz =~ /^\s*Z/i) {
580
+ # ignore any "HH'mm'" after the Z (OS X 10.6 does this)
581
+ $date .= 'Z';
582
+ # tolerate some improper formatting in timezone specification
583
+ } elsif ($tz =~ /^\s*([-+])\s*(\d+)[': ]+(\d*)/) {
584
+ $date .= $1 . $2 . ':' . ($3 || '00');
585
+ }
586
+ }
587
+ return $date;
588
+ }
589
+
590
+ #------------------------------------------------------------------------------
591
+ # Locate any object in the XRef tables (including compressed objects)
592
+ # Inputs: 0) XRef reference, 1) object reference string (or free object number)
593
+ # Returns: offset to object in file or compressed object reference string,
594
+ # 0 if object is free, or undefined on error
595
+ sub LocateAnyObject($$)
596
+ {
597
+ my ($xref, $ref) = @_;
598
+ return undef unless $xref;
599
+ return $$xref{$ref} if exists $$xref{$ref};
600
+ # get the object number
601
+ return undef unless $ref =~ /^(\d+)/;
602
+ my $objNum = $1;
603
+ # return 0 if the object number has been reused (old object is free)
604
+ return 0 if defined $$xref{$objNum};
605
+ #
606
+ # scan our XRef stream dictionaries for this object
607
+ #
608
+ return undef unless $$xref{dicts};
609
+ my $dict;
610
+ foreach $dict (@{$$xref{dicts}}) {
611
+ # quick check to see if the object is in the range for this xref stream
612
+ next if $objNum >= $$dict{Size};
613
+ my $index = $$dict{Index};
614
+ next if $objNum < $$index[0];
615
+ # scan the tables for the specified object
616
+ my $size = $$dict{_entry_size};
617
+ my $num = scalar(@$index) / 2;
618
+ my $tot = 0;
619
+ my $i;
620
+ for ($i=0; $i<$num; ++$i) {
621
+ my $start = $$index[$i*2];
622
+ my $count = $$index[$i*2+1];
623
+ # table is in ascending order, so quit if we have passed the object
624
+ last if $objNum < $start;
625
+ if ($objNum < $start + $count) {
626
+ my $offset = $size * ($objNum - $start + $tot);
627
+ last if $offset + $size > length $$dict{_stream};
628
+ my @c = unpack("x$offset C$size", $$dict{_stream});
629
+ # extract values from this table entry
630
+ # (can be 1, 2, 3, 4, etc.. bytes per value)
631
+ my (@t, $j, $k);
632
+ my $w = $$dict{W};
633
+ for ($j=0; $j<3; ++$j) {
634
+ # use default value if W entry is 0 (as per spec)
635
+ # - 0th element defaults to 1, others default to 0
636
+ $$w[$j] or $t[$j] = ($j ? 0 : 1), next;
637
+ $t[$j] = shift(@c);
638
+ for ($k=1; $k < $$w[$j]; ++$k) {
639
+ $t[$j] = 256 * $t[$j] + shift(@c);
640
+ }
641
+ }
642
+ # by default, use "o g R" as the xref key
643
+ # (o = object number, g = generation number)
644
+ my $ref2 = "$objNum $t[2] R";
645
+ if ($t[0] == 1) {
646
+ # normal object reference:
647
+ # $t[1]=offset of object from start, $t[2]=generation number
648
+ $$xref{$ref2} = $t[1];
649
+ } elsif ($t[0] == 2) {
650
+ # compressed object reference:
651
+ # $t[1]=stream object number, $t[2]=index of object in stream
652
+ $ref2 = "$objNum 0 R";
653
+ $$xref{$ref2} = "I$t[2] $t[1] 0 R";
654
+ } elsif ($t[0] == 0) {
655
+ # free object:
656
+ # $t[1]=next free object in linked list, $t[2]=generation number
657
+ $$xref{$ref2} = 0;
658
+ } else {
659
+ # treat as a null object
660
+ $$xref{$ref2} = undef;
661
+ }
662
+ $$xref{$objNum} = $t[1]; # remember offsets by object number too
663
+ return $$xref{$ref} if $ref eq $ref2;
664
+ return 0; # object is free or was reused
665
+ }
666
+ $tot += $count;
667
+ }
668
+ }
669
+ return undef;
670
+ }
671
+
672
+ #------------------------------------------------------------------------------
673
+ # Locate a regular object in the XRef tables (does not include compressed objects)
674
+ # Inputs: 0) XRef reference, 1) object reference string (or free object number)
675
+ # Returns: offset to object in file, 0 if object is free,
676
+ # or undef on error or if object was compressed
677
+ sub LocateObject($$)
678
+ {
679
+ my ($xref, $ref) = @_;
680
+ my $offset = LocateAnyObject($xref, $ref);
681
+ return undef if $offset and $offset =~ /^I/;
682
+ return $offset;
683
+ }
684
+
685
+ #------------------------------------------------------------------------------
686
+ # Fetch indirect object from file (from inside a stream if required)
687
+ # Inputs: 0) ExifTool object reference, 1) object reference string,
688
+ # 2) xref lookup, 3) object name (for warning messages)
689
+ # Returns: object data or undefined on error
690
+ # Notes: sets $lastFetched to the object reference, or undef if the object
691
+ # was extracted from an encrypted stream
692
+ sub FetchObject($$$$)
693
+ {
694
+ my ($exifTool, $ref, $xref, $tag) = @_;
695
+ $lastFetched = $ref; # save this for decoding if necessary
696
+ my $offset = LocateAnyObject($xref, $ref);
697
+ $lastOffset = $offset;
698
+ unless ($offset) {
699
+ $exifTool->Warn("Bad $tag reference") unless defined $offset;
700
+ return undef;
701
+ }
702
+ my ($data, $obj);
703
+ if ($offset =~ s/^I(\d+) //) {
704
+ my $index = $1; # object index in stream
705
+ my ($objNum) = split ' ', $ref; # save original object number
706
+ $ref = $offset; # now a reference to the containing stream object
707
+ $obj = $streamObjs{$ref};
708
+ unless ($obj) {
709
+ # don't try to load the same object stream twice
710
+ return undef if defined $obj;
711
+ $streamObjs{$ref} = '';
712
+ # load the parent object stream
713
+ $obj = FetchObject($exifTool, $ref, $xref, $tag);
714
+ # make sure it contains everything we need
715
+ return undef unless defined $obj and ref($obj) eq 'HASH';
716
+ return undef unless $$obj{First} and $$obj{N};
717
+ return undef unless DecodeStream($exifTool, $obj);
718
+ # add a special '_table' entry to this dictionary which contains
719
+ # the list of object number/offset pairs from the stream header
720
+ my $num = $$obj{N} * 2;
721
+ my @table = split ' ', $$obj{_stream}, $num;
722
+ return undef unless @table == $num;
723
+ # remove everything before first object in stream
724
+ $$obj{_stream} = substr($$obj{_stream}, $$obj{First});
725
+ $table[$num-1] =~ s/^(\d+).*/$1/s; # trim excess from last number
726
+ $$obj{_table} = \@table;
727
+ # save the object stream so we don't have to re-load it later
728
+ $streamObjs{$ref} = $obj;
729
+ }
730
+ # verify that we have the specified object
731
+ my $i = 2 * $index;
732
+ my $table = $$obj{_table};
733
+ unless ($index < $$obj{N} and $$table[$i] == $objNum) {
734
+ $exifTool->Warn("Bad index for stream object $tag");
735
+ return undef;
736
+ }
737
+ # extract the object at the specified index in the stream
738
+ # (offsets in table are in sequential order, so we can subract from
739
+ # the next offset to get the object length)
740
+ $offset = $$table[$i + 1];
741
+ my $len = ($$table[$i + 3] || length($$obj{_stream})) - $offset;
742
+ $data = substr($$obj{_stream}, $offset, $len);
743
+ # avoid re-decrypting data in already decrypted streams
744
+ undef $lastFetched if $cryptStream;
745
+ return ExtractObject($exifTool, \$data);
746
+ }
747
+ my $raf = $exifTool->{RAF};
748
+ $raf->Seek($offset, 0) or $exifTool->Warn("Bad $tag offset"), return undef;
749
+ # verify that we are reading the expected object
750
+ $raf->ReadLine($data) or $exifTool->Warn("Error reading $tag data"), return undef;
751
+ ($obj = $ref) =~ s/R/obj/;
752
+ unless ($data =~ s/^$obj//) {
753
+ $exifTool->Warn("$tag object ($obj) not found at $offset");
754
+ return undef;
755
+ }
756
+ return ExtractObject($exifTool, \$data, $raf, $xref);
757
+ }
758
+
759
+ #------------------------------------------------------------------------------
760
+ # Convert PDF value to something readable
761
+ # Inputs: 0) PDF object data
762
+ # Returns: converted object
763
+ sub ReadPDFValue($)
764
+ {
765
+ my $str = shift;
766
+ # decode all strings in an array
767
+ if (ref $str eq 'ARRAY') {
768
+ # create new list to not alter the original data when rewriting
769
+ my ($val, @vals);
770
+ foreach $val (@$str) {
771
+ push @vals, ReadPDFValue($val);
772
+ }
773
+ return \@vals;
774
+ }
775
+ length $str or return $str;
776
+ my $delim = substr($str, 0, 1);
777
+ if ($delim eq '(') { # literal string
778
+ $str = $1 if $str =~ /^.*?\((.*)\)/s; # remove brackets
779
+ # decode escape sequences in literal strings
780
+ while ($str =~ /\\(.)/sg) {
781
+ my $n = pos($str) - 2;
782
+ my $c = $1;
783
+ my $r;
784
+ if ($c =~ /[0-7]/) {
785
+ # get up to 2 more octal digits
786
+ $c .= $1 if $str =~ /\G([0-7]{1,2})/g;
787
+ # convert octal escape code
788
+ $r = chr(oct($c) & 0xff);
789
+ } elsif ($c eq "\x0d") {
790
+ # the string is continued if the line ends with '\'
791
+ # (also remove "\x0d\x0a")
792
+ $c .= $1 if $str =~ /\G(\x0a)/g;
793
+ $r = '';
794
+ } elsif ($c eq "\x0a") {
795
+ $r = '';
796
+ } else {
797
+ # convert escaped characters
798
+ ($r = $c) =~ tr/nrtbf/\n\r\t\b\f/;
799
+ }
800
+ substr($str, $n, length($c)+1) = $r;
801
+ # continue search after this character
802
+ pos($str) = $n + length($r);
803
+ }
804
+ Crypt(\$str, $lastFetched) if $cryptString;
805
+ } elsif ($delim eq '<') { # hex string
806
+ # decode hex data
807
+ $str =~ tr/0-9A-Fa-f//dc;
808
+ $str .= '0' if length($str) & 0x01; # (by the spec)
809
+ $str = pack('H*', $str);
810
+ Crypt(\$str, $lastFetched) if $cryptString;
811
+ } elsif ($delim eq '/') { # name
812
+ $str = substr($str, 1);
813
+ # convert escape codes (PDF 1.2 or later)
814
+ $str =~ s/#([0-9a-f]{2})/chr(hex($1))/sgei if $pdfVer >= 1.2;
815
+ }
816
+ return $str;
817
+ }
818
+
819
+ #------------------------------------------------------------------------------
820
+ # Extract PDF object from combination of buffered data and file
821
+ # Inputs: 0) ExifTool object reference, 1) data reference,
822
+ # 2) optional raf reference, 3) optional xref table
823
+ # Returns: converted PDF object or undef on error
824
+ # a) dictionary object --> hash reference
825
+ # b) array object --> array reference
826
+ # c) indirect reference --> scalar reference
827
+ # d) string, name, integer, boolean, null --> scalar value
828
+ # - updates $$dataPt on return to contain unused data
829
+ # - creates two bogus entries ('_stream' and '_tags') in dictionaries to represent
830
+ # the stream data and a list of the tags (not including '_stream' and '_tags')
831
+ # in their original order
832
+ sub ExtractObject($$;$$)
833
+ {
834
+ my ($exifTool, $dataPt, $raf, $xref) = @_;
835
+ my (@tags, $data, $objData);
836
+ my $dict = { };
837
+ my $delim;
838
+
839
+ for (;;) {
840
+ if ($$dataPt =~ /^\s*(<{1,2}|\[|\()/s) {
841
+ $delim = $1;
842
+ $$dataPt =~ s/^\s+//; # remove leading white space
843
+ $objData = ReadToNested($dataPt, $raf);
844
+ return undef unless defined $objData;
845
+ last;
846
+ } elsif ($$dataPt =~ s{^\s*(\S[^[(/<>\s]*)\s*}{}s) {
847
+ #
848
+ # extract boolean, numerical, string, name, null object or indirect reference
849
+ #
850
+ $objData = $1;
851
+ # look for an indirect reference
852
+ if ($objData =~ /^\d+$/ and $$dataPt =~ s/^(\d+)\s+R//s) {
853
+ $objData .= "$1 R";
854
+ $objData = \$objData; # return scalar reference
855
+ }
856
+ return $objData; # return simple scalar or scalar reference
857
+ }
858
+ $raf and $raf->ReadLine($data) or return undef;
859
+ $$dataPt .= $data;
860
+ }
861
+ #
862
+ # return literal string or hex string without parsing
863
+ #
864
+ if ($delim eq '(' or $delim eq '<') {
865
+ return $objData;
866
+ #
867
+ # extract array
868
+ #
869
+ } elsif ($delim eq '[') {
870
+ $objData =~ /^.*?\[(.*)\]/s or return undef;
871
+ my $data = $1; # brackets removed
872
+ my @list;
873
+ for (;;) {
874
+ last unless $data =~ m{\s*(\S[^[(/<>\s]*)}sg;
875
+ my $val = $1;
876
+ if ($val =~ /^(<{1,2}|\[|\()/) {
877
+ my $pos = pos($data) - length($val);
878
+ # nested dict, array, literal string or hex string
879
+ my $buff = substr($data, $pos);
880
+ $val = ReadToNested(\$buff);
881
+ last unless defined $val;
882
+ pos($data) = $pos + length($val);
883
+ $val = ExtractObject($exifTool, \$val);
884
+ } elsif ($val =~ /^\d/) {
885
+ my $pos = pos($data);
886
+ if ($data =~ /\G\s+(\d+)\s+R/g) {
887
+ $val = \ "$val $1 R"; # make a reference
888
+ } else {
889
+ pos($data) = $pos;
890
+ }
891
+ }
892
+ push @list, $val;
893
+ }
894
+ return \@list;
895
+ }
896
+ #
897
+ # extract dictionary
898
+ #
899
+ # Note: entries are not necessarily separated by whitespace (doh!)
900
+ # ie) "/Tag/Name", "/Tag(string)", "/Tag[array]", etc are legal!
901
+ # Also, they may be separated by a comment (ie. "/Tag%comment\nValue"),
902
+ # but comments have already been removed
903
+ while ($objData =~ m{(\s*)/([^/[\]()<>{}\s]+)\s*(\S[^[(/<>\s]*)}sg) {
904
+ my $tag = $2;
905
+ my $val = $3;
906
+ if ($val =~ /^(<{1,2}|\[|\()/) {
907
+ # nested dict, array, literal string or hex string
908
+ $objData = substr($objData, pos($objData)-length($val));
909
+ $val = ReadToNested(\$objData, $raf);
910
+ last unless defined $val;
911
+ $val = ExtractObject($exifTool, \$val);
912
+ pos($objData) = 0;
913
+ } elsif ($val =~ /^\d/) {
914
+ my $pos = pos($objData);
915
+ if ($objData =~ /\G\s+(\d+)\s+R/sg) {
916
+ $val = \ "$val $1 R"; # make a reference
917
+ } else {
918
+ pos($objData) = $pos;
919
+ }
920
+ }
921
+ if ($$dict{$tag}) {
922
+ # duplicate dictionary entries are not allowed
923
+ $exifTool->Warn('Duplicate $tag entry in dictionary (ignored)');
924
+ } else {
925
+ # save the entry
926
+ push @tags, $tag;
927
+ $$dict{$tag} = $val;
928
+ }
929
+ }
930
+ return undef unless @tags;
931
+ $$dict{_tags} = \@tags;
932
+ return $dict unless $raf; # direct objects can not have streams
933
+ #
934
+ # extract the stream object
935
+ #
936
+ # dictionary must specify stream Length
937
+ my $length = $$dict{Length} or return $dict;
938
+ if (ref $length) {
939
+ $length = $$length;
940
+ my $oldpos = $raf->Tell();
941
+ # get the location of the object specifying the length
942
+ # (compressed objects are not allowed)
943
+ my $offset = LocateObject($xref, $length) or return $dict;
944
+ $offset or $exifTool->Warn('Bad Length object'), return $dict;
945
+ $raf->Seek($offset, 0) or $exifTool->Warn('Bad Length offset'), return $dict;
946
+ # verify that we are reading the expected object
947
+ $raf->ReadLine($data) or $exifTool->Warn('Error reading Length data'), return $dict;
948
+ $length =~ s/R/obj/;
949
+ unless ($data =~ /^$length\s+(\d+)?/) {
950
+ $exifTool->Warn("Length object ($length) not found at $offset");
951
+ return $dict;
952
+ }
953
+ if (defined $1) {
954
+ $length = $1;
955
+ } else {
956
+ $raf->ReadLine($data) or $exifTool->Warn('Error reading stream Length'), return $dict;
957
+ $data =~ /^\s*(\d+)/ or $exifTool->Warn('Stream length not found'), return $dict;
958
+ $length = $1;
959
+ }
960
+ $raf->Seek($oldpos, 0); # restore position to start of stream
961
+ }
962
+ # extract the trailing stream data
963
+ for (;;) {
964
+ # find the stream token
965
+ if ($$dataPt =~ /(\S+)/) {
966
+ last unless $1 eq 'stream';
967
+ # read an extra line because it may contain our \x0a
968
+ $$dataPt .= $data if $raf->ReadLine($data);
969
+ # remove our stream header
970
+ $$dataPt =~ s/^\s*stream(\x0a|\x0d\x0a)//s;
971
+ my $more = $length - length($$dataPt);
972
+ if ($more > 0) {
973
+ unless ($raf->Read($data, $more) == $more) {
974
+ $exifTool->Warn('Error reading stream data');
975
+ $$dataPt = '';
976
+ return $dict;
977
+ }
978
+ $$dict{_stream} = $$dataPt . $data;
979
+ $$dataPt = '';
980
+ } elsif ($more < 0) {
981
+ $$dict{_stream} = substr($$dataPt, 0, $length);
982
+ $$dataPt = substr($$dataPt, $length);
983
+ } else {
984
+ $$dict{_stream} = $$dataPt;
985
+ $$dataPt = '';
986
+ }
987
+ last;
988
+ }
989
+ $raf->ReadLine($data) or last;
990
+ $$dataPt .= $data;
991
+ }
992
+ return $dict;
993
+ }
994
+
995
+ #------------------------------------------------------------------------------
996
+ # Read to nested delimiter
997
+ # Inputs: 0) data reference, 1) optional raf reference
998
+ # Returns: data up to and including matching delimiter (or undef on error)
999
+ # - updates data reference with trailing data
1000
+ # - unescapes characters in literal strings
1001
+ my %closingDelim = ( # lookup for matching delimiter
1002
+ '(' => ')',
1003
+ '[' => ']',
1004
+ '<' => '>',
1005
+ '<<' => '>>',
1006
+ );
1007
+ sub ReadToNested($;$)
1008
+ {
1009
+ my ($dataPt, $raf) = @_;
1010
+ my @delim = (''); # closing delimiter list, most deeply nested first
1011
+ pos($$dataPt) = 0; # begin at start of data
1012
+ for (;;) {
1013
+ unless ($$dataPt =~ /(\\*)(\(|\)|<{1,2}|>{1,2}|\[|\]|%)/g) {
1014
+ # must read some more data
1015
+ my $buff;
1016
+ last unless $raf and $raf->ReadLine($buff);
1017
+ $$dataPt .= $buff;
1018
+ pos($$dataPt) = length($$dataPt) - length($buff);
1019
+ next;
1020
+ }
1021
+ # are we in a literal string?
1022
+ if ($delim[0] eq ')') {
1023
+ # ignore escaped delimiters (preceded by odd number of \'s)
1024
+ next if length($1) & 0x01;
1025
+ # ignore all delimiters but unescaped braces
1026
+ next unless $2 eq '(' or $2 eq ')';
1027
+ } elsif ($2 eq '%') {
1028
+ # ignore the comment
1029
+ my $pos = pos($$dataPt) - 1;
1030
+ # remove everything from '%' up to but not including newline
1031
+ $$dataPt =~ /.*/g;
1032
+ my $end = pos($$dataPt);
1033
+ $$dataPt = substr($$dataPt, 0, $pos) . substr($$dataPt, $end);
1034
+ pos($$dataPt) = $pos;
1035
+ next;
1036
+ }
1037
+ if ($closingDelim{$2}) {
1038
+ # push the corresponding closing delimiter
1039
+ unshift @delim, $closingDelim{$2};
1040
+ next;
1041
+ }
1042
+ unless ($2 eq $delim[0]) {
1043
+ # handle the case where we find a ">>>" and interpret it
1044
+ # as ">> >" instead of "> >>"
1045
+ next unless $2 eq '>>' and $delim[0] eq '>';
1046
+ pos($$dataPt) = pos($$dataPt) - 1;
1047
+ }
1048
+ shift @delim; # remove from nesting list
1049
+ next if $delim[0]; # keep going if we have more nested delimiters
1050
+ my $pos = pos($$dataPt);
1051
+ my $buff = substr($$dataPt, 0, $pos);
1052
+ $$dataPt = substr($$dataPt, $pos);
1053
+ return $buff; # success!
1054
+ }
1055
+ return undef; # didn't find matching delimiter
1056
+ }
1057
+
1058
+ #------------------------------------------------------------------------------
1059
+ # Decode LZW-encoded data (ref 1)
1060
+ # Inputs: 0) data reference
1061
+ # Returns: true on success and data is decoded, or false and data is untouched
1062
+ sub DecodeLZW($)
1063
+ {
1064
+ my $dataPt = shift;
1065
+ return 0 if length $$dataPt < 4;
1066
+ my @lzw = (map(chr, 0..255), undef, undef); # LZW code table
1067
+ my $mask = 0x01ff; # mask for least-significant 9 bits
1068
+ my @dat = unpack 'n*', $$dataPt . "\0";
1069
+ my $word = ($dat[0] << 16) | $dat[1];
1070
+ my ($bit, $pos, $bits, $out) = (0, 2, 9, '');
1071
+ my $lastVal;
1072
+ for (;;) {
1073
+ # bits are packed MSB first in PDF LZW (the PDF spec doesn't mention this)
1074
+ my $shift = 32 - ($bit + $bits);
1075
+ if ($shift < 0) {
1076
+ return 0 if $pos >= @dat; # missing EOD marker
1077
+ $word = (($word & 0xffff) << 16) | $dat[$pos++]; # read next word
1078
+ $bit -= 16;
1079
+ $shift += 16;
1080
+ };
1081
+ my $code = ($word >> $shift) & $mask;
1082
+ $bit += $bits;
1083
+ my $val = $lzw[$code];
1084
+ if (defined $val) {
1085
+ # store new code as previous sequence plus 1st char of new sequence
1086
+ push @lzw, $lastVal . substr($val, 0, 1) if defined $lastVal;
1087
+ } elsif ($code == @lzw) { # new code
1088
+ return 0 unless defined $lastVal;
1089
+ # we are using the code that we are about to generate, so the last
1090
+ # character in the new sequence must be the same as the first
1091
+ # character in the previous sequence (makes sense if you think about it)
1092
+ $val = $lastVal . substr($lastVal, 0, 1);
1093
+ push @lzw, $val;
1094
+ } elsif ($code == 256) { # clear table
1095
+ splice @lzw, 258;
1096
+ $bits = 9;
1097
+ $mask = 0x1ff;
1098
+ undef $lastVal;
1099
+ next;
1100
+ } elsif ($code == 257) { # EOD marker
1101
+ last; # all done!
1102
+ } else {
1103
+ return 0;
1104
+ }
1105
+ $out .= $val; # add this byte sequence to the output
1106
+ # we added a new entry to the LZW table, so we must increase
1107
+ # the bit width if necessary, up to a maximum of 12
1108
+ @lzw >= $mask and $bits < 12 and ++$bits, $mask |= $mask << 1;
1109
+ $lastVal = $val;
1110
+ }
1111
+ $$dataPt = $out; # return decompressed data
1112
+ return 1;
1113
+ }
1114
+
1115
+ #------------------------------------------------------------------------------
1116
+ # Decode filtered stream
1117
+ # Inputs: 0) ExifTool object reference, 1) dictionary reference
1118
+ # Returns: true if stream has been decoded OK
1119
+ sub DecodeStream($$)
1120
+ {
1121
+ local $_;
1122
+ my ($exifTool, $dict) = @_;
1123
+
1124
+ return 0 unless $$dict{_stream}; # no stream to decode
1125
+
1126
+ # get list of filters
1127
+ my (@filters, @decodeParms, $filter);
1128
+ if (ref $$dict{Filter} eq 'ARRAY') {
1129
+ @filters = @{$$dict{Filter}};
1130
+ } elsif (defined $$dict{Filter}) {
1131
+ @filters = ($$dict{Filter});
1132
+ }
1133
+ # be sure we can process all the filters before we take the time to do the decryption
1134
+ foreach $filter (@filters) {
1135
+ next if $supportedFilter{$filter};
1136
+ $exifTool->WarnOnce("Unsupported Filter $filter");
1137
+ return 0;
1138
+ }
1139
+ # apply decryption first if required (and if the default encryption
1140
+ # has not been overridden by a Crypt filter. Note: the Crypt filter
1141
+ # must be first in the Filter array: ref 3, page 38)
1142
+ unless (defined $$dict{_decrypted} or ($filters[0] and $filters[0] eq '/Crypt')) {
1143
+ CryptStream($dict, $lastFetched);
1144
+ }
1145
+ return 1 unless $$dict{Filter}; # Filter entry is mandatory
1146
+ return 0 if defined $$dict{_filtered}; # avoid double-filtering
1147
+ $$dict{_filtered} = 1; # set flag to prevent double-filtering
1148
+
1149
+ # get array of DecodeParms dictionaries
1150
+ if (ref $$dict{DecodeParms} eq 'ARRAY') {
1151
+ @decodeParms = @{$$dict{DecodeParms}};
1152
+ } else {
1153
+ @decodeParms = ($$dict{DecodeParms});
1154
+ }
1155
+
1156
+ foreach $filter (@filters) {
1157
+ my $decodeParms = shift @decodeParms;
1158
+
1159
+ if ($filter eq '/FlateDecode') {
1160
+ # make sure we support the predictor (if used) before decoding
1161
+ my $pre;
1162
+ if (ref $decodeParms eq 'HASH') {
1163
+ $pre = $$decodeParms{Predictor};
1164
+ if ($pre and $pre ne '1' and $pre ne '12') {
1165
+ $exifTool->WarnOnce("FlateDecode Predictor $pre currently not supported");
1166
+ return 0;
1167
+ }
1168
+ }
1169
+ if (eval 'require Compress::Zlib') {
1170
+ my $inflate = Compress::Zlib::inflateInit();
1171
+ my ($buff, $stat);
1172
+ $inflate and ($buff, $stat) = $inflate->inflate($$dict{_stream});
1173
+ if ($inflate and $stat == Compress::Zlib::Z_STREAM_END()) {
1174
+ $$dict{_stream} = $buff;
1175
+ } else {
1176
+ $exifTool->Warn('Error inflating stream');
1177
+ return 0;
1178
+ }
1179
+ } else {
1180
+ $exifTool->WarnOnce('Install Compress::Zlib to process filtered streams');
1181
+ return 0;
1182
+ }
1183
+ next unless $pre and $pre eq '12'; # 12 = 'up' prediction
1184
+
1185
+ # apply anti-predictor
1186
+ my $cols = $$decodeParms{Columns};
1187
+ unless ($cols) {
1188
+ # currently only support 'up' prediction
1189
+ $exifTool->WarnOnce('No Columns for decoding stream');
1190
+ return 0;
1191
+ }
1192
+ my @bytes = unpack('C*', $$dict{_stream});
1193
+ my @pre = (0) x $cols; # initialize predictor array
1194
+ my $buff = '';
1195
+ while (@bytes > $cols) {
1196
+ unless (($_ = shift @bytes) == 2) {
1197
+ $exifTool->WarnOnce("Unsupported PNG filter $_"); # (yes, PNG)
1198
+ return 0;
1199
+ }
1200
+ foreach (@pre) {
1201
+ $_ = ($_ + shift(@bytes)) & 0xff;
1202
+ }
1203
+ $buff .= pack('C*', @pre);
1204
+ }
1205
+ $$dict{_stream} = $buff;
1206
+
1207
+ } elsif ($filter eq '/Crypt') {
1208
+
1209
+ # (we shouldn't have to check the _decrypted flag since we
1210
+ # already checked the _filtered flag, but what the heck...)
1211
+ next if defined $$dict{_decrypted};
1212
+ # assume Identity filter (the default) if DecodeParms are missing
1213
+ next unless ref $decodeParms eq 'HASH';
1214
+ my $name = $$decodeParms{Name};
1215
+ next unless defined $name or $name eq 'Identity';
1216
+ if ($name ne 'StdCF') {
1217
+ $exifTool->WarnOnce("Unsupported Crypt Filter $name");
1218
+ return 0;
1219
+ }
1220
+ unless ($cryptInfo) {
1221
+ $exifTool->WarnOnce('Missing Encrypt StdCF entry');
1222
+ return 0;
1223
+ }
1224
+ # decrypt the stream manually because we want to:
1225
+ # 1) ignore $cryptStream (StmF) setting
1226
+ # 2) ignore EncryptMetadata setting (I can't find mention of how to
1227
+ # reconcile this in the spec., but this would make sense)
1228
+ # 3) avoid adding the crypt key extension (ref 3, page 58, Algorithm 1b)
1229
+ # 4) set _decrypted flag so we will recrypt according to StmF when
1230
+ # writing (since we don't yet write Filter'd streams)
1231
+ Crypt(\$$dict{_stream}, 'none');
1232
+ $$dict{_decrypted} = ($cryptStream ? 1 : 0);
1233
+
1234
+ } elsif ($filter eq '/LZWDecode') {
1235
+
1236
+ # make sure we don't have any unsupported decoding parameters
1237
+ if (ref $decodeParms eq 'HASH') {
1238
+ if ($$decodeParms{Predictor}) {
1239
+ $exifTool->WarnOnce("LZWDecode Predictor $$decodeParms{Predictor} currently not supported");
1240
+ return 0;
1241
+ } elsif ($$decodeParms{EarlyChange}) {
1242
+ $exifTool->WarnOnce("LZWDecode EarlyChange currently not supported");
1243
+ return 0;
1244
+ }
1245
+ }
1246
+ unless (DecodeLZW(\$$dict{_stream})) {
1247
+ $exifTool->WarnOnce('LZW decompress error');
1248
+ return 0;
1249
+ }
1250
+
1251
+ } elsif ($filter eq '/ASCIIHexDecode') {
1252
+
1253
+ $$dict{_stream} =~ s/>.*//; # truncate at '>' (end of data mark)
1254
+ $$dict{_stream} =~ tr/0-9a-zA-Z//d; # remove illegal characters
1255
+ $$dict{_stream} = pack 'H*', $$dict{_stream};
1256
+
1257
+ }
1258
+ }
1259
+ return 1;
1260
+ }
1261
+
1262
+ #------------------------------------------------------------------------------
1263
+ # Initialize state for RC4 en/decryption (ref 2)
1264
+ # Inputs: 0) RC4 key string
1265
+ # Returns: RC4 key hash reference
1266
+ sub RC4Init($)
1267
+ {
1268
+ my @key = unpack('C*', shift);
1269
+ my @state = (0 .. 255);
1270
+ my ($i, $j) = (0, 0);
1271
+ while ($i < 256) {
1272
+ my $st = $state[$i];
1273
+ $j = ($j + $st + $key[$i % scalar(@key)]) & 0xff;
1274
+ $state[$i++] = $state[$j];
1275
+ $state[$j] = $st;
1276
+ }
1277
+ return { State => \@state, XY => [ 0, 0 ] };
1278
+ }
1279
+
1280
+ #------------------------------------------------------------------------------
1281
+ # Apply RC4 en/decryption (ref 2)
1282
+ # Inputs: 0) data reference, 1) RC4 key hash reference or RC4 key string
1283
+ # - can call this method directly with a key string, or with with the key
1284
+ # reference returned by RC4Init
1285
+ # - RC4 is a symmetric algorithm, so encryption is the same as decryption
1286
+ sub RC4Crypt($$)
1287
+ {
1288
+ my ($dataPt, $key) = @_;
1289
+ $key = RC4Init($key) unless ref $key eq 'HASH';
1290
+ my $state = $$key{State};
1291
+ my ($x, $y) = @{$$key{XY}};
1292
+
1293
+ my @data = unpack('C*', $$dataPt);
1294
+ foreach (@data) {
1295
+ $x = ($x + 1) & 0xff;
1296
+ my $stx = $$state[$x];
1297
+ $y = ($stx + $y) & 0xff;
1298
+ my $sty = $$state[$x] = $$state[$y];
1299
+ $$state[$y] = $stx;
1300
+ $_ ^= $$state[($stx + $sty) & 0xff];
1301
+ }
1302
+ $$key{XY} = [ $x, $y ];
1303
+ $$dataPt = pack('C*', @data);
1304
+ }
1305
+
1306
+ #------------------------------------------------------------------------------
1307
+ # Update AES cipher with a bit of data
1308
+ # Inputs: 0) data
1309
+ # Returns: encrypted data
1310
+ my $cipherMore;
1311
+ sub CipherUpdate($)
1312
+ {
1313
+ my $dat = shift;
1314
+ my $pos = 0;
1315
+ $dat = $cipherMore . $dat if length $dat;
1316
+ while ($pos + 16 <= length($dat)) {
1317
+ substr($dat,$pos,16) = Image::ExifTool::AES::Cipher(substr($dat,$pos,16));
1318
+ $pos += 16;
1319
+ }
1320
+ if ($pos < length $dat) {
1321
+ $cipherMore = substr($dat,$pos);
1322
+ $dat = substr($dat,0,$pos);
1323
+ } else {
1324
+ $cipherMore = '';
1325
+ }
1326
+ return $dat;
1327
+ }
1328
+
1329
+ #------------------------------------------------------------------------------
1330
+ # Get encrypted hash
1331
+ # Inputs: 0) Password, 1) salt, 2) vector, 3) encryption revision
1332
+ # Returns: hash
1333
+ sub GetHash($$$$)
1334
+ {
1335
+ my ($password, $salt, $vector, $rev) = @_;
1336
+
1337
+ # return Rev 5 hash
1338
+ return Digest::SHA::sha256($password, $salt, $vector) if $rev == 5;
1339
+
1340
+ # compute Rev 6 hardened hash
1341
+ # (ref http://code.google.com/p/origami-pdf/source/browse/lib/origami/encryption.rb)
1342
+ my $blockSize = 32;
1343
+ my $input = Digest::SHA::sha256($password, $salt, $vector) . ("\0" x 32);
1344
+ my $key = substr($input, 0, 16);
1345
+ my $iv = substr($input, 16, 16);
1346
+ my $h;
1347
+ my $x = '';
1348
+ my $i = 0;
1349
+ while ($i < 64 or $i < ord(substr($x,-1,1))+32) {
1350
+
1351
+ my $block = substr($input, 0, $blockSize);
1352
+ $x = '';
1353
+ Image::ExifTool::AES::Crypt(\$x, $key, $iv, 1);
1354
+ $cipherMore = '';
1355
+
1356
+ my ($j, $digest);
1357
+ for ($j=0; $j<64; ++$j) {
1358
+ $x = '';
1359
+ $x .= CipherUpdate($password) if length $password;
1360
+ $x .= CipherUpdate($block);
1361
+ $x .= CipherUpdate($vector) if length $vector;
1362
+ if ($j == 0) {
1363
+ my @a = unpack('C16', $x);
1364
+ my $sum = 0;
1365
+ $sum += $_ foreach @a;
1366
+ # set SHA block size (32, 48 or 64 bytes = SHA-256, 384 or 512)
1367
+ $blockSize = 32 + ($sum % 3) * 16;
1368
+ $digest = Digest::SHA->new($blockSize * 8);
1369
+ }
1370
+ $digest->add($x);
1371
+ }
1372
+
1373
+ $h = $digest->digest();
1374
+ $key = substr($h, 0, 16);
1375
+ substr($input,0,16) = $h;
1376
+ $iv = substr($h, 16, 16);
1377
+ ++$i;
1378
+ }
1379
+ return substr($h, 0, 32);
1380
+ }
1381
+
1382
+ #------------------------------------------------------------------------------
1383
+ # Initialize decryption
1384
+ # Inputs: 0) ExifTool object reference, 1) Encrypt dictionary reference,
1385
+ # 2) ID from file trailer dictionary
1386
+ # Returns: error string or undef on success (and sets $cryptInfo)
1387
+ sub DecryptInit($$$)
1388
+ {
1389
+ local $_;
1390
+ my ($exifTool, $encrypt, $id) = @_;
1391
+
1392
+ undef $cryptInfo;
1393
+ unless ($encrypt and ref $encrypt eq 'HASH') {
1394
+ return 'Error loading Encrypt object';
1395
+ }
1396
+ my $filt = $$encrypt{Filter};
1397
+ unless ($filt and $filt =~ s/^\///) {
1398
+ return 'Encrypt dictionary has no Filter!';
1399
+ }
1400
+ # extract some interesting tags
1401
+ my $ver = $$encrypt{V} || 0;
1402
+ my $rev = $$encrypt{R} || 0;
1403
+ my $enc = "$filt V$ver";
1404
+ $enc .= ".$rev" if $filt eq 'Standard';
1405
+ $enc .= " ($1)" if $$encrypt{SubFilter} and $$encrypt{SubFilter} =~ /^\/(.*)/;
1406
+ $enc .= ' (' . ($$encrypt{Length} || 40) . '-bit)' if $filt eq 'Standard';
1407
+ my $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Encrypt');
1408
+ $exifTool->HandleTag($tagTablePtr, 'Filter', $enc);
1409
+ if ($filt ne 'Standard') {
1410
+ return "Encryption filter $filt currently not supported";
1411
+ } elsif (not defined $$encrypt{R}) {
1412
+ return 'Standard security handler missing revision';
1413
+ }
1414
+ unless ($$encrypt{O} and $$encrypt{P} and $$encrypt{U}) {
1415
+ return 'Incomplete Encrypt specification';
1416
+ }
1417
+ if ("$ver.$rev" >= 5.6) {
1418
+ # apologize for poor performance (AES is a pure Perl implementation)
1419
+ $exifTool->Warn('Decryption is very slow for encryption V5.6 or higher', 1);
1420
+ }
1421
+ $exifTool->HandleTag($tagTablePtr, 'P', $$encrypt{P});
1422
+
1423
+ my %parm; # optional parameters extracted from Encrypt dictionary
1424
+
1425
+ if ($ver == 1 or $ver == 2) {
1426
+ $cryptString = $cryptStream = 1;
1427
+ } elsif ($ver == 4 or $ver == 5) {
1428
+ # initialize our $cryptString and $cryptStream flags
1429
+ foreach ('StrF', 'StmF') {
1430
+ my $flagPt = $_ eq 'StrF' ? \$cryptString : \$cryptStream;
1431
+ $$flagPt = $$encrypt{$_};
1432
+ undef $$flagPt if $$flagPt and $$flagPt eq '/Identity';
1433
+ return "Unsupported $_ encryption $$flagPt" if $$flagPt and $$flagPt ne '/StdCF';
1434
+ }
1435
+ if ($cryptString or $cryptStream) {
1436
+ return 'Missing or invalid Encrypt StdCF entry' unless ref $$encrypt{CF} eq 'HASH' and
1437
+ ref $$encrypt{CF}{StdCF} eq 'HASH' and $$encrypt{CF}{StdCF}{CFM};
1438
+ my $cryptMeth = $$encrypt{CF}{StdCF}{CFM};
1439
+ unless ($cryptMeth =~ /^\/(V2|AESV2|AESV3)$/) {
1440
+ return "Unsupported encryption method $cryptMeth";
1441
+ }
1442
+ # set "_aesv2" or "_aesv3" flag in %$encrypt hash if AES encryption was used
1443
+ $$encrypt{'_' . lc($1)} = 1 if $cryptMeth =~ /^\/(AESV2|AESV3)$/;
1444
+ }
1445
+ if ($ver == 5) {
1446
+ # validate OE and UE entries
1447
+ foreach ('OE', 'UE') {
1448
+ return "Missing Encrypt $_ entry" unless $$encrypt{$_};
1449
+ $parm{$_} = ReadPDFValue($$encrypt{$_});
1450
+ return "Invalid Encrypt $_ entry" unless length $parm{$_} == 32;
1451
+ }
1452
+ require Image::ExifTool::AES; # will need this later
1453
+ }
1454
+ } else {
1455
+ return "Encryption version $ver currently not supported";
1456
+ }
1457
+ $id or return "Can't decrypt (no document ID)";
1458
+
1459
+ # make sure we have the necessary libraries available
1460
+ if ($ver < 5) {
1461
+ unless (eval 'require Digest::MD5') {
1462
+ return "Install Digest::MD5 to process encrypted PDF";
1463
+ }
1464
+ } else {
1465
+ unless (eval 'require Digest::SHA') {
1466
+ return "Install Digest::SHA to process AES-256 encrypted PDF";
1467
+ }
1468
+ }
1469
+
1470
+ # calculate file-level en/decryption key
1471
+ my $pad = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
1472
+ "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
1473
+ my $o = ReadPDFValue($$encrypt{O});
1474
+ my $u = ReadPDFValue($$encrypt{U});
1475
+
1476
+ # set flag indicating whether metadata is encrypted
1477
+ # (in version 4 and higher, metadata streams may not be encrypted)
1478
+ if ($ver < 4 or not $$encrypt{EncryptMetadata} or $$encrypt{EncryptMetadata} !~ /false/i) {
1479
+ $$encrypt{_meta} = 1;
1480
+ }
1481
+ # try no password first, then try provided password if available
1482
+ my ($try, $key);
1483
+ for ($try=0; ; ++$try) {
1484
+ my $password;
1485
+ if ($try == 0) {
1486
+ $password = '';
1487
+ } elsif ($try == 1) {
1488
+ $password = $exifTool->Options('Password');
1489
+ return 'Document is password protected (use Password option)' unless defined $password;
1490
+ # make sure there is no UTF-8 flag on the password
1491
+ if ($] >= 5.006 and (eval 'require Encode; Encode::is_utf8($password)' or $@)) {
1492
+ # repack by hand if Encode isn't available
1493
+ $password = $@ ? pack('C*',unpack('U0C*',$password)) : Encode::encode('utf8',$password);
1494
+ }
1495
+ } else {
1496
+ return 'Incorrect password';
1497
+ }
1498
+ if ($ver < 5) {
1499
+ if (length $password) {
1500
+ # password must be encoding in PDFDocEncoding (ref iso32000)
1501
+ $password = $exifTool->Encode($password, 'PDFDoc');
1502
+ # truncate or pad the password to exactly 32 bytes
1503
+ if (length($password) > 32) {
1504
+ $password = substr($password, 0, 32);
1505
+ } elsif (length($password) < 32) {
1506
+ $password .= substr($pad, 0, 32-length($password));
1507
+ }
1508
+ } else {
1509
+ $password = $pad;
1510
+ }
1511
+ $key = $password . $o . pack('V', $$encrypt{P}) . $id;
1512
+ my $rep = 1;
1513
+ if ($rev == 3 or $rev == 4) {
1514
+ # must add this if metadata not encrypted
1515
+ $key .= "\xff\xff\xff\xff" unless $$encrypt{_meta};
1516
+ $rep += 50; # repeat MD5 50 more times if revision is 3 or greater
1517
+ }
1518
+ my ($len, $i, $dat);
1519
+ if ($ver == 1) {
1520
+ $len = 5;
1521
+ } else {
1522
+ $len = $$encrypt{Length} || 40;
1523
+ $len >= 40 or return 'Bad Encrypt Length';
1524
+ $len = int($len / 8);
1525
+ }
1526
+ for ($i=0; $i<$rep; ++$i) {
1527
+ $key = substr(Digest::MD5::md5($key), 0, $len);
1528
+ }
1529
+ # decrypt U to see if a user password is required
1530
+ if ($rev >= 3) {
1531
+ $dat = Digest::MD5::md5($pad . $id);
1532
+ RC4Crypt(\$dat, $key);
1533
+ for ($i=1; $i<=19; ++$i) {
1534
+ my @key = unpack('C*', $key);
1535
+ foreach (@key) { $_ ^= $i; }
1536
+ RC4Crypt(\$dat, pack('C*', @key));
1537
+ }
1538
+ $dat .= substr($u, 16);
1539
+ } else {
1540
+ $dat = $pad;
1541
+ RC4Crypt(\$dat, $key);
1542
+ }
1543
+ last if $dat eq $u; # all done if this was the correct key
1544
+ } else {
1545
+ return 'Invalid O or U Encrypt entries' if length($o) < 48 or length($u) < 48;
1546
+ if (length $password) {
1547
+ # Note: this should be good for passwords containing reasonable characters,
1548
+ # but to be bullet-proof we need to apply the SASLprep (IETF RFC 4013) profile
1549
+ # of stringprep (IETF RFC 3454) to the password before encoding in UTF-8
1550
+ $password = $exifTool->Encode($password, 'UTF8');
1551
+ $password = substr($password, 0, 127) if length($password) > 127;
1552
+ }
1553
+ # test for the owner password
1554
+ my $sha = GetHash($password, substr($o,32,8), substr($u,0,48), $rev);
1555
+ if ($sha eq substr($o, 0, 32)) {
1556
+ $key = GetHash($password, substr($o,40,8), substr($u,0,48), $rev);
1557
+ my $dat = ("\0" x 16) . $parm{OE};
1558
+ # decrypt with no padding
1559
+ my $err = Image::ExifTool::AES::Crypt(\$dat, $key, 0, 1);
1560
+ return $err if $err;
1561
+ $key = $dat; # use this as the file decryption key
1562
+ last;
1563
+ }
1564
+ # test for the user password
1565
+ $sha = GetHash($password, substr($u,32,8), '', $rev);
1566
+ if ($sha eq substr($u, 0, 32)) {
1567
+ $key = GetHash($password, substr($u,40,8), '', $rev);
1568
+ my $dat = ("\0" x 16) . $parm{UE};
1569
+ my $err = Image::ExifTool::AES::Crypt(\$dat, $key, 0, 1);
1570
+ return $err if $err;
1571
+ $key = $dat; # use this as the file decryption key
1572
+ last;
1573
+ }
1574
+ }
1575
+ }
1576
+ $$encrypt{_key} = $key; # save the file-level encryption key
1577
+ $cryptInfo = $encrypt; # save reference to the file-level Encrypt object
1578
+ return undef; # success!
1579
+ }
1580
+
1581
+ #------------------------------------------------------------------------------
1582
+ # Decrypt/Encrypt data
1583
+ # Inputs: 0) data ref
1584
+ # 1) PDF object reference to use as crypt key extension (may be 'none' to
1585
+ # avoid extending the encryption key, as for streams with Crypt Filter)
1586
+ # 2) encrypt flag (false for decryption)
1587
+ sub Crypt($$;$)
1588
+ {
1589
+ return unless $cryptInfo;
1590
+ my ($dataPt, $keyExt, $encrypt) = @_;
1591
+ # do not decrypt if the key extension object is undefined
1592
+ # (this doubles as a flag to disable decryption/encryption)
1593
+ return unless defined $keyExt;
1594
+ my $key = $$cryptInfo{_key};
1595
+ # apply the necessary crypt key extension
1596
+ unless ($$cryptInfo{_aesv3}) {
1597
+ unless ($keyExt eq 'none') {
1598
+ # extend crypt key using object and generation number
1599
+ unless ($keyExt =~ /^(I\d+ )?(\d+) (\d+)/) {
1600
+ $$cryptInfo{_error} = 'Invalid object reference for encryption';
1601
+ return;
1602
+ }
1603
+ $key .= substr(pack('V', $2), 0, 3) . substr(pack('V', $3), 0, 2);
1604
+ }
1605
+ # add AES-128 salt if necessary (this little gem is conveniently
1606
+ # omitted from the Adobe PDF 1.6 documentation, causing me to
1607
+ # waste 12 hours trying to figure out why this wasn't working --
1608
+ # it appears in ISO32000 though, so I should have been using that)
1609
+ $key .= 'sAlT' if $$cryptInfo{_aesv2};
1610
+ my $len = length($key);
1611
+ $key = Digest::MD5::md5($key); # get 16-byte MD5 digest
1612
+ $key = substr($key, 0, $len) if $len < 16; # trim if necessary
1613
+ }
1614
+ # perform the decryption/encryption
1615
+ if ($$cryptInfo{_aesv2} or $$cryptInfo{_aesv3}) {
1616
+ require Image::ExifTool::AES;
1617
+ my $err = Image::ExifTool::AES::Crypt($dataPt, $key, $encrypt);
1618
+ $err and $$cryptInfo{_error} = $err;
1619
+ } else {
1620
+ RC4Crypt($dataPt, $key);
1621
+ }
1622
+ }
1623
+
1624
+ #------------------------------------------------------------------------------
1625
+ # Decrypt/Encrypt stream data
1626
+ # Inputs: 0) dictionary ref, 1) PDF object reference to use as crypt key extension
1627
+ sub CryptStream($$)
1628
+ {
1629
+ return unless $cryptStream;
1630
+ my ($dict, $keyExt) = @_;
1631
+ my $type = $$dict{Type} || '';
1632
+ # XRef streams are not encrypted (ref 3, page 50),
1633
+ # and Metadata may or may not be encrypted
1634
+ if ($cryptInfo and $type ne '/XRef' and
1635
+ ($$cryptInfo{_meta} or $type ne '/Metadata'))
1636
+ {
1637
+ Crypt(\$$dict{_stream}, $keyExt, $$dict{_decrypted});
1638
+ # toggle _decrypted flag
1639
+ $$dict{_decrypted} = ($$dict{_decrypted} ? undef : 1);
1640
+ } else {
1641
+ $$dict{_decrypted} = 0; # stream should never be encrypted
1642
+ }
1643
+ }
1644
+
1645
+ #------------------------------------------------------------------------------
1646
+ # Generate a new PDF tag (based on its ID) and add it to a tag table
1647
+ # Inputs: 0) tag table ref, 1) tag ID
1648
+ # Returns: tag info ref
1649
+ sub NewPDFTag($$)
1650
+ {
1651
+ my ($tagTablePtr, $tag) = @_;
1652
+ my $name = $tag;
1653
+ # translate URL-like escape sequences
1654
+ $name =~ s/#([0-9a-f]{2})/chr(hex($1))/ige;
1655
+ $name =~ s/[^-\w]+/_/g; # translate invalid characters to an underline
1656
+ $name =~ s/(^|_)([a-z])/\U$2/g; # start words with upper case
1657
+ my $tagInfo = { Name => $name };
1658
+ AddTagToTable($tagTablePtr, $tag, $tagInfo);
1659
+ return $tagInfo;
1660
+ }
1661
+
1662
+ #------------------------------------------------------------------------------
1663
+ # Process AcroForm dictionary to set HasXMLFormsArchitecture flag
1664
+ # Inputs: Same as ProcessDict
1665
+ sub ProcessAcroForm($$$$;$$)
1666
+ {
1667
+ my ($exifTool, $tagTablePtr, $dict, $xref, $nesting, $type) = @_;
1668
+ $exifTool->HandleTag($tagTablePtr, '_has_xfa', $$dict{XFA} ? 'true' : 'false');
1669
+ return ProcessDict($exifTool, $tagTablePtr, $dict, $xref, $nesting, $type);
1670
+ }
1671
+
1672
+ #------------------------------------------------------------------------------
1673
+ # Process PDF dictionary extract tag values
1674
+ # Inputs: 0) ExifTool object reference, 1) tag table reference
1675
+ # 2) dictionary reference, 3) cross-reference table reference,
1676
+ # 4) nesting depth, 5) dictionary capture type
1677
+ sub ProcessDict($$$$;$$)
1678
+ {
1679
+ my ($exifTool, $tagTablePtr, $dict, $xref, $nesting, $type) = @_;
1680
+ my $verbose = $exifTool->Options('Verbose');
1681
+ my $unknown = $$tagTablePtr{EXTRACT_UNKNOWN};
1682
+ my $embedded = (defined $unknown and not $unknown and $exifTool->Options('ExtractEmbedded'));
1683
+ my @tags = @{$$dict{_tags}};
1684
+ my ($next, %join);
1685
+ my $index = 0;
1686
+
1687
+ $nesting = ($nesting || 0) + 1;
1688
+ if ($nesting > 50) {
1689
+ $exifTool->WarnOnce('Nesting too deep (directory ignored)');
1690
+ return;
1691
+ }
1692
+ # save entire dictionary for rewriting if specified
1693
+ if ($$exifTool{PDF_CAPTURE} and $$tagTablePtr{VARS} and
1694
+ $tagTablePtr->{VARS}->{CAPTURE})
1695
+ {
1696
+ my $name;
1697
+ foreach $name (@{$tagTablePtr->{VARS}->{CAPTURE}}) {
1698
+ next if $exifTool->{PDF_CAPTURE}->{$name};
1699
+ # make sure we load the right type if indicated
1700
+ next if $type and $type ne $name;
1701
+ $exifTool->{PDF_CAPTURE}->{$name} = $dict;
1702
+ last;
1703
+ }
1704
+ }
1705
+ #
1706
+ # extract information from all tags in the dictionary
1707
+ #
1708
+ for (;;) {
1709
+ my ($tag, $isSubDoc);
1710
+ if (@tags) {
1711
+ $tag = shift @tags;
1712
+ } elsif (defined $next and not $next) {
1713
+ $tag = 'Next';
1714
+ $next = 1;
1715
+ } else {
1716
+ last;
1717
+ }
1718
+ my $val = $$dict{$tag};
1719
+ my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
1720
+ if ($tagInfo) {
1721
+ undef $tagInfo if $$tagInfo{NoProcess};
1722
+ } elsif ($embedded and $tag =~ /^(.*?)(\d+)$/ and
1723
+ $$tagTablePtr{$1} and (ref $val ne 'SCALAR' or not $fetched{$$val}))
1724
+ {
1725
+ my ($name, $num) = ($1, $2);
1726
+ $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $name);
1727
+ if (ref $tagInfo eq 'HASH' and $$tagInfo{JoinStreams}) {
1728
+ $fetched{$$val} = 1;
1729
+ my $obj = FetchObject($exifTool, $$val, $xref, $tag);
1730
+ $join{$name} = [] unless $join{$name};
1731
+ next unless ref $obj eq 'HASH' and $$obj{_stream};
1732
+ # save all the stream data to join later
1733
+ DecodeStream($exifTool, $obj);
1734
+ $join{$name}->[$num] = $$obj{_stream};
1735
+ undef $tagInfo; # don't process
1736
+ } else {
1737
+ $isSubDoc = 1; # treat as a sub-document
1738
+ }
1739
+ }
1740
+ if ($verbose) {
1741
+ my ($val2, $extra);
1742
+ if (ref $val eq 'SCALAR') {
1743
+ $extra = ", indirect object ($$val)";
1744
+ if ($fetched{$$val}) {
1745
+ $val2 = "ref($$val)";
1746
+ } elsif ($tag eq 'Next' and not $next) {
1747
+ # handle 'Next' links after all others
1748
+ $next = 0;
1749
+ next;
1750
+ } else {
1751
+ $fetched{$$val} = 1;
1752
+ $val = FetchObject($exifTool, $$val, $xref, $tag);
1753
+ unless (defined $val) {
1754
+ my $str;
1755
+ if (defined $lastOffset) {
1756
+ $val2 = '<free>';
1757
+ $str = 'Object was freed';
1758
+ } else {
1759
+ $val2 = '<err>';
1760
+ $str = 'Error reading object';
1761
+ }
1762
+ $exifTool->VPrint(0, "$$exifTool{INDENT}${str}:\n");
1763
+ }
1764
+ }
1765
+ } elsif (ref $val eq 'HASH') {
1766
+ $extra = ', direct dictionary';
1767
+ } elsif (ref $val eq 'ARRAY') {
1768
+ $extra = ', direct array of ' . scalar(@$val) . ' objects';
1769
+ } else {
1770
+ $extra = ', direct object';
1771
+ }
1772
+ my $isSubdir;
1773
+ if (ref $val eq 'HASH') {
1774
+ $isSubdir = 1;
1775
+ } elsif (ref $val eq 'ARRAY') {
1776
+ # recurse into objects in arrays only if they are lists of
1777
+ # dictionaries or indirect objects which could be dictionaries
1778
+ $isSubdir = 1 if @$val;
1779
+ foreach (@$val) {
1780
+ next if ref $_ eq 'HASH' or ref $_ eq 'SCALAR';
1781
+ undef $isSubdir;
1782
+ last;
1783
+ }
1784
+ }
1785
+ if ($isSubdir) {
1786
+ # create bogus subdirectory to recurse into this dict
1787
+ $tagInfo or $tagInfo = {
1788
+ Name => $tag,
1789
+ SubDirectory => { TagTable => 'Image::ExifTool::PDF::Unknown' },
1790
+ };
1791
+ } else {
1792
+ if (ref $val eq 'ARRAY') {
1793
+ my @list = @$val;
1794
+ foreach (@list) {
1795
+ $_ = "ref($$_)" if ref $_ eq 'SCALAR';
1796
+ $_ = '<undef>' unless defined $_;
1797
+ }
1798
+ $val2 = '[' . join(',',@list) . ']';
1799
+ }
1800
+ # generate tag info if we will use it later
1801
+ if (not $tagInfo and defined $val and $unknown) {
1802
+ $tagInfo = NewPDFTag($tagTablePtr, $tag);
1803
+ }
1804
+ }
1805
+ $exifTool->VerboseInfo($tag, $tagInfo,
1806
+ Value => $val2 || $val,
1807
+ Extra => $extra,
1808
+ Index => $index++,
1809
+ );
1810
+ next unless defined $val;
1811
+ }
1812
+ unless ($tagInfo) {
1813
+ # add any tag found in Info dictionary to table
1814
+ next unless $unknown;
1815
+ $tagInfo = NewPDFTag($tagTablePtr, $tag);
1816
+ }
1817
+ # increment document number if necessary
1818
+ my ($oldDocNum, $oldNumTags);
1819
+ if ($isSubDoc) {
1820
+ $oldDocNum = $$exifTool{DOC_NUM};
1821
+ $oldNumTags = $$exifTool{NUM_FOUND};
1822
+ $$exifTool{DOC_NUM} = ++$$exifTool{DOC_COUNT};
1823
+ }
1824
+ if ($$tagInfo{SubDirectory}) {
1825
+ # process the subdirectory
1826
+ my @subDicts;
1827
+ if (ref $val eq 'ARRAY') {
1828
+ @subDicts = @{$val};
1829
+ } else {
1830
+ @subDicts = ( $val );
1831
+ }
1832
+ # loop through all values of this tag
1833
+ for (;;) {
1834
+ my $subDict = shift @subDicts or last;
1835
+ # save last fetched object in case we fetch another one here
1836
+ my $prevFetched = $lastFetched;
1837
+ if (ref $subDict eq 'SCALAR') {
1838
+ # only fetch once (other copies are obsolete)
1839
+ next if $fetched{$$subDict};
1840
+ if ($$tagInfo{IgnoreDuplicates}) {
1841
+ my $flag = "ProcessedPDF_$tag";
1842
+ if ($$exifTool{$flag}) {
1843
+ next if $exifTool->WarnOnce("Ignored duplicate $tag dictionary", 2);
1844
+ } else {
1845
+ $$exifTool{$flag} = 1;
1846
+ }
1847
+ }
1848
+ # load dictionary via an indirect reference
1849
+ $fetched{$$subDict} = 1;
1850
+ my $obj = FetchObject($exifTool, $$subDict, $xref, $tag);
1851
+ unless (defined $obj) {
1852
+ unless (defined $lastOffset) {
1853
+ $exifTool->Warn("Error reading $tag object ($$subDict)");
1854
+ }
1855
+ next;
1856
+ }
1857
+ $subDict = $obj;
1858
+ }
1859
+ if (ref $subDict eq 'ARRAY') {
1860
+ # convert array of key/value pairs to a hash
1861
+ next if @$subDict < 2;
1862
+ my %hash = ( _tags => [] );
1863
+ while (@$subDict >= 2) {
1864
+ my $key = shift @$subDict;
1865
+ $key =~ s/^\///;
1866
+ push @{$hash{_tags}}, $key;
1867
+ $hash{$key} = shift @$subDict;
1868
+ }
1869
+ $subDict = \%hash;
1870
+ } else {
1871
+ next unless ref $subDict eq 'HASH';
1872
+ }
1873
+ # set flag to re-crypt all strings when rewriting if the dictionary
1874
+ # came from an encrypted stream
1875
+ $$subDict{_needCrypt}{'*'} = 1 unless $lastFetched;
1876
+ my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
1877
+ if (not $verbose) {
1878
+ my $proc = $$subTablePtr{PROCESS_PROC} || \&ProcessDict;
1879
+ &$proc($exifTool, $subTablePtr, $subDict, $xref, $nesting);
1880
+ } elsif ($next) {
1881
+ # handle 'Next' links at this level to avoid deep recursion
1882
+ undef $next;
1883
+ $index = 0;
1884
+ $tagTablePtr = $subTablePtr;
1885
+ $dict = $subDict;
1886
+ @tags = @{$$subDict{_tags}};
1887
+ $exifTool->VerboseDir($tag, scalar(@tags));
1888
+ } else {
1889
+ my $oldIndent = $exifTool->{INDENT};
1890
+ my $oldDir = $exifTool->{DIR_NAME};
1891
+ $exifTool->{INDENT} .= '| ';
1892
+ $exifTool->{DIR_NAME} = $tag;
1893
+ $exifTool->VerboseDir($tag, scalar(@{$$subDict{_tags}}));
1894
+ ProcessDict($exifTool, $subTablePtr, $subDict, $xref, $nesting);
1895
+ $exifTool->{INDENT} = $oldIndent;
1896
+ $exifTool->{DIR_NAME} = $oldDir;
1897
+ }
1898
+ $lastFetched = $prevFetched;
1899
+ }
1900
+ } else {
1901
+ # fetch object if necessary
1902
+ # (OS X 10.6 writes indirect objects in the Info dictionary!)
1903
+ if (ref $val eq 'SCALAR') {
1904
+ my $prevFetched = $lastFetched;
1905
+ # (note: fetching the same object multiple times is OK here)
1906
+ $val = FetchObject($exifTool, $$val, $xref, $tag);
1907
+ if (defined $val) {
1908
+ $val = ReadPDFValue($val);
1909
+ # set flag to re-encrypt if necessary if rewritten
1910
+ $$dict{_needCrypt}{$tag} = ($lastFetched ? 0 : 1) if $cryptString;
1911
+ $lastFetched = $prevFetched; # restore last fetched object reference
1912
+ }
1913
+ } else {
1914
+ $val = ReadPDFValue($val);
1915
+ }
1916
+ # convert from UTF-16 (big endian) to UTF-8 or Latin if necessary
1917
+ # unless this is binary data (hex-encoded strings would not have been converted)
1918
+ if (ref $val) {
1919
+ if (ref $val eq 'ARRAY') {
1920
+ my $v;
1921
+ foreach $v (@$val) {
1922
+ $exifTool->FoundTag($tagInfo, $v);
1923
+ }
1924
+ }
1925
+ } elsif (defined $val) {
1926
+ my $format = $$tagInfo{Format} || $$tagInfo{Writable} || 'string';
1927
+ $val = ConvertPDFDate($val) if $format eq 'date';
1928
+ if (not $$tagInfo{Binary} and $val =~ /[\x18-\x1f\x80-\xff]/) {
1929
+ # text string is already in Unicode if it starts with "\xfe\xff",
1930
+ # otherwise we must first convert from PDFDocEncoding
1931
+ $val = $exifTool->Decode($val, ($val=~s/^\xfe\xff// ? 'UCS2' : 'PDFDoc'), 'MM');
1932
+ }
1933
+ if ($$tagInfo{List}) {
1934
+ # separate tokens in comma or whitespace delimited lists
1935
+ my @values = ($val =~ /,/) ? split /,+\s*/, $val : split ' ', $val;
1936
+ foreach $val (@values) {
1937
+ $exifTool->FoundTag($tagInfo, $val);
1938
+ }
1939
+ } else {
1940
+ # a simple tag value
1941
+ $exifTool->FoundTag($tagInfo, $val);
1942
+ }
1943
+ }
1944
+ }
1945
+ if ($isSubDoc) {
1946
+ # restore original document number
1947
+ $$exifTool{DOC_NUM} = $oldDocNum;
1948
+ --$$exifTool{DOC_COUNT} if $oldNumTags == $$exifTool{NUM_FOUND};
1949
+ }
1950
+ }
1951
+ #
1952
+ # extract information from joined streams if necessary
1953
+ #
1954
+
1955
+ if (%join) {
1956
+ my ($tag, $i);
1957
+ foreach $tag (sort keys %join) {
1958
+ my $list = $join{$tag};
1959
+ last unless defined $$list[1] and $$list[1] =~ /^%.*?([\x0d\x0a]*)/;
1960
+ my $buff = "%!PS-Adobe-3.0$1"; # add PS header with same line break
1961
+ for ($i=1; defined $$list[$i]; ++$i) {
1962
+ $buff .= $$list[$i];
1963
+ undef $$list[$i]; # free memory
1964
+ }
1965
+ # increment document number for tags extracted from embedded EPS
1966
+ my $oldDocNum = $$exifTool{DOC_NUM};
1967
+ my $oldNumTags = $$exifTool{NUM_FOUND};
1968
+ $$exifTool{DOC_NUM} = ++$$exifTool{DOC_COUNT};
1969
+ # extract PostScript information
1970
+ $exifTool->HandleTag($tagTablePtr, $tag, $buff);
1971
+ $$exifTool{DOC_NUM} = $oldDocNum;
1972
+ # revert document counter if we didn't add any new tags
1973
+ --$$exifTool{DOC_COUNT} if $oldNumTags == $$exifTool{NUM_FOUND};
1974
+ delete $$exifTool{DOC_NUM};
1975
+ }
1976
+ }
1977
+ #
1978
+ # extract information from stream object if it exists (ie. Metadata stream)
1979
+ #
1980
+ for (;;) { # (cheap goto)
1981
+ last unless $$dict{_stream};
1982
+ my $tag = '_stream';
1983
+ # add Subtype (if it exists) to stream name and remove leading '/'
1984
+ ($tag = $$dict{Subtype} . $tag) =~ s/^\/// if $$dict{Subtype};
1985
+ last unless $$tagTablePtr{$tag};
1986
+ my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag) or last;
1987
+ unless ($$tagInfo{SubDirectory}) {
1988
+ # don't build filter lists across different images
1989
+ delete $$exifTool{LIST_TAGS}{$$tagTablePtr{Filter}};
1990
+ # we arrive here only when extracting embedded images
1991
+ # - only extract known image types and ignore others
1992
+ my $filter = $$dict{Filter} || '';
1993
+ $filter = @$filter[-1] if ref $filter eq 'ARRAY'; # (get last Filter type)
1994
+ my $result;
1995
+ if ($filter eq '/DCTDecode' or $filter eq '/JPXDecode') {
1996
+ DecodeStream($exifTool, $dict) or last;
1997
+ # save the image itself
1998
+ $exifTool->FoundTag($tagInfo, \$$dict{_stream});
1999
+ # extract information from embedded image
2000
+ $result = $exifTool->ExtractInfo(\$$dict{_stream}, { ReEntry => 1 });
2001
+ }
2002
+ unless ($result) {
2003
+ $exifTool->FoundTag('FileType', defined $result ? '(unknown)' : '(unsupported)');
2004
+ }
2005
+ last;
2006
+ }
2007
+ # decode stream if necessary
2008
+ DecodeStream($exifTool, $dict) or last;
2009
+ # extract information from stream
2010
+ my %dirInfo = (
2011
+ DataPt => \$$dict{_stream},
2012
+ DataLen => length $$dict{_stream},
2013
+ DirStart => 0,
2014
+ DirLen => length $$dict{_stream},
2015
+ Parent => 'PDF',
2016
+ );
2017
+ my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
2018
+ unless ($exifTool->ProcessDirectory(\%dirInfo, $subTablePtr)) {
2019
+ $exifTool->Warn("Error processing $$tagInfo{Name} information");
2020
+ }
2021
+ last;
2022
+ }
2023
+ }
2024
+
2025
+ #------------------------------------------------------------------------------
2026
+ # Extract information from PDF file
2027
+ # Inputs: 0) ExifTool object reference, 1) dirInfo reference
2028
+ # Returns: 0 if not a PDF file, 1 on success, otherwise a negative error number
2029
+ sub ReadPDF($$)
2030
+ {
2031
+ my ($exifTool, $dirInfo) = @_;
2032
+ my $raf = $$dirInfo{RAF};
2033
+ my $verbose = $exifTool->Options('Verbose');
2034
+ my ($buff, $encrypt, $id);
2035
+ #
2036
+ # validate PDF file
2037
+ #
2038
+ # (linearization dictionary must be in the first 1024 bytes of the file)
2039
+ $raf->Read($buff, 1024) >= 8 or return 0;
2040
+ $buff =~ /^%PDF-(\d+\.\d+)/ or return 0;
2041
+ $pdfVer = $1;
2042
+ $exifTool->SetFileType(); # set the FileType tag
2043
+ $exifTool->Warn("May not be able to read a PDF version $pdfVer file") if $pdfVer >= 2.0;
2044
+ # store PDFVersion tag
2045
+ my $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Root');
2046
+ $exifTool->HandleTag($tagTablePtr, 'Version', $pdfVer);
2047
+ $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Main');
2048
+ #
2049
+ # check for a linearized PDF (only if reading)
2050
+ #
2051
+ my $capture = $$exifTool{PDF_CAPTURE};
2052
+ unless ($capture) {
2053
+ my $lin = 'false';
2054
+ if ($buff =~ /<</g) {
2055
+ $buff = substr($buff, pos($buff) - 2);
2056
+ my $dict = ExtractObject($exifTool, \$buff);
2057
+ if (ref $dict eq 'HASH' and $$dict{Linearized} and $$dict{L}) {
2058
+ if (not $$exifTool{VALUE}{FileSize}) {
2059
+ undef $lin; # can't determine if it is linearized
2060
+ } elsif ($$dict{L} == $$exifTool{VALUE}{FileSize}) {
2061
+ $lin = 'true';
2062
+ }
2063
+ }
2064
+ }
2065
+ $exifTool->HandleTag($tagTablePtr, '_linearized', $lin) if $lin;
2066
+ }
2067
+ #
2068
+ # read the xref tables referenced from startxref at the end of the file
2069
+ #
2070
+ my @xrefOffsets;
2071
+ $raf->Seek(0, 2) or return -2;
2072
+ # the %%EOF must occur within the last 1024 bytes of the file (PDF spec, appendix H)
2073
+ my $len = $raf->Tell();
2074
+ $len = 1024 if $len > 1024;
2075
+ $raf->Seek(-$len, 2) or return -2;
2076
+ $raf->Read($buff, $len) == $len or return -3;
2077
+ # find the LAST xref table in the file (may be multiple %%EOF marks)
2078
+ $buff =~ /^.*startxref(\s+)(\d+)(\s+)%%EOF/s or return -4;
2079
+ my $ws = $1 . $3;
2080
+ my $xr = $2;
2081
+ push @xrefOffsets, $xr, 'Main';
2082
+ # set input record separator
2083
+ local $/ = $ws =~ /(\x0d\x0a|\x0d|\x0a)/ ? $1 : "\x0a";
2084
+ my (%xref, @mainDicts, %loaded, $mainFree);
2085
+ # initialize variables to capture when rewriting
2086
+ if ($capture) {
2087
+ $capture->{startxref} = $xr;
2088
+ $capture->{xref} = \%xref;
2089
+ $capture->{newline} = $/;
2090
+ $capture->{mainFree} = $mainFree = { };
2091
+ }
2092
+ XRef:
2093
+ while (@xrefOffsets) {
2094
+ my $offset = shift @xrefOffsets;
2095
+ my $type = shift @xrefOffsets;
2096
+ next if $loaded{$offset}; # avoid infinite recursion
2097
+ unless ($raf->Seek($offset, 0)) {
2098
+ %loaded or return -5;
2099
+ $exifTool->Warn('Bad offset for secondary xref table');
2100
+ next;
2101
+ }
2102
+ # Note: care must be taken because ReadLine may read more than we want if
2103
+ # the newline sequence for this table is different than the rest of the file
2104
+ for (;;) {
2105
+ unless ($raf->ReadLine($buff)) {
2106
+ %loaded or return -6;
2107
+ $exifTool->Warn('Bad offset for secondary xref table');
2108
+ next XRef;
2109
+ }
2110
+ last if $buff =~/\S/; # skip blank lines
2111
+ }
2112
+ my $loadXRefStream;
2113
+ if ($buff =~ s/^\s*xref\s+//s) {
2114
+ # load xref table
2115
+ for (;;) {
2116
+ # read another line if necessary (skipping blank lines)
2117
+ $raf->ReadLine($buff) or return -6 until $buff =~ /\S/;
2118
+ last if $buff =~ s/^\s*trailer([\s<[(])/$1/s;
2119
+ $buff =~ s/^\s*(\d+)\s+(\d+)\s+//s or return -4;
2120
+ my ($start, $num) = ($1, $2);
2121
+ $raf->Seek(-length($buff), 1) or return -4;
2122
+ my $i;
2123
+ for ($i=0; $i<$num; ++$i) {
2124
+ $raf->Read($buff, 20) == 20 or return -6;
2125
+ $buff =~ /^\s*(\d{10}) (\d{5}) (f|n)/s or return -4;
2126
+ my $num = $start + $i;
2127
+ # save offset for newest copy of all objects
2128
+ # (or next object number for free objects)
2129
+ unless (defined $xref{$num}) {
2130
+ my ($offset, $gen) = (int($1), int($2));
2131
+ $xref{$num} = $offset;
2132
+ if ($3 eq 'f') {
2133
+ # save free objects in last xref table for rewriting
2134
+ $$mainFree{$num} = [ $offset, $gen, 'f' ] if $mainFree;
2135
+ next;
2136
+ }
2137
+ # also save offset keyed by object reference string
2138
+ $xref{"$num $gen R"} = $offset;
2139
+ }
2140
+ }
2141
+ # (I have a sample from Adobe which has an empty xref table)
2142
+ # %xref or return -4; # xref table may not be empty
2143
+ $buff = '';
2144
+ }
2145
+ undef $mainFree; # only do this for the last xref table
2146
+ } elsif ($buff =~ s/^\s*(\d+)\s+(\d+)\s+obj//s) {
2147
+ # this is a PDF-1.5 cross-reference stream dictionary
2148
+ $loadXRefStream = 1;
2149
+ } else {
2150
+ %loaded or return -4;
2151
+ $exifTool->Warn('Invalid secondary xref table');
2152
+ next;
2153
+ }
2154
+ my $mainDict = ExtractObject($exifTool, \$buff, $raf, \%xref);
2155
+ unless (ref $mainDict eq 'HASH') {
2156
+ %loaded or return -8;
2157
+ $exifTool->Warn('Error loading secondary dictionary');
2158
+ next;
2159
+ }
2160
+ if ($loadXRefStream) {
2161
+ # decode and save our XRef stream from PDF-1.5 file
2162
+ # (but parse it later as required to save time)
2163
+ # Note: this technique can potentially result in an old object
2164
+ # being used if the file was incrementally updated and an older
2165
+ # object from an xref table was replaced by a newer object in an
2166
+ # xref stream. But doing so isn't a good idea (if allowed at all)
2167
+ # because a PDF 1.4 consumer would also make this same mistake.
2168
+ if ($$mainDict{Type} eq '/XRef' and $$mainDict{W} and
2169
+ @{$$mainDict{W}} > 2 and $$mainDict{Size} and
2170
+ DecodeStream($exifTool, $mainDict))
2171
+ {
2172
+ # create Index entry if it doesn't exist
2173
+ $$mainDict{Index} or $$mainDict{Index} = [ 0, $$mainDict{Size} ];
2174
+ # create '_entry_size' entry for internal use
2175
+ my $w = $$mainDict{W};
2176
+ my $size = 0;
2177
+ foreach (@$w) { $size += $_; }
2178
+ $$mainDict{_entry_size} = $size;
2179
+ # save this stream dictionary to use later if required
2180
+ $xref{dicts} = [] unless $xref{dicts};
2181
+ push @{$xref{dicts}}, $mainDict;
2182
+ } else {
2183
+ %loaded or return -9;
2184
+ $exifTool->Warn('Invalid xref stream in secondary dictionary');
2185
+ }
2186
+ }
2187
+ $loaded{$offset} = 1;
2188
+ # load XRef stream in hybrid file if it exists
2189
+ push @xrefOffsets, $$mainDict{XRefStm}, 'XRefStm' if $$mainDict{XRefStm};
2190
+ $encrypt = $$mainDict{Encrypt} if $$mainDict{Encrypt};
2191
+ if ($$mainDict{ID} and ref $$mainDict{ID} eq 'ARRAY') {
2192
+ $id = ReadPDFValue($mainDict->{ID}->[0]);
2193
+ }
2194
+ push @mainDicts, $mainDict, $type;
2195
+ # load previous xref table if it exists
2196
+ push @xrefOffsets, $$mainDict{Prev}, 'Prev' if $$mainDict{Prev};
2197
+ }
2198
+ #
2199
+ # extract encryption information if necessary
2200
+ #
2201
+ if ($encrypt) {
2202
+ if (ref $encrypt eq 'SCALAR') {
2203
+ $encrypt = FetchObject($exifTool, $$encrypt, \%xref, 'Encrypt');
2204
+ }
2205
+ # generate Encryption tag information
2206
+ my $err = DecryptInit($exifTool, $encrypt, $id);
2207
+ if ($err) {
2208
+ $exifTool->Warn($err);
2209
+ $$capture{Error} = $err if $capture;
2210
+ return -1;
2211
+ }
2212
+ }
2213
+ #
2214
+ # extract the information beginning with each of the main dictionaries
2215
+ #
2216
+ my $i = 0;
2217
+ my $num = (scalar @mainDicts) / 2;
2218
+ while (@mainDicts) {
2219
+ my $dict = shift @mainDicts;
2220
+ my $type = shift @mainDicts;
2221
+ if ($verbose) {
2222
+ ++$i;
2223
+ my $n = scalar(@{$$dict{_tags}});
2224
+ $exifTool->VPrint(0, "PDF dictionary ($i of $num) with $n entries:\n");
2225
+ }
2226
+ ProcessDict($exifTool, $tagTablePtr, $dict, \%xref, 0, $type);
2227
+ }
2228
+ # handle any decryption errors
2229
+ if ($encrypt) {
2230
+ my $err = $$encrypt{_error};
2231
+ if ($err) {
2232
+ $exifTool->Warn($err);
2233
+ $$capture{Error} = $err if $capture;
2234
+ return -1;
2235
+ }
2236
+ }
2237
+ return 1;
2238
+ }
2239
+
2240
+ #------------------------------------------------------------------------------
2241
+ # ReadPDF() warning strings for each error return value
2242
+ my %pdfWarning = (
2243
+ # -1 is reserved as error return value with no associated warning
2244
+ -2 => 'Error seeking in file',
2245
+ -3 => 'Error reading file',
2246
+ -4 => 'Invalid xref table',
2247
+ -5 => 'Invalid xref offset',
2248
+ -6 => 'Error reading xref table',
2249
+ -7 => 'Error reading trailer',
2250
+ -8 => 'Error reading main dictionary',
2251
+ -9 => 'Invalid xref stream in main dictionary',
2252
+ );
2253
+
2254
+ #------------------------------------------------------------------------------
2255
+ # Extract information from PDF file
2256
+ # Inputs: 0) ExifTool object reference, 1) dirInfo reference
2257
+ # Returns: 1 if this was a valid PDF file
2258
+ sub ProcessPDF($$)
2259
+ {
2260
+ my ($exifTool, $dirInfo) = @_;
2261
+
2262
+ undef $cryptInfo; # (must not delete after returning so writer can use it)
2263
+ undef $cryptStream;
2264
+ undef $cryptString;
2265
+ my $result = ReadPDF($exifTool, $dirInfo);
2266
+ if ($result < 0) {
2267
+ $exifTool->Warn($pdfWarning{$result}) if $pdfWarning{$result};
2268
+ $result = 1;
2269
+ }
2270
+ # clean up and return
2271
+ undef %streamObjs;
2272
+ undef %fetched;
2273
+ return $result;
2274
+ }
2275
+
2276
+ 1; # end
2277
+
2278
+
2279
+ __END__
2280
+
2281
+ =head1 NAME
2282
+
2283
+ Image::ExifTool::PDF - Read PDF meta information
2284
+
2285
+ =head1 SYNOPSIS
2286
+
2287
+ This module is loaded automatically by Image::ExifTool when required.
2288
+
2289
+ =head1 DESCRIPTION
2290
+
2291
+ This code reads meta information from PDF (Adobe Portable Document Format)
2292
+ files. It supports object streams introduced in PDF-1.5 but only with a
2293
+ limited set of Filter and Predictor algorithms, however all standard
2294
+ encryption methods through PDF-1.7 extension level 3 are supported,
2295
+ including AESV2 (AES-128) and AESV3 (AES-256).
2296
+
2297
+ =head1 AUTHOR
2298
+
2299
+ Copyright 2003-2013, Phil Harvey (phil at owl.phy.queensu.ca)
2300
+
2301
+ This library is free software; you can redistribute it and/or modify it
2302
+ under the same terms as Perl itself.
2303
+
2304
+ =head1 REFERENCES
2305
+
2306
+ =over 4
2307
+
2308
+ =item L<http://partners.adobe.com/public/developer/pdf/index_reference.html>
2309
+
2310
+ =item L<Crypt::RC4|Crypt::RC4>
2311
+
2312
+ =item L<http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf>
2313
+
2314
+ =item L<http://www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000.pdf>
2315
+
2316
+ =item L<http://tools.ietf.org/search/rfc3454>
2317
+
2318
+ =item L<http://www.armware.dk/RFC/rfc/rfc4013.html>
2319
+
2320
+ =back
2321
+
2322
+ =head1 SEE ALSO
2323
+
2324
+ L<Image::ExifTool::TagNames/PDF Tags>,
2325
+ L<Image::ExifTool(3pm)|Image::ExifTool>
2326
+
2327
+ =cut