diff --git a/.ci/install.sh b/.ci/install.sh index 8a3b8fee4..36bce295c 100755 --- a/.ci/install.sh +++ b/.ci/install.sh @@ -30,6 +30,7 @@ pip install -U pytest-cov pip install pyroma pip install test-image-results pip install numpy +if [ "$TRAVIS_PYTHON_VERSION" == "3.9-dev" ]; then pip install setuptools==47.3.1 ; fi if [[ $TRAVIS_PYTHON_VERSION == 3.* ]]; then # arm64, ppc64le, s390x CPUs: # "ERROR: Could not find a version that satisfies the requirement pyqt5" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b8d2c6374..eb8cada0d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -98,7 +98,7 @@ jobs: - name: Docs if: startsWith(matrix.os, 'ubuntu') && matrix.python-version == 3.8 run: | - pip install sphinx-rtd-theme + pip install sphinx-removed-in sphinx-rtd-theme make doccheck - name: After success diff --git a/.travis.yml b/.travis.yml index 980506368..bfe366000 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,6 +46,9 @@ matrix: env: PYTHONOPTIMIZE=2 services: xvfb + allow_failures: + - python: "3.9-dev" + install: - | if [ "$LINT" == "true" ]; then diff --git a/CHANGES.rst b/CHANGES.rst index c63f05e6a..e06508f38 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog (Pillow) ================== +8.0.0 (unreleased) +------------------ + +- Allow ImageOps.autocontrast to specify low and high cutoffs separately #4749 + [millionhz, radarhere] + 7.2.0 (2020-07-01) ------------------ @@ -5581,7 +5587,7 @@ Pre-fork any other pixel value means opaque. This is faster than using an "L" transparency mask. - + Properly writes EPS files (and properly prints images to postscript + + Properly writes EPS files (and properly prints images to PostScript printers as well). + Reads 4-bit BMP files, as well as 4 and 8-bit Windows ICO and CUR @@ -5664,7 +5670,7 @@ Pre-fork + Added the "pilfile" utility, which quickly identifies image files (without loading them, in most cases). - + Added the "pilprint" utility, which prints image files to Postscript + + Added the "pilprint" utility, which prints image files to PostScript printers. + Added a rudimentary version of the "pilview" utility, which is @@ -5678,5 +5684,5 @@ Pre-fork Jack). This allows you to read images through the Img extensions file format handlers. See the file "Lib/ImgExtImagePlugin.py" for details. - + Postscript printing is provided through the PSDraw module. See the + + PostScript printing is provided through the PSDraw module. See the handbook for details. diff --git a/Tests/test_imageops.py b/Tests/test_imageops.py index 3d0afba9c..864df447e 100644 --- a/Tests/test_imageops.py +++ b/Tests/test_imageops.py @@ -300,3 +300,14 @@ def test_exif_transpose(): "Tests/images/hopper_orientation_" + str(i) + ext ) as orientation_im: check(orientation_im) + + +def test_autocontrast_cutoff(): + # Test the cutoff argument of autocontrast + with Image.open("Tests/images/bw_gradient.png") as img: + + def autocontrast(cutoff): + return ImageOps.autocontrast(img, cutoff).histogram() + + assert autocontrast(10) == autocontrast((10, 10)) + assert autocontrast(10) != autocontrast((1, 10)) diff --git a/docs/PIL.rst b/docs/PIL.rst index 4b10184fa..fa036b9cc 100644 --- a/docs/PIL.rst +++ b/docs/PIL.rst @@ -93,8 +93,8 @@ can be found here. :undoc-members: :show-inheritance: -:class:`PngImagePlugin.iTXt` Class ----------------------------------- +:class:`.PngImagePlugin.iTXt` Class +----------------------------------- .. autoclass:: PIL.PngImagePlugin.iTXt :members: @@ -107,8 +107,8 @@ can be found here. :param lang: language code :param tkey: UTF-8 version of the key name -:class:`PngImagePlugin.PngInfo` Class -------------------------------------- +:class:`.PngImagePlugin.PngInfo` Class +-------------------------------------- .. autoclass:: PIL.PngImagePlugin.PngInfo :members: diff --git a/docs/conf.py b/docs/conf.py index d95ec2a4a..ddfb24fe3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -27,7 +27,14 @@ needs_sphinx = "2.4" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx.ext.intersphinx"] +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "sphinx.ext.viewcode", + "sphinx_removed_in", +] + +intersphinx_mapping = {"python": ("https://docs.python.org/3", None)} # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: diff --git a/docs/deprecations.rst b/docs/deprecations.rst index f78842ac1..af8fc7527 100644 --- a/docs/deprecations.rst +++ b/docs/deprecations.rst @@ -78,7 +78,8 @@ period of deprecation has passed. Python 2.7 ~~~~~~~~~~ -*Removed in version 7.0.0.* +.. deprecated:: 6.0.0 +.. versionremoved:: 7.0.0 Python 2.7 reached end-of-life on 2020-01-01. Pillow 6.x was the last series to support Python 2. @@ -86,7 +87,8 @@ support Python 2. Image.__del__ ~~~~~~~~~~~~~ -*Removed in version 7.0.0.* +.. deprecated:: 6.1.0 +.. versionremoved:: 7.0.0 Implicitly closing the image's underlying file in ``Image.__del__`` has been removed. Use a context manager or call ``Image.close()`` instead to close the file in a @@ -109,7 +111,8 @@ Use instead: PIL.*ImagePlugin.__version__ attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*Removed in version 7.0.0.* +.. deprecated:: 6.0.0 +.. versionremoved:: 7.0.0 The version constants of individual plugins have been removed. Use ``PIL.__version__`` instead. @@ -134,7 +137,8 @@ Removed Removed Removed PyQt4 and PySide ~~~~~~~~~~~~~~~~ -*Removed in version 7.0.0.* +.. deprecated:: 6.0.0 +.. versionremoved:: 7.0.0 Qt 4 reached end-of-life on 2015-12-19. Its Python bindings are also EOL: PyQt4 since 2018-08-31 and PySide since 2015-10-14. @@ -145,7 +149,8 @@ or PySide2. Setting the size of TIFF images ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*Removed in version 7.0.0.* +.. deprecated:: 5.3.0 +.. versionremoved:: 7.0.0 Setting the size of a TIFF image directly (eg. ``im.size = (256, 256)``) throws an error. Use ``Image.resize`` instead. @@ -153,7 +158,8 @@ an error. Use ``Image.resize`` instead. VERSION constant ~~~~~~~~~~~~~~~~ -*Removed in version 6.0.0.* +.. deprecated:: 5.2.0 +.. versionremoved:: 6.0.0 ``VERSION`` (the old PIL version, always 1.1.7) has been removed. Use ``__version__`` instead. @@ -161,7 +167,8 @@ VERSION constant Undocumented ImageOps functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*Removed in version 6.0.0.* +.. deprecated:: 4.3.0 +.. versionremoved:: 6.0.0 Several undocumented functions in ``ImageOps`` have been removed. Use the equivalents in ``ImageFilter`` instead: @@ -179,7 +186,8 @@ Removed Use instead PIL.OleFileIO ~~~~~~~~~~~~~ -*Removed in version 6.0.0.* +.. deprecated:: 4.0.0 +.. versionremoved:: 6.0.0 PIL.OleFileIO was removed as a vendored file and in Pillow 4.0.0 (2017-01) in favour of the upstream olefile Python package, and replaced with an ``ImportError`` in 5.0.0 diff --git a/docs/handbook/image-file-formats.rst b/docs/handbook/image-file-formats.rst index 6bcff7135..0355e1d18 100644 --- a/docs/handbook/image-file-formats.rst +++ b/docs/handbook/image-file-formats.rst @@ -473,7 +473,7 @@ image formats, EXIF data is not guaranteed to be present in :py:attr:`~PIL.Image.Image.info` until :py:meth:`~PIL.Image.Image.load` has been called. -The :py:meth:`~PIL.Image.Image.open` method sets the following +The :py:func:`~PIL.Image.open` function sets the following :py:attr:`~PIL.Image.Image.info` properties, when appropriate: **chromaticity** @@ -501,12 +501,14 @@ The :py:meth:`~PIL.Image.Image.open` method sets the following This key is omitted if the image is not a transparent palette image. +.. _png-text: + ``open`` also sets ``Image.text`` to a dictionary of the values of the ``tEXt``, ``zTXt``, and ``iTXt`` chunks of the PNG image. Individual compressed chunks are limited to a decompressed size of -``PngImagePlugin.MAX_TEXT_CHUNK``, by default 1MB, to prevent +:data:`.PngImagePlugin.MAX_TEXT_CHUNK`, by default 1MB, to prevent decompression bombs. Additionally, the total size of all of the text -chunks is limited to ``PngImagePlugin.MAX_TEXT_MEMORY``, defaulting to +chunks is limited to :data:`.PngImagePlugin.MAX_TEXT_MEMORY`, defaulting to 64MB. The :py:meth:`~PIL.Image.Image.save` method supports the following options: @@ -611,6 +613,8 @@ where applicable: Any APNG file containing sequence errors is treated as an invalid image. The APNG loader will not attempt to repair and reorder files containing sequence errors. +.. _apng-saving: + Saving ~~~~~~ @@ -774,7 +778,7 @@ The :py:meth:`~PIL.Image.open` method sets the following The :py:attr:`~PIL.Image.Image.tag_v2` attribute contains a dictionary of TIFF metadata. The keys are numerical indexes from -:py:attr:`~PIL.TiffTags.TAGS_V2`. Values are strings or numbers for single +:py:data:`.TiffTags.TAGS_V2`. Values are strings or numbers for single items, multiple values are returned in a tuple of values. Rational numbers are returned as a :py:class:`~PIL.TiffImagePlugin.IFDRational` object. @@ -827,7 +831,7 @@ The :py:meth:`~PIL.Image.Image.save` method can take the following keyword argum object and setting the type in :py:attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v2.tagtype` with the appropriate numerical value from - ``TiffTags.TYPES``. + :py:data:`.TiffTags.TYPES`. .. versionadded:: 2.3.0 @@ -844,7 +848,7 @@ The :py:meth:`~PIL.Image.Image.save` method can take the following keyword argum Previous versions only supported some tags when writing using libtiff. The supported list is found in - :py:attr:`~PIL:TiffTags.LIBTIFF_CORE`. + :py:data:`.TiffTags.LIBTIFF_CORE`. .. versionadded:: 6.1.0 @@ -857,7 +861,7 @@ The :py:meth:`~PIL.Image.Image.save` method can take the following keyword argum **compression** A string containing the desired compression method for the file. (valid only with libtiff installed) Valid compression - methods are: ``None``, ``"tiff_ccitt"``, ``"group3"``, + methods are: :data:`None`, ``"tiff_ccitt"``, ``"group3"``, ``"group4"``, ``"tiff_jpeg"``, ``"tiff_adobe_deflate"``, ``"tiff_thunderscan"``, ``"tiff_deflate"``, ``"tiff_sgilog"``, ``"tiff_sgilog24"``, ``"tiff_raw_16"`` diff --git a/docs/handbook/tutorial.rst b/docs/handbook/tutorial.rst index 94a8e3aa1..b24a6eb4b 100644 --- a/docs/handbook/tutorial.rst +++ b/docs/handbook/tutorial.rst @@ -406,13 +406,13 @@ Using the ImageSequence Iterator class # ...do something to frame... -Postscript printing +PostScript printing ------------------- The Python Imaging Library includes functions to print images, text and -graphics on Postscript printers. Here’s a simple example: +graphics on PostScript printers. Here’s a simple example: -Drawing Postscript +Drawing PostScript ^^^^^^^^^^^^^^^^^^ :: @@ -453,8 +453,8 @@ If everything goes well, the result is an :py:class:`PIL.Image.Image` object. Otherwise, an :exc:`OSError` exception is raised. You can use a file-like object instead of the filename. The object must -implement :py:meth:`~file.read`, :py:meth:`~file.seek` and -:py:meth:`~file.tell` methods, and be opened in binary mode. +implement ``file.read``, ``file.seek`` and ``file.tell`` methods, +and be opened in binary mode. Reading from an open file ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/handbook/writing-your-own-file-decoder.rst b/docs/handbook/writing-your-own-file-decoder.rst index 42a6c4822..c73ad9cab 100644 --- a/docs/handbook/writing-your-own-file-decoder.rst +++ b/docs/handbook/writing-your-own-file-decoder.rst @@ -3,9 +3,9 @@ Writing Your Own Image Plugin ============================= -The Pillow uses a plug-in model which allows you to add your own +Pillow uses a plugin model which allows you to add your own decoders to the library, without any changes to the library -itself. Such plug-ins usually have names like +itself. Such plugins usually have names like :file:`XxxImagePlugin.py`, where ``Xxx`` is a unique format name (usually an abbreviation). @@ -14,7 +14,7 @@ itself. Such plug-ins usually have names like :file:`ImagePlugin.py`. You will need to import your image plugin manually. -Pillow decodes files in 2 stages: +Pillow decodes files in two stages: 1. It loops over the available image plugins in the loaded order, and calls the plugin's ``_accept`` function with the first 16 bytes of @@ -26,7 +26,7 @@ Pillow decodes files in 2 stages: called, which sets up a decoder for each tile and feeds the data to it. -An image plug-in should contain a format handler derived from the +An image plugin should contain a format handler derived from the :py:class:`PIL.ImageFile.ImageFile` base class. This class should provide an :py:meth:`_open` method, which reads the file header and sets up at least the :py:attr:`~PIL.Image.Image.mode` and @@ -43,7 +43,7 @@ registered, via a call to the :py:mod:`~PIL.Image` module. Example ------- -The following plug-in supports a simple format, which has a 128-byte header +The following plugin supports a simple format, which has a 128-byte header consisting of the words “SPAM” followed by the width, height, and pixel size in bits. The header fields are separated by spaces. The image data follows directly after the header, and can be either bi-level, greyscale, or 24-bit @@ -82,14 +82,14 @@ true color. raise SyntaxError("unknown number of bits") # data descriptor - self.tile = [ - ("raw", (0, 0) + self.size, 128, (self.mode, 0, 1)) - ] + self.tile = [("raw", (0, 0) + self.size, 128, (self.mode, 0, 1))] + Image.register_open(SpamImageFile.format, SpamImageFile, _accept) Image.register_extension(SpamImageFile.format, ".spam") - Image.register_extension(SpamImageFile.format, ".spa") # dos version + Image.register_extension(SpamImageFile.format, ".spa") # DOS version + The format handler must always set the :py:attr:`~PIL.Image.Image.size` and :py:attr:`~PIL.Image.Image.mode` @@ -132,7 +132,7 @@ The fields are used as follows: **parameters** Parameters to the decoder. The contents of this field depends on the decoder specified by the first field in the tile descriptor tuple. If the - decoder doesn’t need any parameters, use None for this field. + decoder doesn’t need any parameters, use :data:`None` for this field. Note that the :py:attr:`tile` attribute contains a list of tile descriptors, not just a single descriptor. @@ -175,7 +175,7 @@ The fields are used as follows: The **raw mode** field is used to determine how the data should be unpacked to match PIL’s internal pixel layout. PIL supports a large set of raw modes; for a -complete list, see the table in the :py:mod:`Unpack.c` module. The following +complete list, see the table in the :file:`Unpack.c` module. The following table describes some commonly used **raw modes**: +-----------+-----------------------------------------------------------------+ @@ -211,7 +211,7 @@ Note that for the most common cases, the raw mode is simply the same as the mode The Python Imaging Library supports many other decoders, including JPEG, PNG, and PackBits. For details, see the :file:`decode.c` source file, and the -standard plug-in implementations provided with the library. +standard plugin implementations provided with the library. Decoding floating point data ---------------------------- diff --git a/docs/porting.rst b/docs/porting.rst index d962e9330..2943d72fd 100644 --- a/docs/porting.rst +++ b/docs/porting.rst @@ -19,7 +19,8 @@ to this:: from PIL import Image -The :py:mod:`~PIL._imaging` module has been moved. You can now import it like this:: +The :py:mod:`PIL._imaging` module has been moved to :py:mod:`PIL.Image.core`. +You can now import it like this:: from PIL.Image import core as _imaging diff --git a/docs/reference/Image.rst b/docs/reference/Image.rst index 23f3eb03c..f24d382b8 100644 --- a/docs/reference/Image.rst +++ b/docs/reference/Image.rst @@ -268,8 +268,8 @@ This flips the input image by using the :data:`FLIP_LEFT_RIGHT` method. .. automethod:: PIL.Image.Image.load .. automethod:: PIL.Image.Image.close -Attributes ----------- +Image Attributes +---------------- Instances of the :py:class:`Image` class have the following attributes: @@ -285,7 +285,7 @@ Instances of the :py:class:`Image` class have the following attributes: The file format of the source file. For images created by the library itself (via a factory function, or by running a method on an existing - image), this attribute is set to ``None``. + image), this attribute is set to :data:`None`. .. py:attribute:: Image.mode :type: str @@ -314,7 +314,7 @@ Instances of the :py:class:`Image` class have the following attributes: Colour palette table, if any. If mode is "P" or "PA", this should be an instance of the :py:class:`~PIL.ImagePalette.ImagePalette` class. - Otherwise, it should be set to ``None``. + Otherwise, it should be set to :data:`None`. .. py:attribute:: Image.info :type: dict @@ -360,6 +360,16 @@ Instances of the :py:class:`Image` class have the following attributes: .. seealso:: :attr:`~Image.is_animated`, :func:`~Image.seek` and :func:`~Image.tell` +Classes +------- + +.. autoclass:: PIL.Image.Exif + :members: + :undoc-members: + :show-inheritance: +.. autoclass:: PIL.Image.ImagePointHandler +.. autoclass:: PIL.Image.ImageTransformHandler + Constants --------- diff --git a/docs/reference/ImageDraw.rst b/docs/reference/ImageDraw.rst index fd74b69c1..3faa0d3e0 100644 --- a/docs/reference/ImageDraw.rst +++ b/docs/reference/ImageDraw.rst @@ -212,7 +212,7 @@ Methods .. versionadded:: 1.1.5 .. note:: This option was broken until version 1.1.6. - :param joint: Joint type between a sequence of lines. It can be ``"curve"``, for rounded edges, or ``None``. + :param joint: Joint type between a sequence of lines. It can be ``"curve"``, for rounded edges, or :data:`None`. .. versionadded:: 5.3.0 diff --git a/docs/reference/ImageFilter.rst b/docs/reference/ImageFilter.rst index 1b93c53e7..c85da4fb5 100644 --- a/docs/reference/ImageFilter.rst +++ b/docs/reference/ImageFilter.rst @@ -66,3 +66,29 @@ image enhancement filters: .. autoclass:: PIL.ImageFilter.ModeFilter :members: + +.. class:: Filter + + An abstract mixin used for filtering images + (for use with :py:meth:`~PIL.Image.Image.filter`). + + Implementors must provide the following method: + + .. method:: filter(self, image) + + Applies a filter to a single-band image, or a single band of an image. + + :returns: A filtered copy of the image. + +.. class:: MultibandFilter + + An abstract mixin used for filtering multi-band images + (for use with :py:meth:`~PIL.Image.Image.filter`). + + Implementors must provide the following method: + + .. method:: filter(self, image) + + Applies a filter to a multi-band image. + + :returns: A filtered copy of the image. diff --git a/docs/reference/ImageFont.rst b/docs/reference/ImageFont.rst index b3c3cce57..fc61cac13 100644 --- a/docs/reference/ImageFont.rst +++ b/docs/reference/ImageFont.rst @@ -6,7 +6,7 @@ The :py:mod:`~PIL.ImageFont` module defines a class with the same name. Instances of this class store bitmap fonts, and are used with the -:py:meth:`PIL.ImageDraw.Draw.text` method. +:py:meth:`PIL.ImageDraw.ImageDraw.text` method. PIL uses its own font file format to store bitmap fonts. You can use the :command:`pilfont` utility from diff --git a/docs/reference/ImageGrab.rst b/docs/reference/ImageGrab.rst index a9427be9c..ac83b2255 100644 --- a/docs/reference/ImageGrab.rst +++ b/docs/reference/ImageGrab.rst @@ -27,7 +27,7 @@ or the clipboard to a PIL image memory. .. versionadded:: 6.2.0 :param xdisplay: - X11 Display address. Pass ``None`` to grab the default system screen. Pass ``""`` to grab the default X11 screen on Windows or macOS. + X11 Display address. Pass :data:`None` to grab the default system screen. Pass ``""`` to grab the default X11 screen on Windows or macOS. You can check X11 support using :py:func:`PIL.features.check_feature` with ``feature="xcb"``. diff --git a/docs/reference/ImageQt.rst b/docs/reference/ImageQt.rst index 887eab9ba..34d4cef51 100644 --- a/docs/reference/ImageQt.rst +++ b/docs/reference/ImageQt.rst @@ -9,7 +9,7 @@ objects from PIL images. .. versionadded:: 1.1.6 -.. py:class:: ImageQt.ImageQt(image) +.. py:class:: ImageQt(image) Creates an :py:class:`~PIL.ImageQt.ImageQt` object from a PIL :py:class:`~PIL.Image.Image` object. This class is a subclass of diff --git a/docs/reference/PSDraw.rst b/docs/reference/PSDraw.rst index 958385818..3e8512e7a 100644 --- a/docs/reference/PSDraw.rst +++ b/docs/reference/PSDraw.rst @@ -4,7 +4,7 @@ :py:mod:`~PIL.PSDraw` Module ============================ -The :py:mod:`~PIL.PSDraw` module provides simple print support for Postscript +The :py:mod:`~PIL.PSDraw` module provides simple print support for PostScript printers. You can print text, graphics and images through this module. .. autoclass:: PIL.PSDraw.PSDraw diff --git a/docs/reference/TiffTags.rst b/docs/reference/TiffTags.rst index a53788a9f..1441185dd 100644 --- a/docs/reference/TiffTags.rst +++ b/docs/reference/TiffTags.rst @@ -60,3 +60,8 @@ metadata tag numbers, names, and type information. The ``TYPES`` dictionary maps the TIFF type short integer to a human readable type name. + +.. py:data:: PIL.TiffTags.LIBTIFF_CORE + :type: list + + A list of supported tag IDs when writing using LibTIFF. diff --git a/docs/reference/internal_modules.rst b/docs/reference/internal_modules.rst index 288a049ee..1105ff76e 100644 --- a/docs/reference/internal_modules.rst +++ b/docs/reference/internal_modules.rst @@ -36,3 +36,12 @@ Internal Modules This is the master version number for Pillow, all other uses reference this module. + +:mod:`PIL.Image.core` Module +---------------------------- + +.. module:: PIL._imaging +.. module:: PIL.Image.core + +An internal interface module previously known as :mod:`~PIL._imaging`, +implemented in :file:`_imaging.c`. diff --git a/docs/reference/plugins.rst b/docs/reference/plugins.rst index ef080b6db..7094f8784 100644 --- a/docs/reference/plugins.rst +++ b/docs/reference/plugins.rst @@ -229,20 +229,12 @@ Plugin reference --------------------------------- .. automodule:: PIL.PngImagePlugin - :members: ChunkStream, PngStream, getchunks, is_cid, putchunk - :show-inheritance: -.. autoclass:: PIL.PngImagePlugin.ChunkStream - :members: - :undoc-members: - :show-inheritance: -.. autoclass:: PIL.PngImagePlugin.PngImageFile - :members: - :undoc-members: - :show-inheritance: -.. autoclass:: PIL.PngImagePlugin.PngStream - :members: + :members: ChunkStream, PngImageFile, PngStream, getchunks, is_cid, putchunk, + MAX_TEXT_CHUNK, MAX_TEXT_MEMORY, APNG_BLEND_OP_SOURCE, APNG_BLEND_OP_OVER, + APNG_DISPOSE_OP_NONE, APNG_DISPOSE_OP_BACKGROUND, APNG_DISPOSE_OP_PREVIOUS :undoc-members: :show-inheritance: + :member-order: groupwise :mod:`~PIL.PpmImagePlugin` Module diff --git a/docs/releasenotes/4.1.0.rst b/docs/releasenotes/4.1.0.rst index dc5d73479..4d6598d8e 100644 --- a/docs/releasenotes/4.1.0.rst +++ b/docs/releasenotes/4.1.0.rst @@ -10,9 +10,9 @@ Several deprecated items have been removed. resolution', 'resolution unit', and 'date time' has been removed. Underscores should be used instead. -* The methods :py:meth:`PIL.ImageDraw.ImageDraw.setink`, - :py:meth:`PIL.ImageDraw.ImageDraw.setfill`, and - :py:meth:`PIL.ImageDraw.ImageDraw.setfont` have been removed. +* The methods ``PIL.ImageDraw.ImageDraw.setink``, + ``PIL.ImageDraw.ImageDraw.setfill``, and + ``PIL.ImageDraw.ImageDraw.setfont`` have been removed. Closing Files When Opening Images diff --git a/docs/releasenotes/4.2.0.rst b/docs/releasenotes/4.2.0.rst index 906eeab8d..aee93bef6 100644 --- a/docs/releasenotes/4.2.0.rst +++ b/docs/releasenotes/4.2.0.rst @@ -34,9 +34,9 @@ Removed Deprecated Items Several deprecated items have been removed. -* The methods :py:meth:`PIL.ImageWin.Dib.fromstring`, - :py:meth:`PIL.ImageWin.Dib.tostring` and - :py:meth:`PIL.TiffImagePlugin.ImageFileDirectory_v2.as_dict` have +* The methods ``PIL.ImageWin.Dib.fromstring``, + ``PIL.ImageWin.Dib.tostring`` and + ``PIL.TiffImagePlugin.ImageFileDirectory_v2.as_dict`` have been removed. * Before Pillow 4.2.0, attempting to save an RGBA image as JPEG would diff --git a/docs/releasenotes/4.3.0.rst b/docs/releasenotes/4.3.0.rst index 6fa554e23..ea81fc45e 100644 --- a/docs/releasenotes/4.3.0.rst +++ b/docs/releasenotes/4.3.0.rst @@ -124,7 +124,7 @@ This release contains several performance improvements: * ``Image.transpose`` has been accelerated 15% or more by using a cache friendly algorithm. * ImageFilters based on Kernel convolution are significantly faster - due to the new MultibandFilter feature. + due to the new :py:class:`~PIL.ImageFilter.MultibandFilter` feature. * All memory allocation for images is now done in blocks, rather than falling back to an allocation for each scan line for images larger than the block size. diff --git a/docs/releasenotes/5.3.0.rst b/docs/releasenotes/5.3.0.rst index cce671c32..bff56566b 100644 --- a/docs/releasenotes/5.3.0.rst +++ b/docs/releasenotes/5.3.0.rst @@ -34,7 +34,7 @@ Curved joints for line sequences ``ImageDraw.Draw.line`` draws a line, or lines, between points. Previously, when multiple points are given, for a larger ``width``, the joints between these lines looked unsightly. There is now an additional optional argument, -``joint``, defaulting to ``None``. When it is set to ``curved``, the joints +``joint``, defaulting to :data:`None`. When it is set to ``curved``, the joints between the lines will become rounded. ImageOps.colorize diff --git a/docs/releasenotes/7.0.0.rst b/docs/releasenotes/7.0.0.rst index 73c44275c..80002b0ce 100644 --- a/docs/releasenotes/7.0.0.rst +++ b/docs/releasenotes/7.0.0.rst @@ -66,7 +66,7 @@ See :ref:`concept-filters` to learn the difference. In short, Image.draft() return value ^^^^^^^^^^^^^^^^^^^^^^^^^^ -If the :py:meth:`~PIL.Image.Image.draft` method has no effect, it returns ``None``. +If the :py:meth:`~PIL.Image.Image.draft` method has no effect, it returns :data:`None`. If it does have an effect, then it previously returned the image itself. However, unlike other `chain methods`_, :py:meth:`~PIL.Image.Image.draft` does not return a modified version of the image, but modifies it in-place. So instead, if @@ -95,7 +95,7 @@ the closer the result to the fair resampling. The smaller ``reducing_gap``, the faster resizing. With ``reducing_gap`` greater or equal to 3.0, the result is indistinguishable from fair resampling. -The default value for :py:meth:`~PIL.Image.Image.resize` is ``None``, +The default value for :py:meth:`~PIL.Image.Image.resize` is :data:`None`, which means that the optimization is turned off by default. The default value for :py:meth:`~PIL.Image.Image.thumbnail` is 2.0, diff --git a/docs/releasenotes/7.1.0.rst b/docs/releasenotes/7.1.0.rst index 55a970c1e..35e5c4464 100644 --- a/docs/releasenotes/7.1.0.rst +++ b/docs/releasenotes/7.1.0.rst @@ -63,7 +63,7 @@ Support has been added for ``ImageGrab.grab()`` on Linux using the X server with the XCB library. An optional ``xdisplay`` parameter has been added to select the X server, -with the default value of ``None`` using the default X server. +with the default value of :data:`None` using the default X server. Passing a different value on Windows or macOS will force taking a snapshot using the selected X server; pass an empty string to use the default X server. diff --git a/requirements.txt b/requirements.txt index 0e0d38cdd..25eb0ea11 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,4 +10,5 @@ pyroma pytest pytest-cov sphinx>=2.4 +sphinx-removed-in sphinx-rtd-theme diff --git a/src/PIL/EpsImagePlugin.py b/src/PIL/EpsImagePlugin.py index 652dc489a..16d7ae039 100644 --- a/src/PIL/EpsImagePlugin.py +++ b/src/PIL/EpsImagePlugin.py @@ -191,7 +191,7 @@ def _accept(prefix): ## -# Image plugin for Encapsulated Postscript. This plugin supports only +# Image plugin for Encapsulated PostScript. This plugin supports only # a few variants of this format. @@ -262,7 +262,7 @@ class EpsImageFile(ImageFile.ImageFile): else: self.info[k] = "" elif s[0] == "%": - # handle non-DSC Postscript comments that some + # handle non-DSC PostScript comments that some # tools mistakenly put in the Comments section pass else: @@ -352,7 +352,7 @@ def _save(im, fp, filename, eps=1): im.load() # - # determine postscript image mode + # determine PostScript image mode if im.mode == "L": operator = (8, 1, "image") elif im.mode == "RGB": diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 9154cc43a..03829d9a9 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -717,7 +717,7 @@ class Image: :param encoder_name: What encoder to use. The default is to use the standard "raw" encoder. :param args: Extra arguments to the encoder. - :rtype: A bytes object. + :returns: A :py:class:`bytes` object. """ # may pass tuple instead of argument list @@ -1577,6 +1577,13 @@ class Image: single argument. The function is called once for each possible pixel value, and the resulting table is applied to all bands of the image. + + It may also be an :py:class:`~PIL.Image.ImagePointHandler` + object:: + + class Example(Image.ImagePointHandler): + def point(self, data): + # Return result :param mode: Output mode (default is same as input). In the current version, this can only be used if the source image has mode "L" or "P", and the output has mode "1" or the @@ -2358,10 +2365,10 @@ class Image: object:: class Example(Image.ImageTransformHandler): - def transform(size, method, data, resample, fill=1): + def transform(self, size, data, resample, fill=1): # Return result - It may also be an object with a :py:meth:`~method.getdata` method + It may also be an object with a ``method.getdata`` method that returns a tuple supplying new **method** and **data** values:: class Example: @@ -2540,12 +2547,20 @@ class Image: class ImagePointHandler: - # used as a mixin by point transforms (for use with im.point) + """ + Used as a mixin by point transforms + (for use with :py:meth:`~PIL.Image.Image.point`) + """ + pass class ImageTransformHandler: - # used as a mixin by geometry transforms (for use with im.transform) + """ + Used as a mixin by geometry transforms + (for use with :py:meth:`~PIL.Image.Image.transform`) + """ + pass @@ -2853,8 +2868,8 @@ def open(fp, mode="r"): :py:func:`~PIL.Image.new`. See :ref:`file-handling`. :param fp: A filename (string), pathlib.Path object or a file object. - The file object must implement :py:meth:`~file.read`, - :py:meth:`~file.seek`, and :py:meth:`~file.tell` methods, + The file object must implement ``file.read``, + ``file.seek`, and ``file.tell`` methods, and be opened in binary mode. :param mode: The mode. If given, this argument must be "r". :returns: An :py:class:`~PIL.Image.Image` object. diff --git a/src/PIL/ImageChops.py b/src/PIL/ImageChops.py index c1a2574e4..9fccedcb2 100644 --- a/src/PIL/ImageChops.py +++ b/src/PIL/ImageChops.py @@ -293,7 +293,7 @@ def logical_xor(image1, image2): def blend(image1, image2, alpha): """Blend images using constant transparency weight. Alias for - :py:meth:`PIL.Image.Image.blend`. + :py:func:`PIL.Image.blend`. :rtype: :py:class:`~PIL.Image.Image` """ @@ -303,7 +303,7 @@ def blend(image1, image2, alpha): def composite(image1, image2, mask): """Create composite using transparency mask. Alias for - :py:meth:`PIL.Image.Image.composite`. + :py:func:`PIL.Image.composite`. :rtype: :py:class:`~PIL.Image.Image` """ diff --git a/src/PIL/ImageFilter.py b/src/PIL/ImageFilter.py index 3e61a6ca1..18c550c84 100644 --- a/src/PIL/ImageFilter.py +++ b/src/PIL/ImageFilter.py @@ -49,7 +49,7 @@ class Kernel(BuiltinFilter): version, this must be (3,3) or (5,5). :param kernel: A sequence containing kernel weights. :param scale: Scale factor. If given, the result for each pixel is - divided by this value. the default is the sum of the + divided by this value. The default is the sum of the kernel weights. :param offset: Offset. If given, this value is added to the result, after it has been divided by the scale factor. diff --git a/src/PIL/ImageOps.py b/src/PIL/ImageOps.py index e4e0840b8..157da0b52 100644 --- a/src/PIL/ImageOps.py +++ b/src/PIL/ImageOps.py @@ -70,7 +70,9 @@ def autocontrast(image, cutoff=0, ignore=None): becomes white (255). :param image: The image to process. - :param cutoff: How many percent to cut off from the histogram. + :param cutoff: The percent to cut off from the histogram on the low and + high ends. Either a tuple of (low, high), or a single + number for both. :param ignore: The background pixel value (use None for no background). :return: An image. """ @@ -88,12 +90,14 @@ def autocontrast(image, cutoff=0, ignore=None): h[ix] = 0 if cutoff: # cut off pixels from both ends of the histogram + if not isinstance(cutoff, tuple): + cutoff = (cutoff, cutoff) # get number of pixels n = 0 for ix in range(256): n = n + h[ix] # remove cutoff% pixels from the low end - cut = n * cutoff // 100 + cut = n * cutoff[0] // 100 for lo in range(256): if cut > h[lo]: cut = cut - h[lo] @@ -103,8 +107,8 @@ def autocontrast(image, cutoff=0, ignore=None): cut = 0 if cut <= 0: break - # remove cutoff% samples from the hi end - cut = n * cutoff // 100 + # remove cutoff% samples from the high end + cut = n * cutoff[1] // 100 for hi in range(255, -1, -1): if cut > h[hi]: cut = cut - h[hi] diff --git a/src/PIL/JpegImagePlugin.py b/src/PIL/JpegImagePlugin.py index b4795c302..f18eedb20 100644 --- a/src/PIL/JpegImagePlugin.py +++ b/src/PIL/JpegImagePlugin.py @@ -488,7 +488,7 @@ def _getexif(self): def _getmp(self): # Extract MP information. This method was inspired by the "highly # experimental" _getexif version that's been in use for years now, - # itself based on the ImageFileDirectory class in the TIFF plug-in. + # itself based on the ImageFileDirectory class in the TIFF plugin. # The MP record essentially consists of a TIFF file embedded in a JPEG # application marker. diff --git a/src/PIL/PSDraw.py b/src/PIL/PSDraw.py index 762d31e88..3cfcbaf28 100644 --- a/src/PIL/PSDraw.py +++ b/src/PIL/PSDraw.py @@ -2,7 +2,7 @@ # The Python Imaging Library # $Id$ # -# simple postscript graphics interface +# Simple PostScript graphics interface # # History: # 1996-04-20 fl Created @@ -20,13 +20,13 @@ import sys from . import EpsImagePlugin ## -# Simple Postscript graphics interface. +# Simple PostScript graphics interface. class PSDraw: """ Sets up printing to the given file. If **fp** is omitted, - :py:attr:`sys.stdout` is assumed. + :py:data:`sys.stdout` is assumed. """ def __init__(self, fp=None): @@ -41,7 +41,7 @@ class PSDraw: self.fp.write(bytes(to_write, "UTF-8")) def begin_document(self, id=None): - """Set up printing of a document. (Write Postscript DSC header.)""" + """Set up printing of a document. (Write PostScript DSC header.)""" # FIXME: incomplete self._fp_write( "%!PS-Adobe-3.0\n" @@ -57,7 +57,7 @@ class PSDraw: self.isofont = {} def end_document(self): - """Ends printing. (Write Postscript DSC footer.)""" + """Ends printing. (Write PostScript DSC footer.)""" self._fp_write("%%EndDocument\nrestore showpage\n%%End\n") if hasattr(self.fp, "flush"): self.fp.flush() @@ -66,7 +66,7 @@ class PSDraw: """ Selects which font to use. - :param font: A Postscript font name + :param font: A PostScript font name :param size: Size in points. """ if font not in self.isofont: @@ -79,7 +79,7 @@ class PSDraw: def line(self, xy0, xy1): """ Draws a line between the two points. Coordinates are given in - Postscript point coordinates (72 points per inch, (0, 0) is the lower + PostScript point coordinates (72 points per inch, (0, 0) is the lower left corner of the page). """ xy = xy0 + xy1 @@ -143,10 +143,10 @@ class PSDraw: # -------------------------------------------------------------------- -# Postscript driver +# PostScript driver # -# EDROFF.PS -- Postscript driver for Edroff 2 +# EDROFF.PS -- PostScript driver for Edroff 2 # # History: # 94-01-25 fl: created (edroff 2.04) @@ -176,7 +176,7 @@ EDROFF_PS = """\ """ # -# VDI.PS -- Postscript driver for VDI meta commands +# VDI.PS -- PostScript driver for VDI meta commands # # History: # 94-01-25 fl: created (edroff 2.04) diff --git a/src/PIL/PngImagePlugin.py b/src/PIL/PngImagePlugin.py index e027953dd..9d048b211 100644 --- a/src/PIL/PngImagePlugin.py +++ b/src/PIL/PngImagePlugin.py @@ -76,21 +76,50 @@ _MODES = { _simple_palette = re.compile(b"^\xff*\x00\xff*$") -# Maximum decompressed size for a iTXt or zTXt chunk. -# Eliminates decompression bombs where compressed chunks can expand 1000x MAX_TEXT_CHUNK = ImageFile.SAFEBLOCK -# Set the maximum total text chunk size. +""" +Maximum decompressed size for a iTXt or zTXt chunk. +Eliminates decompression bombs where compressed chunks can expand 1000x. +See :ref:`Text in PNG File Format`. +""" MAX_TEXT_MEMORY = 64 * MAX_TEXT_CHUNK +""" +Set the maximum total text chunk size. +See :ref:`Text in PNG File Format`. +""" # APNG frame disposal modes APNG_DISPOSE_OP_NONE = 0 +""" +No disposal is done on this frame before rendering the next frame. +See :ref:`Saving APNG sequences`. +""" APNG_DISPOSE_OP_BACKGROUND = 1 +""" +This frame’s modified region is cleared to fully transparent black before rendering +the next frame. +See :ref:`Saving APNG sequences`. +""" APNG_DISPOSE_OP_PREVIOUS = 2 +""" +This frame’s modified region is reverted to the previous frame’s contents before +rendering the next frame. +See :ref:`Saving APNG sequences`. +""" # APNG frame blend modes APNG_BLEND_OP_SOURCE = 0 +""" +All color components of this frame, including alpha, overwrite the previous output +image contents. +See :ref:`Saving APNG sequences`. +""" APNG_BLEND_OP_OVER = 1 +""" +This frame should be alpha composited with the previous output image contents. +See :ref:`Saving APNG sequences`. +""" def _safe_zlib_decompress(s): diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index 73e9a2763..b56072737 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -776,7 +776,7 @@ class ImageFileDirectory_v2(MutableMapping): self.tagtype[tag] = typ msg += " - value: " + ( - "" % size if size > 32 else str(data) + "" % size if size > 32 else repr(data) ) logger.debug(msg) @@ -993,7 +993,7 @@ class TiffImageFile(ImageFile.ImageFile): logger.debug("*** TiffImageFile._open ***") logger.debug("- __first: {}".format(self.__first)) - logger.debug("- ifh: {}".format(ifh)) + logger.debug("- ifh: {!r}".format(ifh)) # Use !r to avoid str(bytes) # and load the first frame self._seek(0) diff --git a/src/libImaging/Imaging.h b/src/libImaging/Imaging.h index 47f577139..d7dbe0325 100644 --- a/src/libImaging/Imaging.h +++ b/src/libImaging/Imaging.h @@ -185,8 +185,6 @@ extern Imaging ImagingNew2Dirty(const char* mode, Imaging imOut, Imaging imIn); extern void ImagingDelete(Imaging im); extern Imaging ImagingNewBlock(const char* mode, int xsize, int ysize); -extern Imaging ImagingNewMap(const char* filename, int readonly, - const char* mode, int xsize, int ysize); extern Imaging ImagingNewPrologue(const char *mode, int xsize, int ysize); @@ -348,9 +346,6 @@ extern Imaging ImagingChopAnd(Imaging imIn1, Imaging imIn2); extern Imaging ImagingChopOr(Imaging imIn1, Imaging imIn2); extern Imaging ImagingChopXor(Imaging imIn1, Imaging imIn2); -/* Image measurement */ -extern void ImagingCrack(Imaging im, int x0, int y0); - /* Graphics */ extern int ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1, float start, float end, const void* ink, int width, @@ -396,10 +391,6 @@ extern Imaging ImagingEffectNoise(int xsize, int ysize, float sigma); extern Imaging ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality); -/* Obsolete */ -extern int ImagingToString(Imaging im, int orientation, char *buffer); -extern int ImagingFromString(Imaging im, int orientation, char *buffer); - /* File I/O */ /* -------- */ @@ -408,9 +399,6 @@ extern int ImagingFromString(Imaging im, int orientation, char *buffer); extern Imaging ImagingOpenPPM(const char* filename); extern int ImagingSavePPM(Imaging im, const char* filename); -/* Utility functions */ -extern UINT32 ImagingCRC32(UINT32 crc, UINT8* buffer, int bytes); - /* Codecs */ typedef struct ImagingCodecStateInstance *ImagingCodecState; typedef int (*ImagingCodec)(Imaging im, ImagingCodecState state, @@ -473,7 +461,6 @@ extern int ImagingRawEncode(Imaging im, ImagingCodecState state, UINT8* buffer, int bytes); extern int ImagingSgiRleDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t bytes); -extern int ImagingSgiRleDecodeCleanup(ImagingCodecState state); extern int ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t bytes); extern int ImagingTgaRleDecode(Imaging im, ImagingCodecState state,