Aluode/PerceptionLabPortable
0
1#
2# The Python Imaging Library.
3# $Id$
4#
5# the Image class wrapper
6#
7# partial release history:
8# 1995-09-09 fl Created
9# 1996-03-11 fl PIL release 0.0 (proof of concept)
10# 1996-04-30 fl PIL release 0.1b1
11# 1999-07-28 fl PIL release 1.0 final
12# 2000-06-07 fl PIL release 1.1
13# 2000-10-20 fl PIL release 1.1.1
14# 2001-05-07 fl PIL release 1.1.2
15# 2002-03-15 fl PIL release 1.1.3
16# 2003-05-10 fl PIL release 1.1.4
17# 2005-03-28 fl PIL release 1.1.5
18# 2006-12-02 fl PIL release 1.1.6
19# 2009-11-15 fl PIL release 1.1.7
20#
21# Copyright (c) 1997-2009 by Secret Labs AB. All rights reserved.
22# Copyright (c) 1995-2009 by Fredrik Lundh.
23#
24# See the README file for information on usage and redistribution.
25#
26
27from __future__ import annotations
28
29import abc
30import atexit
31import builtins
32import io
33import logging
34import math
35import os
36import re
37import struct
38import sys
39import tempfile
40import warnings
41from collections.abc import MutableMapping
42from enum import IntEnum
43from typing import IO, Protocol, cast
44
45# VERSION was removed in Pillow 6.0.0.
46# PILLOW_VERSION was removed in Pillow 9.0.0.
47# Use __version__ instead.
48from . import (
49 ExifTags,
50 ImageMode,
51 TiffTags,
52 UnidentifiedImageError,
53 __version__,
54 _plugins,
55)
56from ._binary import i32le, o32be, o32le
57from ._deprecate import deprecate
58from ._util import DeferredError, is_path
59
60ElementTree: ModuleType | None
61try:
62 from defusedxml import ElementTree
63except ImportError:
64 ElementTree = None
65
66TYPE_CHECKING = False
67if TYPE_CHECKING:
68 from collections.abc import Callable, Iterator, Sequence
69 from types import ModuleType
70 from typing import Any, Literal
71
72logger = logging.getLogger(__name__)
73
74
75class DecompressionBombWarning(RuntimeWarning):
76 pass
77
78
79class DecompressionBombError(Exception):
80 pass
81
82
83WARN_POSSIBLE_FORMATS: bool = False
84
85# Limit to around a quarter gigabyte for a 24-bit (3 bpp) image
86MAX_IMAGE_PIXELS: int | None = int(1024 * 1024 * 1024 // 4 // 3)
87
88
89try:
90 # If the _imaging C module is not present, Pillow will not load.
91 # Note that other modules should not refer to _imaging directly;
92 # import Image and use the Image.core variable instead.
93 # Also note that Image.core is not a publicly documented interface,
94 # and should be considered private and subject to change.
95 from . import _imaging as core
96
97 if __version__ != getattr(core, "PILLOW_VERSION", None):
98 msg = (
99 "The _imaging extension was built for another version of Pillow or PIL:\n"
100 f"Core version: {getattr(core, 'PILLOW_VERSION', None)}\n"
101 f"Pillow version: {__version__}"
102 )
103 raise ImportError(msg)
104
105except ImportError as v:
106 # Explanations for ways that we know we might have an import error
107 if str(v).startswith("Module use of python"):
108 # The _imaging C module is present, but not compiled for
109 # the right version (windows only). Print a warning, if
110 # possible.
111 warnings.warn(
112 "The _imaging extension was built for another version of Python.",
113 RuntimeWarning,
114 )
115 elif str(v).startswith("The _imaging extension"):
116 warnings.warn(str(v), RuntimeWarning)
117 # Fail here anyway. Don't let people run with a mostly broken Pillow.
118 # see docs/porting.rst
119 raise
120
121
122#
123# Constants
124
125
126# transpose
127class Transpose(IntEnum):
128 FLIP_LEFT_RIGHT = 0
129 FLIP_TOP_BOTTOM = 1
130 ROTATE_90 = 2
131 ROTATE_180 = 3
132 ROTATE_270 = 4
133 TRANSPOSE = 5
134 TRANSVERSE = 6
135
136
137# transforms (also defined in Imaging.h)
138class Transform(IntEnum):
139 AFFINE = 0
140 EXTENT = 1
141 PERSPECTIVE = 2
142 QUAD = 3
143 MESH = 4
144
145
146# resampling filters (also defined in Imaging.h)
147class Resampling(IntEnum):
148 NEAREST = 0
149 BOX = 4
150 BILINEAR = 2
151 HAMMING = 5
152 BICUBIC = 3
153 LANCZOS = 1
154
155
156_filters_support = {
157 Resampling.BOX: 0.5,
158 Resampling.BILINEAR: 1.0,
159 Resampling.HAMMING: 1.0,
160 Resampling.BICUBIC: 2.0,
161 Resampling.LANCZOS: 3.0,
162}
163
164
165# dithers
166class Dither(IntEnum):
167 NONE = 0
168 ORDERED = 1 # Not yet implemented
169 RASTERIZE = 2 # Not yet implemented
170 FLOYDSTEINBERG = 3 # default
171
172
173# palettes/quantizers
174class Palette(IntEnum):
175 WEB = 0
176 ADAPTIVE = 1
177
178
179class Quantize(IntEnum):
180 MEDIANCUT = 0
181 MAXCOVERAGE = 1
182 FASTOCTREE = 2
183 LIBIMAGEQUANT = 3
184
185
186module = sys.modules[__name__]
187for enum in (Transpose, Transform, Resampling, Dither, Palette, Quantize):
188 for item in enum:
189 setattr(module, item.name, item.value)
190
191
192if hasattr(core, "DEFAULT_STRATEGY"):
193 DEFAULT_STRATEGY = core.DEFAULT_STRATEGY
194 FILTERED = core.FILTERED
195 HUFFMAN_ONLY = core.HUFFMAN_ONLY
196 RLE = core.RLE
197 FIXED = core.FIXED
198
199
200# --------------------------------------------------------------------
201# Registries
202
203TYPE_CHECKING = False
204if TYPE_CHECKING:
205 import mmap
206 from xml.etree.ElementTree import Element
207
208 from IPython.lib.pretty import PrettyPrinter
209
210 from . import ImageFile, ImageFilter, ImagePalette, ImageQt, TiffImagePlugin
211 from ._typing import CapsuleType, NumpyArray, StrOrBytesPath
212ID: list[str] = []
213OPEN: dict[
214 str,
215 tuple[
216 Callable[[IO[bytes], str | bytes], ImageFile.ImageFile],
217 Callable[[bytes], bool | str] | None,
218 ],
219] = {}
220MIME: dict[str, str] = {}
221SAVE: dict[str, Callable[[Image, IO[bytes], str | bytes], None]] = {}
222SAVE_ALL: dict[str, Callable[[Image, IO[bytes], str | bytes], None]] = {}
223EXTENSION: dict[str, str] = {}
224DECODERS: dict[str, type[ImageFile.PyDecoder]] = {}
225ENCODERS: dict[str, type[ImageFile.PyEncoder]] = {}
226
227# --------------------------------------------------------------------
228# Modes
229
230_ENDIAN = "<" if sys.byteorder == "little" else ">"
231
232
233def _conv_type_shape(im: Image) -> tuple[tuple[int, ...], str]:
234 m = ImageMode.getmode(im.mode)
235 shape: tuple[int, ...] = (im.height, im.width)
236 extra = len(m.bands)
237 if extra != 1:
238 shape += (extra,)
239 return shape, m.typestr
240
241
242MODES = [
243 "1",
244 "CMYK",
245 "F",
246 "HSV",
247 "I",
248 "I;16",
249 "I;16B",
250 "I;16L",
251 "I;16N",
252 "L",
253 "LA",
254 "La",
255 "LAB",
256 "P",
257 "PA",
258 "RGB",
259 "RGBA",
260 "RGBa",
261 "RGBX",
262 "YCbCr",
263]
264
265# raw modes that may be memory mapped. NOTE: if you change this, you
266# may have to modify the stride calculation in map.c too!
267_MAPMODES = ("L", "P", "RGBX", "RGBA", "CMYK", "I;16", "I;16L", "I;16B")
268
269
270def getmodebase(mode: str) -> str:
271 """
272 Gets the "base" mode for given mode. This function returns "L" for
273 images that contain grayscale data, and "RGB" for images that
274 contain color data.
275
276 :param mode: Input mode.
277 :returns: "L" or "RGB".
278 :exception KeyError: If the input mode was not a standard mode.
279 """
280 return ImageMode.getmode(mode).basemode
281
282
283def getmodetype(mode: str) -> str:
284 """
285 Gets the storage type mode. Given a mode, this function returns a
286 single-layer mode suitable for storing individual bands.
287
288 :param mode: Input mode.
289 :returns: "L", "I", or "F".
290 :exception KeyError: If the input mode was not a standard mode.
291 """
292 return ImageMode.getmode(mode).basetype
293
294
295def getmodebandnames(mode: str) -> tuple[str, ...]:
296 """
297 Gets a list of individual band names. Given a mode, this function returns
298 a tuple containing the names of individual bands (use
299 :py:method:`~PIL.Image.getmodetype` to get the mode used to store each
300 individual band.
301
302 :param mode: Input mode.
303 :returns: A tuple containing band names. The length of the tuple
304 gives the number of bands in an image of the given mode.
305 :exception KeyError: If the input mode was not a standard mode.
306 """
307 return ImageMode.getmode(mode).bands
308
309
310def getmodebands(mode: str) -> int:
311 """
312 Gets the number of individual bands for this mode.
313
314 :param mode: Input mode.
315 :returns: The number of bands in this mode.
316 :exception KeyError: If the input mode was not a standard mode.
317 """
318 return len(ImageMode.getmode(mode).bands)
319
320
321# --------------------------------------------------------------------
322# Helpers
323
324_initialized = 0
325
326
327def preinit() -> None:
328 """
329 Explicitly loads BMP, GIF, JPEG, PPM and PPM file format drivers.
330
331 It is called when opening or saving images.
332 """
333
334 global _initialized
335 if _initialized >= 1:
336 return
337
338 try:
339 from . import BmpImagePlugin
340
341 assert BmpImagePlugin
342 except ImportError:
343 pass
344 try:
345 from . import GifImagePlugin
346
347 assert GifImagePlugin
348 except ImportError:
349 pass
350 try:
351 from . import JpegImagePlugin
352
353 assert JpegImagePlugin
354 except ImportError:
355 pass
356 try:
357 from . import PpmImagePlugin
358
359 assert PpmImagePlugin
360 except ImportError:
361 pass
362 try:
363 from . import PngImagePlugin
364
365 assert PngImagePlugin
366 except ImportError:
367 pass
368
369 _initialized = 1
370
371
372def init() -> bool:
373 """
374 Explicitly initializes the Python Imaging Library. This function
375 loads all available file format drivers.
376
377 It is called when opening or saving images if :py:meth:`~preinit()` is
378 insufficient, and by :py:meth:`~PIL.features.pilinfo`.
379 """
380
381 global _initialized
382 if _initialized >= 2:
383 return False
384
385 parent_name = __name__.rpartition(".")[0]
386 for plugin in _plugins:
387 try:
388 logger.debug("Importing %s", plugin)
389 __import__(f"{parent_name}.{plugin}", globals(), locals(), [])
390 except ImportError as e:
391 logger.debug("Image: failed to import %s: %s", plugin, e)
392
393 if OPEN or SAVE:
394 _initialized = 2
395 return True
396 return False
397
398
399# --------------------------------------------------------------------
400# Codec factories (used by tobytes/frombytes and ImageFile.load)
401
402
403def _getdecoder(
404 mode: str, decoder_name: str, args: Any, extra: tuple[Any, ...] = ()
405) -> core.ImagingDecoder | ImageFile.PyDecoder:
406 # tweak arguments
407 if args is None:
408 args = ()
409 elif not isinstance(args, tuple):
410 args = (args,)
411
412 try:
413 decoder = DECODERS[decoder_name]
414 except KeyError:
415 pass
416 else:
417 return decoder(mode, *args + extra)
418
419 try:
420 # get decoder
421 decoder = getattr(core, f"{decoder_name}_decoder")
422 except AttributeError as e:
423 msg = f"decoder {decoder_name} not available"
424 raise OSError(msg) from e
425 return decoder(mode, *args + extra)
426
427
428def _getencoder(
429 mode: str, encoder_name: str, args: Any, extra: tuple[Any, ...] = ()
430) -> core.ImagingEncoder | ImageFile.PyEncoder:
431 # tweak arguments
432 if args is None:
433 args = ()
434 elif not isinstance(args, tuple):
435 args = (args,)
436
437 try:
438 encoder = ENCODERS[encoder_name]
439 except KeyError:
440 pass
441 else:
442 return encoder(mode, *args + extra)
443
444 try:
445 # get encoder
446 encoder = getattr(core, f"{encoder_name}_encoder")
447 except AttributeError as e:
448 msg = f"encoder {encoder_name} not available"
449 raise OSError(msg) from e
450 return encoder(mode, *args + extra)
451
452
453# --------------------------------------------------------------------
454# Simple expression analyzer
455
456
457class ImagePointTransform:
458 """
459 Used with :py:meth:`~PIL.Image.Image.point` for single band images with more than
460 8 bits, this represents an affine transformation, where the value is multiplied by
461 ``scale`` and ``offset`` is added.
462 """
463
464 def __init__(self, scale: float, offset: float) -> None:
465 self.scale = scale
466 self.offset = offset
467
468 def __neg__(self) -> ImagePointTransform:
469 return ImagePointTransform(-self.scale, -self.offset)
470
471 def __add__(self, other: ImagePointTransform | float) -> ImagePointTransform:
472 if isinstance(other, ImagePointTransform):
473 return ImagePointTransform(
474 self.scale + other.scale, self.offset + other.offset
475 )
476 return ImagePointTransform(self.scale, self.offset + other)
477
478 __radd__ = __add__
479
480 def __sub__(self, other: ImagePointTransform | float) -> ImagePointTransform:
481 return self + -other
482
483 def __rsub__(self, other: ImagePointTransform | float) -> ImagePointTransform:
484 return other + -self
485
486 def __mul__(self, other: ImagePointTransform | float) -> ImagePointTransform:
487 if isinstance(other, ImagePointTransform):
488 return NotImplemented
489 return ImagePointTransform(self.scale * other, self.offset * other)
490
491 __rmul__ = __mul__
492
493 def __truediv__(self, other: ImagePointTransform | float) -> ImagePointTransform:
494 if isinstance(other, ImagePointTransform):
495 return NotImplemented
496 return ImagePointTransform(self.scale / other, self.offset / other)
497
498
499def _getscaleoffset(
500 expr: Callable[[ImagePointTransform], ImagePointTransform | float],
501) -> tuple[float, float]:
502 a = expr(ImagePointTransform(1, 0))
503 return (a.scale, a.offset) if isinstance(a, ImagePointTransform) else (0, a)
504
505
506# --------------------------------------------------------------------
507# Implementation wrapper
508
509
510class SupportsGetData(Protocol):
511 def getdata(
512 self,
513 ) -> tuple[Transform, Sequence[int]]: ...
514
515
516class Image:
517 """
518 This class represents an image object. To create
519 :py:class:`~PIL.Image.Image` objects, use the appropriate factory
520 functions. There's hardly ever any reason to call the Image constructor
521 directly.
522
523 * :py:func:`~PIL.Image.open`
524 * :py:func:`~PIL.Image.new`
525 * :py:func:`~PIL.Image.frombytes`
526 """
527
528 format: str | None = None
529 format_description: str | None = None
530 _close_exclusive_fp_after_loading = True
531
532 def __init__(self) -> None:
533 # FIXME: take "new" parameters / other image?
534 self._im: core.ImagingCore | DeferredError | None = None
535 self._mode = ""
536 self._size = (0, 0)
537 self.palette: ImagePalette.ImagePalette | None = None
538 self.info: dict[str | tuple[int, int], Any] = {}
539 self.readonly = 0
540 self._exif: Exif | None = None
541
542 @property
543 def im(self) -> core.ImagingCore:
544 if isinstance(self._im, DeferredError):
545 raise self._im.ex
546 assert self._im is not None
547 return self._im
548
549 @im.setter
550 def im(self, im: core.ImagingCore) -> None:
551 self._im = im
552
553 @property
554 def width(self) -> int:
555 return self.size[0]
556
557 @property
558 def height(self) -> int:
559 return self.size[1]
560
561 @property
562 def size(self) -> tuple[int, int]:
563 return self._size
564
565 @property
566 def mode(self) -> str:
567 return self._mode
568
569 @property
570 def readonly(self) -> int:
571 return (self._im and self._im.readonly) or self._readonly
572
573 @readonly.setter
574 def readonly(self, readonly: int) -> None:
575 self._readonly = readonly
576
577 def _new(self, im: core.ImagingCore) -> Image:
578 new = Image()
579 new.im = im
580 new._mode = im.mode
581 new._size = im.size
582 if im.mode in ("P", "PA"):
583 if self.palette:
584 new.palette = self.palette.copy()
585 else:
586 from . import ImagePalette
587
588 new.palette = ImagePalette.ImagePalette()
589 new.info = self.info.copy()
590 return new
591
592 # Context manager support
593 def __enter__(self) -> Image:
594 return self
595
596 def __exit__(self, *args: object) -> None:
597 pass
598
599 def close(self) -> None:
600 """
601 This operation will destroy the image core and release its memory.
602 The image data will be unusable afterward.
603
604 This function is required to close images that have multiple frames or
605 have not had their file read and closed by the
606 :py:meth:`~PIL.Image.Image.load` method. See :ref:`file-handling` for
607 more information.
608 """
609 if getattr(self, "map", None):
610 if sys.platform == "win32" and hasattr(sys, "pypy_version_info"):
611 self.map.close()
612 self.map: mmap.mmap | None = None
613
614 # Instead of simply setting to None, we're setting up a
615 # deferred error that will better explain that the core image
616 # object is gone.
617 self._im = DeferredError(ValueError("Operation on closed image"))
618
619 def _copy(self) -> None:
620 self.load()
621 self.im = self.im.copy()
622 self.readonly = 0
623
624 def _ensure_mutable(self) -> None:
625 if self.readonly:
626 self._copy()
627 else:
628 self.load()
629
630 def _dump(
631 self, file: str | None = None, format: str | None = None, **options: Any
632 ) -> str:
633 suffix = ""
634 if format:
635 suffix = f".{format}"
636
637 if not file:
638 f, filename = tempfile.mkstemp(suffix)
639 os.close(f)
640 else:
641 filename = file
642 if not filename.endswith(suffix):
643 filename = filename + suffix
644
645 self.load()
646
647 if not format or format == "PPM":
648 self.im.save_ppm(filename)
649 else:
650 self.save(filename, format, **options)
651
652 return filename
653
654 def __eq__(self, other: object) -> bool:
655 if self.__class__ is not other.__class__:
656 return False
657 assert isinstance(other, Image)
658 return (
659 self.mode == other.mode
660 and self.size == other.size
661 and self.info == other.info
662 and self.getpalette() == other.getpalette()
663 and self.tobytes() == other.tobytes()
664 )
665
666 def __repr__(self) -> str:
667 return (
668 f"<{self.__class__.__module__}.{self.__class__.__name__} "
669 f"image mode={self.mode} size={self.size[0]}x{self.size[1]} "
670 f"at 0x{id(self):X}>"
671 )
672
673 def _repr_pretty_(self, p: PrettyPrinter, cycle: bool) -> None:
674 """IPython plain text display support"""
675
676 # Same as __repr__ but without unpredictable id(self),
677 # to keep Jupyter notebook `text/plain` output stable.
678 p.text(
679 f"<{self.__class__.__module__}.{self.__class__.__name__} "
680 f"image mode={self.mode} size={self.size[0]}x{self.size[1]}>"
681 )
682
683 def _repr_image(self, image_format: str, **kwargs: Any) -> bytes | None:
684 """Helper function for iPython display hook.
685
686 :param image_format: Image format.
687 :returns: image as bytes, saved into the given format.
688 """
689 b = io.BytesIO()
690 try:
691 self.save(b, image_format, **kwargs)
692 except Exception:
693 return None
694 return b.getvalue()
695
696 def _repr_png_(self) -> bytes | None:
697 """iPython display hook support for PNG format.
698
699 :returns: PNG version of the image as bytes
700 """
701 return self._repr_image("PNG", compress_level=1)
702
703 def _repr_jpeg_(self) -> bytes | None:
704 """iPython display hook support for JPEG format.
705
706 :returns: JPEG version of the image as bytes
707 """
708 return self._repr_image("JPEG")
709
710 @property
711 def __array_interface__(self) -> dict[str, str | bytes | int | tuple[int, ...]]:
712 # numpy array interface support
713 new: dict[str, str | bytes | int | tuple[int, ...]] = {"version": 3}
714 if self.mode == "1":
715 # Binary images need to be extended from bits to bytes
716 # See: https://github.com/python-pillow/Pillow/issues/350
717 new["data"] = self.tobytes("raw", "L")
718 else:
719 new["data"] = self.tobytes()
720 new["shape"], new["typestr"] = _conv_type_shape(self)
721 return new
722
723 def __arrow_c_schema__(self) -> object:
724 self.load()
725 return self.im.__arrow_c_schema__()
726
727 def __arrow_c_array__(
728 self, requested_schema: object | None = None
729 ) -> tuple[object, object]:
730 self.load()
731 return (self.im.__arrow_c_schema__(), self.im.__arrow_c_array__())
732
733 def __getstate__(self) -> list[Any]:
734 im_data = self.tobytes() # load image first
735 return [self.info, self.mode, self.size, self.getpalette(), im_data]
736
737 def __setstate__(self, state: list[Any]) -> None:
738 Image.__init__(self)
739 info, mode, size, palette, data = state[:5]
740 self.info = info
741 self._mode = mode
742 self._size = size
743 self.im = core.new(mode, size)
744 if mode in ("L", "LA", "P", "PA") and palette:
745 self.putpalette(palette)
746 self.frombytes(data)
747
748 def tobytes(self, encoder_name: str = "raw", *args: Any) -> bytes:
749 """
750 Return image as a bytes object.
751
752 .. warning::
753
754 This method returns raw image data derived from Pillow's internal
755 storage. For compressed image data (e.g. PNG, JPEG) use
756 :meth:`~.save`, with a BytesIO parameter for in-memory data.
757
758 :param encoder_name: What encoder to use.
759
760 The default is to use the standard "raw" encoder.
761 To see how this packs pixel data into the returned
762 bytes, see :file:`libImaging/Pack.c`.
763
764 A list of C encoders can be seen under codecs
765 section of the function array in
766 :file:`_imaging.c`. Python encoders are registered
767 within the relevant plugins.
768 :param args: Extra arguments to the encoder.
769 :returns: A :py:class:`bytes` object.
770 """
771
772 encoder_args: Any = args
773 if len(encoder_args) == 1 and isinstance(encoder_args[0], tuple):
774 # may pass tuple instead of argument list
775 encoder_args = encoder_args[0]
776
777 if encoder_name == "raw" and encoder_args == ():
778 encoder_args = self.mode
779
780 self.load()
781
782 if self.width == 0 or self.height == 0:
783 return b""
784
785 # unpack data
786 e = _getencoder(self.mode, encoder_name, encoder_args)
787 e.setimage(self.im)
788
789 from . import ImageFile
790
791 bufsize = max(ImageFile.MAXBLOCK, self.size[0] * 4) # see RawEncode.c
792
793 output = []
794 while True:
795 bytes_consumed, errcode, data = e.encode(bufsize)
796 output.append(data)
797 if errcode:
798 break
799 if errcode < 0:
800 msg = f"encoder error {errcode} in tobytes"
801 raise RuntimeError(msg)
802
803 return b"".join(output)
804
805 def tobitmap(self, name: str = "image") -> bytes:
806 """
807 Returns the image converted to an X11 bitmap.
808
809 .. note:: This method only works for mode "1" images.
810
811 :param name: The name prefix to use for the bitmap variables.
812 :returns: A string containing an X11 bitmap.
813 :raises ValueError: If the mode is not "1"
814 """
815
816 self.load()
817 if self.mode != "1":
818 msg = "not a bitmap"
819 raise ValueError(msg)
820 data = self.tobytes("xbm")
821 return b"".join(
822 [
823 f"#define {name}_width {self.size[0]}\n".encode("ascii"),
824 f"#define {name}_height {self.size[1]}\n".encode("ascii"),
825 f"static char {name}_bits[] = {{\n".encode("ascii"),
826 data,
827 b"};",
828 ]
829 )
830
831 def frombytes(
832 self,
833 data: bytes | bytearray | SupportsArrayInterface,
834 decoder_name: str = "raw",
835 *args: Any,
836 ) -> None:
837 """
838 Loads this image with pixel data from a bytes object.
839
840 This method is similar to the :py:func:`~PIL.Image.frombytes` function,
841 but loads data into this image instead of creating a new image object.
842 """
843
844 if self.width == 0 or self.height == 0:
845 return
846
847 decoder_args: Any = args
848 if len(decoder_args) == 1 and isinstance(decoder_args[0], tuple):
849 # may pass tuple instead of argument list
850 decoder_args = decoder_args[0]
851
852 # default format
853 if decoder_name == "raw" and decoder_args == ():
854 decoder_args = self.mode
855
856 # unpack data
857 d = _getdecoder(self.mode, decoder_name, decoder_args)
858 d.setimage(self.im)
859 s = d.decode(data)
860
861 if s[0] >= 0:
862 msg = "not enough image data"
863 raise ValueError(msg)
864 if s[1] != 0:
865 msg = "cannot decode image data"
866 raise ValueError(msg)
867
868 def load(self) -> core.PixelAccess | None:
869 """
870 Allocates storage for the image and loads the pixel data. In
871 normal cases, you don't need to call this method, since the
872 Image class automatically loads an opened image when it is
873 accessed for the first time.
874
875 If the file associated with the image was opened by Pillow, then this
876 method will close it. The exception to this is if the image has
877 multiple frames, in which case the file will be left open for seek
878 operations. See :ref:`file-handling` for more information.
879
880 :returns: An image access object.
881 :rtype: :py:class:`.PixelAccess`
882 """
883 if self._im is not None and self.palette and self.palette.dirty:
884 # realize palette
885 mode, arr = self.palette.getdata()
886 self.im.putpalette(self.palette.mode, mode, arr)
887 self.palette.dirty = 0
888 self.palette.rawmode = None
889 if "transparency" in self.info and mode in ("LA", "PA"):
890 if isinstance(self.info["transparency"], int):
891 self.im.putpalettealpha(self.info["transparency"], 0)
892 else:
893 self.im.putpalettealphas(self.info["transparency"])
894 self.palette.mode = "RGBA"
895 else:
896 self.palette.palette = self.im.getpalette(
897 self.palette.mode, self.palette.mode
898 )
899
900 if self._im is not None:
901 return self.im.pixel_access(self.readonly)
902 return None
903
904 def verify(self) -> None:
905 """
906 Verifies the contents of a file. For data read from a file, this
907 method attempts to determine if the file is broken, without
908 actually decoding the image data. If this method finds any
909 problems, it raises suitable exceptions. If you need to load
910 the image after using this method, you must reopen the image
911 file.
912 """
913 pass
914
915 def convert(
916 self,
917 mode: str | None = None,
918 matrix: tuple[float, ...] | None = None,
919 dither: Dither | None = None,
920 palette: Palette = Palette.WEB,
921 colors: int = 256,
922 ) -> Image:
923 """
924 Returns a converted copy of this image. For the "P" mode, this
925 method translates pixels through the palette. If mode is
926 omitted, a mode is chosen so that all information in the image
927 and the palette can be represented without a palette.
928
929 This supports all possible conversions between "L", "RGB" and "CMYK". The
930 ``matrix`` argument only supports "L" and "RGB".
931
932 When translating a color image to grayscale (mode "L"),
933 the library uses the ITU-R 601-2 luma transform::
934
935 L = R * 299/1000 + G * 587/1000 + B * 114/1000
936
937 The default method of converting a grayscale ("L") or "RGB"
938 image into a bilevel (mode "1") image uses Floyd-Steinberg
939 dither to approximate the original image luminosity levels. If
940 dither is ``None``, all values larger than 127 are set to 255 (white),
941 all other values to 0 (black). To use other thresholds, use the
942 :py:meth:`~PIL.Image.Image.point` method.
943
944 When converting from "RGBA" to "P" without a ``matrix`` argument,
945 this passes the operation to :py:meth:`~PIL.Image.Image.quantize`,
946 and ``dither`` and ``palette`` are ignored.
947
948 When converting from "PA", if an "RGBA" palette is present, the alpha
949 channel from the image will be used instead of the values from the palette.
950
951 :param mode: The requested mode. See: :ref:`concept-modes`.
952 :param matrix: An optional conversion matrix. If given, this
953 should be 4- or 12-tuple containing floating point values.
954 :param dither: Dithering method, used when converting from
955 mode "RGB" to "P" or from "RGB" or "L" to "1".
956 Available methods are :data:`Dither.NONE` or :data:`Dither.FLOYDSTEINBERG`
957 (default). Note that this is not used when ``matrix`` is supplied.
958 :param palette: Palette to use when converting from mode "RGB"
959 to "P". Available palettes are :data:`Palette.WEB` or
960 :data:`Palette.ADAPTIVE`.
961 :param colors: Number of colors to use for the :data:`Palette.ADAPTIVE`
962 palette. Defaults to 256.
963 :rtype: :py:class:`~PIL.Image.Image`
964 :returns: An :py:class:`~PIL.Image.Image` object.
965 """
966
967 self.load()
968
969 has_transparency = "transparency" in self.info
970 if not mode and self.mode == "P":
971 # determine default mode
972 if self.palette:
973 mode = self.palette.mode
974 else:
975 mode = "RGB"
976 if mode == "RGB" and has_transparency:
977 mode = "RGBA"
978 if not mode or (mode == self.mode and not matrix):
979 return self.copy()
980
981 if matrix:
982 # matrix conversion
983 if mode not in ("L", "RGB"):
984 msg = "illegal conversion"
985 raise ValueError(msg)
986 im = self.im.convert_matrix(mode, matrix)
987 new_im = self._new(im)
988 if has_transparency and self.im.bands == 3:
989 transparency = new_im.info["transparency"]
990
991 def convert_transparency(
992 m: tuple[float, ...], v: tuple[int, int, int]
993 ) -> int:
994 value = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3] * 0.5
995 return max(0, min(255, int(value)))
996
997 if mode == "L":
998 transparency = convert_transparency(matrix, transparency)
999 elif len(mode) == 3:
1000 transparency = tuple(
1001 convert_transparency(matrix[i * 4 : i * 4 + 4], transparency)
1002 for i in range(len(transparency))
1003 )
1004 new_im.info["transparency"] = transparency
1005 return new_im
1006
1007 if self.mode == "RGBA":
1008 if mode == "P":
1009 return self.quantize(colors)
1010 elif mode == "PA":
1011 r, g, b, a = self.split()
1012 rgb = merge("RGB", (r, g, b))
1013 p = rgb.quantize(colors)
1014 return merge("PA", (p, a))
1015
1016 trns = None
1017 delete_trns = False
1018 # transparency handling
1019 if has_transparency:
1020 if (self.mode in ("1", "L", "I", "I;16") and mode in ("LA", "RGBA")) or (
1021 self.mode == "RGB" and mode in ("La", "LA", "RGBa", "RGBA")
1022 ):
1023 # Use transparent conversion to promote from transparent
1024 # color to an alpha channel.
1025 new_im = self._new(
1026 self.im.convert_transparent(mode, self.info["transparency"])
1027 )
1028 del new_im.info["transparency"]
1029 return new_im
1030 elif self.mode in ("L", "RGB", "P") and mode in ("L", "RGB", "P"):
1031 t = self.info["transparency"]
1032 if isinstance(t, bytes):
1033 # Dragons. This can't be represented by a single color
1034 warnings.warn(
1035 "Palette images with Transparency expressed in bytes should be "
1036 "converted to RGBA images"
1037 )
1038 delete_trns = True
1039 else:
1040 # get the new transparency color.
1041 # use existing conversions
1042 trns_im = new(self.mode, (1, 1))
1043 if self.mode == "P":
1044 assert self.palette is not None
1045 trns_im.putpalette(self.palette, self.palette.mode)
1046 if isinstance(t, tuple):
1047 err = "Couldn't allocate a palette color for transparency"
1048 assert trns_im.palette is not None
1049 try:
1050 t = trns_im.palette.getcolor(t, self)
1051 except ValueError as e:
1052 if str(e) == "cannot allocate more than 256 colors":
1053 # If all 256 colors are in use,
1054 # then there is no need for transparency
1055 t = None
1056 else:
1057 raise ValueError(err) from e
1058 if t is None:
1059 trns = None
1060 else:
1061 trns_im.putpixel((0, 0), t)
1062
1063 if mode in ("L", "RGB"):
1064 trns_im = trns_im.convert(mode)
1065 else:
1066 # can't just retrieve the palette number, got to do it
1067 # after quantization.
1068 trns_im = trns_im.convert("RGB")
1069 trns = trns_im.getpixel((0, 0))
1070
1071 elif self.mode == "P" and mode in ("LA", "PA", "RGBA"):
1072 t = self.info["transparency"]
1073 delete_trns = True
1074
1075 if isinstance(t, bytes):
1076 self.im.putpalettealphas(t)
1077 elif isinstance(t, int):
1078 self.im.putpalettealpha(t, 0)
1079 else:
1080 msg = "Transparency for P mode should be bytes or int"
1081 raise ValueError(msg)
1082
1083 if mode == "P" and palette == Palette.ADAPTIVE:
1084 im = self.im.quantize(colors)
1085 new_im = self._new(im)
1086 from . import ImagePalette
1087
1088 new_im.palette = ImagePalette.ImagePalette(
1089 "RGB", new_im.im.getpalette("RGB")
1090 )
1091 if delete_trns:
1092 # This could possibly happen if we requantize to fewer colors.
1093 # The transparency would be totally off in that case.
1094 del new_im.info["transparency"]
1095 if trns is not None:
1096 try:
1097 new_im.info["transparency"] = new_im.palette.getcolor(
1098 cast(tuple[int, ...], trns), # trns was converted to RGB
1099 new_im,
1100 )
1101 except Exception:
1102 # if we can't make a transparent color, don't leave the old
1103 # transparency hanging around to mess us up.
1104 del new_im.info["transparency"]
1105 warnings.warn("Couldn't allocate palette entry for transparency")
1106 return new_im
1107
1108 if "LAB" in (self.mode, mode):
1109 im = self
1110 if mode == "LAB":
1111 if im.mode not in ("RGB", "RGBA", "RGBX"):
1112 im = im.convert("RGBA")
1113 other_mode = im.mode
1114 else:
1115 other_mode = mode
1116 if other_mode in ("RGB", "RGBA", "RGBX"):
1117 from . import ImageCms
1118
1119 srgb = ImageCms.createProfile("sRGB")
1120 lab = ImageCms.createProfile("LAB")
1121 profiles = [lab, srgb] if im.mode == "LAB" else [srgb, lab]
1122 transform = ImageCms.buildTransform(
1123 profiles[0], profiles[1], im.mode, mode
1124 )
1125 return transform.apply(im)
1126
1127 # colorspace conversion
1128 if dither is None:
1129 dither = Dither.FLOYDSTEINBERG
1130
1131 try:
1132 im = self.im.convert(mode, dither)
1133 except ValueError:
1134 try:
1135 # normalize source image and try again
1136 modebase = getmodebase(self.mode)
1137 if modebase == self.mode:
1138 raise
1139 im = self.im.convert(modebase)
1140 im = im.convert(mode, dither)
1141 except KeyError as e:
1142 msg = "illegal conversion"
1143 raise ValueError(msg) from e
1144
1145 new_im = self._new(im)
1146 if mode in ("P", "PA") and palette != Palette.ADAPTIVE:
1147 from . import ImagePalette
1148
1149 new_im.palette = ImagePalette.ImagePalette("RGB", im.getpalette("RGB"))
1150 if delete_trns:
1151 # crash fail if we leave a bytes transparency in an rgb/l mode.
1152 del new_im.info["transparency"]
1153 if trns is not None:
1154 if new_im.mode == "P" and new_im.palette:
1155 try:
1156 new_im.info["transparency"] = new_im.palette.getcolor(
1157 cast(tuple[int, ...], trns), new_im # trns was converted to RGB
1158 )
1159 except ValueError as e:
1160 del new_im.info["transparency"]
1161 if str(e) != "cannot allocate more than 256 colors":
1162 # If all 256 colors are in use,
1163 # then there is no need for transparency
1164 warnings.warn(
1165 "Couldn't allocate palette entry for transparency"
1166 )
1167 else:
1168 new_im.info["transparency"] = trns
1169 return new_im
1170
1171 def quantize(
1172 self,
1173 colors: int = 256,
1174 method: int | None = None,
1175 kmeans: int = 0,
1176 palette: Image | None = None,
1177 dither: Dither = Dither.FLOYDSTEINBERG,
1178 ) -> Image:
1179 """
1180 Convert the image to 'P' mode with the specified number
1181 of colors.
1182
1183 :param colors: The desired number of colors, <= 256
1184 :param method: :data:`Quantize.MEDIANCUT` (median cut),
1185 :data:`Quantize.MAXCOVERAGE` (maximum coverage),
1186 :data:`Quantize.FASTOCTREE` (fast octree),
1187 :data:`Quantize.LIBIMAGEQUANT` (libimagequant; check support
1188 using :py:func:`PIL.features.check_feature` with
1189 ``feature="libimagequant"``).
1190
1191 By default, :data:`Quantize.MEDIANCUT` will be used.
1192
1193 The exception to this is RGBA images. :data:`Quantize.MEDIANCUT`
1194 and :data:`Quantize.MAXCOVERAGE` do not support RGBA images, so
1195 :data:`Quantize.FASTOCTREE` is used by default instead.
1196 :param kmeans: Integer greater than or equal to zero.
1197 :param palette: Quantize to the palette of given
1198 :py:class:`PIL.Image.Image`.
1199 :param dither: Dithering method, used when converting from
1200 mode "RGB" to "P" or from "RGB" or "L" to "1".
