Merge remote-tracking branch 'upstream/master' into flake8_winbuild

Conflicts:
	winbuild/config.py
This commit is contained in:
hugovk 2015-06-30 09:46:11 +03:00
commit 02caa81bfe
25 changed files with 181 additions and 33 deletions

View File

@ -4,9 +4,18 @@ Changelog (Pillow)
2.9.0 (Unreleased) 2.9.0 (Unreleased)
------------------ ------------------
- Update tiff and tk tcl 8.5 versions #1303 - Fixed ValueError in Python 2.6 #1315 #1316
[cgohlke, radarhere]
- Fixed tox test script path #1308
[radarhere] [radarhere]
- Added width and height properties #1304
[radarhere]
- Update tiff and tk tcl 8.5 versions #1303
[radarhere, wiredfool]
- Add functions to convert: Image <-> QImage; Image <-> QPixmap #1217 - Add functions to convert: Image <-> QImage; Image <-> QPixmap #1217
[radarhere, rominf] [radarhere, rominf]

View File

@ -1,14 +1,16 @@
include *.c include *.c
include *.h include *.h
include *.in
include *.md include *.md
include *.py include *.py
include *.sh
include *.rst include *.rst
include *.sh
include *.txt include *.txt
include *.yaml include *.yaml
include *.yml
include .coveragerc include .coveragerc
include .gitattributes include .gitattributes
include .travis.yml
include LICENSE include LICENSE
include Makefile include Makefile
include tox.ini include tox.ini
@ -16,7 +18,6 @@ recursive-include PIL *.md
recursive-include Scripts *.py recursive-include Scripts *.py
recursive-include Scripts *.rst recursive-include Scripts *.rst
recursive-include Scripts *.sh recursive-include Scripts *.sh
recursive-include Scripts README.rst
recursive-include Tests *.bdf recursive-include Tests *.bdf
recursive-include Tests *.bin recursive-include Tests *.bin
recursive-include Tests *.bmp recursive-include Tests *.bmp
@ -33,11 +34,13 @@ recursive-include Tests *.html
recursive-include Tests *.icc recursive-include Tests *.icc
recursive-include Tests *.icns recursive-include Tests *.icns
recursive-include Tests *.ico recursive-include Tests *.ico
recursive-include Tests *.im
recursive-include Tests *.j2k recursive-include Tests *.j2k
recursive-include Tests *.jp2 recursive-include Tests *.jp2
recursive-include Tests *.jpg recursive-include Tests *.jpg
recursive-include Tests *.lut recursive-include Tests *.lut
recursive-include Tests *.mpo recursive-include Tests *.mpo
recursive-include Tests *.msp
recursive-include Tests *.pbm recursive-include Tests *.pbm
recursive-include Tests *.pcf recursive-include Tests *.pcf
recursive-include Tests *.pcx recursive-include Tests *.pcx
@ -59,8 +62,8 @@ recursive-include Tests *.tiff
recursive-include Tests *.ttf recursive-include Tests *.ttf
recursive-include Tests *.txt recursive-include Tests *.txt
recursive-include Tests *.webp recursive-include Tests *.webp
recursive-include Tests *.xbm
recursive-include Tests *.xpm recursive-include Tests *.xpm
recursive-include Tests *.msp
recursive-include Tk *.c recursive-include Tk *.c
recursive-include Tk *.rst recursive-include Tk *.rst
recursive-include depends *.rst recursive-include depends *.rst
@ -71,9 +74,13 @@ recursive-include docs *.html
recursive-include docs *.py recursive-include docs *.py
recursive-include docs *.rst recursive-include docs *.rst
recursive-include docs *.txt recursive-include docs *.txt
recursive-include docs BUILDME
recursive-include docs COPYING
recursive-include docs Guardfile
recursive-include docs Makefile recursive-include docs Makefile
recursive-include docs Guardfile
recursive-include docs COPYING
recursive-include docs BUILDME
recursive-include libImaging *.c recursive-include libImaging *.c
recursive-include libImaging *.h recursive-include libImaging *.h
recursive-include winbuild *.gitignore
recursive-include winbuild *.md
recursive-include winbuild *.opt
recursive-include winbuild *.py

View File

@ -1,5 +1,6 @@
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html # https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
.PHONY: clean coverage doc docserve help inplace install install-req release-test sdist test upload upload-test .PHONY: clean coverage doc docserve help inplace install install-req release-test sdist test upload upload-test
.DEFAULT_GOAL := release-test
clean: clean:
python setup.py clean python setup.py clean

View File

@ -127,8 +127,14 @@ class FliImageFile(ImageFile.ImageFile):
return return
if frame < self.__frame: if frame < self.__frame:
self._seek(0) self._seek(0)
last_frame = self.__frame
for f in range(self.__frame + 1, frame + 1): for f in range(self.__frame + 1, frame + 1):
try:
self._seek(f) self._seek(f)
except EOFError:
self.seek(last_frame)
raise EOFError("no more images in FLI file")
def _seek(self, frame): def _seek(self, frame):
if frame == 0: if frame == 0:

View File

@ -107,8 +107,14 @@ class GifImageFile(ImageFile.ImageFile):
return return
if frame < self.__frame: if frame < self.__frame:
self._seek(0) self._seek(0)
last_frame = self.__frame
for f in range(self.__frame + 1, frame + 1): for f in range(self.__frame + 1, frame + 1):
try:
self._seek(f) self._seek(f)
except EOFError:
self.seek(last_frame)
raise EOFError("no more images in GIF file")
def _seek(self, frame): def _seek(self, frame):
@ -241,7 +247,7 @@ class GifImageFile(ImageFile.ImageFile):
if not self.tile: if not self.tile:
# self.__fp = None # self.__fp = None
raise EOFError("no more images in GIF file") raise EOFError
self.mode = "L" self.mode = "L"
if self.palette: if self.palette:

View File

@ -504,6 +504,14 @@ class Image(object):
self.readonly = 0 self.readonly = 0
self.pyaccess = None self.pyaccess = None
@property
def width(self):
return self.size[0]
@property
def height(self):
return self.size[1]
def _new(self, im): def _new(self, im):
new = Image() new = Image()
new.im = im new.im = im

View File

@ -548,7 +548,7 @@ class ImageFileDirectory(collections.MutableMapping):
# and doesn't match the tiff spec: 8-bit byte that # and doesn't match the tiff spec: 8-bit byte that
# contains a 7-bit ASCII code; the last byte must be # contains a 7-bit ASCII code; the last byte must be
# NUL (binary zero). Also, I don't think this was well # NUL (binary zero). Also, I don't think this was well
# excersized before. # exercised before.
data = value = b"" + value.encode('ascii', 'replace') + b"\0" data = value = b"" + value.encode('ascii', 'replace') + b"\0"
else: else:
# integer data # integer data

View File

@ -12,7 +12,7 @@
# ;-) # ;-)
VERSION = '1.1.7' # PIL version VERSION = '1.1.7' # PIL version
PILLOW_VERSION = '2.9.0.dev0' # Pillow PILLOW_VERSION = '2.9.0.dev1' # Pillow
_plugins = ['BmpImagePlugin', _plugins = ['BmpImagePlugin',
'BufrStubImagePlugin', 'BufrStubImagePlugin',

View File

@ -34,6 +34,18 @@ class TestFileDcx(PillowTestCase):
im = Image.open(TEST_FILE) im = Image.open(TEST_FILE)
self.assertEqual(im.n_frames, 1) self.assertEqual(im.n_frames, 1)
def test_eoferror(self):
im = Image.open(TEST_FILE)
n_frames = im.n_frames
while True:
n_frames -= 1
try:
im.seek(n_frames)
break
except EOFError:
self.assertTrue(im.tell() < n_frames)
def test_seek_too_far(self): def test_seek_too_far(self):
# Arrange # Arrange
im = Image.open(TEST_FILE) im = Image.open(TEST_FILE)

View File

@ -20,7 +20,19 @@ class TestFileFli(PillowTestCase):
def test_n_frames(self): def test_n_frames(self):
im = Image.open(test_file) im = Image.open(test_file)
self.assertEqual(im.n_frames, 2) self.assertEqual(im.n_frames, 1)
def test_eoferror(self):
im = Image.open(test_file)
n_frames = im.n_frames
while True:
n_frames -= 1
try:
im.seek(n_frames)
break
except EOFError:
self.assertTrue(im.tell() < n_frames)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -135,8 +135,23 @@ class TestFileGif(PillowTestCase):
self.assertEqual(framecount, 5) self.assertEqual(framecount, 5)
def test_n_frames(self): def test_n_frames(self):
im = Image.open(TEST_GIF)
self.assertEqual(im.n_frames, 1)
im = Image.open("Tests/images/iss634.gif") im = Image.open("Tests/images/iss634.gif")
self.assertEqual(im.n_frames, 43) self.assertEqual(im.n_frames, 42)
def test_eoferror(self):
im = Image.open(TEST_GIF)
n_frames = im.n_frames
while True:
n_frames -= 1
try:
im.seek(n_frames)
break
except EOFError:
self.assertTrue(im.tell() < n_frames)
def test_dispose_none(self): def test_dispose_none(self):
img = Image.open("Tests/images/dispose_none.gif") img = Image.open("Tests/images/dispose_none.gif")

View File

@ -19,6 +19,18 @@ class TestFileIm(PillowTestCase):
im = Image.open(TEST_IM) im = Image.open(TEST_IM)
self.assertEqual(im.n_frames, 1) self.assertEqual(im.n_frames, 1)
def test_eoferror(self):
im = Image.open(TEST_IM)
n_frames = im.n_frames
while True:
n_frames -= 1
try:
im.seek(n_frames)
break
except EOFError:
self.assertTrue(im.tell() < n_frames)
def test_roundtrip(self): def test_roundtrip(self):
out = self.tempfile('temp.im') out = self.tempfile('temp.im')
im = hopper() im = hopper()

View File

@ -99,6 +99,18 @@ class TestFileMpo(PillowTestCase):
im = Image.open("Tests/images/sugarshack.mpo") im = Image.open("Tests/images/sugarshack.mpo")
self.assertEqual(im.n_frames, 2) self.assertEqual(im.n_frames, 2)
def test_eoferror(self):
im = Image.open("Tests/images/sugarshack.mpo")
n_frames = im.n_frames
while True:
n_frames -= 1
try:
im.seek(n_frames)
break
except EOFError:
self.assertTrue(im.tell() < n_frames)
def test_image_grab(self): def test_image_grab(self):
for test_file in test_files: for test_file in test_files:
im = Image.open(test_file) im = Image.open(test_file)

View File

@ -23,6 +23,19 @@ class TestImagePsd(PillowTestCase):
im = Image.open(test_file) im = Image.open(test_file)
self.assertEqual(im.n_frames, 2) self.assertEqual(im.n_frames, 2)
def test_eoferror(self):
im = Image.open(test_file)
n_frames = im.n_frames
while True:
n_frames -= 1
try:
# PSD seek index starts at 1 rather than 0
im.seek(n_frames+1)
break
except EOFError:
self.assertTrue(im.tell() < n_frames)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -157,6 +157,18 @@ class TestFileTiff(PillowTestCase):
im = Image.open('Tests/images/multipage.tiff') im = Image.open('Tests/images/multipage.tiff')
self.assertEqual(im.n_frames, 3) self.assertEqual(im.n_frames, 3)
def test_eoferror(self):
im = Image.open('Tests/images/multipage-lastframe.tif')
n_frames = im.n_frames
while True:
n_frames -= 1
try:
im.seek(n_frames)
break
except EOFError:
self.assertTrue(im.tell() < n_frames)
def test_multipage(self): def test_multipage(self):
# issue #862 # issue #862
im = Image.open('Tests/images/multipage.tiff') im = Image.open('Tests/images/multipage.tiff')

View File

@ -30,6 +30,15 @@ class TestImage(PillowTestCase):
# self.assertRaises( # self.assertRaises(
# MemoryError, lambda: Image.new("L", (1000000, 1000000))) # MemoryError, lambda: Image.new("L", (1000000, 1000000)))
def test_width_height(self):
im = Image.new("RGB", (1, 2))
self.assertEqual(im.width, 1)
self.assertEqual(im.height, 2)
im.size = (3, 4)
self.assertEqual(im.width, 3)
self.assertEqual(im.height, 4)
def test_invalid_image(self): def test_invalid_image(self):
if str is bytes: if str is bytes:
import StringIO import StringIO

View File

@ -19,7 +19,7 @@ class TestToQImage(PillowQtTestCase, PillowTestCase):
self.assertFalse(data.isNull()) self.assertFalse(data.isNull())
# Test saving the file # Test saving the file
tempfile = self.tempfile('temp_{}.png'.format(mode)) tempfile = self.tempfile('temp_{0}.png'.format(mode))
data.save(tempfile) data.save(tempfile)

View File

@ -19,7 +19,7 @@ class TestToQPixmap(PillowQPixmapTestCase, PillowTestCase):
self.assertFalse(data.isNull()) self.assertFalse(data.isNull())
# Test saving the file # Test saving the file
tempfile = self.tempfile('temp_{}.png'.format(mode)) tempfile = self.tempfile('temp_{0}.png'.format(mode))
data.save(tempfile) data.save(tempfile)

View File

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

View File

@ -1,5 +1,4 @@
version: 2.9.pre.{build} version: 2.9.pre.{build}
shallow_clone: true
clone_folder: c:\pillow clone_folder: c:\pillow
init: init:
- ECHO %PYTHON% - ECHO %PYTHON%

View File

@ -181,6 +181,18 @@ Instances of the :py:class:`Image` class have the following attributes:
:type: ``(width, height)`` :type: ``(width, height)``
.. py:attribute:: width
Image width, in pixels.
:type: :py:class:`int`
.. py:attribute:: height
Image height, in pixels.
:type: :py:class:`int`
.. py:attribute:: palette .. py:attribute:: palette
Colour palette table, if any. If mode is “P”, this should be an instance of Colour palette table, if any. If mode is “P”, this should be an instance of

View File

@ -90,7 +90,7 @@ except (ImportError, OSError):
NAME = 'Pillow' NAME = 'Pillow'
PILLOW_VERSION = '2.9.0.dev0' PILLOW_VERSION = '2.9.0.dev1'
TCL_ROOT = None TCL_ROOT = None
JPEG_ROOT = None JPEG_ROOT = None
JPEG2K_ROOT = None JPEG2K_ROOT = None

View File

@ -11,4 +11,4 @@ commands =
{envpython} setup.py clean {envpython} setup.py clean
{envpython} setup.py build_ext --inplace {envpython} setup.py build_ext --inplace
{envpython} selftest.py {envpython} selftest.py
{envpython} Tests/run.py --installed {envpython} test-installed.py --installed

View File

@ -93,18 +93,19 @@ endlocal
""" % compiler """ % compiler
def cp_tk(): def cp_tk(ver_85, ver_86):
versions = {'ver_85':ver_85, 'ver_86':ver_86}
return r""" return r"""
mkdir %INCLIB%\tcl85\include\X11 mkdir %%INCLIB%%\tcl85\include\X11
copy /Y /B %BUILD%\tcl8.5.13\generic\*.h %INCLIB%\tcl85\include\ copy /Y /B %%BUILD%%\tcl%(ver_85)s\generic\*.h %%INCLIB%%\tcl85\include\
copy /Y /B %BUILD%\tk8.5.13\generic\*.h %INCLIB%\tcl85\include\ copy /Y /B %%BUILD%%\tk%(ver_85)s\generic\*.h %%INCLIB%%\tcl85\include\
copy /Y /B %BUILD%\tk8.5.13\xlib\X11\* %INCLIB%\tcl85\include\X11\ copy /Y /B %%BUILD%%\tk%(ver_85)s\xlib\X11\* %%INCLIB%%\tcl85\include\X11\
mkdir %INCLIB%\tcl86\include\X11 mkdir %%INCLIB%%\tcl86\include\X11
copy /Y /B %BUILD%\tcl8.6.4\generic\*.h %INCLIB%\tcl86\include\ copy /Y /B %%BUILD%%\tcl%(ver_86)s\generic\*.h %%INCLIB%%\tcl86\include\
copy /Y /B %BUILD%\tk8.6.4\generic\*.h %INCLIB%\tcl86\include\ copy /Y /B %%BUILD%%\tk%(ver_86)s\generic\*.h %%INCLIB%%\tcl86\include\
copy /Y /B %BUILD%\tk8.6.4\xlib\X11\* %INCLIB%\tcl86\include\X11\ copy /Y /B %%BUILD%%\tk%(ver_86)s\xlib\X11\* %%INCLIB%%\tcl86\include\X11\
""" """ % versions
def header(): def header():
@ -307,7 +308,7 @@ def add_compiler(compiler):
mkdirs() mkdirs()
fetch_libs() fetch_libs()
# extract_binlib() # extract_binlib()
script = [header(), cp_tk()] script = [header(), cp_tk(libs['tk-8.5']['version'],libs['tk-8.6']['version'] )]
if 'PYTHON' in os.environ: if 'PYTHON' in os.environ:

View File

@ -24,7 +24,7 @@ libs = {
}, },
'tiff': { 'tiff': {
'url': 'ftp://ftp.remotesensing.org/pub/libtiff/tiff-4.0.4.zip', 'url': 'ftp://ftp.remotesensing.org/pub/libtiff/tiff-4.0.4.zip',
'hash': 'md5:8f538a34156188f9a8dcddb679c65d1e', # not found - generated by wiredfool 'hash': 'md5:8f538a34156188f9a8dcddb679c65d1e',
'dir': 'tiff-4.0.4', 'dir': 'tiff-4.0.4',
}, },
'freetype': { 'freetype': {
@ -46,6 +46,7 @@ libs = {
'url': SF_MIRROR+'/project/tcl/Tcl/8.5.18/tk8518-src.zip', 'url': SF_MIRROR+'/project/tcl/Tcl/8.5.18/tk8518-src.zip',
'hash': 'sha1:273f55148777413774aa722ecad25cabda1e31ae', 'hash': 'sha1:273f55148777413774aa722ecad25cabda1e31ae',
'dir': '', 'dir': '',
'version':'8.5.18',
}, },
'tcl-8.6': { 'tcl-8.6': {
'url': SF_MIRROR+'/project/tcl/Tcl/8.6.4/tcl864-src.zip', 'url': SF_MIRROR+'/project/tcl/Tcl/8.6.4/tcl864-src.zip',
@ -56,6 +57,7 @@ libs = {
'url': SF_MIRROR+'/project/tcl/Tcl/8.6.4/tk864-src.zip', 'url': SF_MIRROR+'/project/tcl/Tcl/8.6.4/tk864-src.zip',
'hash': 'md5:111d45061a69e7f5250b6ec8ca7c4f35', 'hash': 'md5:111d45061a69e7f5250b6ec8ca7c4f35',
'dir': '', 'dir': '',
'version':'8.6.4',
}, },
'webp': { 'webp': {
'url': 'http://downloads.webmproject.org/releases/webp/libwebp-0.4.3.tar.gz', 'url': 'http://downloads.webmproject.org/releases/webp/libwebp-0.4.3.tar.gz',