Merge branch 'master' into tifftags

This commit is contained in:
wiredfool 2013-10-02 22:30:01 -07:00
commit 30e6c6d1ab
24 changed files with 420 additions and 301 deletions

View File

@ -1,9 +1,33 @@
Changelog (Pillow)
==================
2.2.0 (2013-10-01)
2.2.1 (2013-10-02)
------------------
- Fix #356: Error installing Pillow 2.2.0 on Mac OS X (due to hard dep on brew)
[wiredfool]
2.2.0 (2013-10-02)
------------------
- Fix #254: Bug in image transformations resulting from uninitialized memory
[nikmolnar]
- Fix for encoding of b_whitespace, similar to closed issue #272
[mhogg]
- Fix #273: Add numpy array interface support for 16 and 32 bit integer modes
[cgohlke]
- Partial fix for #290: Add preliminary support for TIFF tags.
[wiredfool]
- Fix #251 and #326: circumvent classification of pngtest_bad.png as malware
[cgohlke]
- Add typedef uint64_t for MSVC.
[cgohlke]
- Fix #329: setup.py: better support for C_INCLUDE_PATH, LD_RUN_PATH, etc.
[nu774]

View File

@ -1,7 +1,7 @@
Contributors (Pillow)
=====================
.. Note:: New contributors: please add your name here and send a pull request
.. Note:: Contributors: please add your name here
- Alex Po <alex-86p __at__ yandex.ru>
- Anton Vlasenko <antares.spica __at__ gmail.com>

View File

@ -1,21 +1,52 @@
exclude .hgignore
exclude .hgtags
exclude BUILDME.bat
exclude make-manifest.py
exclude SHIP
exclude SHIP.bat
include *.rst
include *.c
include *.h
include selftest.py tox.ini
include COPYING
recursive-include Tests *.py *.txt
graft Tests/fonts
graft Tests/icc
graft Tests/images
recursive-include Scripts *.py README
graft Images
recursive-include docs *.txt *.html *.rst *.css *.py README CHANGES CONTENTS Makefile make.bat BUILDME LICENSE COPYING
recursive-include libImaging *.c *.h
recursive-include Tk *.c *.txt
recursive-include Sane *.c *.txt CHANGES README *.py
include *.py
include *.rst
include .gitattributes
include .travis.yml
include Makefile
include tox.ini
recursive-include Images *.bdf
recursive-include Images *.fli
recursive-include Images *.gif
recursive-include Images *.ico
recursive-include Images *.jpg
recursive-include Images *.pbm
recursive-include Images *.pil
recursive-include Images *.png
recursive-include Images *.ppm
recursive-include Images *.psd
recursive-include Images *.tar
recursive-include Images *.webp
recursive-include Images *.xpm
recursive-include Sane *.c
recursive-include Sane *.py
recursive-include Sane *.txt
recursive-include Sane CHANGES
recursive-include Sane README
recursive-include Scripts *.py
recursive-include Scripts README
recursive-include Tests *.bin
recursive-include Tests *.icm
recursive-include Tests *.jpg
recursive-include Tests *.pcf
recursive-include Tests *.pcx
recursive-include Tests *.png
recursive-include Tests *.ppm
recursive-include Tests *.py
recursive-include Tests *.tif
recursive-include Tests *.tiff
recursive-include Tests *.ttf
recursive-include Tests *.txt
recursive-include Tk *.c
recursive-include Tk *.txt
recursive-include docs *.bat
recursive-include docs *.gitignore
recursive-include docs *.py
recursive-include docs *.rst
recursive-include docs Makefile
recursive-include docs BUILDME
recursive-include docs COPYING
recursive-include docs LICENSE
recursive-include libImaging *.c
recursive-include libImaging *.h

7
Makefile Normal file
View File

@ -0,0 +1,7 @@
pre:
bin/python setup.py develop
bin/python selftest.py
bin/python Tests/run.py
check-manifest
pyroma .
viewdoc

View File

@ -224,6 +224,18 @@ _MODE_CONV = {
"RGBA": ('|u1', 4),
"CMYK": ('|u1', 4),
"YCbCr": ('|u1', 3),
"I;16": ('=u2', None),
"I;16B": ('>u2', None),
"I;16L": ('<u2', None),
"I;16S": ('=i2', None),
"I;16BS": ('>i2', None),
"I;16LS": ('<i2', None),
"I;32": ('=u4', None),
"I;32B": ('>u4', None),
"I;32L": ('<u4', None),
"I;32S": ('=i4', None),
"I;32BS": ('>i4', None),
"I;32LS": ('<i4', None),
}
def _conv_type_shape(im):

View File

@ -359,51 +359,55 @@ class JpegImageFile(ImageFile.ImageFile):
self.tile = []
def _getexif(self):
# Extract EXIF information. This method is highly experimental,
# and is likely to be replaced with something better in a future
# version.
from PIL import TiffImagePlugin
import io
def fixup(value):
if len(value) == 1:
return value[0]
return value
# The EXIF record consists of a TIFF file embedded in a JPEG
# application marker (!).
try:
data = self.info["exif"]
except KeyError:
return None
file = io.BytesIO(data[6:])
head = file.read(8)
exif = {}
# process dictionary
return _getexif(self)
def _getexif(self):
# Extract EXIF information. This method is highly experimental,
# and is likely to be replaced with something better in a future
# version.
from PIL import TiffImagePlugin
import io
def fixup(value):
if len(value) == 1:
return value[0]
return value
# The EXIF record consists of a TIFF file embedded in a JPEG
# application marker (!).
try:
data = self.info["exif"]
except KeyError:
return None
file = io.BytesIO(data[6:])
head = file.read(8)
exif = {}
# process dictionary
info = TiffImagePlugin.ImageFileDirectory(head)
info.load(file)
for key, value in info.items():
exif[key] = fixup(value)
# get exif extension
try:
file.seek(exif[0x8769])
except KeyError:
pass
else:
info = TiffImagePlugin.ImageFileDirectory(head)
info.load(file)
for key, value in info.items():
exif[key] = fixup(value)
# get exif extension
try:
file.seek(exif[0x8769])
except KeyError:
pass
else:
info = TiffImagePlugin.ImageFileDirectory(head)
info.load(file)
for key, value in info.items():
exif[key] = fixup(value)
# get gpsinfo extension
try:
file.seek(exif[0x8825])
except KeyError:
pass
else:
info = TiffImagePlugin.ImageFileDirectory(head)
info.load(file)
exif[0x8825] = gps = {}
for key, value in info.items():
gps[key] = fixup(value)
return exif
# get gpsinfo extension
try:
file.seek(exif[0x8825])
except KeyError:
pass
else:
info = TiffImagePlugin.ImageFileDirectory(head)
info.load(file)
exif[0x8825] = gps = {}
for key, value in info.items():
gps[key] = fixup(value)
return exif
# --------------------------------------------------------------------
# stuff to save JPEG files

View File

@ -24,7 +24,15 @@ from PIL import Image, ImageFile
#
# --------------------------------------------------------------------
b_whitespace = string.whitespace.encode('ascii','ignore')
b_whitespace = string.whitespace
try:
import locale
locale_lang,locale_enc = locale.getlocale()
if locale_enc is None:
locale_lang,locale_enc = locale.getdefaultlocale()
b_whitespace = b_whitespace.decode(locale_enc)
except: pass
b_whitespace = b_whitespace.encode('ascii','ignore')
MODES = {
# standard

View File

@ -39,8 +39,8 @@ class WebPImageFile(ImageFile.ImageFile):
self.tile = [("raw", (0, 0) + self.size, 0, self.mode)]
def _getexif(self):
from PIL.JpegImagePlugin import JpegImageFile
return JpegImageFile._getexif.im_func(self)
from PIL.JpegImagePlugin import _getexif
return _getexif(self)
def _save(im, fp, filename):

View File

@ -12,7 +12,7 @@
# ;-)
VERSION = '1.1.7' # PIL version
PILLOW_VERSION = '2.1.0' # Pillow
PILLOW_VERSION = '2.2.1' # Pillow
_plugins = ['ArgImagePlugin',
'BmpImagePlugin',

17
PIL/tests.py Normal file
View File

@ -0,0 +1,17 @@
import unittest
class PillowTests(unittest.TestCase):
"""
Can we start moving the test suite here?
"""
def test_suite_should_move_here(self):
"""
Great idea!
"""
assert True is True
if __name__ == '__main__':
unittest.main()

View File

@ -1,18 +1,20 @@
Pillow
======
.. Note:: Pillow < 2.0.0 supports Python versions 2.4, 2.5, 2.6, 2.7; Pillow >= 2.0.0 supports Python versions 2.6, 2.7, 3.2, 3.3.
*Python Imaging Library (Fork)*
.. Note:: Pillow >= 2.1.0 no longer supports "import _imaging". Please use "from PIL.Image import core as _imaging" instead.
Pillow is the "friendly" PIL fork by Alex Clark and Contributors. PIL is the Python Imaging Library by Fredrik Lundh and Contributors.
.. image:: https://travis-ci.org/python-imaging/Pillow.png
:target: https://travis-ci.org/python-imaging/Pillow
Pillow is the "friendly" PIL fork by Alex Clark and Contributors. PIL is the Python Imaging Library by Fredrik Lundh and Contributors.
Introduction
------------
.. Note:: Pillow >= 2.1.0 no longer supports "import _imaging". Please use "from PIL.Image import core as _imaging" instead.
.. Note:: Pillow < 2.0.0 supports Python versions 2.4, 2.5, 2.6, 2.7; Pillow >= 2.0.0 supports Python versions 2.6, 2.7, 3.2, 3.3.
The fork author's goal is to foster active development of PIL through:
- Continuous integration testing via `Travis CI <https://travis-ci.org/python-imaging/Pillow>`_
@ -45,21 +47,30 @@ Installation
.. Note:: PIL and Pillow currently cannot co-exist in the same environment. If you want to use Pillow, please remove PIL first.
TL;DR:
::
You can install Pillow with ``pip``::
$ pip install Pillow
For more information, please see http://python-imaging.github.io/ or below.
Or ``easy_install`` (for installing `Python Eggs <http://peak.telecommunity.com/DevCenter/PythonEggs>`_, as pip does not support them)::
$ easy_install Pillow
Or download the compressed archive from PyPI, extract it, and inside it run::
$ python setup.py install
For more information, please see http://pillow.readthedocs.org/en/latest/ or below.
Documentation
-------------
The API documentation included with PIL has been converted (from HTML generated by pythondoc) to reStructured text (via pandoc) and is now `hosted by readthedocs.org <http://pillow.readthedocs.org>`_. This is a work in progress: in order to re-generate new API documentation, either `pythondoc <http://effbot.org/zone/pythondoc.htm>`_ will have to be run again or the pythondoc functionality must be converted to Sphinx.
Community
---------
Community Support
-----------------
Developer
~~~~~~~~~
PIL needs you! Please help us maintain the Python Imaging Library here:
@ -67,14 +78,12 @@ PIL needs you! Please help us maintain the Python Imaging Library here:
- Freenode (irc://irc.freenode.net#pil)
- Image-SIG (http://mail.python.org/mailman/listinfo/image-sig)
Support
~~~~~~~
Financial
~~~~~~~~~
If you don't want to help with development, you can help us financially. Your donation will be very much appreciated.
Pillow is a volunteer effort led by Alex Clark. If you can't help with development, please help us financially; your assistance is very much needed and appreciated!
.. Note:: New contributors: please add your name (and donation preference) here and send a pull request.
Pillow is a (labor of love) volunteer effort led by Alex Clark. Any contributor interested in receiving donations for their Pillow contributions may add their name (and donation preference) here.
.. Note:: Contributors: please add your name and donation preference here.
+--------------------------------------+---------------------------------------+
| **Developer** | **Preference** |
@ -82,15 +91,15 @@ Pillow is a (labor of love) volunteer effort led by Alex Clark. Any contributor
| Alex Clark (fork author) | http://gittip.com/aclark4life |
+--------------------------------------+---------------------------------------+
Developer
---------
Developer Notes
---------------
.. Note:: If there is a binary package for your system, that is the easiest way to install Pillow. Currently we only provide binaries for Windows (via Python eggs).
Build from source
~~~~~~~~~~~~~~~~~
Some (most?) of Pillow's features require external libraries.
Many of Pillow's features require external libraries:
* **libjpeg** provides JPEG functionality.
@ -122,7 +131,7 @@ Platform-specific instructions
Linux
+++++
**We don't currently provide binaries for Linux.** If you didn't build Python from source, make sure you have Python's development libraries installed. In Debian or Ubuntu::
**We do not provide binaries for Linux.** If you didn't build Python from source, make sure you have Python's development libraries installed. In Debian or Ubuntu::
$ sudo apt-get install python-dev python-setuptools
@ -141,7 +150,7 @@ Prerequisites are installed with on **Ubuntu 12.04 LTS** or **Raspian Wheezy 7.0
Mac OS X
++++++++
**We don't currently provide binaries for OS X.** So you'll need XCode to install Pillow. (XCode 4.2 on 10.6 will work with the Official Python binary distribution. Otherwise, use whatever XCode you used to compile Python.)
**We do not provide binaries for OS X.** So you'll need XCode to install Pillow. (XCode 4.2 on 10.6 will work with the Official Python binary distribution. Otherwise, use whatever XCode you used to compile Python.)
The easiest way to install the prerequisites is via `Homebrew <http://mxcl.github.com/homebrew/>`_. After you install Homebrew, run::
@ -154,12 +163,26 @@ If you've built your own Python, then you should be able to install Pillow using
Windows
+++++++
.. Note:: Since pip does not support eggs we use easy_install instead.
We provide binaries for Windows in the form of Python Eggs and `Python Wheels <http://wheel.readthedocs.org/en/latest/index.html>`_:
Python Eggs
^^^^^^^^^^^
.. Note:: Pip does not support Python Eggs; use easy_install instead.
::
$ easy_install Pillow
Python Wheels
^^^^^^^^^^^^^
.. Note:: Experimental. Requires Setuptools >=0.8 and Pip >=1.4.1
::
$ pip install --use-wheel Pillow
Platform support
~~~~~~~~~~~~~~~~
@ -167,33 +190,33 @@ Current platform support for Pillow. Binary distributions are contributed for ea
.. Note:: Contributors please test on your platform, edit this document and send a pull request
+----------------------------------+-------------+------------------------------+-----------------------+
|**Operating system** |**Supported**|**Tested Python versions** |**Tested processors** |
+----------------------------------+-------------+------------------------------+-----------------------+
| CentOS 6.3 |Yes | 2.7,3.3 |x86 |
+----------------------------------+-------------+------------------------------+-----------------------+
| Mac OS X 10.8 Mountain Lion |Yes | 2.6,2.7,3.2,3.3 |x86-64 |
+----------------------------------+-------------+------------------------------+-----------------------+
| Mac OS X 10.7 Lion |Yes | 2.7 |x86-64 |
+----------------------------------+-------------+------------------------------+-----------------------+
| Redhat Linux 6 |Yes | 2.6 |x86 |
+----------------------------------+-------------+------------------------------+-----------------------+
| Ubuntu Linux 10.04 LTS |Yes | 2.6 |x86,x86-64 |
+----------------------------------+-------------+------------------------------+-----------------------+
| Ubuntu Linux 12.04 LTS |Yes | 2.6,2.7,3.2,3.3 |x86,x86-64 |
+----------------------------------+-------------+------------------------------+-----------------------+
| Raspian Wheezy |Yes | 2.7,3.2 |arm |
+----------------------------------+-------------+------------------------------+-----------------------+
| Gentoo Linux |Yes | 2.7,3.2 |x86-64 |
+----------------------------------+-------------+------------------------------+-----------------------+
| Windows 7 Pro |Yes | 2.7,3.2 |x86 |
+----------------------------------+-------------+------------------------------+-----------------------+
| Windows Server 2008 R2 Enterprise|Yes | 3.3 |x86-64 |
+----------------------------------+-------------+------------------------------+-----------------------+
| Windows 8 Pro |Yes | 2.6,2.7,3.2,3.3,PyPy1.9 [1]_ |x86 [2]_,x86-64 |
+----------------------------------+-------------+------------------------------+-----------------------+
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
|**Operating system** |**Supported**|**Tested Python versions** |**Tested Pillow versions** |**Tested processors** |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
| CentOS 6.3 |Yes | 2.7,3.3 | |x86 |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
| Mac OS X 10.8 Mountain Lion |Yes | 2.6,2.7,3.2,3.3 | |x86-64 |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
| Mac OS X 10.7 Lion |Yes | 2.7 | 2.2.0 |x86-64 |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
| Redhat Linux 6 |Yes | 2.6 | |x86 |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
| Ubuntu Linux 10.04 LTS |Yes | 2.6 | 2.2.0 |x86,x86-64 |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
| Ubuntu Linux 12.04 LTS |Yes | 2.6,2.7,3.2,3.3 | 2.2.0 |x86,x86-64 |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
| Raspian Wheezy |Yes | 2.7,3.2 | 2.2.0 |arm |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
| Gentoo Linux |Yes | 2.7,3.2 | 2.1.0 |x86-64 |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
| Windows 7 Pro |Yes | 2.7,3.2 | |x86 |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
| Windows Server 2008 R2 Enterprise|Yes | 3.3 | |x86-64 |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
| Windows 8 Pro |Yes | 2.6,2.7,3.2,3.3,PyPy1.9 [1]_ | 2.2.0 |x86 [2]_,x86-64 |
+----------------------------------+-------------+------------------------------+------------------------------+-----------------------+
.. [1] x86 only
.. [1] x86 only, 2.1.0 tested
.. [2] In some cases, x86 support may indicate 32-bit compilation on 64-bit architecture (vs. compilation on 32-bit hardware).
Port existing PIL-based code to Pillow

View File

@ -1,151 +0,0 @@
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
Hqz9H24IVyP3c8UAAAAAAElFTkSuQmCC

Binary file not shown.

View File

@ -212,18 +212,14 @@ def test_roundtrip_text():
def test_scary():
# Check reading of evil PNG file. For information, see:
# http://scary.beasts.org/security/CESA-2004-001.txt
# The first byte is removed from pngtest_bad.png
# to avoid classification as malware.
import base64
file = "Tests/images/pngtest_bad.png.base64"
data = None
with open("Tests/images/pngtest_bad.png.bin", 'rb') as fd:
data = b'\x89' + fd.read()
if py3:
data = base64.decodebytes(open(file, 'rb').read())
else:
data = base64.decodestring(open(file, 'rb').read())
file = BytesIO(data)
assert_exception(IOError, lambda: Image.open(file))
pngfile = BytesIO(data)
assert_exception(IOError, lambda: Image.open(pngfile))
def test_trns_rgb():
# Check writing and reading of tRNS chunks for RGB images.

View File

@ -9,10 +9,6 @@ try:
except:
skip('webp support not installed')
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
def test_read_exif_metadata():
@ -40,7 +36,7 @@ def test_write_exif_metadata():
image = Image.open(file_path)
expected_exif = image.info['exif']
buffer = StringIO()
buffer = BytesIO()
image.save(buffer, "webp", exif=expected_exif)
@ -73,7 +69,7 @@ def test_write_icc_metadata():
image = Image.open(file_path)
expected_icc_profile = image.info['icc_profile']
buffer = StringIO()
buffer = BytesIO()
image.save(buffer, "webp", icc_profile=expected_icc_profile)

View File

@ -2,4 +2,81 @@ from tester import *
from PIL import Image
success()
def test_extent():
im = lena('RGB')
(w,h) = im.size
transformed = im.transform(im.size, Image.EXTENT,
(0,0,
w//2,h//2), # ul -> lr
Image.BILINEAR)
scaled = im.resize((w*2, h*2), Image.BILINEAR).crop((0,0,w,h))
assert_image_similar(transformed, scaled, 10) # undone -- precision?
def test_quad():
# one simple quad transform, equivalent to scale & crop upper left quad
im = lena('RGB')
(w,h) = im.size
transformed = im.transform(im.size, Image.QUAD,
(0,0,0,h//2,
w//2,h//2,w//2,0), # ul -> ccw around quad
Image.BILINEAR)
scaled = im.resize((w*2, h*2), Image.BILINEAR).crop((0,0,w,h))
assert_image_equal(transformed, scaled)
def test_mesh():
# this should be a checkerboard of halfsized lenas in ul, lr
im = lena('RGBA')
(w,h) = im.size
transformed = im.transform(im.size, Image.MESH,
[((0,0,w//2,h//2), # box
(0,0,0,h,
w,h,w,0)), # ul -> ccw around quad
((w//2,h//2,w,h), # box
(0,0,0,h,
w,h,w,0))], # ul -> ccw around quad
Image.BILINEAR)
#transformed.save('transformed.png')
scaled = im.resize((w//2, h//2), Image.BILINEAR)
checker = Image.new('RGBA', im.size)
checker.paste(scaled, (0,0))
checker.paste(scaled, (w//2,h//2))
assert_image_equal(transformed, checker)
# now, check to see that the extra area is (0,0,0,0)
blank = Image.new('RGBA', (w//2,h//2), (0,0,0,0))
assert_image_equal(blank, transformed.crop((w//2,0,w,h//2)))
assert_image_equal(blank, transformed.crop((0,h//2,w//2,h)))
def test_blank_fill():
# attempting to hit
# https://github.com/python-imaging/Pillow/issues/254 reported
#
# issue is that transforms with transparent overflow area
# contained junk from previous images, especially on systems with
# constrained memory. So, attempt to fill up memory with a
# pattern, free it, and then run the mesh test again. Using a 1Mp
# image with 4 bands, for 4 megs of data allocated, x 64. OMM (64
# bit 12.04 VM with 512 megs available, this fails with Pillow <
# a0eaf06cc5f62a6fb6de556989ac1014ff3348ea
#
# Running by default, but I'd totally understand not doing it in
# the future
foo = [Image.new('RGBA',(1024,1024), (a,a,a,a))
for a in range(1,65)]
# Yeah. Watch some JIT optimize this out.
foo = None
test_mesh()

View File

@ -71,8 +71,8 @@ def test_render_equal():
def test_render_multiline():
im = Image.new(mode='RGB', size=(300,100))
ttf = ImageFont.truetype(font_path, font_size)
draw = ImageDraw.Draw(im)
ttf = ImageFont.truetype(font_path, font_size)
line_spacing = draw.textsize('A', font=ttf)[1] + 8
lines = ['hey you', 'you are awesome', 'this looks awkward']
y = 0
@ -80,8 +80,13 @@ def test_render_multiline():
draw.text((0, y), line, font=ttf)
y += line_spacing
target = 'Tests/images/multiline_text.png'
target_img = Image.open(target)
assert_image_equal(im, target_img)
# some versions of freetype have different horizontal spacing.
# setting a tight epsilon, I'm showing the original test failure
# at epsilon = ~38.
assert_image_similar(im, target_img,.5)

View File

@ -1,6 +1,7 @@
from tester import *
from PIL import Image
import struct
try:
import site
@ -56,9 +57,52 @@ def test_numpy_to_image():
assert_image(to_image(numpy.uint8, 4), "RGBA", (10, 10))
# based on an erring example at http://is.gd/6F0esS
# based on an erring example at http://is.gd/6F0esS (which resolves to)
# http://stackoverflow.com/questions/10854903/what-is-causing-dimension-dependent-attributeerror-in-pil-fromarray-function
def test_3d_array():
a = numpy.ones((10, 10, 10), dtype=numpy.uint8)
assert_image(Image.fromarray(a[1, :, :]), "L", (10, 10))
assert_image(Image.fromarray(a[:, 1, :]), "L", (10, 10))
assert_image(Image.fromarray(a[:, :, 1]), "L", (10, 10))
def _test_img_equals_nparray(img, np):
assert_equal(img.size, np.shape[0:2])
px = img.load()
for x in range(0, img.size[0], int(img.size[0]/10)):
for y in range(0, img.size[1], int(img.size[1]/10)):
assert_deep_equal(px[x,y], np[y,x])
def test_16bit():
img = Image.open('Tests/images/12bit.cropped.tif')
np_img = numpy.array(img)
_test_img_equals_nparray(img, np_img)
assert_equal(np_img.dtype, numpy.dtype('uint16'))
def test_to_array():
def _to_array(mode, dtype):
img = lena(mode)
np_img = numpy.array(img)
_test_img_equals_nparray(img, np_img)
assert_equal(np_img.dtype, numpy.dtype(dtype))
modes = [("L", 'uint8'),
("I", 'int32'),
("F", 'float32'),
("RGB", 'uint8'),
("RGBA", 'uint8'),
("RGBX", 'uint8'),
("CMYK", 'uint8'),
("YCbCr", 'uint8'),
("I;16", 'uint16'),
("I;16B", '>u2'),
("I;16L", 'uint16'),
]
for mode in modes:
assert_no_exception(lambda: _to_array(*mode))

View File

@ -67,6 +67,19 @@ def assert_equal(a, b, msg=None):
else:
failure(msg or "got %r, expected %r" % (a, b))
def assert_deep_equal(a, b, msg=None):
try:
if len(a) == len(b):
if all([x==y for x,y in zip(a,b)]):
success()
else:
failure(msg or "got %s, expected %s" % (a,b))
else:
failure(msg or "got length %s, expected %s" % (len(a), len(b)))
except:
assert_equal(a,b,msg)
def assert_match(v, pattern, msg=None):
import re
if re.match(pattern, v):

View File

@ -71,7 +71,7 @@
* See the README file for information on usage and redistribution.
*/
#define PILLOW_VERSION "2.1.0"
#define PILLOW_VERSION "2.2.1"
#include "Python.h"

View File

@ -48,9 +48,9 @@ copyright = u'1997-2011 by Secret Labs AB, 1995-2011 by Fredrik Lundh, 2010-2013
# built documents.
#
# The short X.Y version.
version = '2.1.0'
version = '2.2.0'
# The full version, including alpha/beta/rc tags.
release = '2.1.0'
release = '2.2.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -14,6 +14,7 @@
#ifdef _MSC_VER
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif

View File

@ -36,6 +36,7 @@
#include "Imaging.h"
#include <string.h>
int ImagingNewCount = 0;
@ -333,6 +334,7 @@ ImagingNewBlock(const char *mode, int xsize, int ysize)
im->block = (char *) malloc(bytes);
if (im->block) {
memset(im->block, 0, bytes);
for (y = i = 0; y < im->ysize; y++) {
im->image[y] = im->block + i;

View File

@ -1,3 +1,11 @@
# > pyroma .
# ------------------------------
# Checking .
# Found Pillow
# ------------------------------
# Final rating: 10/10
# Your cheese is so fresh most people think it's a cream: Mascarpone
# ------------------------------
from __future__ import print_function
import glob
import os
@ -74,7 +82,7 @@ except ImportError:
NAME = 'Pillow'
VERSION = '2.1.0'
VERSION = '2.2.1'
TCL_ROOT = None
JPEG_ROOT = None
ZLIB_ROOT = None
@ -169,13 +177,17 @@ class pil_build_ext(build_ext):
# freetype2 ships with X11
_add_directory(library_dirs, "/usr/X11/lib")
_add_directory(include_dirs, "/usr/X11/include")
# if brew is installed, use its lib and include directories
import commands
status, homebrew = commands.getstatusoutput('brew --prefix')
if status == 0:
_add_directory(library_dirs, os.path.join(homebrew, 'lib'))
_add_directory(include_dirs, os.path.join(homebrew, 'include'))
# if homebrew is installed, use its lib and include directories
import subprocess
try:
prefix = subprocess.check_output(['brew', '--prefix'])
if prefix:
prefix = prefix.strip()
_add_directory(library_dirs, os.path.join(prefix, 'lib'))
_add_directory(include_dirs, os.path.join(prefix, 'include'))
except:
pass # homebrew not installed
elif sys.platform.startswith("linux"):
for platform_ in (plat.processor(), plat.architecture()[0]):
@ -560,7 +572,7 @@ class pil_build_ext(build_ext):
setup(
name=NAME,
version=VERSION,
description='Python Imaging Library (fork)',
description='Python Imaging Library (Fork)',
long_description=(
_read('README.rst') + b'\n' +
_read('CHANGES.rst') + b'\n' +
@ -586,10 +598,8 @@ setup(
ext_modules=[Extension("PIL._imaging", ["_imaging.c"])],
include_package_data=True,
packages=find_packages(),
provides=[
'PIL'
],
scripts=glob.glob("Scripts/pil*.py"),
test_suite='PIL.tests',
keywords=["Imaging",],
license='Standard PIL License',
zip_safe=True,