You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

673 lines
20 KiB

4 years ago
  1. #
  2. # The Python Imaging Library.
  3. # $Id$
  4. #
  5. # base class for image file handlers
  6. #
  7. # history:
  8. # 1995-09-09 fl Created
  9. # 1996-03-11 fl Fixed load mechanism.
  10. # 1996-04-15 fl Added pcx/xbm decoders.
  11. # 1996-04-30 fl Added encoders.
  12. # 1996-12-14 fl Added load helpers
  13. # 1997-01-11 fl Use encode_to_file where possible
  14. # 1997-08-27 fl Flush output in _save
  15. # 1998-03-05 fl Use memory mapping for some modes
  16. # 1999-02-04 fl Use memory mapping also for "I;16" and "I;16B"
  17. # 1999-05-31 fl Added image parser
  18. # 2000-10-12 fl Set readonly flag on memory-mapped images
  19. # 2002-03-20 fl Use better messages for common decoder errors
  20. # 2003-04-21 fl Fall back on mmap/map_buffer if map is not available
  21. # 2003-10-30 fl Added StubImageFile class
  22. # 2004-02-25 fl Made incremental parser more robust
  23. #
  24. # Copyright (c) 1997-2004 by Secret Labs AB
  25. # Copyright (c) 1995-2004 by Fredrik Lundh
  26. #
  27. # See the README file for information on usage and redistribution.
  28. #
  29. from . import Image
  30. from ._util import isPath
  31. import io
  32. import sys
  33. import struct
  34. MAXBLOCK = 65536
  35. SAFEBLOCK = 1024*1024
  36. LOAD_TRUNCATED_IMAGES = False
  37. ERRORS = {
  38. -1: "image buffer overrun error",
  39. -2: "decoding error",
  40. -3: "unknown error",
  41. -8: "bad configuration",
  42. -9: "out of memory error"
  43. }
  44. def raise_ioerror(error):
  45. try:
  46. message = Image.core.getcodecstatus(error)
  47. except AttributeError:
  48. message = ERRORS.get(error)
  49. if not message:
  50. message = "decoder error %d" % error
  51. raise IOError(message + " when reading image file")
  52. #
  53. # --------------------------------------------------------------------
  54. # Helpers
  55. def _tilesort(t):
  56. # sort on offset
  57. return t[2]
  58. #
  59. # --------------------------------------------------------------------
  60. # ImageFile base class
  61. class ImageFile(Image.Image):
  62. "Base class for image file format handlers."
  63. def __init__(self, fp=None, filename=None):
  64. Image.Image.__init__(self)
  65. self._min_frame = 0
  66. self.tile = None
  67. self.readonly = 1 # until we know better
  68. self.decoderconfig = ()
  69. self.decodermaxblock = MAXBLOCK
  70. if isPath(fp):
  71. # filename
  72. self.fp = open(fp, "rb")
  73. self.filename = fp
  74. self._exclusive_fp = True
  75. else:
  76. # stream
  77. self.fp = fp
  78. self.filename = filename
  79. # can be overridden
  80. self._exclusive_fp = None
  81. try:
  82. self._open()
  83. except (IndexError, # end of data
  84. TypeError, # end of data (ord)
  85. KeyError, # unsupported mode
  86. EOFError, # got header but not the first frame
  87. struct.error) as v:
  88. # close the file only if we have opened it this constructor
  89. if self._exclusive_fp:
  90. self.fp.close()
  91. raise SyntaxError(v)
  92. if not self.mode or self.size[0] <= 0:
  93. raise SyntaxError("not identified by this driver")
  94. def draft(self, mode, size):
  95. "Set draft mode"
  96. pass
  97. def get_format_mimetype(self):
  98. if self.format is None:
  99. return
  100. return Image.MIME.get(self.format.upper())
  101. def verify(self):
  102. "Check file integrity"
  103. # raise exception if something's wrong. must be called
  104. # directly after open, and closes file when finished.
  105. if self._exclusive_fp:
  106. self.fp.close()
  107. self.fp = None
  108. def load(self):
  109. "Load image data based on tile list"
  110. pixel = Image.Image.load(self)
  111. if self.tile is None:
  112. raise IOError("cannot load this image")
  113. if not self.tile:
  114. return pixel
  115. self.map = None
  116. use_mmap = self.filename and len(self.tile) == 1
  117. # As of pypy 2.1.0, memory mapping was failing here.
  118. use_mmap = use_mmap and not hasattr(sys, 'pypy_version_info')
  119. readonly = 0
  120. # look for read/seek overrides
  121. try:
  122. read = self.load_read
  123. # don't use mmap if there are custom read/seek functions
  124. use_mmap = False
  125. except AttributeError:
  126. read = self.fp.read
  127. try:
  128. seek = self.load_seek
  129. use_mmap = False
  130. except AttributeError:
  131. seek = self.fp.seek
  132. if use_mmap:
  133. # try memory mapping
  134. decoder_name, extents, offset, args = self.tile[0]
  135. if decoder_name == "raw" and len(args) >= 3 and \
  136. args[0] == self.mode and \
  137. args[0] in Image._MAPMODES:
  138. try:
  139. if hasattr(Image.core, "map"):
  140. # use built-in mapper WIN32 only
  141. self.map = Image.core.map(self.filename)
  142. self.map.seek(offset)
  143. self.im = self.map.readimage(
  144. self.mode, self.size, args[1], args[2]
  145. )
  146. else:
  147. # use mmap, if possible
  148. import mmap
  149. with open(self.filename, "r") as fp:
  150. self.map = mmap.mmap(fp.fileno(), 0,
  151. access=mmap.ACCESS_READ)
  152. self.im = Image.core.map_buffer(
  153. self.map, self.size, decoder_name, extents,
  154. offset, args)
  155. readonly = 1
  156. # After trashing self.im,
  157. # we might need to reload the palette data.
  158. if self.palette:
  159. self.palette.dirty = 1
  160. except (AttributeError, EnvironmentError, ImportError):
  161. self.map = None
  162. self.load_prepare()
  163. err_code = -3 # initialize to unknown error
  164. if not self.map:
  165. # sort tiles in file order
  166. self.tile.sort(key=_tilesort)
  167. try:
  168. # FIXME: This is a hack to handle TIFF's JpegTables tag.
  169. prefix = self.tile_prefix
  170. except AttributeError:
  171. prefix = b""
  172. for decoder_name, extents, offset, args in self.tile:
  173. decoder = Image._getdecoder(self.mode, decoder_name,
  174. args, self.decoderconfig)
  175. try:
  176. seek(offset)
  177. decoder.setimage(self.im, extents)
  178. if decoder.pulls_fd:
  179. decoder.setfd(self.fp)
  180. status, err_code = decoder.decode(b"")
  181. else:
  182. b = prefix
  183. while True:
  184. try:
  185. s = read(self.decodermaxblock)
  186. except (IndexError, struct.error):
  187. # truncated png/gif
  188. if LOAD_TRUNCATED_IMAGES:
  189. break
  190. else:
  191. raise IOError("image file is truncated")
  192. if not s: # truncated jpeg
  193. if LOAD_TRUNCATED_IMAGES:
  194. break
  195. else:
  196. self.tile = []
  197. raise IOError("image file is truncated "
  198. "(%d bytes not processed)" %
  199. len(b))
  200. b = b + s
  201. n, err_code = decoder.decode(b)
  202. if n < 0:
  203. break
  204. b = b[n:]
  205. finally:
  206. # Need to cleanup here to prevent leaks
  207. decoder.cleanup()
  208. self.tile = []
  209. self.readonly = readonly
  210. self.load_end()
  211. if self._exclusive_fp and self._close_exclusive_fp_after_loading:
  212. self.fp.close()
  213. self.fp = None
  214. if not self.map and not LOAD_TRUNCATED_IMAGES and err_code < 0:
  215. # still raised if decoder fails to return anything
  216. raise_ioerror(err_code)
  217. return Image.Image.load(self)
  218. def load_prepare(self):
  219. # create image memory if necessary
  220. if not self.im or\
  221. self.im.mode != self.mode or self.im.size != self.size:
  222. self.im = Image.core.new(self.mode, self.size)
  223. # create palette (optional)
  224. if self.mode == "P":
  225. Image.Image.load(self)
  226. def load_end(self):
  227. # may be overridden
  228. pass
  229. # may be defined for contained formats
  230. # def load_seek(self, pos):
  231. # pass
  232. # may be defined for blocked formats (e.g. PNG)
  233. # def load_read(self, bytes):
  234. # pass
  235. def _seek_check(self, frame):
  236. if (frame < self._min_frame or
  237. # Only check upper limit on frames if additional seek operations
  238. # are not required to do so
  239. (not (hasattr(self, "_n_frames") and self._n_frames is None) and
  240. frame >= self.n_frames+self._min_frame)):
  241. raise EOFError("attempt to seek outside sequence")
  242. return self.tell() != frame
  243. class StubImageFile(ImageFile):
  244. """
  245. Base class for stub image loaders.
  246. A stub loader is an image loader that can identify files of a
  247. certain format, but relies on external code to load the file.
  248. """
  249. def _open(self):
  250. raise NotImplementedError(
  251. "StubImageFile subclass must implement _open"
  252. )
  253. def load(self):
  254. loader = self._load()
  255. if loader is None:
  256. raise IOError("cannot find loader for this %s file" % self.format)
  257. image = loader.load(self)
  258. assert image is not None
  259. # become the other object (!)
  260. self.__class__ = image.__class__
  261. self.__dict__ = image.__dict__
  262. def _load(self):
  263. "(Hook) Find actual image loader."
  264. raise NotImplementedError(
  265. "StubImageFile subclass must implement _load"
  266. )
  267. class Parser(object):
  268. """
  269. Incremental image parser. This class implements the standard
  270. feed/close consumer interface.
  271. """
  272. incremental = None
  273. image = None
  274. data = None
  275. decoder = None
  276. offset = 0
  277. finished = 0
  278. def reset(self):
  279. """
  280. (Consumer) Reset the parser. Note that you can only call this
  281. method immediately after you've created a parser; parser
  282. instances cannot be reused.
  283. """
  284. assert self.data is None, "cannot reuse parsers"
  285. def feed(self, data):
  286. """
  287. (Consumer) Feed data to the parser.
  288. :param data: A string buffer.
  289. :exception IOError: If the parser failed to parse the image file.
  290. """
  291. # collect data
  292. if self.finished:
  293. return
  294. if self.data is None:
  295. self.data = data
  296. else:
  297. self.data = self.data + data
  298. # parse what we have
  299. if self.decoder:
  300. if self.offset > 0:
  301. # skip header
  302. skip = min(len(self.data), self.offset)
  303. self.data = self.data[skip:]
  304. self.offset = self.offset - skip
  305. if self.offset > 0 or not self.data:
  306. return
  307. n, e = self.decoder.decode(self.data)
  308. if n < 0:
  309. # end of stream
  310. self.data = None
  311. self.finished = 1
  312. if e < 0:
  313. # decoding error
  314. self.image = None
  315. raise_ioerror(e)
  316. else:
  317. # end of image
  318. return
  319. self.data = self.data[n:]
  320. elif self.image:
  321. # if we end up here with no decoder, this file cannot
  322. # be incrementally parsed. wait until we've gotten all
  323. # available data
  324. pass
  325. else:
  326. # attempt to open this file
  327. try:
  328. with io.BytesIO(self.data) as fp:
  329. im = Image.open(fp)
  330. except IOError:
  331. # traceback.print_exc()
  332. pass # not enough data
  333. else:
  334. flag = hasattr(im, "load_seek") or hasattr(im, "load_read")
  335. if flag or len(im.tile) != 1:
  336. # custom load code, or multiple tiles
  337. self.decode = None
  338. else:
  339. # initialize decoder
  340. im.load_prepare()
  341. d, e, o, a = im.tile[0]
  342. im.tile = []
  343. self.decoder = Image._getdecoder(
  344. im.mode, d, a, im.decoderconfig
  345. )
  346. self.decoder.setimage(im.im, e)
  347. # calculate decoder offset
  348. self.offset = o
  349. if self.offset <= len(self.data):
  350. self.data = self.data[self.offset:]
  351. self.offset = 0
  352. self.image = im
  353. def __enter__(self):
  354. return self
  355. def __exit__(self, *args):
  356. self.close()
  357. def close(self):
  358. """
  359. (Consumer) Close the stream.
  360. :returns: An image object.
  361. :exception IOError: If the parser failed to parse the image file either
  362. because it cannot be identified or cannot be
  363. decoded.
  364. """
  365. # finish decoding
  366. if self.decoder:
  367. # get rid of what's left in the buffers
  368. self.feed(b"")
  369. self.data = self.decoder = None
  370. if not self.finished:
  371. raise IOError("image was incomplete")
  372. if not self.image:
  373. raise IOError("cannot parse this image")
  374. if self.data:
  375. # incremental parsing not possible; reopen the file
  376. # not that we have all data
  377. with io.BytesIO(self.data) as fp:
  378. try:
  379. self.image = Image.open(fp)
  380. finally:
  381. self.image.load()
  382. return self.image
  383. # --------------------------------------------------------------------
  384. def _save(im, fp, tile, bufsize=0):
  385. """Helper to save image based on tile list
  386. :param im: Image object.
  387. :param fp: File object.
  388. :param tile: Tile list.
  389. :param bufsize: Optional buffer size
  390. """
  391. im.load()
  392. if not hasattr(im, "encoderconfig"):
  393. im.encoderconfig = ()
  394. tile.sort(key=_tilesort)
  395. # FIXME: make MAXBLOCK a configuration parameter
  396. # It would be great if we could have the encoder specify what it needs
  397. # But, it would need at least the image size in most cases. RawEncode is
  398. # a tricky case.
  399. bufsize = max(MAXBLOCK, bufsize, im.size[0] * 4) # see RawEncode.c
  400. if fp == sys.stdout:
  401. fp.flush()
  402. return
  403. try:
  404. fh = fp.fileno()
  405. fp.flush()
  406. except (AttributeError, io.UnsupportedOperation):
  407. # compress to Python file-compatible object
  408. for e, b, o, a in tile:
  409. e = Image._getencoder(im.mode, e, a, im.encoderconfig)
  410. if o > 0:
  411. fp.seek(o, 0)
  412. e.setimage(im.im, b)
  413. if e.pushes_fd:
  414. e.setfd(fp)
  415. l, s = e.encode_to_pyfd()
  416. else:
  417. while True:
  418. l, s, d = e.encode(bufsize)
  419. fp.write(d)
  420. if s:
  421. break
  422. if s < 0:
  423. raise IOError("encoder error %d when writing image file" % s)
  424. e.cleanup()
  425. else:
  426. # slight speedup: compress to real file object
  427. for e, b, o, a in tile:
  428. e = Image._getencoder(im.mode, e, a, im.encoderconfig)
  429. if o > 0:
  430. fp.seek(o, 0)
  431. e.setimage(im.im, b)
  432. if e.pushes_fd:
  433. e.setfd(fp)
  434. l, s = e.encode_to_pyfd()
  435. else:
  436. s = e.encode_to_file(fh, bufsize)
  437. if s < 0:
  438. raise IOError("encoder error %d when writing image file" % s)
  439. e.cleanup()
  440. if hasattr(fp, "flush"):
  441. fp.flush()
  442. def _safe_read(fp, size):
  443. """
  444. Reads large blocks in a safe way. Unlike fp.read(n), this function
  445. doesn't trust the user. If the requested size is larger than
  446. SAFEBLOCK, the file is read block by block.
  447. :param fp: File handle. Must implement a <b>read</b> method.
  448. :param size: Number of bytes to read.
  449. :returns: A string containing up to <i>size</i> bytes of data.
  450. """
  451. if size <= 0:
  452. return b""
  453. if size <= SAFEBLOCK:
  454. return fp.read(size)
  455. data = []
  456. while size > 0:
  457. block = fp.read(min(size, SAFEBLOCK))
  458. if not block:
  459. break
  460. data.append(block)
  461. size -= len(block)
  462. return b"".join(data)
  463. class PyCodecState(object):
  464. def __init__(self):
  465. self.xsize = 0
  466. self.ysize = 0
  467. self.xoff = 0
  468. self.yoff = 0
  469. def extents(self):
  470. return (self.xoff, self.yoff,
  471. self.xoff+self.xsize, self.yoff+self.ysize)
  472. class PyDecoder(object):
  473. """
  474. Python implementation of a format decoder. Override this class and
  475. add the decoding logic in the `decode` method.
  476. See :ref:`Writing Your Own File Decoder in Python<file-decoders-py>`
  477. """
  478. _pulls_fd = False
  479. def __init__(self, mode, *args):
  480. self.im = None
  481. self.state = PyCodecState()
  482. self.fd = None
  483. self.mode = mode
  484. self.init(args)
  485. def init(self, args):
  486. """
  487. Override to perform decoder specific initialization
  488. :param args: Array of args items from the tile entry
  489. :returns: None
  490. """
  491. self.args = args
  492. @property
  493. def pulls_fd(self):
  494. return self._pulls_fd
  495. def decode(self, buffer):
  496. """
  497. Override to perform the decoding process.
  498. :param buffer: A bytes object with the data to be decoded.
  499. If `handles_eof` is set, then `buffer` will be empty and `self.fd`
  500. will be set.
  501. :returns: A tuple of (bytes consumed, errcode).
  502. If finished with decoding return <0 for the bytes consumed.
  503. Err codes are from `ERRORS`
  504. """
  505. raise NotImplementedError()
  506. def cleanup(self):
  507. """
  508. Override to perform decoder specific cleanup
  509. :returns: None
  510. """
  511. pass
  512. def setfd(self, fd):
  513. """
  514. Called from ImageFile to set the python file-like object
  515. :param fd: A python file-like object
  516. :returns: None
  517. """
  518. self.fd = fd
  519. def setimage(self, im, extents=None):
  520. """
  521. Called from ImageFile to set the core output image for the decoder
  522. :param im: A core image object
  523. :param extents: a 4 tuple of (x0, y0, x1, y1) defining the rectangle
  524. for this tile
  525. :returns: None
  526. """
  527. # following c code
  528. self.im = im
  529. if extents:
  530. (x0, y0, x1, y1) = extents
  531. else:
  532. (x0, y0, x1, y1) = (0, 0, 0, 0)
  533. if x0 == 0 and x1 == 0:
  534. self.state.xsize, self.state.ysize = self.im.size
  535. else:
  536. self.state.xoff = x0
  537. self.state.yoff = y0
  538. self.state.xsize = x1 - x0
  539. self.state.ysize = y1 - y0
  540. if self.state.xsize <= 0 or self.state.ysize <= 0:
  541. raise ValueError("Size cannot be negative")
  542. if (self.state.xsize + self.state.xoff > self.im.size[0] or
  543. self.state.ysize + self.state.yoff > self.im.size[1]):
  544. raise ValueError("Tile cannot extend outside image")
  545. def set_as_raw(self, data, rawmode=None):
  546. """
  547. Convenience method to set the internal image from a stream of raw data
  548. :param data: Bytes to be set
  549. :param rawmode: The rawmode to be used for the decoder.
  550. If not specified, it will default to the mode of the image
  551. :returns: None
  552. """
  553. if not rawmode:
  554. rawmode = self.mode
  555. d = Image._getdecoder(self.mode, 'raw', (rawmode))
  556. d.setimage(self.im, self.state.extents())
  557. s = d.decode(data)
  558. if s[0] >= 0:
  559. raise ValueError("not enough image data")
  560. if s[1] != 0:
  561. raise ValueError("cannot decode image data")