Merge branch 'master' into block-storage

# Conflicts:
#	docs/releasenotes/4.3.0.rst
This commit is contained in:
Alexander 2017-09-23 04:07:09 +03:00
commit b51d77e4e5
22 changed files with 185 additions and 100 deletions

View File

@ -4,6 +4,9 @@ Changelog (Pillow)
4.3.0 (unreleased)
------------------
- Fixed support for building on Windows/msys2. Added Appveyor CI coverage for python3 on msys2 #2476
[wiredfool]
- Fix ValueError in Exif/Tiff IFD #2719
[wiredfool]

View File

@ -72,8 +72,7 @@ class ContainerIO(object):
"""
Read data.
@def read(bytes=0)
:param bytes: Number of bytes to read. If omitted or zero,
:param n: Number of bytes to read. If omitted or zero,
read until end of region.
:returns: An 8-bit string.
"""

View File

@ -767,7 +767,7 @@ def getdata(im, offset=(0, 0), **params):
:param im: Image object
:param offset: Tuple of (x, y) pixels. Defaults to (0,0)
:param **params: E.g. duration or other encoder info parameters
:param \**params: E.g. duration or other encoder info parameters
:returns: List of Bytes containing gif encoded frame data
"""

View File

@ -10,6 +10,8 @@ environment:
EXECUTABLE: python.exe
PIP_DIR: Scripts
VENV: NO
TEST_OPTIONS:
DEPLOY: YES
matrix:
- PYTHON: C:/vp/pypy2
EXECUTABLE: bin/pypy.exe
@ -21,6 +23,11 @@ environment:
- PYTHON: C:/Python34-x64
- PYTHON: C:/Python33
- PYTHON: C:/Python33-x64
- PYTHON: C:/msys64/mingw32
EXECUTABLE: bin/python3
PIP_DIR: bin
TEST_OPTIONS: --processes=0
DEPLOY: NO
install:
@ -36,19 +43,38 @@ install:
{
c:\pillow\winbuild\appveyor_install_pypy.cmd
}
- c:\python34\python.exe c:\pillow\winbuild\build_dep.py
- c:\pillow\winbuild\build_deps.cmd
- ps: |
if ($env:PYTHON -eq "c:/msys64/mingw32")
{
c:\msys64\usr\bin\bash -l -c c:\\pillow\\winbuild\\appveyor_install_msys2_deps.sh
}
else
{
c:\python34\python.exe c:\pillow\winbuild\build_dep.py
c:\pillow\winbuild\build_deps.cmd
$host.SetShouldExit(0)
}
build_script:
- '%PYTHON%\%EXECUTABLE% c:\pillow\winbuild\build.py'
- ps: |
if ($env:PYTHON -eq "c:/msys64/mingw32")
{
c:\msys64\usr\bin\bash -l -c c:\\pillow\\winbuild\\appveyor_build_msys2.sh
Write-Host "through install"
$host.SetShouldExit(0)
}
else
{
& $env:PYTHON/$env:EXECUTABLE c:\pillow\winbuild\build.py
$host.SetShouldExit(0)
}
- cd c:\pillow
- dir dist\*.egg
- '%PYTHON%\%EXECUTABLE% selftest.py --installed'
test_script:
- cd c:\pillow
- '%PYTHON%\%PIP_DIR%\pip.exe install nose'
- '%PYTHON%\%EXECUTABLE% test-installed.py -v -s'
- '%PYTHON%\%EXECUTABLE% test-installed.py -v -s %TEST_OPTIONS%'
matrix:
fast_finish: true
@ -59,7 +85,7 @@ artifacts:
- path: pillow\dist\*.wheel
name: wheel
after_test:
before_deploy:
- '%PYTHON%\%PIP_DIR%\pip.exe install wheel'
- cd c:\pillow\winbuild\
- '%PYTHON%\%EXECUTABLE% c:\pillow\winbuild\build.py --wheel'
@ -77,6 +103,8 @@ deploy:
artifact: /.*egg|wheel/
on:
branch: master
deploy: YES
# Uncomment the following line to get RDP access after the build/test and block for
# up to the timeout limit (~1hr)

View File

@ -32,12 +32,6 @@ Install Pillow with :command:`pip`::
$ pip install Pillow
Or use :command:`easy_install` for installing `Python Eggs
<http://peak.telecommunity.com/DevCenter/PythonEggs>`_ as
:command:`pip` does not support them::
$ easy_install Pillow
Windows Installation
^^^^^^^^^^^^^^^^^^^^
@ -49,10 +43,6 @@ libraries included::
> pip install Pillow
or::
> easy_install Pillow
macOS Installation
^^^^^^^^^^^^^^^^^^
@ -339,6 +329,20 @@ Prerequisites are installed on **Fedora 23** with::
$ sudo dnf install libtiff-devel libjpeg-devel zlib-devel freetype-devel \
lcms2-devel libwebp-devel tcl-devel tk-devel libraqm-devel
See also the ``Dockerfile``\s in the Test Infrastructure repo
(https://github.com/python-pillow/docker-images) for a known working
install process for other tested distros.
Building on Android
^^^^^^^^^^^^^^^^^^^
Basic Android support has been added for compilation within the Termux
environment. The dependencies can be installed by::
$ pkg -y install python python-dev ndk-sysroot clang make \
libjpeg-turbo-dev
This has been tested within the Termux app on ChromeOS, on x86.
Platform Support
@ -348,8 +352,7 @@ Current platform support for Pillow. Binary distributions are
contributed for each release on a volunteer basis, but the source
should compile and run everywhere platform support is listed. In
general, we aim to support all current versions of Linux, macOS, and
Windows. Note that Android is not currently supported, but there have
been reports of success.
Windows.
Continuous Integration Targets
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -369,6 +372,10 @@ These platforms are built and tested for every change.
+----------------------------------+-------------------------------+-----------------------+
| Debian Stretch | 2.7 |x86 |
+----------------------------------+-------------------------------+-----------------------+
| Fedora 24 | 2.7 |x86-64 |
+----------------------------------+-------------------------------+-----------------------+
| Fedora 26 | 2.7 |x86-64 |
+----------------------------------+-------------------------------+-----------------------+
| Mac OS X 10.10 Yosemite* | 2.7, 3.3, 3.4, 3.5, 3.6 |x86-64 |
+----------------------------------+-------------------------------+-----------------------+
| Ubuntu Linux 16.04 LTS | 2.7 |x86-64 |
@ -380,7 +387,9 @@ These platforms are built and tested for every change.
+----------------------------------+-------------------------------+-----------------------+
| Ubuntu Linux 12.04 LTS | 2.7 |x86-64 |
+----------------------------------+-------------------------------+-----------------------+
| Windows Server 2012 R2 | 2.7,3.3,3.4,pypy |x86, x86-64 |
| Windows Server 2012 R2 | 2.7,3.3,3.4 |x86, x86-64 |
| | | |
| | pypy, 3.5/mingw |x86 |
+----------------------------------+-------------------------------+-----------------------+
\* Mac OS X CI is not run for every commit, but is run for every release.

View File

@ -1,53 +1,19 @@
4.3.0
-----
Get One Channel From Image
==========================
New method :py:meth:`PIL.Image.Image.getchannel` is added.
It returns single channel by index or name. For example,
``image.getchannel("A")`` will return alpha channel as separate image.
``getchannel`` should work up to 6 times faster than ``image.split()[0]``
in previous Pillow versions.
Box Blur
========
New filter :py:class:`PIL.ImageFilter.BoxBlur` is added.
Partial Resampling
==================
Added new argument ``box`` for :py:meth:`PIL.Image.Image.resize`. This
argument defines a source rectangle from within the source image to be
resized. This is very similar to the ``image.crop(box).resize(size)``
sequence except that ``box`` can be specified with subpixel accuracy.
Loading 16-bit TIFF Images
==========================
Pillow now can read 16-bit multichannel TIFF files including files
with alpha transparency. The image data is truncated to 8-bit
precision.
Performance
API Changes
===========
This release contains several performance improvements:
* Many memory bandwidth-bounded operations such as crop, image allocation,
conversion, split into bands and merging from bands are up to 2x faster.
* Upscaling of multichannel images (such as RGB) is accelerated by 5-10%
* JPEG loading is accelerated up to 15% and JPEG saving up to 20% when
using a recent version of libjpeg-turbo.
Deprecations
^^^^^^^^^^^^
Several undocumented functions in ImageOps have been deprecated:
``gaussian_blur``, ``gblur``, ``unsharp_mask``, ``usm`` and
``box_blur``. Use the equivalent operations in ImageFilter
instead. These functions will be removed in a future release.
TIFF Metadata Changes
=====================
^^^^^^^^^^^^^^^^^^^^^
* TIFF tags with unknown type/quantity now default to being bare
values if they are 1 element, where previously they would be a
@ -61,9 +27,8 @@ TIFF Metadata Changes
items, as there can be multiple items, one for UTF-8, and one for
UTF-16.
Core Image API Changes
======================
^^^^^^^^^^^^^^^^^^^^^^
These are internal functions that should not have been used by user
code, but they were accessible from the python layer.
@ -77,3 +42,70 @@ have been removed.
The ``PIL.Image.core.getcount`` methods have been removed, use
``PIL.Image.core.get_stats()['new_count']`` property instead.
API Additions
=============
Get One Channel From Image
^^^^^^^^^^^^^^^^^^^^^^^^^^
A new method :py:meth:`PIL.Image.Image.getchannel` has been added to
return a single channel by index or name. For example,
``image.getchannel("A")`` will return alpha channel as separate image.
``getchannel`` should work up to 6 times faster than
``image.split()[0]`` in previous Pillow versions.
Box Blur
^^^^^^^^
A new filter, :py:class:`PIL.ImageFilter.BoxBlur`, has been
added. This is a filter with similar results to a Gaussian blur, but
is much faster.
Partial Resampling
^^^^^^^^^^^^^^^^^^
Added new argument ``box`` for :py:meth:`PIL.Image.Image.resize`. This
argument defines a source rectangle from within the source image to be
resized. This is very similar to the ``image.crop(box).resize(size)``
sequence except that ``box`` can be specified with subpixel accuracy.
New Transpose Operation
^^^^^^^^^^^^^^^^^^^^^^^
The ``Image.TRANSVERSE`` operation has been added to
:py:meth:`PIL.Image.Image.transpose`. This is equivalent to a transpose
operation about the opposite diagonal.
Multiband Filters
^^^^^^^^^^^^^^^^^
There is a new :py:class:`PIL.ImageFilter.MultibandFilter` base class
for image filters that can run on all channels of an image in one
operation. The original :py:class:`PIL.ImageFilter.Filter` class
remains for image filters that can process only single band images, or
require splitting of channels prior to filtering.
Loading 16-bit TIFF Images
==========================
Pillow now can read 16-bit multichannel TIFF files including files
with alpha transparency. The image data is truncated to 8-bit
precision.
Performance
===========
This release contains several performance improvements:
* Many memory bandwidth-bounded operations such as crop, image allocation,
conversion, split into bands and merging from bands are up to 2x faster.
* Upscaling of multichannel images (such as RGB) is accelerated by 5-10%
* JPEG loading is accelerated up to 15% and JPEG saving up to 20% when
using a recent version of libjpeg-turbo.
* ``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.

View File

@ -47,8 +47,6 @@ ImagingAlphaComposite(Imaging imDst, Imaging imSrc)
if (!imOut)
return NULL;
ImagingCopyInfo(imOut, imDst);
for (y = 0; y < imDst->ysize; y++) {
rgba8* dst = (rgba8*) imDst->image[y];
rgba8* src = (rgba8*) imSrc->image[y];

View File

@ -26,8 +26,11 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha)
int x, y;
/* Check arguments */
if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8)
return ImagingError_ModeError();
if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8
|| imIn1->palette || strcmp(imIn1->mode, "1") == 0
|| imIn2->palette || strcmp(imIn2->mode, "1") == 0)
return ImagingError_ModeError();
if (imIn1->type != imIn2->type ||
imIn1->bands != imIn2->bands ||
imIn1->xsize != imIn2->xsize ||
@ -44,8 +47,6 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha)
if (!imOut)
return NULL;
ImagingCopyInfo(imOut, imIn1);
if (alpha >= 0 && alpha <= 1.0) {
/* Interpolate between bands */
for (y = 0; y < imIn1->ysize; y++) {

View File

@ -32,7 +32,7 @@ _copy(Imaging imOut, Imaging imIn)
if (!imOut)
return NULL;
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
ImagingSectionEnter(&cookie);
if (imIn->block != NULL && imOut->block != NULL)

View File

@ -41,7 +41,7 @@ ImagingCrop(Imaging imIn, int sx0, int sy0, int sx1, int sy1)
if (!imOut)
return NULL;
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
if (sx0 < 0 || sy0 < 0 || sx1 > imIn->xsize || sy1 > imIn->ysize)
(void) ImagingFill(imOut, &zero);

View File

@ -144,7 +144,7 @@ ImagingEffectSpread(Imaging imIn, int distance)
SPREAD(INT32, image32);
}
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
return imOut;
}

View File

@ -78,7 +78,7 @@ ImagingExpand(Imaging imIn, int xmargin, int ymargin, int mode)
}
ImagingSectionLeave(&cookie);
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
return imOut;
}

View File

@ -25,7 +25,7 @@ ImagingFlipLeftRight(Imaging imOut, Imaging imIn)
if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize)
return (Imaging) ImagingError_Mismatch();
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
#define FLIP_LEFT_RIGHT(INT, image) \
for (y = 0; y < imIn->ysize; y++) { \
@ -63,7 +63,7 @@ ImagingFlipTopBottom(Imaging imOut, Imaging imIn)
if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize)
return (Imaging) ImagingError_Mismatch();
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
ImagingSectionEnter(&cookie);
@ -89,7 +89,7 @@ ImagingRotate90(Imaging imOut, Imaging imIn)
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize)
return (Imaging) ImagingError_Mismatch();
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
#define ROTATE_90(INT, image) \
for (y = 0; y < imIn->ysize; y += ROTATE_CHUNK) { \
@ -139,7 +139,7 @@ ImagingTranspose(Imaging imOut, Imaging imIn)
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize)
return (Imaging) ImagingError_Mismatch();
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
#define TRANSPOSE(INT, image) \
for (y = 0; y < imIn->ysize; y += ROTATE_CHUNK) { \
@ -188,7 +188,7 @@ ImagingTransverse(Imaging imOut, Imaging imIn)
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize)
return (Imaging) ImagingError_Mismatch();
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
#define TRANSVERSE(INT, image) \
for (y = 0; y < imIn->ysize; y += ROTATE_CHUNK) { \
@ -238,7 +238,7 @@ ImagingRotate180(Imaging imOut, Imaging imIn)
if (imIn->xsize != imOut->xsize || imIn->ysize != imOut->ysize)
return (Imaging) ImagingError_Mismatch();
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
#define ROTATE_180(INT, image) \
for (y = 0; y < imIn->ysize; y++, yr--) { \
@ -278,7 +278,7 @@ ImagingRotate270(Imaging imOut, Imaging imIn)
if (imIn->xsize != imOut->ysize || imIn->ysize != imOut->xsize)
return (Imaging) ImagingError_Mismatch();
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
#define ROTATE_270(INT, image) \
for (y = 0; y < imIn->ysize; y += ROTATE_CHUNK) { \
@ -717,7 +717,7 @@ ImagingGenericTransform(
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0)
return (Imaging) ImagingError_ModeError();
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
ImagingSectionEnter(&cookie);
@ -764,7 +764,7 @@ ImagingScaleAffine(Imaging imOut, Imaging imIn,
if (!imOut || !imIn || strcmp(imIn->mode, imOut->mode) != 0)
return (Imaging) ImagingError_ModeError();
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
if (x0 < 0)
x0 = 0;
@ -854,7 +854,7 @@ affine_fixed(Imaging imOut, Imaging imIn,
int xx, yy;
int a0, a1, a2, a3, a4, a5;
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
xsize = (int) imIn->xsize;
ysize = (int) imIn->ysize;
@ -956,7 +956,7 @@ ImagingTransformAffine(Imaging imOut, Imaging imIn,
following code is used. maybe we should fall back on the slow
generic transform engine in this case? */
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
xsize = (int) imIn->xsize;
ysize = (int) imIn->ysize;

View File

@ -194,7 +194,7 @@ extern Imaging ImagingNewPrologueSubtype(const char *mode,
int xsize, int ysize,
int structure_size);
extern void ImagingCopyInfo(Imaging destination, Imaging source);
extern void ImagingCopyPalette(Imaging destination, Imaging source);
extern void ImagingHistogramDelete(ImagingHistogram histogram);

View File

@ -72,7 +72,7 @@ ImagingModeFilter(Imaging im, int size)
}
ImagingCopyInfo(imOut, im);
ImagingCopyPalette(imOut, im);
return imOut;
}

View File

@ -31,7 +31,7 @@ ImagingOffset(Imaging im, int xoffset, int yoffset)
if (!imOut)
return NULL;
ImagingCopyInfo(imOut, im);
ImagingCopyPalette(imOut, im);
/* make offsets positive to avoid negative coordinates */
xoffset %= im->xsize;

View File

@ -180,7 +180,7 @@ ImagingPoint(Imaging imIn, const char* mode, const void* table)
} else
point = im_point_32_8;
ImagingCopyInfo(imOut, imIn);
ImagingCopyPalette(imOut, imIn);
ImagingSectionEnter(&cookie);
@ -216,8 +216,6 @@ ImagingPointTransform(Imaging imIn, double scale, double offset)
if (!imOut)
return NULL;
ImagingCopyInfo(imOut, imIn);
switch (imIn->type) {
case IMAGING_TYPE_INT32:
ImagingSectionEnter(&cookie);

View File

@ -103,7 +103,7 @@ ImagingRankFilter(Imaging im, int size, int rank)
return (Imaging) ImagingError_ModeError();
}
ImagingCopyInfo(imOut, im);
ImagingCopyPalette(imOut, im);
return imOut;

View File

@ -24,7 +24,7 @@
* 1998-10-26 fl Added "I;16" and "I;16B" storage modes (experimental)
* 1998-12-29 fl Fixed allocation bug caused by previous fix
* 1999-02-03 fl Added "RGBa" and "BGR" modes (experimental)
* 2001-04-22 fl Fixed potential memory leak in ImagingCopyInfo
* 2001-04-22 fl Fixed potential memory leak in ImagingCopyPalette
* 2003-09-26 fl Added "LA" and "PA" modes (experimental)
* 2005-10-02 fl Added image counter
*
@ -567,7 +567,7 @@ ImagingNew2Dirty(const char* mode, Imaging imOut, Imaging imIn)
}
void
ImagingCopyInfo(Imaging destination, Imaging source)
ImagingCopyPalette(Imaging destination, Imaging source)
{
if (source->palette) {
if (destination->palette)

View File

@ -17,7 +17,7 @@ import sys
import subprocess
from distutils.command.build_ext import build_ext
from distutils import sysconfig
from distutils import sysconfig, ccompiler
from setuptools import Extension, setup, find_packages
# monkey patch import hook. Even though flake8 says it's not used, it is.
@ -44,6 +44,9 @@ DEBUG = False
class DependencyException(Exception): pass
class RequiredDependencyException(Exception): pass
PLATFORM_MINGW = 'mingw' in ccompiler.get_default_compiler()
PLATFORM_PYPY = hasattr(sys, 'pypy_version_info')
def _dbg(s, tp=None):
if DEBUG:
if tp:
@ -607,7 +610,7 @@ class pil_build_ext(build_ext):
if struct.unpack("h", "\0\1".encode('ascii'))[0] == 1:
defs.append(("WORDS_BIGENDIAN", None))
if sys.platform == "win32" and not hasattr(sys, 'pypy_version_info'):
if sys.platform == "win32" and not (PLATFORM_PYPY or PLATFORM_MINGW):
defs.append(("PILLOW_VERSION", '"\\"%s\\""'%PILLOW_VERSION))
else:
defs.append(("PILLOW_VERSION", '"%s"'%PILLOW_VERSION))
@ -781,7 +784,7 @@ try:
test_suite='nose.collector',
keywords=["Imaging", ],
license='Standard PIL License',
zip_safe=not debug_build(), )
zip_safe=not (debug_build() or PLATFORM_MINGW), )
except RequiredDependencyException as err:
msg = """

View File

@ -0,0 +1,3 @@
#!/bin/sh
cd /c/pillow && /mingw32/$EXECUTABLE setup.py install

View File

@ -0,0 +1,11 @@
#!/bin/sh
pacman -S --noconfirm mingw32/mingw-w64-i686-python3 \
mingw32/mingw-w64-i686-python3-pip \
mingw32/mingw-w64-i686-python3-setuptools \
mingw32/mingw-w64-i686-python2-pip \
mingw32/mingw-w64-i686-python2-setuptools \
mingw-w64-i686-libjpeg-turbo
/mingw32/bin/pip install nose olefile
/mingw32/bin/pip3 install nose olefile