TiffImagePlugin.py 74 KB

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