TiffImagePlugin.py 67 KB

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