Skip to content

Commit

Permalink
Merge branch 'block-storage' into simd/4.3-demo
Browse files Browse the repository at this point in the history
  • Loading branch information
homm committed Sep 23, 2017
2 parents 912541a + 3859639 commit ce46395
Show file tree
Hide file tree
Showing 24 changed files with 230 additions and 124 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Expand Up @@ -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]

Expand Down
3 changes: 1 addition & 2 deletions PIL/ContainerIO.py
Expand Up @@ -72,8 +72,7 @@ def read(self, n=0):
"""
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.
"""
Expand Down
2 changes: 1 addition & 1 deletion PIL/GifImagePlugin.py
Expand Up @@ -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
"""
Expand Down
7 changes: 4 additions & 3 deletions Tests/test_core_resources.py
Expand Up @@ -129,14 +129,15 @@ def test_clear_cache_stats(self):
Image.core.set_block_size(4096)
Image.new('RGB', (256, 256))
Image.new('RGB', (256, 256))
Image.core.clear_cache()
# Keep 16 blocks in cache
Image.core.clear_cache(16)

stats = Image.core.get_stats()
self.assertGreaterEqual(stats['new_count'], 2)
self.assertGreaterEqual(stats['allocated_blocks'], 64)
self.assertGreaterEqual(stats['reused_blocks'], 64)
self.assertGreaterEqual(stats['freed_blocks'], 64)
self.assertEqual(stats['blocks_cached'], 0)
self.assertGreaterEqual(stats['freed_blocks'], 48)
self.assertEqual(stats['blocks_cached'], 16)

def test_large_images(self):
Image.core.reset_stats()
Expand Down
6 changes: 4 additions & 2 deletions _imaging.c
Expand Up @@ -3466,10 +3466,12 @@ _set_blocks_max(PyObject* self, PyObject* args)
static PyObject*
_clear_cache(PyObject* self, PyObject* args)
{
if (!PyArg_ParseTuple(args, ":clear_cache"))
int i = 0;

if (!PyArg_ParseTuple(args, "|i:clear_cache", &i))
return NULL;

ImagingMemoryClearCache(&ImagingDefaultArena, 0);
ImagingMemoryClearCache(&ImagingDefaultArena, i);

Py_INCREF(Py_None);
return Py_None;
Expand Down
42 changes: 35 additions & 7 deletions appveyor.yml
Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -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
Expand All @@ -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'
Expand All @@ -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)
Expand Down
35 changes: 22 additions & 13 deletions docs/installation.rst
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^
Expand All @@ -49,10 +43,6 @@ libraries included::

> pip install Pillow

or::

> easy_install Pillow


macOS Installation
^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -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
Expand All @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -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 |
Expand All @@ -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.
Expand Down
120 changes: 76 additions & 44 deletions docs/releasenotes/4.3.0.rst
@@ -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
Expand All @@ -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.
Expand All @@ -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.
2 changes: 0 additions & 2 deletions libImaging/AlphaComposite.c
Expand Up @@ -78,8 +78,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];
Expand Down
9 changes: 5 additions & 4 deletions libImaging/Blend.c
Expand Up @@ -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 ||
Expand All @@ -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++) {
Expand Down

0 comments on commit ce46395

Please sign in to comment.