TiffImagePlugin.py 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990
  1. #
  2. # The Python Imaging Library.
  3. # $Id$
  4. #
  5. # TIFF file handling
  6. #
  7. # TIFF is a flexible, if somewhat aged, image file format originally
  8. # defined by Aldus. Although TIFF supports a wide variety of pixel
  9. # layouts and compression methods, the name doesn't really stand for
  10. # "thousands of incompatible file formats," it just feels that way.
  11. #
  12. # To read TIFF data from a stream, the stream must be seekable. For
  13. # progressive decoding, make sure to use TIFF files where the tag
  14. # directory is placed first in the file.
  15. #
  16. # History:
  17. # 1995-09-01 fl Created
  18. # 1996-05-04 fl Handle JPEGTABLES tag
  19. # 1996-05-18 fl Fixed COLORMAP support
  20. # 1997-01-05 fl Fixed PREDICTOR support
  21. # 1997-08-27 fl Added support for rational tags (from Perry Stoll)
  22. # 1998-01-10 fl Fixed seek/tell (from Jan Blom)
  23. # 1998-07-15 fl Use private names for internal variables
  24. # 1999-06-13 fl Rewritten for PIL 1.0 (1.0)
  25. # 2000-10-11 fl Additional fixes for Python 2.0 (1.1)
  26. # 2001-04-17 fl Fixed rewind support (seek to frame 0) (1.2)
  27. # 2001-05-12 fl Added write support for more tags (from Greg Couch) (1.3)
  28. # 2001-12-18 fl Added workaround for broken Matrox library
  29. # 2002-01-18 fl Don't mess up if photometric tag is missing (D. Alan Stewart)
  30. # 2003-05-19 fl Check FILLORDER tag
  31. # 2003-09-26 fl Added RGBa support
  32. # 2004-02-24 fl Added DPI support; fixed rational write support
  33. # 2005-02-07 fl Added workaround for broken Corel Draw 10 files
  34. # 2006-01-09 fl Added support for float/double tags (from Russell Nelson)
  35. #
  36. # Copyright (c) 1997-2006 by Secret Labs AB. All rights reserved.
  37. # Copyright (c) 1995-1997 by Fredrik Lundh
  38. #
  39. # See the README file for information on usage and redistribution.
  40. #
  41. import io
  42. import itertools
  43. import logging
  44. import os
  45. import struct
  46. import warnings
  47. from collections.abc import MutableMapping
  48. from fractions import Fraction
  49. from numbers import Number, Rational
  50. from . import Image, ImageFile, ImagePalette, TiffTags
  51. from ._binary import o8
  52. from .TiffTags import TYPES
  53. logger = logging.getLogger(__name__)
  54. # Set these to true to force use of libtiff for reading or writing.
  55. READ_LIBTIFF = False
  56. WRITE_LIBTIFF = False
  57. IFD_LEGACY_API = True
  58. II = b"II" # little-endian (Intel style)
  59. MM = b"MM" # big-endian (Motorola style)
  60. #
  61. # --------------------------------------------------------------------
  62. # Read TIFF files
  63. # a few tag names, just to make the code below a bit more readable
  64. IMAGEWIDTH = 256
  65. IMAGELENGTH = 257
  66. BITSPERSAMPLE = 258
  67. COMPRESSION = 259
  68. PHOTOMETRIC_INTERPRETATION = 262
  69. FILLORDER = 266
  70. IMAGEDESCRIPTION = 270
  71. STRIPOFFSETS = 273
  72. SAMPLESPERPIXEL = 277
  73. ROWSPERSTRIP = 278
  74. STRIPBYTECOUNTS = 279
  75. X_RESOLUTION = 282
  76. Y_RESOLUTION = 283
  77. PLANAR_CONFIGURATION = 284
  78. RESOLUTION_UNIT = 296
  79. TRANSFERFUNCTION = 301
  80. SOFTWARE = 305
  81. DATE_TIME = 306
  82. ARTIST = 315
  83. PREDICTOR = 317
  84. COLORMAP = 320
  85. TILEOFFSETS = 324
  86. SUBIFD = 330
  87. EXTRASAMPLES = 338
  88. SAMPLEFORMAT = 339
  89. JPEGTABLES = 347
  90. REFERENCEBLACKWHITE = 532
  91. COPYRIGHT = 33432
  92. IPTC_NAA_CHUNK = 33723 # newsphoto properties
  93. PHOTOSHOP_CHUNK = 34377 # photoshop properties
  94. ICCPROFILE = 34675
  95. EXIFIFD = 34665
  96. XMP = 700
  97. JPEGQUALITY = 65537 # pseudo-tag by libtiff
  98. # https://github.com/imagej/ImageJA/blob/master/src/main/java/ij/io/TiffDecoder.java
  99. IMAGEJ_META_DATA_BYTE_COUNTS = 50838
  100. IMAGEJ_META_DATA = 50839
  101. COMPRESSION_INFO = {
  102. # Compression => pil compression name
  103. 1: "raw",
  104. 2: "tiff_ccitt",
  105. 3: "group3",
  106. 4: "group4",
  107. 5: "tiff_lzw",
  108. 6: "tiff_jpeg", # obsolete
  109. 7: "jpeg",
  110. 8: "tiff_adobe_deflate",
  111. 32771: "tiff_raw_16", # 16-bit padding
  112. 32773: "packbits",
  113. 32809: "tiff_thunderscan",
  114. 32946: "tiff_deflate",
  115. 34676: "tiff_sgilog",
  116. 34677: "tiff_sgilog24",
  117. 34925: "lzma",
  118. 50000: "zstd",
  119. 50001: "webp",
  120. }
  121. COMPRESSION_INFO_REV = {v: k for k, v in COMPRESSION_INFO.items()}
  122. OPEN_INFO = {
  123. # (ByteOrder, PhotoInterpretation, SampleFormat, FillOrder, BitsPerSample,
  124. # ExtraSamples) => mode, rawmode
  125. (II, 0, (1,), 1, (1,), ()): ("1", "1;I"),
  126. (MM, 0, (1,), 1, (1,), ()): ("1", "1;I"),
  127. (II, 0, (1,), 2, (1,), ()): ("1", "1;IR"),
  128. (MM, 0, (1,), 2, (1,), ()): ("1", "1;IR"),
  129. (II, 1, (1,), 1, (1,), ()): ("1", "1"),
  130. (MM, 1, (1,), 1, (1,), ()): ("1", "1"),
  131. (II, 1, (1,), 2, (1,), ()): ("1", "1;R"),
  132. (MM, 1, (1,), 2, (1,), ()): ("1", "1;R"),
  133. (II, 0, (1,), 1, (2,), ()): ("L", "L;2I"),
  134. (MM, 0, (1,), 1, (2,), ()): ("L", "L;2I"),
  135. (II, 0, (1,), 2, (2,), ()): ("L", "L;2IR"),
  136. (MM, 0, (1,), 2, (2,), ()): ("L", "L;2IR"),
  137. (II, 1, (1,), 1, (2,), ()): ("L", "L;2"),
  138. (MM, 1, (1,), 1, (2,), ()): ("L", "L;2"),
  139. (II, 1, (1,), 2, (2,), ()): ("L", "L;2R"),
  140. (MM, 1, (1,), 2, (2,), ()): ("L", "L;2R"),
  141. (II, 0, (1,), 1, (4,), ()): ("L", "L;4I"),
  142. (MM, 0, (1,), 1, (4,), ()): ("L", "L;4I"),
  143. (II, 0, (1,), 2, (4,), ()): ("L", "L;4IR"),
  144. (MM, 0, (1,), 2, (4,), ()): ("L", "L;4IR"),
  145. (II, 1, (1,), 1, (4,), ()): ("L", "L;4"),
  146. (MM, 1, (1,), 1, (4,), ()): ("L", "L;4"),
  147. (II, 1, (1,), 2, (4,), ()): ("L", "L;4R"),
  148. (MM, 1, (1,), 2, (4,), ()): ("L", "L;4R"),
  149. (II, 0, (1,), 1, (8,), ()): ("L", "L;I"),
  150. (MM, 0, (1,), 1, (8,), ()): ("L", "L;I"),
  151. (II, 0, (1,), 2, (8,), ()): ("L", "L;IR"),
  152. (MM, 0, (1,), 2, (8,), ()): ("L", "L;IR"),
  153. (II, 1, (1,), 1, (8,), ()): ("L", "L"),
  154. (MM, 1, (1,), 1, (8,), ()): ("L", "L"),
  155. (II, 1, (1,), 2, (8,), ()): ("L", "L;R"),
  156. (MM, 1, (1,), 2, (8,), ()): ("L", "L;R"),
  157. (II, 1, (1,), 1, (12,), ()): ("I;16", "I;12"),
  158. (II, 1, (1,), 1, (16,), ()): ("I;16", "I;16"),
  159. (MM, 1, (1,), 1, (16,), ()): ("I;16B", "I;16B"),
  160. (II, 1, (2,), 1, (16,), ()): ("I", "I;16S"),
  161. (MM, 1, (2,), 1, (16,), ()): ("I", "I;16BS"),
  162. (II, 0, (3,), 1, (32,), ()): ("F", "F;32F"),
  163. (MM, 0, (3,), 1, (32,), ()): ("F", "F;32BF"),
  164. (II, 1, (1,), 1, (32,), ()): ("I", "I;32N"),
  165. (II, 1, (2,), 1, (32,), ()): ("I", "I;32S"),
  166. (MM, 1, (2,), 1, (32,), ()): ("I", "I;32BS"),
  167. (II, 1, (3,), 1, (32,), ()): ("F", "F;32F"),
  168. (MM, 1, (3,), 1, (32,), ()): ("F", "F;32BF"),
  169. (II, 1, (1,), 1, (8, 8), (2,)): ("LA", "LA"),
  170. (MM, 1, (1,), 1, (8, 8), (2,)): ("LA", "LA"),
  171. (II, 2, (1,), 1, (8, 8, 8), ()): ("RGB", "RGB"),
  172. (MM, 2, (1,), 1, (8, 8, 8), ()): ("RGB", "RGB"),
  173. (II, 2, (1,), 2, (8, 8, 8), ()): ("RGB", "RGB;R"),
  174. (MM, 2, (1,), 2, (8, 8, 8), ()): ("RGB", "RGB;R"),
  175. (II, 2, (1,), 1, (8, 8, 8, 8), ()): ("RGBA", "RGBA"), # missing ExtraSamples
  176. (MM, 2, (1,), 1, (8, 8, 8, 8), ()): ("RGBA", "RGBA"), # missing ExtraSamples
  177. (II, 2, (1,), 1, (8, 8, 8, 8), (0,)): ("RGBX", "RGBX"),
  178. (MM, 2, (1,), 1, (8, 8, 8, 8), (0,)): ("RGBX", "RGBX"),
  179. (II, 2, (1,), 1, (8, 8, 8, 8, 8), (0, 0)): ("RGBX", "RGBXX"),
  180. (MM, 2, (1,), 1, (8, 8, 8, 8, 8), (0, 0)): ("RGBX", "RGBXX"),
  181. (II, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0, 0)): ("RGBX", "RGBXXX"),
  182. (MM, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0, 0)): ("RGBX", "RGBXXX"),
  183. (II, 2, (1,), 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"),
  184. (MM, 2, (1,), 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"),
  185. (II, 2, (1,), 1, (8, 8, 8, 8, 8), (1, 0)): ("RGBA", "RGBaX"),
  186. (MM, 2, (1,), 1, (8, 8, 8, 8, 8), (1, 0)): ("RGBA", "RGBaX"),
  187. (II, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (1, 0, 0)): ("RGBA", "RGBaXX"),
  188. (MM, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (1, 0, 0)): ("RGBA", "RGBaXX"),
  189. (II, 2, (1,), 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"),
  190. (MM, 2, (1,), 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"),
  191. (II, 2, (1,), 1, (8, 8, 8, 8, 8), (2, 0)): ("RGBA", "RGBAX"),
  192. (MM, 2, (1,), 1, (8, 8, 8, 8, 8), (2, 0)): ("RGBA", "RGBAX"),
  193. (II, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (2, 0, 0)): ("RGBA", "RGBAXX"),
  194. (MM, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (2, 0, 0)): ("RGBA", "RGBAXX"),
  195. (II, 2, (1,), 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10
  196. (MM, 2, (1,), 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10
  197. (II, 2, (1,), 1, (16, 16, 16), ()): ("RGB", "RGB;16L"),
  198. (MM, 2, (1,), 1, (16, 16, 16), ()): ("RGB", "RGB;16B"),
  199. (II, 2, (1,), 1, (16, 16, 16, 16), ()): ("RGBA", "RGBA;16L"),
  200. (MM, 2, (1,), 1, (16, 16, 16, 16), ()): ("RGBA", "RGBA;16B"),
  201. (II, 2, (1,), 1, (16, 16, 16, 16), (0,)): ("RGBX", "RGBX;16L"),
  202. (MM, 2, (1,), 1, (16, 16, 16, 16), (0,)): ("RGBX", "RGBX;16B"),
  203. (II, 2, (1,), 1, (16, 16, 16, 16), (1,)): ("RGBA", "RGBa;16L"),
  204. (MM, 2, (1,), 1, (16, 16, 16, 16), (1,)): ("RGBA", "RGBa;16B"),
  205. (II, 2, (1,), 1, (16, 16, 16, 16), (2,)): ("RGBA", "RGBA;16L"),
  206. (MM, 2, (1,), 1, (16, 16, 16, 16), (2,)): ("RGBA", "RGBA;16B"),
  207. (II, 3, (1,), 1, (1,), ()): ("P", "P;1"),
  208. (MM, 3, (1,), 1, (1,), ()): ("P", "P;1"),
  209. (II, 3, (1,), 2, (1,), ()): ("P", "P;1R"),
  210. (MM, 3, (1,), 2, (1,), ()): ("P", "P;1R"),
  211. (II, 3, (1,), 1, (2,), ()): ("P", "P;2"),
  212. (MM, 3, (1,), 1, (2,), ()): ("P", "P;2"),
  213. (II, 3, (1,), 2, (2,), ()): ("P", "P;2R"),
  214. (MM, 3, (1,), 2, (2,), ()): ("P", "P;2R"),
  215. (II, 3, (1,), 1, (4,), ()): ("P", "P;4"),
  216. (MM, 3, (1,), 1, (4,), ()): ("P", "P;4"),
  217. (II, 3, (1,), 2, (4,), ()): ("P", "P;4R"),
  218. (MM, 3, (1,), 2, (4,), ()): ("P", "P;4R"),
  219. (II, 3, (1,), 1, (8,), ()): ("P", "P"),
  220. (MM, 3, (1,), 1, (8,), ()): ("P", "P"),
  221. (II, 3, (1,), 1, (8, 8), (2,)): ("PA", "PA"),
  222. (MM, 3, (1,), 1, (8, 8), (2,)): ("PA", "PA"),
  223. (II, 3, (1,), 2, (8,), ()): ("P", "P;R"),
  224. (MM, 3, (1,), 2, (8,), ()): ("P", "P;R"),
  225. (II, 5, (1,), 1, (8, 8, 8, 8), ()): ("CMYK", "CMYK"),
  226. (MM, 5, (1,), 1, (8, 8, 8, 8), ()): ("CMYK", "CMYK"),
  227. (II, 5, (1,), 1, (8, 8, 8, 8, 8), (0,)): ("CMYK", "CMYKX"),
  228. (MM, 5, (1,), 1, (8, 8, 8, 8, 8), (0,)): ("CMYK", "CMYKX"),
  229. (II, 5, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0)): ("CMYK", "CMYKXX"),
  230. (MM, 5, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0)): ("CMYK", "CMYKXX"),
  231. (II, 5, (1,), 1, (16, 16, 16, 16), ()): ("CMYK", "CMYK;16L"),
  232. # JPEG compressed images handled by LibTiff and auto-converted to RGBX
  233. # Minimal Baseline TIFF requires YCbCr images to have 3 SamplesPerPixel
  234. (II, 6, (1,), 1, (8, 8, 8), ()): ("RGB", "RGBX"),
  235. (MM, 6, (1,), 1, (8, 8, 8), ()): ("RGB", "RGBX"),
  236. (II, 8, (1,), 1, (8, 8, 8), ()): ("LAB", "LAB"),
  237. (MM, 8, (1,), 1, (8, 8, 8), ()): ("LAB", "LAB"),
  238. }
  239. PREFIXES = [
  240. b"MM\x00\x2A", # Valid TIFF header with big-endian byte order
  241. b"II\x2A\x00", # Valid TIFF header with little-endian byte order
  242. b"MM\x2A\x00", # Invalid TIFF header, assume big-endian
  243. b"II\x00\x2A", # Invalid TIFF header, assume little-endian
  244. ]
  245. def _accept(prefix):
  246. return prefix[:4] in PREFIXES
  247. def _limit_rational(val, max_val):
  248. inv = abs(val) > 1
  249. n_d = IFDRational(1 / val if inv else val).limit_rational(max_val)
  250. return n_d[::-1] if inv else n_d
  251. def _limit_signed_rational(val, max_val, min_val):
  252. frac = Fraction(val)
  253. n_d = frac.numerator, frac.denominator
  254. if min(n_d) < min_val:
  255. n_d = _limit_rational(val, abs(min_val))
  256. if max(n_d) > max_val:
  257. val = Fraction(*n_d)
  258. n_d = _limit_rational(val, max_val)
  259. return n_d
  260. ##
  261. # Wrapper for TIFF IFDs.
  262. _load_dispatch = {}
  263. _write_dispatch = {}
  264. class IFDRational(Rational):
  265. """Implements a rational class where 0/0 is a legal value to match
  266. the in the wild use of exif rationals.
  267. e.g., DigitalZoomRatio - 0.00/0.00 indicates that no digital zoom was used
  268. """
  269. """ If the denominator is 0, store this as a float('nan'), otherwise store
  270. as a fractions.Fraction(). Delegate as appropriate
  271. """
  272. __slots__ = ("_numerator", "_denominator", "_val")
  273. def __init__(self, value, denominator=1):
  274. """
  275. :param value: either an integer numerator, a
  276. float/rational/other number, or an IFDRational
  277. :param denominator: Optional integer denominator
  278. """
  279. if isinstance(value, IFDRational):
  280. self._numerator = value.numerator
  281. self._denominator = value.denominator
  282. self._val = value._val
  283. return
  284. if isinstance(value, Fraction):
  285. self._numerator = value.numerator
  286. self._denominator = value.denominator
  287. else:
  288. self._numerator = value
  289. self._denominator = denominator
  290. if denominator == 0:
  291. self._val = float("nan")
  292. elif denominator == 1:
  293. self._val = Fraction(value)
  294. else:
  295. self._val = Fraction(value, denominator)
  296. @property
  297. def numerator(a):
  298. return a._numerator
  299. @property
  300. def denominator(a):
  301. return a._denominator
  302. def limit_rational(self, max_denominator):
  303. """
  304. :param max_denominator: Integer, the maximum denominator value
  305. :returns: Tuple of (numerator, denominator)
  306. """
  307. if self.denominator == 0:
  308. return (self.numerator, self.denominator)
  309. f = self._val.limit_denominator(max_denominator)
  310. return (f.numerator, f.denominator)
  311. def __repr__(self):
  312. return str(float(self._val))
  313. def __hash__(self):
  314. return self._val.__hash__()
  315. def __eq__(self, other):
  316. val = self._val
  317. if isinstance(other, IFDRational):
  318. other = other._val
  319. if isinstance(other, float):
  320. val = float(val)
  321. return val == other
  322. def __getstate__(self):
  323. return [self._val, self._numerator, self._denominator]
  324. def __setstate__(self, state):
  325. IFDRational.__init__(self, 0)
  326. _val, _numerator, _denominator = state
  327. self._val = _val
  328. self._numerator = _numerator
  329. self._denominator = _denominator
  330. def _delegate(op):
  331. def delegate(self, *args):
  332. return getattr(self._val, op)(*args)
  333. return delegate
  334. """ a = ['add','radd', 'sub', 'rsub', 'mul', 'rmul',
  335. 'truediv', 'rtruediv', 'floordiv', 'rfloordiv',
  336. 'mod','rmod', 'pow','rpow', 'pos', 'neg',
  337. 'abs', 'trunc', 'lt', 'gt', 'le', 'ge', 'bool',
  338. 'ceil', 'floor', 'round']
  339. print("\n".join("__%s__ = _delegate('__%s__')" % (s,s) for s in a))
  340. """
  341. __add__ = _delegate("__add__")
  342. __radd__ = _delegate("__radd__")
  343. __sub__ = _delegate("__sub__")
  344. __rsub__ = _delegate("__rsub__")
  345. __mul__ = _delegate("__mul__")
  346. __rmul__ = _delegate("__rmul__")
  347. __truediv__ = _delegate("__truediv__")
  348. __rtruediv__ = _delegate("__rtruediv__")
  349. __floordiv__ = _delegate("__floordiv__")
  350. __rfloordiv__ = _delegate("__rfloordiv__")
  351. __mod__ = _delegate("__mod__")
  352. __rmod__ = _delegate("__rmod__")
  353. __pow__ = _delegate("__pow__")
  354. __rpow__ = _delegate("__rpow__")
  355. __pos__ = _delegate("__pos__")
  356. __neg__ = _delegate("__neg__")
  357. __abs__ = _delegate("__abs__")
  358. __trunc__ = _delegate("__trunc__")
  359. __lt__ = _delegate("__lt__")
  360. __gt__ = _delegate("__gt__")
  361. __le__ = _delegate("__le__")
  362. __ge__ = _delegate("__ge__")
  363. __bool__ = _delegate("__bool__")
  364. __ceil__ = _delegate("__ceil__")
  365. __floor__ = _delegate("__floor__")
  366. __round__ = _delegate("__round__")
  367. class ImageFileDirectory_v2(MutableMapping):
  368. """This class represents a TIFF tag directory. To speed things up, we
  369. don't decode tags unless they're asked for.
  370. Exposes a dictionary interface of the tags in the directory::
  371. ifd = ImageFileDirectory_v2()
  372. ifd[key] = 'Some Data'
  373. ifd.tagtype[key] = TiffTags.ASCII
  374. print(ifd[key])
  375. 'Some Data'
  376. Individual values are returned as the strings or numbers, sequences are
  377. returned as tuples of the values.
  378. The tiff metadata type of each item is stored in a dictionary of
  379. tag types in
  380. :attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v2.tagtype`. The types
  381. are read from a tiff file, guessed from the type added, or added
  382. manually.
  383. Data Structures:
  384. * self.tagtype = {}
  385. * Key: numerical tiff tag number
  386. * Value: integer corresponding to the data type from
  387. ~PIL.TiffTags.TYPES`
  388. .. versionadded:: 3.0.0
  389. """
  390. """
  391. Documentation:
  392. 'internal' data structures:
  393. * self._tags_v2 = {} Key: numerical tiff tag number
  394. Value: decoded data, as tuple for multiple values
  395. * self._tagdata = {} Key: numerical tiff tag number
  396. Value: undecoded byte string from file
  397. * self._tags_v1 = {} Key: numerical tiff tag number
  398. Value: decoded data in the v1 format
  399. Tags will be found in the private attributes self._tagdata, and in
  400. self._tags_v2 once decoded.
  401. self.legacy_api is a value for internal use, and shouldn't be
  402. changed from outside code. In cooperation with the
  403. ImageFileDirectory_v1 class, if legacy_api is true, then decoded
  404. tags will be populated into both _tags_v1 and _tags_v2. _tags_v2
  405. will be used if this IFD is used in the TIFF save routine. Tags
  406. should be read from _tags_v1 if legacy_api == true.
  407. """
  408. def __init__(self, ifh=b"II\052\0\0\0\0\0", prefix=None, group=None):
  409. """Initialize an ImageFileDirectory.
  410. To construct an ImageFileDirectory from a real file, pass the 8-byte
  411. magic header to the constructor. To only set the endianness, pass it
  412. as the 'prefix' keyword argument.
  413. :param ifh: One of the accepted magic headers (cf. PREFIXES); also sets
  414. endianness.
  415. :param prefix: Override the endianness of the file.
  416. """
  417. if ifh[:4] not in PREFIXES:
  418. raise SyntaxError(f"not a TIFF file (header {repr(ifh)} not valid)")
  419. self._prefix = prefix if prefix is not None else ifh[:2]
  420. if self._prefix == MM:
  421. self._endian = ">"
  422. elif self._prefix == II:
  423. self._endian = "<"
  424. else:
  425. raise SyntaxError("not a TIFF IFD")
  426. self.group = group
  427. self.tagtype = {}
  428. """ Dictionary of tag types """
  429. self.reset()
  430. (self.next,) = self._unpack("L", ifh[4:])
  431. self._legacy_api = False
  432. prefix = property(lambda self: self._prefix)
  433. offset = property(lambda self: self._offset)
  434. legacy_api = property(lambda self: self._legacy_api)
  435. @legacy_api.setter
  436. def legacy_api(self, value):
  437. raise Exception("Not allowing setting of legacy api")
  438. def reset(self):
  439. self._tags_v1 = {} # will remain empty if legacy_api is false
  440. self._tags_v2 = {} # main tag storage
  441. self._tagdata = {}
  442. self.tagtype = {} # added 2008-06-05 by Florian Hoech
  443. self._next = None
  444. self._offset = None
  445. def __str__(self):
  446. return str(dict(self))
  447. def named(self):
  448. """
  449. :returns: dict of name|key: value
  450. Returns the complete tag dictionary, with named tags where possible.
  451. """
  452. return {
  453. TiffTags.lookup(code, self.group).name: value
  454. for code, value in self.items()
  455. }
  456. def __len__(self):
  457. return len(set(self._tagdata) | set(self._tags_v2))
  458. def __getitem__(self, tag):
  459. if tag not in self._tags_v2: # unpack on the fly
  460. data = self._tagdata[tag]
  461. typ = self.tagtype[tag]
  462. size, handler = self._load_dispatch[typ]
  463. self[tag] = handler(self, data, self.legacy_api) # check type
  464. val = self._tags_v2[tag]
  465. if self.legacy_api and not isinstance(val, (tuple, bytes)):
  466. val = (val,)
  467. return val
  468. def __contains__(self, tag):
  469. return tag in self._tags_v2 or tag in self._tagdata
  470. def __setitem__(self, tag, value):
  471. self._setitem(tag, value, self.legacy_api)
  472. def _setitem(self, tag, value, legacy_api):
  473. basetypes = (Number, bytes, str)
  474. info = TiffTags.lookup(tag, self.group)
  475. values = [value] if isinstance(value, basetypes) else value
  476. if tag not in self.tagtype:
  477. if info.type:
  478. self.tagtype[tag] = info.type
  479. else:
  480. self.tagtype[tag] = TiffTags.UNDEFINED
  481. if all(isinstance(v, IFDRational) for v in values):
  482. self.tagtype[tag] = (
  483. TiffTags.RATIONAL
  484. if all(v >= 0 for v in values)
  485. else TiffTags.SIGNED_RATIONAL
  486. )
  487. elif all(isinstance(v, int) for v in values):
  488. if all(0 <= v < 2 ** 16 for v in values):
  489. self.tagtype[tag] = TiffTags.SHORT
  490. elif all(-(2 ** 15) < v < 2 ** 15 for v in values):
  491. self.tagtype[tag] = TiffTags.SIGNED_SHORT
  492. else:
  493. self.tagtype[tag] = (
  494. TiffTags.LONG
  495. if all(v >= 0 for v in values)
  496. else TiffTags.SIGNED_LONG
  497. )
  498. elif all(isinstance(v, float) for v in values):
  499. self.tagtype[tag] = TiffTags.DOUBLE
  500. elif all(isinstance(v, str) for v in values):
  501. self.tagtype[tag] = TiffTags.ASCII
  502. elif all(isinstance(v, bytes) for v in values):
  503. self.tagtype[tag] = TiffTags.BYTE
  504. if self.tagtype[tag] == TiffTags.UNDEFINED:
  505. values = [
  506. v.encode("ascii", "replace") if isinstance(v, str) else v
  507. for v in values
  508. ]
  509. elif self.tagtype[tag] == TiffTags.RATIONAL:
  510. values = [float(v) if isinstance(v, int) else v for v in values]
  511. is_ifd = self.tagtype[tag] == TiffTags.LONG and isinstance(values, dict)
  512. if not is_ifd:
  513. values = tuple(info.cvt_enum(value) for value in values)
  514. dest = self._tags_v1 if legacy_api else self._tags_v2
  515. # Three branches:
  516. # Spec'd length == 1, Actual length 1, store as element
  517. # Spec'd length == 1, Actual > 1, Warn and truncate. Formerly barfed.
  518. # No Spec, Actual length 1, Formerly (<4.2) returned a 1 element tuple.
  519. # Don't mess with the legacy api, since it's frozen.
  520. if not is_ifd and (
  521. (info.length == 1)
  522. or self.tagtype[tag] == TiffTags.BYTE
  523. or (info.length is None and len(values) == 1 and not legacy_api)
  524. ):
  525. # Don't mess with the legacy api, since it's frozen.
  526. if legacy_api and self.tagtype[tag] in [
  527. TiffTags.RATIONAL,
  528. TiffTags.SIGNED_RATIONAL,
  529. ]: # rationals
  530. values = (values,)
  531. try:
  532. (dest[tag],) = values
  533. except ValueError:
  534. # We've got a builtin tag with 1 expected entry
  535. warnings.warn(
  536. f"Metadata Warning, tag {tag} had too many entries: "
  537. f"{len(values)}, expected 1"
  538. )
  539. dest[tag] = values[0]
  540. else:
  541. # Spec'd length > 1 or undefined
  542. # Unspec'd, and length > 1
  543. dest[tag] = values
  544. def __delitem__(self, tag):
  545. self._tags_v2.pop(tag, None)
  546. self._tags_v1.pop(tag, None)
  547. self._tagdata.pop(tag, None)
  548. def __iter__(self):
  549. return iter(set(self._tagdata) | set(self._tags_v2))
  550. def _unpack(self, fmt, data):
  551. return struct.unpack(self._endian + fmt, data)
  552. def _pack(self, fmt, *values):
  553. return struct.pack(self._endian + fmt, *values)
  554. def _register_loader(idx, size):
  555. def decorator(func):
  556. from .TiffTags import TYPES
  557. if func.__name__.startswith("load_"):
  558. TYPES[idx] = func.__name__[5:].replace("_", " ")
  559. _load_dispatch[idx] = size, func # noqa: F821
  560. return func
  561. return decorator
  562. def _register_writer(idx):
  563. def decorator(func):
  564. _write_dispatch[idx] = func # noqa: F821
  565. return func
  566. return decorator
  567. def _register_basic(idx_fmt_name):
  568. from .TiffTags import TYPES
  569. idx, fmt, name = idx_fmt_name
  570. TYPES[idx] = name
  571. size = struct.calcsize("=" + fmt)
  572. _load_dispatch[idx] = ( # noqa: F821
  573. size,
  574. lambda self, data, legacy_api=True: (
  575. self._unpack("{}{}".format(len(data) // size, fmt), data)
  576. ),
  577. )
  578. _write_dispatch[idx] = lambda self, *values: ( # noqa: F821
  579. b"".join(self._pack(fmt, value) for value in values)
  580. )
  581. list(
  582. map(
  583. _register_basic,
  584. [
  585. (TiffTags.SHORT, "H", "short"),
  586. (TiffTags.LONG, "L", "long"),
  587. (TiffTags.SIGNED_BYTE, "b", "signed byte"),
  588. (TiffTags.SIGNED_SHORT, "h", "signed short"),
  589. (TiffTags.SIGNED_LONG, "l", "signed long"),
  590. (TiffTags.FLOAT, "f", "float"),
  591. (TiffTags.DOUBLE, "d", "double"),
  592. (TiffTags.IFD, "L", "long"),
  593. ],
  594. )
  595. )
  596. @_register_loader(1, 1) # Basic type, except for the legacy API.
  597. def load_byte(self, data, legacy_api=True):
  598. return data
  599. @_register_writer(1) # Basic type, except for the legacy API.
  600. def write_byte(self, data):
  601. return data
  602. @_register_loader(2, 1)
  603. def load_string(self, data, legacy_api=True):
  604. if data.endswith(b"\0"):
  605. data = data[:-1]
  606. return data.decode("latin-1", "replace")
  607. @_register_writer(2)
  608. def write_string(self, value):
  609. # remerge of https://github.com/python-pillow/Pillow/pull/1416
  610. return b"" + value.encode("ascii", "replace") + b"\0"
  611. @_register_loader(5, 8)
  612. def load_rational(self, data, legacy_api=True):
  613. vals = self._unpack("{}L".format(len(data) // 4), data)
  614. def combine(a, b):
  615. return (a, b) if legacy_api else IFDRational(a, b)
  616. return tuple(combine(num, denom) for num, denom in zip(vals[::2], vals[1::2]))
  617. @_register_writer(5)
  618. def write_rational(self, *values):
  619. return b"".join(
  620. self._pack("2L", *_limit_rational(frac, 2 ** 32 - 1)) for frac in values
  621. )
  622. @_register_loader(7, 1)
  623. def load_undefined(self, data, legacy_api=True):
  624. return data
  625. @_register_writer(7)
  626. def write_undefined(self, value):
  627. return value
  628. @_register_loader(10, 8)
  629. def load_signed_rational(self, data, legacy_api=True):
  630. vals = self._unpack("{}l".format(len(data) // 4), data)
  631. def combine(a, b):
  632. return (a, b) if legacy_api else IFDRational(a, b)
  633. return tuple(combine(num, denom) for num, denom in zip(vals[::2], vals[1::2]))
  634. @_register_writer(10)
  635. def write_signed_rational(self, *values):
  636. return b"".join(
  637. self._pack("2l", *_limit_signed_rational(frac, 2 ** 31 - 1, -(2 ** 31)))
  638. for frac in values
  639. )
  640. def _ensure_read(self, fp, size):
  641. ret = fp.read(size)
  642. if len(ret) != size:
  643. raise OSError(
  644. "Corrupt EXIF data. "
  645. f"Expecting to read {size} bytes but only got {len(ret)}. "
  646. )
  647. return ret
  648. def load(self, fp):
  649. self.reset()
  650. self._offset = fp.tell()
  651. try:
  652. for i in range(self._unpack("H", self._ensure_read(fp, 2))[0]):
  653. tag, typ, count, data = self._unpack("HHL4s", self._ensure_read(fp, 12))
  654. tagname = TiffTags.lookup(tag, self.group).name
  655. typname = TYPES.get(typ, "unknown")
  656. msg = f"tag: {tagname} ({tag}) - type: {typname} ({typ})"
  657. try:
  658. unit_size, handler = self._load_dispatch[typ]
  659. except KeyError:
  660. logger.debug(msg + f" - unsupported type {typ}")
  661. continue # ignore unsupported type
  662. size = count * unit_size
  663. if size > 4:
  664. here = fp.tell()
  665. (offset,) = self._unpack("L", data)
  666. msg += f" Tag Location: {here} - Data Location: {offset}"
  667. fp.seek(offset)
  668. data = ImageFile._safe_read(fp, size)
  669. fp.seek(here)
  670. else:
  671. data = data[:size]
  672. if len(data) != size:
  673. warnings.warn(
  674. "Possibly corrupt EXIF data. "
  675. f"Expecting to read {size} bytes but only got {len(data)}."
  676. f" Skipping tag {tag}"
  677. )
  678. logger.debug(msg)
  679. continue
  680. if not data:
  681. logger.debug(msg)
  682. continue
  683. self._tagdata[tag] = data
  684. self.tagtype[tag] = typ
  685. msg += " - value: " + (
  686. "<table: %d bytes>" % size if size > 32 else repr(data)
  687. )
  688. logger.debug(msg)
  689. (self.next,) = self._unpack("L", self._ensure_read(fp, 4))
  690. except OSError as msg:
  691. warnings.warn(str(msg))
  692. return
  693. def tobytes(self, offset=0):
  694. # FIXME What about tagdata?
  695. result = self._pack("H", len(self._tags_v2))
  696. entries = []
  697. offset = offset + len(result) + len(self._tags_v2) * 12 + 4
  698. stripoffsets = None
  699. # pass 1: convert tags to binary format
  700. # always write tags in ascending order
  701. for tag, value in sorted(self._tags_v2.items()):
  702. if tag == STRIPOFFSETS:
  703. stripoffsets = len(entries)
  704. typ = self.tagtype.get(tag)
  705. logger.debug(f"Tag {tag}, Type: {typ}, Value: {repr(value)}")
  706. is_ifd = typ == TiffTags.LONG and isinstance(value, dict)
  707. if is_ifd:
  708. if self._endian == "<":
  709. ifh = b"II\x2A\x00\x08\x00\x00\x00"
  710. else:
  711. ifh = b"MM\x00\x2A\x00\x00\x00\x08"
  712. ifd = ImageFileDirectory_v2(ifh, group=tag)
  713. values = self._tags_v2[tag]
  714. for ifd_tag, ifd_value in values.items():
  715. ifd[ifd_tag] = ifd_value
  716. data = ifd.tobytes(offset)
  717. else:
  718. values = value if isinstance(value, tuple) else (value,)
  719. data = self._write_dispatch[typ](self, *values)
  720. tagname = TiffTags.lookup(tag, self.group).name
  721. typname = "ifd" if is_ifd else TYPES.get(typ, "unknown")
  722. msg = f"save: {tagname} ({tag}) - type: {typname} ({typ})"
  723. msg += " - value: " + (
  724. "<table: %d bytes>" % len(data) if len(data) >= 16 else str(values)
  725. )
  726. logger.debug(msg)
  727. # count is sum of lengths for string and arbitrary data
  728. if is_ifd:
  729. count = 1
  730. elif typ in [TiffTags.BYTE, TiffTags.ASCII, TiffTags.UNDEFINED]:
  731. count = len(data)
  732. else:
  733. count = len(values)
  734. # figure out if data fits into the entry
  735. if len(data) <= 4:
  736. entries.append((tag, typ, count, data.ljust(4, b"\0"), b""))
  737. else:
  738. entries.append((tag, typ, count, self._pack("L", offset), data))
  739. offset += (len(data) + 1) // 2 * 2 # pad to word
  740. # update strip offset data to point beyond auxiliary data
  741. if stripoffsets is not None:
  742. tag, typ, count, value, data = entries[stripoffsets]
  743. if data:
  744. raise NotImplementedError("multistrip support not yet implemented")
  745. value = self._pack("L", self._unpack("L", value)[0] + offset)
  746. entries[stripoffsets] = tag, typ, count, value, data
  747. # pass 2: write entries to file
  748. for tag, typ, count, value, data in entries:
  749. logger.debug(f"{tag} {typ} {count} {repr(value)} {repr(data)}")
  750. result += self._pack("HHL4s", tag, typ, count, value)
  751. # -- overwrite here for multi-page --
  752. result += b"\0\0\0\0" # end of entries
  753. # pass 3: write auxiliary data to file
  754. for tag, typ, count, value, data in entries:
  755. result += data
  756. if len(data) & 1:
  757. result += b"\0"
  758. return result
  759. def save(self, fp):
  760. if fp.tell() == 0: # skip TIFF header on subsequent pages
  761. # tiff header -- PIL always starts the first IFD at offset 8
  762. fp.write(self._prefix + self._pack("HL", 42, 8))
  763. offset = fp.tell()
  764. result = self.tobytes(offset)
  765. fp.write(result)
  766. return offset + len(result)
  767. ImageFileDirectory_v2._load_dispatch = _load_dispatch
  768. ImageFileDirectory_v2._write_dispatch = _write_dispatch
  769. for idx, name in TYPES.items():
  770. name = name.replace(" ", "_")
  771. setattr(ImageFileDirectory_v2, "load_" + name, _load_dispatch[idx][1])
  772. setattr(ImageFileDirectory_v2, "write_" + name, _write_dispatch[idx])
  773. del _load_dispatch, _write_dispatch, idx, name
  774. # Legacy ImageFileDirectory support.
  775. class ImageFileDirectory_v1(ImageFileDirectory_v2):
  776. """This class represents the **legacy** interface to a TIFF tag directory.
  777. Exposes a dictionary interface of the tags in the directory::
  778. ifd = ImageFileDirectory_v1()
  779. ifd[key] = 'Some Data'
  780. ifd.tagtype[key] = TiffTags.ASCII
  781. print(ifd[key])
  782. ('Some Data',)
  783. Also contains a dictionary of tag types as read from the tiff image file,
  784. :attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v1.tagtype`.
  785. Values are returned as a tuple.
  786. .. deprecated:: 3.0.0
  787. """
  788. def __init__(self, *args, **kwargs):
  789. super().__init__(*args, **kwargs)
  790. self._legacy_api = True
  791. tags = property(lambda self: self._tags_v1)
  792. tagdata = property(lambda self: self._tagdata)
  793. # defined in ImageFileDirectory_v2
  794. tagtype: dict
  795. """Dictionary of tag types"""
  796. @classmethod
  797. def from_v2(cls, original):
  798. """Returns an
  799. :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`
  800. instance with the same data as is contained in the original
  801. :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2`
  802. instance.
  803. :returns: :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`
  804. """
  805. ifd = cls(prefix=original.prefix)
  806. ifd._tagdata = original._tagdata
  807. ifd.tagtype = original.tagtype
  808. ifd.next = original.next # an indicator for multipage tiffs
  809. return ifd
  810. def to_v2(self):
  811. """Returns an
  812. :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2`
  813. instance with the same data as is contained in the original
  814. :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`
  815. instance.
  816. :returns: :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2`
  817. """
  818. ifd = ImageFileDirectory_v2(prefix=self.prefix)
  819. ifd._tagdata = dict(self._tagdata)
  820. ifd.tagtype = dict(self.tagtype)
  821. ifd._tags_v2 = dict(self._tags_v2)
  822. return ifd
  823. def __contains__(self, tag):
  824. return tag in self._tags_v1 or tag in self._tagdata
  825. def __len__(self):
  826. return len(set(self._tagdata) | set(self._tags_v1))
  827. def __iter__(self):
  828. return iter(set(self._tagdata) | set(self._tags_v1))
  829. def __setitem__(self, tag, value):
  830. for legacy_api in (False, True):
  831. self._setitem(tag, value, legacy_api)
  832. def __getitem__(self, tag):
  833. if tag not in self._tags_v1: # unpack on the fly
  834. data = self._tagdata[tag]
  835. typ = self.tagtype[tag]
  836. size, handler = self._load_dispatch[typ]
  837. for legacy in (False, True):
  838. self._setitem(tag, handler(self, data, legacy), legacy)
  839. val = self._tags_v1[tag]
  840. if not isinstance(val, (tuple, bytes)):
  841. val = (val,)
  842. return val
  843. # undone -- switch this pointer when IFD_LEGACY_API == False
  844. ImageFileDirectory = ImageFileDirectory_v1
  845. ##
  846. # Image plugin for TIFF files.
  847. class TiffImageFile(ImageFile.ImageFile):
  848. format = "TIFF"
  849. format_description = "Adobe TIFF"
  850. _close_exclusive_fp_after_loading = False
  851. def __init__(self, fp=None, filename=None):
  852. self.tag_v2 = None
  853. """ Image file directory (tag dictionary) """
  854. self.tag = None
  855. """ Legacy tag entries """
  856. super().__init__(fp, filename)
  857. def _open(self):
  858. """Open the first image in a TIFF file"""
  859. # Header
  860. ifh = self.fp.read(8)
  861. self.tag_v2 = ImageFileDirectory_v2(ifh)
  862. # legacy IFD entries will be filled in later
  863. self.ifd = None
  864. # setup frame pointers
  865. self.__first = self.__next = self.tag_v2.next
  866. self.__frame = -1
  867. self.__fp = self.fp
  868. self._frame_pos = []
  869. self._n_frames = None
  870. logger.debug("*** TiffImageFile._open ***")
  871. logger.debug(f"- __first: {self.__first}")
  872. logger.debug(f"- ifh: {repr(ifh)}") # Use repr to avoid str(bytes)
  873. # and load the first frame
  874. self._seek(0)
  875. @property
  876. def n_frames(self):
  877. if self._n_frames is None:
  878. current = self.tell()
  879. self._seek(len(self._frame_pos))
  880. while self._n_frames is None:
  881. self._seek(self.tell() + 1)
  882. self.seek(current)
  883. return self._n_frames
  884. def seek(self, frame):
  885. """Select a given frame as current image"""
  886. if not self._seek_check(frame):
  887. return
  888. self._seek(frame)
  889. # Create a new core image object on second and
  890. # subsequent frames in the image. Image may be
  891. # different size/mode.
  892. Image._decompression_bomb_check(self.size)
  893. self.im = Image.core.new(self.mode, self.size)
  894. def _seek(self, frame):
  895. self.fp = self.__fp
  896. # reset buffered io handle in case fp
  897. # was passed to libtiff, invalidating the buffer
  898. self.fp.tell()
  899. while len(self._frame_pos) <= frame:
  900. if not self.__next:
  901. raise EOFError("no more images in TIFF file")
  902. logger.debug(
  903. f"Seeking to frame {frame}, on frame {self.__frame}, "
  904. f"__next {self.__next}, location: {self.fp.tell()}"
  905. )
  906. self.fp.seek(self.__next)
  907. self._frame_pos.append(self.__next)
  908. logger.debug("Loading tags, location: %s" % self.fp.tell())
  909. self.tag_v2.load(self.fp)
  910. if self.tag_v2.next in self._frame_pos:
  911. # This IFD has already been processed
  912. # Declare this to be the end of the image
  913. self.__next = 0
  914. else:
  915. self.__next = self.tag_v2.next
  916. if self.__next == 0:
  917. self._n_frames = frame + 1
  918. if len(self._frame_pos) == 1:
  919. self.is_animated = self.__next != 0
  920. self.__frame += 1
  921. self.fp.seek(self._frame_pos[frame])
  922. self.tag_v2.load(self.fp)
  923. # fill the legacy tag/ifd entries
  924. self.tag = self.ifd = ImageFileDirectory_v1.from_v2(self.tag_v2)
  925. self.__frame = frame
  926. self._setup()
  927. def tell(self):
  928. """Return the current frame number"""
  929. return self.__frame
  930. def getxmp(self):
  931. """
  932. Returns a dictionary containing the XMP tags.
  933. Requires defusedxml to be installed.
  934. :returns: XMP tags in a dictionary.
  935. """
  936. return self._getxmp(self.tag_v2[700]) if 700 in self.tag_v2 else {}
  937. def load(self):
  938. if self.tile and self.use_load_libtiff:
  939. return self._load_libtiff()
  940. return super().load()
  941. def load_end(self):
  942. if self._tile_orientation:
  943. method = {
  944. 2: Image.FLIP_LEFT_RIGHT,
  945. 3: Image.ROTATE_180,
  946. 4: Image.FLIP_TOP_BOTTOM,
  947. 5: Image.TRANSPOSE,
  948. 6: Image.ROTATE_270,
  949. 7: Image.TRANSVERSE,
  950. 8: Image.ROTATE_90,
  951. }.get(self._tile_orientation)
  952. if method is not None:
  953. self.im = self.im.transpose(method)
  954. self._size = self.im.size
  955. # allow closing if we're on the first frame, there's no next
  956. # This is the ImageFile.load path only, libtiff specific below.
  957. if not self.is_animated:
  958. self._close_exclusive_fp_after_loading = True
  959. def _load_libtiff(self):
  960. """Overload method triggered when we detect a compressed tiff
  961. Calls out to libtiff"""
  962. Image.Image.load(self)
  963. self.load_prepare()
  964. if not len(self.tile) == 1:
  965. raise OSError("Not exactly one tile")
  966. # (self._compression, (extents tuple),
  967. # 0, (rawmode, self._compression, fp))
  968. extents = self.tile[0][1]
  969. args = list(self.tile[0][3])
  970. # To be nice on memory footprint, if there's a
  971. # file descriptor, use that instead of reading
  972. # into a string in python.
  973. # libtiff closes the file descriptor, so pass in a dup.
  974. try:
  975. fp = hasattr(self.fp, "fileno") and os.dup(self.fp.fileno())
  976. # flush the file descriptor, prevents error on pypy 2.4+
  977. # should also eliminate the need for fp.tell
  978. # in _seek
  979. if hasattr(self.fp, "flush"):
  980. self.fp.flush()
  981. except OSError:
  982. # io.BytesIO have a fileno, but returns an OSError if
  983. # it doesn't use a file descriptor.
  984. fp = False
  985. if fp:
  986. args[2] = fp
  987. decoder = Image._getdecoder(
  988. self.mode, "libtiff", tuple(args), self.decoderconfig
  989. )
  990. try:
  991. decoder.setimage(self.im, extents)
  992. except ValueError as e:
  993. raise OSError("Couldn't set the image") from e
  994. close_self_fp = self._exclusive_fp and not self.is_animated
  995. if hasattr(self.fp, "getvalue"):
  996. # We've got a stringio like thing passed in. Yay for all in memory.
  997. # The decoder needs the entire file in one shot, so there's not
  998. # a lot we can do here other than give it the entire file.
  999. # unless we could do something like get the address of the
  1000. # underlying string for stringio.
  1001. #
  1002. # Rearranging for supporting byteio items, since they have a fileno
  1003. # that returns an OSError if there's no underlying fp. Easier to
  1004. # deal with here by reordering.
  1005. logger.debug("have getvalue. just sending in a string from getvalue")
  1006. n, err = decoder.decode(self.fp.getvalue())
  1007. elif fp:
  1008. # we've got a actual file on disk, pass in the fp.
  1009. logger.debug("have fileno, calling fileno version of the decoder.")
  1010. if not close_self_fp:
  1011. self.fp.seek(0)
  1012. # 4 bytes, otherwise the trace might error out
  1013. n, err = decoder.decode(b"fpfp")
  1014. else:
  1015. # we have something else.
  1016. logger.debug("don't have fileno or getvalue. just reading")
  1017. self.fp.seek(0)
  1018. # UNDONE -- so much for that buffer size thing.
  1019. n, err = decoder.decode(self.fp.read())
  1020. self.tile = []
  1021. self.readonly = 0
  1022. self.load_end()
  1023. # libtiff closed the fp in a, we need to close self.fp, if possible
  1024. if close_self_fp:
  1025. self.fp.close()
  1026. self.fp = None # might be shared
  1027. if err < 0:
  1028. raise OSError(err)
  1029. return Image.Image.load(self)
  1030. def _setup(self):
  1031. """Setup this image object based on current tags"""
  1032. if 0xBC01 in self.tag_v2:
  1033. raise OSError("Windows Media Photo files not yet supported")
  1034. # extract relevant tags
  1035. self._compression = COMPRESSION_INFO[self.tag_v2.get(COMPRESSION, 1)]
  1036. self._planar_configuration = self.tag_v2.get(PLANAR_CONFIGURATION, 1)
  1037. # photometric is a required tag, but not everyone is reading
  1038. # the specification
  1039. photo = self.tag_v2.get(PHOTOMETRIC_INTERPRETATION, 0)
  1040. # old style jpeg compression images most certainly are YCbCr
  1041. if self._compression == "tiff_jpeg":
  1042. photo = 6
  1043. fillorder = self.tag_v2.get(FILLORDER, 1)
  1044. logger.debug("*** Summary ***")
  1045. logger.debug(f"- compression: {self._compression}")
  1046. logger.debug(f"- photometric_interpretation: {photo}")
  1047. logger.debug(f"- planar_configuration: {self._planar_configuration}")
  1048. logger.debug(f"- fill_order: {fillorder}")
  1049. logger.debug(f"- YCbCr subsampling: {self.tag.get(530)}")
  1050. # size
  1051. xsize = int(self.tag_v2.get(IMAGEWIDTH))
  1052. ysize = int(self.tag_v2.get(IMAGELENGTH))
  1053. self._size = xsize, ysize
  1054. logger.debug(f"- size: {self.size}")
  1055. sampleFormat = self.tag_v2.get(SAMPLEFORMAT, (1,))
  1056. if len(sampleFormat) > 1 and max(sampleFormat) == min(sampleFormat) == 1:
  1057. # SAMPLEFORMAT is properly per band, so an RGB image will
  1058. # be (1,1,1). But, we don't support per band pixel types,
  1059. # and anything more than one band is a uint8. So, just
  1060. # take the first element. Revisit this if adding support
  1061. # for more exotic images.
  1062. sampleFormat = (1,)
  1063. bps_tuple = self.tag_v2.get(BITSPERSAMPLE, (1,))
  1064. extra_tuple = self.tag_v2.get(EXTRASAMPLES, ())
  1065. if photo in (2, 6, 8): # RGB, YCbCr, LAB
  1066. bps_count = 3
  1067. elif photo == 5: # CMYK
  1068. bps_count = 4
  1069. else:
  1070. bps_count = 1
  1071. bps_count += len(extra_tuple)
  1072. # Some files have only one value in bps_tuple,
  1073. # while should have more. Fix it
  1074. if bps_count > len(bps_tuple) and len(bps_tuple) == 1:
  1075. bps_tuple = bps_tuple * bps_count
  1076. samplesPerPixel = self.tag_v2.get(
  1077. SAMPLESPERPIXEL,
  1078. 3 if self._compression == "tiff_jpeg" and photo in (2, 6) else 1,
  1079. )
  1080. if len(bps_tuple) != samplesPerPixel:
  1081. raise SyntaxError("unknown data organization")
  1082. # mode: check photometric interpretation and bits per pixel
  1083. key = (
  1084. self.tag_v2.prefix,
  1085. photo,
  1086. sampleFormat,
  1087. fillorder,
  1088. bps_tuple,
  1089. extra_tuple,
  1090. )
  1091. logger.debug(f"format key: {key}")
  1092. try:
  1093. self.mode, rawmode = OPEN_INFO[key]
  1094. except KeyError as e:
  1095. logger.debug("- unsupported format")
  1096. raise SyntaxError("unknown pixel mode") from e
  1097. logger.debug(f"- raw mode: {rawmode}")
  1098. logger.debug(f"- pil mode: {self.mode}")
  1099. self.info["compression"] = self._compression
  1100. xres = self.tag_v2.get(X_RESOLUTION, 1)
  1101. yres = self.tag_v2.get(Y_RESOLUTION, 1)
  1102. if xres and yres:
  1103. resunit = self.tag_v2.get(RESOLUTION_UNIT)
  1104. if resunit == 2: # dots per inch
  1105. self.info["dpi"] = (xres, yres)
  1106. elif resunit == 3: # dots per centimeter. convert to dpi
  1107. self.info["dpi"] = (xres * 2.54, yres * 2.54)
  1108. elif resunit is None: # used to default to 1, but now 2)
  1109. self.info["dpi"] = (xres, yres)
  1110. # For backward compatibility,
  1111. # we also preserve the old behavior
  1112. self.info["resolution"] = xres, yres
  1113. else: # No absolute unit of measurement
  1114. self.info["resolution"] = xres, yres
  1115. # build tile descriptors
  1116. x = y = layer = 0
  1117. self.tile = []
  1118. self.use_load_libtiff = READ_LIBTIFF or self._compression != "raw"
  1119. if self.use_load_libtiff:
  1120. # Decoder expects entire file as one tile.
  1121. # There's a buffer size limit in load (64k)
  1122. # so large g4 images will fail if we use that
  1123. # function.
  1124. #
  1125. # Setup the one tile for the whole image, then
  1126. # use the _load_libtiff function.
  1127. # libtiff handles the fillmode for us, so 1;IR should
  1128. # actually be 1;I. Including the R double reverses the
  1129. # bits, so stripes of the image are reversed. See
  1130. # https://github.com/python-pillow/Pillow/issues/279
  1131. if fillorder == 2:
  1132. # Replace fillorder with fillorder=1
  1133. key = key[:3] + (1,) + key[4:]
  1134. logger.debug(f"format key: {key}")
  1135. # this should always work, since all the
  1136. # fillorder==2 modes have a corresponding
  1137. # fillorder=1 mode
  1138. self.mode, rawmode = OPEN_INFO[key]
  1139. # libtiff always returns the bytes in native order.
  1140. # we're expecting image byte order. So, if the rawmode
  1141. # contains I;16, we need to convert from native to image
  1142. # byte order.
  1143. if rawmode == "I;16":
  1144. rawmode = "I;16N"
  1145. if ";16B" in rawmode:
  1146. rawmode = rawmode.replace(";16B", ";16N")
  1147. if ";16L" in rawmode:
  1148. rawmode = rawmode.replace(";16L", ";16N")
  1149. # YCbCr images with new jpeg compression with pixels in one plane
  1150. # unpacked straight into RGB values
  1151. if (
  1152. photo == 6
  1153. and self._compression == "jpeg"
  1154. and self._planar_configuration == 1
  1155. ):
  1156. rawmode = "RGB"
  1157. # Offset in the tile tuple is 0, we go from 0,0 to
  1158. # w,h, and we only do this once -- eds
  1159. a = (rawmode, self._compression, False, self.tag_v2.offset)
  1160. self.tile.append(("libtiff", (0, 0, xsize, ysize), 0, a))
  1161. elif STRIPOFFSETS in self.tag_v2 or TILEOFFSETS in self.tag_v2:
  1162. # striped image
  1163. if STRIPOFFSETS in self.tag_v2:
  1164. offsets = self.tag_v2[STRIPOFFSETS]
  1165. h = self.tag_v2.get(ROWSPERSTRIP, ysize)
  1166. w = self.size[0]
  1167. else:
  1168. # tiled image
  1169. offsets = self.tag_v2[TILEOFFSETS]
  1170. w = self.tag_v2.get(322)
  1171. h = self.tag_v2.get(323)
  1172. for offset in offsets:
  1173. if x + w > xsize:
  1174. stride = w * sum(bps_tuple) / 8 # bytes per line
  1175. else:
  1176. stride = 0
  1177. tile_rawmode = rawmode
  1178. if self._planar_configuration == 2:
  1179. # each band on it's own layer
  1180. tile_rawmode = rawmode[layer]
  1181. # adjust stride width accordingly
  1182. stride /= bps_count
  1183. a = (tile_rawmode, int(stride), 1)
  1184. self.tile.append(
  1185. (
  1186. self._compression,
  1187. (x, y, min(x + w, xsize), min(y + h, ysize)),
  1188. offset,
  1189. a,
  1190. )
  1191. )
  1192. x = x + w
  1193. if x >= self.size[0]:
  1194. x, y = 0, y + h
  1195. if y >= self.size[1]:
  1196. x = y = 0
  1197. layer += 1
  1198. else:
  1199. logger.debug("- unsupported data organization")
  1200. raise SyntaxError("unknown data organization")
  1201. # Fix up info.
  1202. if ICCPROFILE in self.tag_v2:
  1203. self.info["icc_profile"] = self.tag_v2[ICCPROFILE]
  1204. # fixup palette descriptor
  1205. if self.mode in ["P", "PA"]:
  1206. palette = [o8(b // 256) for b in self.tag_v2[COLORMAP]]
  1207. self.palette = ImagePalette.raw("RGB;L", b"".join(palette))
  1208. self._tile_orientation = self.tag_v2.get(0x0112)
  1209. def _close__fp(self):
  1210. try:
  1211. if self.__fp != self.fp:
  1212. self.__fp.close()
  1213. except AttributeError:
  1214. pass
  1215. finally:
  1216. self.__fp = None
  1217. #
  1218. # --------------------------------------------------------------------
  1219. # Write TIFF files
  1220. # little endian is default except for image modes with
  1221. # explicit big endian byte-order
  1222. SAVE_INFO = {
  1223. # mode => rawmode, byteorder, photometrics,
  1224. # sampleformat, bitspersample, extra
  1225. "1": ("1", II, 1, 1, (1,), None),
  1226. "L": ("L", II, 1, 1, (8,), None),
  1227. "LA": ("LA", II, 1, 1, (8, 8), 2),
  1228. "P": ("P", II, 3, 1, (8,), None),
  1229. "PA": ("PA", II, 3, 1, (8, 8), 2),
  1230. "I": ("I;32S", II, 1, 2, (32,), None),
  1231. "I;16": ("I;16", II, 1, 1, (16,), None),
  1232. "I;16S": ("I;16S", II, 1, 2, (16,), None),
  1233. "F": ("F;32F", II, 1, 3, (32,), None),
  1234. "RGB": ("RGB", II, 2, 1, (8, 8, 8), None),
  1235. "RGBX": ("RGBX", II, 2, 1, (8, 8, 8, 8), 0),
  1236. "RGBA": ("RGBA", II, 2, 1, (8, 8, 8, 8), 2),
  1237. "CMYK": ("CMYK", II, 5, 1, (8, 8, 8, 8), None),
  1238. "YCbCr": ("YCbCr", II, 6, 1, (8, 8, 8), None),
  1239. "LAB": ("LAB", II, 8, 1, (8, 8, 8), None),
  1240. "I;32BS": ("I;32BS", MM, 1, 2, (32,), None),
  1241. "I;16B": ("I;16B", MM, 1, 1, (16,), None),
  1242. "I;16BS": ("I;16BS", MM, 1, 2, (16,), None),
  1243. "F;32BF": ("F;32BF", MM, 1, 3, (32,), None),
  1244. }
  1245. def _save(im, fp, filename):
  1246. try:
  1247. rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode]
  1248. except KeyError as e:
  1249. raise OSError(f"cannot write mode {im.mode} as TIFF") from e
  1250. ifd = ImageFileDirectory_v2(prefix=prefix)
  1251. compression = im.encoderinfo.get("compression", im.info.get("compression"))
  1252. if compression is None:
  1253. compression = "raw"
  1254. elif compression == "tiff_jpeg":
  1255. # OJPEG is obsolete, so use new-style JPEG compression instead
  1256. compression = "jpeg"
  1257. elif compression == "tiff_deflate":
  1258. compression = "tiff_adobe_deflate"
  1259. libtiff = WRITE_LIBTIFF or compression != "raw"
  1260. # required for color libtiff images
  1261. ifd[PLANAR_CONFIGURATION] = getattr(im, "_planar_configuration", 1)
  1262. ifd[IMAGEWIDTH] = im.size[0]
  1263. ifd[IMAGELENGTH] = im.size[1]
  1264. # write any arbitrary tags passed in as an ImageFileDirectory
  1265. info = im.encoderinfo.get("tiffinfo", {})
  1266. logger.debug("Tiffinfo Keys: %s" % list(info))
  1267. if isinstance(info, ImageFileDirectory_v1):
  1268. info = info.to_v2()
  1269. for key in info:
  1270. ifd[key] = info.get(key)
  1271. try:
  1272. ifd.tagtype[key] = info.tagtype[key]
  1273. except Exception:
  1274. pass # might not be an IFD. Might not have populated type
  1275. # additions written by Greg Couch, gregc@cgl.ucsf.edu
  1276. # inspired by image-sig posting from Kevin Cazabon, kcazabon@home.com
  1277. if hasattr(im, "tag_v2"):
  1278. # preserve tags from original TIFF image file
  1279. for key in (
  1280. RESOLUTION_UNIT,
  1281. X_RESOLUTION,
  1282. Y_RESOLUTION,
  1283. IPTC_NAA_CHUNK,
  1284. PHOTOSHOP_CHUNK,
  1285. XMP,
  1286. ):
  1287. if key in im.tag_v2:
  1288. ifd[key] = im.tag_v2[key]
  1289. ifd.tagtype[key] = im.tag_v2.tagtype[key]
  1290. # preserve ICC profile (should also work when saving other formats
  1291. # which support profiles as TIFF) -- 2008-06-06 Florian Hoech
  1292. icc = im.encoderinfo.get("icc_profile", im.info.get("icc_profile"))
  1293. if icc:
  1294. ifd[ICCPROFILE] = icc
  1295. for key, name in [
  1296. (IMAGEDESCRIPTION, "description"),
  1297. (X_RESOLUTION, "resolution"),
  1298. (Y_RESOLUTION, "resolution"),
  1299. (X_RESOLUTION, "x_resolution"),
  1300. (Y_RESOLUTION, "y_resolution"),
  1301. (RESOLUTION_UNIT, "resolution_unit"),
  1302. (SOFTWARE, "software"),
  1303. (DATE_TIME, "date_time"),
  1304. (ARTIST, "artist"),
  1305. (COPYRIGHT, "copyright"),
  1306. ]:
  1307. if name in im.encoderinfo:
  1308. ifd[key] = im.encoderinfo[name]
  1309. dpi = im.encoderinfo.get("dpi")
  1310. if dpi:
  1311. ifd[RESOLUTION_UNIT] = 2
  1312. ifd[X_RESOLUTION] = dpi[0]
  1313. ifd[Y_RESOLUTION] = dpi[1]
  1314. if bits != (1,):
  1315. ifd[BITSPERSAMPLE] = bits
  1316. if len(bits) != 1:
  1317. ifd[SAMPLESPERPIXEL] = len(bits)
  1318. if extra is not None:
  1319. ifd[EXTRASAMPLES] = extra
  1320. if format != 1:
  1321. ifd[SAMPLEFORMAT] = format
  1322. ifd[PHOTOMETRIC_INTERPRETATION] = photo
  1323. if im.mode in ["P", "PA"]:
  1324. lut = im.im.getpalette("RGB", "RGB;L")
  1325. ifd[COLORMAP] = tuple(v * 256 for v in lut)
  1326. # data orientation
  1327. stride = len(bits) * ((im.size[0] * bits[0] + 7) // 8)
  1328. # aim for 64 KB strips when using libtiff writer
  1329. if libtiff:
  1330. rows_per_strip = min((2 ** 16 + stride - 1) // stride, im.size[1])
  1331. # JPEG encoder expects multiple of 8 rows
  1332. if compression == "jpeg":
  1333. rows_per_strip = min(((rows_per_strip + 7) // 8) * 8, im.size[1])
  1334. else:
  1335. rows_per_strip = im.size[1]
  1336. strip_byte_counts = stride * rows_per_strip
  1337. strips_per_image = (im.size[1] + rows_per_strip - 1) // rows_per_strip
  1338. ifd[ROWSPERSTRIP] = rows_per_strip
  1339. if strip_byte_counts >= 2 ** 16:
  1340. ifd.tagtype[STRIPBYTECOUNTS] = TiffTags.LONG
  1341. ifd[STRIPBYTECOUNTS] = (strip_byte_counts,) * (strips_per_image - 1) + (
  1342. stride * im.size[1] - strip_byte_counts * (strips_per_image - 1),
  1343. )
  1344. ifd[STRIPOFFSETS] = tuple(
  1345. range(0, strip_byte_counts * strips_per_image, strip_byte_counts)
  1346. ) # this is adjusted by IFD writer
  1347. # no compression by default:
  1348. ifd[COMPRESSION] = COMPRESSION_INFO_REV.get(compression, 1)
  1349. if libtiff:
  1350. if "quality" in im.encoderinfo:
  1351. quality = im.encoderinfo["quality"]
  1352. if not isinstance(quality, int) or quality < 0 or quality > 100:
  1353. raise ValueError("Invalid quality setting")
  1354. if compression != "jpeg":
  1355. raise ValueError(
  1356. "quality setting only supported for 'jpeg' compression"
  1357. )
  1358. ifd[JPEGQUALITY] = quality
  1359. logger.debug("Saving using libtiff encoder")
  1360. logger.debug("Items: %s" % sorted(ifd.items()))
  1361. _fp = 0
  1362. if hasattr(fp, "fileno"):
  1363. try:
  1364. fp.seek(0)
  1365. _fp = os.dup(fp.fileno())
  1366. except io.UnsupportedOperation:
  1367. pass
  1368. # optional types for non core tags
  1369. types = {}
  1370. # SAMPLEFORMAT is determined by the image format and should not be copied
  1371. # from legacy_ifd.
  1372. # STRIPOFFSETS and STRIPBYTECOUNTS are added by the library
  1373. # based on the data in the strip.
  1374. # The other tags expect arrays with a certain length (fixed or depending on
  1375. # BITSPERSAMPLE, etc), passing arrays with a different length will result in
  1376. # segfaults. Block these tags until we add extra validation.
  1377. # SUBIFD may also cause a segfault.
  1378. blocklist = [
  1379. REFERENCEBLACKWHITE,
  1380. SAMPLEFORMAT,
  1381. STRIPBYTECOUNTS,
  1382. STRIPOFFSETS,
  1383. TRANSFERFUNCTION,
  1384. SUBIFD,
  1385. ]
  1386. atts = {}
  1387. # bits per sample is a single short in the tiff directory, not a list.
  1388. atts[BITSPERSAMPLE] = bits[0]
  1389. # Merge the ones that we have with (optional) more bits from
  1390. # the original file, e.g x,y resolution so that we can
  1391. # save(load('')) == original file.
  1392. legacy_ifd = {}
  1393. if hasattr(im, "tag"):
  1394. legacy_ifd = im.tag.to_v2()
  1395. for tag, value in itertools.chain(
  1396. ifd.items(), getattr(im, "tag_v2", {}).items(), legacy_ifd.items()
  1397. ):
  1398. # Libtiff can only process certain core items without adding
  1399. # them to the custom dictionary.
  1400. # Custom items are supported for int, float, unicode, string and byte
  1401. # values. Other types and tuples require a tagtype.
  1402. if tag not in TiffTags.LIBTIFF_CORE:
  1403. if not Image.core.libtiff_support_custom_tags:
  1404. continue
  1405. if tag in ifd.tagtype:
  1406. types[tag] = ifd.tagtype[tag]
  1407. elif not (isinstance(value, (int, float, str, bytes))):
  1408. continue
  1409. else:
  1410. type = TiffTags.lookup(tag).type
  1411. if type:
  1412. types[tag] = type
  1413. if tag not in atts and tag not in blocklist:
  1414. if isinstance(value, str):
  1415. atts[tag] = value.encode("ascii", "replace") + b"\0"
  1416. elif isinstance(value, IFDRational):
  1417. atts[tag] = float(value)
  1418. else:
  1419. atts[tag] = value
  1420. logger.debug("Converted items: %s" % sorted(atts.items()))
  1421. # libtiff always expects the bytes in native order.
  1422. # we're storing image byte order. So, if the rawmode
  1423. # contains I;16, we need to convert from native to image
  1424. # byte order.
  1425. if im.mode in ("I;16B", "I;16"):
  1426. rawmode = "I;16N"
  1427. # Pass tags as sorted list so that the tags are set in a fixed order.
  1428. # This is required by libtiff for some tags. For example, the JPEGQUALITY
  1429. # pseudo tag requires that the COMPRESS tag was already set.
  1430. tags = list(atts.items())
  1431. tags.sort()
  1432. a = (rawmode, compression, _fp, filename, tags, types)
  1433. e = Image._getencoder(im.mode, "libtiff", a, im.encoderconfig)
  1434. e.setimage(im.im, (0, 0) + im.size)
  1435. while True:
  1436. # undone, change to self.decodermaxblock:
  1437. l, s, d = e.encode(16 * 1024)
  1438. if not _fp:
  1439. fp.write(d)
  1440. if s:
  1441. break
  1442. if s < 0:
  1443. raise OSError(f"encoder error {s} when writing image file")
  1444. else:
  1445. offset = ifd.save(fp)
  1446. ImageFile._save(
  1447. im, fp, [("raw", (0, 0) + im.size, offset, (rawmode, stride, 1))]
  1448. )
  1449. # -- helper for multi-page save --
  1450. if "_debug_multipage" in im.encoderinfo:
  1451. # just to access o32 and o16 (using correct byte order)
  1452. im._debug_multipage = ifd
  1453. class AppendingTiffWriter:
  1454. fieldSizes = [
  1455. 0, # None
  1456. 1, # byte
  1457. 1, # ascii
  1458. 2, # short
  1459. 4, # long
  1460. 8, # rational
  1461. 1, # sbyte
  1462. 1, # undefined
  1463. 2, # sshort
  1464. 4, # slong
  1465. 8, # srational
  1466. 4, # float
  1467. 8, # double
  1468. ]
  1469. # StripOffsets = 273
  1470. # FreeOffsets = 288
  1471. # TileOffsets = 324
  1472. # JPEGQTables = 519
  1473. # JPEGDCTables = 520
  1474. # JPEGACTables = 521
  1475. Tags = {273, 288, 324, 519, 520, 521}
  1476. def __init__(self, fn, new=False):
  1477. if hasattr(fn, "read"):
  1478. self.f = fn
  1479. self.close_fp = False
  1480. else:
  1481. self.name = fn
  1482. self.close_fp = True
  1483. try:
  1484. self.f = open(fn, "w+b" if new else "r+b")
  1485. except OSError:
  1486. self.f = open(fn, "w+b")
  1487. self.beginning = self.f.tell()
  1488. self.setup()
  1489. def setup(self):
  1490. # Reset everything.
  1491. self.f.seek(self.beginning, os.SEEK_SET)
  1492. self.whereToWriteNewIFDOffset = None
  1493. self.offsetOfNewPage = 0
  1494. self.IIMM = IIMM = self.f.read(4)
  1495. if not IIMM:
  1496. # empty file - first page
  1497. self.isFirst = True
  1498. return
  1499. self.isFirst = False
  1500. if IIMM == b"II\x2a\x00":
  1501. self.setEndian("<")
  1502. elif IIMM == b"MM\x00\x2a":
  1503. self.setEndian(">")
  1504. else:
  1505. raise RuntimeError("Invalid TIFF file header")
  1506. self.skipIFDs()
  1507. self.goToEnd()
  1508. def finalize(self):
  1509. if self.isFirst:
  1510. return
  1511. # fix offsets
  1512. self.f.seek(self.offsetOfNewPage)
  1513. IIMM = self.f.read(4)
  1514. if not IIMM:
  1515. # raise RuntimeError("nothing written into new page")
  1516. # Make it easy to finish a frame without committing to a new one.
  1517. return
  1518. if IIMM != self.IIMM:
  1519. raise RuntimeError("IIMM of new page doesn't match IIMM of first page")
  1520. IFDoffset = self.readLong()
  1521. IFDoffset += self.offsetOfNewPage
  1522. self.f.seek(self.whereToWriteNewIFDOffset)
  1523. self.writeLong(IFDoffset)
  1524. self.f.seek(IFDoffset)
  1525. self.fixIFD()
  1526. def newFrame(self):
  1527. # Call this to finish a frame.
  1528. self.finalize()
  1529. self.setup()
  1530. def __enter__(self):
  1531. return self
  1532. def __exit__(self, exc_type, exc_value, traceback):
  1533. if self.close_fp:
  1534. self.close()
  1535. return False
  1536. def tell(self):
  1537. return self.f.tell() - self.offsetOfNewPage
  1538. def seek(self, offset, whence=io.SEEK_SET):
  1539. if whence == os.SEEK_SET:
  1540. offset += self.offsetOfNewPage
  1541. self.f.seek(offset, whence)
  1542. return self.tell()
  1543. def goToEnd(self):
  1544. self.f.seek(0, os.SEEK_END)
  1545. pos = self.f.tell()
  1546. # pad to 16 byte boundary
  1547. padBytes = 16 - pos % 16
  1548. if 0 < padBytes < 16:
  1549. self.f.write(bytes(padBytes))
  1550. self.offsetOfNewPage = self.f.tell()
  1551. def setEndian(self, endian):
  1552. self.endian = endian
  1553. self.longFmt = self.endian + "L"
  1554. self.shortFmt = self.endian + "H"
  1555. self.tagFormat = self.endian + "HHL"
  1556. def skipIFDs(self):
  1557. while True:
  1558. IFDoffset = self.readLong()
  1559. if IFDoffset == 0:
  1560. self.whereToWriteNewIFDOffset = self.f.tell() - 4
  1561. break
  1562. self.f.seek(IFDoffset)
  1563. numTags = self.readShort()
  1564. self.f.seek(numTags * 12, os.SEEK_CUR)
  1565. def write(self, data):
  1566. return self.f.write(data)
  1567. def readShort(self):
  1568. (value,) = struct.unpack(self.shortFmt, self.f.read(2))
  1569. return value
  1570. def readLong(self):
  1571. (value,) = struct.unpack(self.longFmt, self.f.read(4))
  1572. return value
  1573. def rewriteLastShortToLong(self, value):
  1574. self.f.seek(-2, os.SEEK_CUR)
  1575. bytesWritten = self.f.write(struct.pack(self.longFmt, value))
  1576. if bytesWritten is not None and bytesWritten != 4:
  1577. raise RuntimeError(f"wrote only {bytesWritten} bytes but wanted 4")
  1578. def rewriteLastShort(self, value):
  1579. self.f.seek(-2, os.SEEK_CUR)
  1580. bytesWritten = self.f.write(struct.pack(self.shortFmt, value))
  1581. if bytesWritten is not None and bytesWritten != 2:
  1582. raise RuntimeError(f"wrote only {bytesWritten} bytes but wanted 2")
  1583. def rewriteLastLong(self, value):
  1584. self.f.seek(-4, os.SEEK_CUR)
  1585. bytesWritten = self.f.write(struct.pack(self.longFmt, value))
  1586. if bytesWritten is not None and bytesWritten != 4:
  1587. raise RuntimeError(f"wrote only {bytesWritten} bytes but wanted 4")
  1588. def writeShort(self, value):
  1589. bytesWritten = self.f.write(struct.pack(self.shortFmt, value))
  1590. if bytesWritten is not None and bytesWritten != 2:
  1591. raise RuntimeError(f"wrote only {bytesWritten} bytes but wanted 2")
  1592. def writeLong(self, value):
  1593. bytesWritten = self.f.write(struct.pack(self.longFmt, value))
  1594. if bytesWritten is not None and bytesWritten != 4:
  1595. raise RuntimeError(f"wrote only {bytesWritten} bytes but wanted 4")
  1596. def close(self):
  1597. self.finalize()
  1598. self.f.close()
  1599. def fixIFD(self):
  1600. numTags = self.readShort()
  1601. for i in range(numTags):
  1602. tag, fieldType, count = struct.unpack(self.tagFormat, self.f.read(8))
  1603. fieldSize = self.fieldSizes[fieldType]
  1604. totalSize = fieldSize * count
  1605. isLocal = totalSize <= 4
  1606. if not isLocal:
  1607. offset = self.readLong()
  1608. offset += self.offsetOfNewPage
  1609. self.rewriteLastLong(offset)
  1610. if tag in self.Tags:
  1611. curPos = self.f.tell()
  1612. if isLocal:
  1613. self.fixOffsets(
  1614. count, isShort=(fieldSize == 2), isLong=(fieldSize == 4)
  1615. )
  1616. self.f.seek(curPos + 4)
  1617. else:
  1618. self.f.seek(offset)
  1619. self.fixOffsets(
  1620. count, isShort=(fieldSize == 2), isLong=(fieldSize == 4)
  1621. )
  1622. self.f.seek(curPos)
  1623. offset = curPos = None
  1624. elif isLocal:
  1625. # skip the locally stored value that is not an offset
  1626. self.f.seek(4, os.SEEK_CUR)
  1627. def fixOffsets(self, count, isShort=False, isLong=False):
  1628. if not isShort and not isLong:
  1629. raise RuntimeError("offset is neither short nor long")
  1630. for i in range(count):
  1631. offset = self.readShort() if isShort else self.readLong()
  1632. offset += self.offsetOfNewPage
  1633. if isShort and offset >= 65536:
  1634. # offset is now too large - we must convert shorts to longs
  1635. if count != 1:
  1636. raise RuntimeError("not implemented") # XXX TODO
  1637. # simple case - the offset is just one and therefore it is
  1638. # local (not referenced with another offset)
  1639. self.rewriteLastShortToLong(offset)
  1640. self.f.seek(-10, os.SEEK_CUR)
  1641. self.writeShort(TiffTags.LONG) # rewrite the type to LONG
  1642. self.f.seek(8, os.SEEK_CUR)
  1643. elif isShort:
  1644. self.rewriteLastShort(offset)
  1645. else:
  1646. self.rewriteLastLong(offset)
  1647. def _save_all(im, fp, filename):
  1648. encoderinfo = im.encoderinfo.copy()
  1649. encoderconfig = im.encoderconfig
  1650. append_images = list(encoderinfo.get("append_images", []))
  1651. if not hasattr(im, "n_frames") and not append_images:
  1652. return _save(im, fp, filename)
  1653. cur_idx = im.tell()
  1654. try:
  1655. with AppendingTiffWriter(fp) as tf:
  1656. for ims in [im] + append_images:
  1657. ims.encoderinfo = encoderinfo
  1658. ims.encoderconfig = encoderconfig
  1659. if not hasattr(ims, "n_frames"):
  1660. nfr = 1
  1661. else:
  1662. nfr = ims.n_frames
  1663. for idx in range(nfr):
  1664. ims.seek(idx)
  1665. ims.load()
  1666. _save(ims, tf, filename)
  1667. tf.newFrame()
  1668. finally:
  1669. im.seek(cur_idx)
  1670. #
  1671. # --------------------------------------------------------------------
  1672. # Register
  1673. Image.register_open(TiffImageFile.format, TiffImageFile, _accept)
  1674. Image.register_save(TiffImageFile.format, _save)
  1675. Image.register_save_all(TiffImageFile.format, _save_all)
  1676. Image.register_extensions(TiffImageFile.format, [".tif", ".tiff"])
  1677. Image.register_mime(TiffImageFile.format, "image/tiff")