Merge #772 and master

This commit is contained in:
wiredfool 2014-07-08 10:29:53 -07:00
commit 552effb90d
118 changed files with 555 additions and 242 deletions

View File

@ -14,9 +14,10 @@ python:
- 3.4
install:
- "sudo apt-get -qq install libfreetype6-dev liblcms2-dev python-qt4 ghostscript libffi-dev libjpeg-turbo-progs cmake"
- "sudo apt-get -qq install libfreetype6-dev liblcms2-dev python-qt4 ghostscript libffi-dev libjpeg-turbo-progs cmake imagemagick"
- "pip install cffi"
- "pip install coveralls nose pyroma"
- "pip install coveralls nose"
- travis_retry pip install pyroma
- if [ "$TRAVIS_PYTHON_VERSION" == "2.6" ]; then pip install unittest2; fi
# webp

View File

@ -1,6 +1,25 @@
Changelog (Pillow)
==================
2.6.0 (unreleased)
------------------
- Fix return value of FreeTypeFont.textsize() does not include font offsets
[tk0miya]
- Fix dispose calculations for animated GIFs #765
[larsjsol]
- 32bit mult overflow fix #782
[wiredfool]
- Added class checking to Image __eq__ function #775
[radarhere, hugovk]
- Test PalmImagePlugin and method to skip known bad tests #776
[hugovk, wiredfool]
2.5.0 (2014-07-01)
------------------

View File

@ -17,8 +17,6 @@
import os
from PIL import Image, _binary
import marshal
try:
import zlib
except ImportError:
@ -26,6 +24,7 @@ except ImportError:
WIDTH = 800
def puti16(fp, values):
# write network order (big-endian) 16-bit sequence
for v in values:
@ -33,6 +32,7 @@ def puti16(fp, values):
v += 65536
fp.write(_binary.o16be(v))
##
# Base class for raster font file handlers.
@ -95,9 +95,8 @@ class FontFile:
# print chr(i), dst, s
self.metrics[i] = d, dst, s
def save1(self, filename):
"Save font in version 1 format"
def save(self, filename):
"Save font"
self.compile()
@ -107,7 +106,7 @@ class FontFile:
# font metrics
fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
fp.write(b"PILfont\n")
fp.write((";;;;;;%d;\n" % self.ysize).encode('ascii')) # HACK!!!
fp.write((";;;;;;%d;\n" % self.ysize).encode('ascii')) # HACK!!!
fp.write(b"DATA\n")
for id in range(256):
m = self.metrics[id]
@ -117,30 +116,4 @@ class FontFile:
puti16(fp, m[0] + m[1] + m[2])
fp.close()
def save2(self, filename):
"Save font in version 2 format"
# THIS IS WORK IN PROGRESS
self.compile()
data = marshal.dumps((self.metrics, self.info))
if zlib:
data = b"z" + zlib.compress(data, 9)
else:
data = b"u" + data
fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
fp.write(b"PILfont2\n" + self.name + "\n" + "DATA\n")
fp.write(data)
self.bitmap.save(fp, "PNG")
fp.close()
save = save1 # for now
# End of file

View File

@ -96,8 +96,15 @@ class GifImageFile(ImageFile.ImageFile):
# rewind
self.__offset = 0
self.dispose = None
self.dispose_extent = [0, 0, 0, 0] #x0, y0, x1, y1
self.__frame = -1
self.__fp.seek(self.__rewind)
self._prev_im = None
self.disposal_method = 0
else:
# ensure that the previous frame was loaded
if not self.im:
self.load()
if frame != self.__frame + 1:
raise ValueError("cannot seek to frame %d" % frame)
@ -114,8 +121,7 @@ class GifImageFile(ImageFile.ImageFile):
self.__offset = 0
if self.dispose:
self.im = self.dispose
self.dispose = None
self.im.paste(self.dispose, self.dispose_extent)
from copy import copy
self.palette = copy(self.global_palette)
@ -140,17 +146,16 @@ class GifImageFile(ImageFile.ImageFile):
if flags & 1:
self.info["transparency"] = i8(block[3])
self.info["duration"] = i16(block[1:3]) * 10
try:
# disposal methods
if flags & 8:
# replace with background colour
self.dispose = Image.core.fill("P", self.size,
self.info["background"])
elif flags & 16:
# replace with previous contents
self.dispose = self.im.copy()
except (AttributeError, KeyError):
pass
# disposal method - find the value of bits 4 - 6
dispose_bits = 0b00011100 & flags
dispose_bits = dispose_bits >> 2
if dispose_bits:
# only set the dispose if it is not
# unspecified. I'm not sure if this is
# correct, but it seems to prevent the last
# frame from looking odd for some animations
self.disposal_method = dispose_bits
elif i8(s) == 255:
#
# application extension
@ -172,6 +177,7 @@ class GifImageFile(ImageFile.ImageFile):
# extent
x0, y0 = i16(s[0:]), i16(s[2:])
x1, y1 = x0 + i16(s[4:]), y0 + i16(s[6:])
self.dispose_extent = x0, y0, x1, y1
flags = i8(s[8])
interlace = (flags & 64) != 0
@ -194,6 +200,26 @@ class GifImageFile(ImageFile.ImageFile):
pass
# raise IOError, "illegal GIF tag `%x`" % i8(s)
try:
if self.disposal_method < 2:
# do not dispose or none specified
self.dispose = None
elif self.disposal_method == 2:
# replace with background colour
self.dispose = Image.core.fill("P", self.size,
self.info["background"])
else:
# replace with previous contents
if self.im:
self.dispose = self.im.copy()
# only dispose the extent in this frame
if self.dispose:
self.dispose = self.dispose.crop(self.dispose_extent)
except (AttributeError, KeyError):
pass
if not self.tile:
# self.__fp = None
raise EOFError("no more images in GIF file")
@ -205,6 +231,18 @@ class GifImageFile(ImageFile.ImageFile):
def tell(self):
return self.__frame
def load_end(self):
ImageFile.ImageFile.load_end(self)
# if the disposal method is 'do not dispose', transparent
# pixels should show the content of the previous frame
if self._prev_im and self.disposal_method == 1:
# we do this by pasting the updated area onto the previous
# frame which we then use as the current image content
updated = self.im.crop(self.dispose_extent)
self._prev_im.paste(updated, self.dispose_extent, updated.convert('RGBA'))
self.im = self._prev_im
self._prev_im = self.im.copy()
# --------------------------------------------------------------------
# Write GIF files

View File

@ -573,6 +573,8 @@ class Image:
return file
def __eq__(self, other):
if self.__class__.__name__ != other.__class__.__name__:
return False
a = (self.mode == other.mode)
b = (self.size == other.size)
c = (self.getpalette() == other.getpalette())

View File

@ -147,7 +147,8 @@ class FreeTypeFont:
return self.font.ascent, self.font.descent
def getsize(self, text):
return self.font.getsize(text)[0]
size, offset = self.font.getsize(text)
return (size[0] + offset[0], size[1] + offset[1])
def getoffset(self, text):
return self.font.getsize(text)[1]

View File

@ -12,74 +12,75 @@ __version__ = "1.0"
from PIL import Image, ImageFile, _binary
_Palm8BitColormapValues = (
( 255, 255, 255 ), ( 255, 204, 255 ), ( 255, 153, 255 ), ( 255, 102, 255 ),
( 255, 51, 255 ), ( 255, 0, 255 ), ( 255, 255, 204 ), ( 255, 204, 204 ),
( 255, 153, 204 ), ( 255, 102, 204 ), ( 255, 51, 204 ), ( 255, 0, 204 ),
( 255, 255, 153 ), ( 255, 204, 153 ), ( 255, 153, 153 ), ( 255, 102, 153 ),
( 255, 51, 153 ), ( 255, 0, 153 ), ( 204, 255, 255 ), ( 204, 204, 255 ),
( 204, 153, 255 ), ( 204, 102, 255 ), ( 204, 51, 255 ), ( 204, 0, 255 ),
( 204, 255, 204 ), ( 204, 204, 204 ), ( 204, 153, 204 ), ( 204, 102, 204 ),
( 204, 51, 204 ), ( 204, 0, 204 ), ( 204, 255, 153 ), ( 204, 204, 153 ),
( 204, 153, 153 ), ( 204, 102, 153 ), ( 204, 51, 153 ), ( 204, 0, 153 ),
( 153, 255, 255 ), ( 153, 204, 255 ), ( 153, 153, 255 ), ( 153, 102, 255 ),
( 153, 51, 255 ), ( 153, 0, 255 ), ( 153, 255, 204 ), ( 153, 204, 204 ),
( 153, 153, 204 ), ( 153, 102, 204 ), ( 153, 51, 204 ), ( 153, 0, 204 ),
( 153, 255, 153 ), ( 153, 204, 153 ), ( 153, 153, 153 ), ( 153, 102, 153 ),
( 153, 51, 153 ), ( 153, 0, 153 ), ( 102, 255, 255 ), ( 102, 204, 255 ),
( 102, 153, 255 ), ( 102, 102, 255 ), ( 102, 51, 255 ), ( 102, 0, 255 ),
( 102, 255, 204 ), ( 102, 204, 204 ), ( 102, 153, 204 ), ( 102, 102, 204 ),
( 102, 51, 204 ), ( 102, 0, 204 ), ( 102, 255, 153 ), ( 102, 204, 153 ),
( 102, 153, 153 ), ( 102, 102, 153 ), ( 102, 51, 153 ), ( 102, 0, 153 ),
( 51, 255, 255 ), ( 51, 204, 255 ), ( 51, 153, 255 ), ( 51, 102, 255 ),
( 51, 51, 255 ), ( 51, 0, 255 ), ( 51, 255, 204 ), ( 51, 204, 204 ),
( 51, 153, 204 ), ( 51, 102, 204 ), ( 51, 51, 204 ), ( 51, 0, 204 ),
( 51, 255, 153 ), ( 51, 204, 153 ), ( 51, 153, 153 ), ( 51, 102, 153 ),
( 51, 51, 153 ), ( 51, 0, 153 ), ( 0, 255, 255 ), ( 0, 204, 255 ),
( 0, 153, 255 ), ( 0, 102, 255 ), ( 0, 51, 255 ), ( 0, 0, 255 ),
( 0, 255, 204 ), ( 0, 204, 204 ), ( 0, 153, 204 ), ( 0, 102, 204 ),
( 0, 51, 204 ), ( 0, 0, 204 ), ( 0, 255, 153 ), ( 0, 204, 153 ),
( 0, 153, 153 ), ( 0, 102, 153 ), ( 0, 51, 153 ), ( 0, 0, 153 ),
( 255, 255, 102 ), ( 255, 204, 102 ), ( 255, 153, 102 ), ( 255, 102, 102 ),
( 255, 51, 102 ), ( 255, 0, 102 ), ( 255, 255, 51 ), ( 255, 204, 51 ),
( 255, 153, 51 ), ( 255, 102, 51 ), ( 255, 51, 51 ), ( 255, 0, 51 ),
( 255, 255, 0 ), ( 255, 204, 0 ), ( 255, 153, 0 ), ( 255, 102, 0 ),
( 255, 51, 0 ), ( 255, 0, 0 ), ( 204, 255, 102 ), ( 204, 204, 102 ),
( 204, 153, 102 ), ( 204, 102, 102 ), ( 204, 51, 102 ), ( 204, 0, 102 ),
( 204, 255, 51 ), ( 204, 204, 51 ), ( 204, 153, 51 ), ( 204, 102, 51 ),
( 204, 51, 51 ), ( 204, 0, 51 ), ( 204, 255, 0 ), ( 204, 204, 0 ),
( 204, 153, 0 ), ( 204, 102, 0 ), ( 204, 51, 0 ), ( 204, 0, 0 ),
( 153, 255, 102 ), ( 153, 204, 102 ), ( 153, 153, 102 ), ( 153, 102, 102 ),
( 153, 51, 102 ), ( 153, 0, 102 ), ( 153, 255, 51 ), ( 153, 204, 51 ),
( 153, 153, 51 ), ( 153, 102, 51 ), ( 153, 51, 51 ), ( 153, 0, 51 ),
( 153, 255, 0 ), ( 153, 204, 0 ), ( 153, 153, 0 ), ( 153, 102, 0 ),
( 153, 51, 0 ), ( 153, 0, 0 ), ( 102, 255, 102 ), ( 102, 204, 102 ),
( 102, 153, 102 ), ( 102, 102, 102 ), ( 102, 51, 102 ), ( 102, 0, 102 ),
( 102, 255, 51 ), ( 102, 204, 51 ), ( 102, 153, 51 ), ( 102, 102, 51 ),
( 102, 51, 51 ), ( 102, 0, 51 ), ( 102, 255, 0 ), ( 102, 204, 0 ),
( 102, 153, 0 ), ( 102, 102, 0 ), ( 102, 51, 0 ), ( 102, 0, 0 ),
( 51, 255, 102 ), ( 51, 204, 102 ), ( 51, 153, 102 ), ( 51, 102, 102 ),
( 51, 51, 102 ), ( 51, 0, 102 ), ( 51, 255, 51 ), ( 51, 204, 51 ),
( 51, 153, 51 ), ( 51, 102, 51 ), ( 51, 51, 51 ), ( 51, 0, 51 ),
( 51, 255, 0 ), ( 51, 204, 0 ), ( 51, 153, 0 ), ( 51, 102, 0 ),
( 51, 51, 0 ), ( 51, 0, 0 ), ( 0, 255, 102 ), ( 0, 204, 102 ),
( 0, 153, 102 ), ( 0, 102, 102 ), ( 0, 51, 102 ), ( 0, 0, 102 ),
( 0, 255, 51 ), ( 0, 204, 51 ), ( 0, 153, 51 ), ( 0, 102, 51 ),
( 0, 51, 51 ), ( 0, 0, 51 ), ( 0, 255, 0 ), ( 0, 204, 0 ),
( 0, 153, 0 ), ( 0, 102, 0 ), ( 0, 51, 0 ), ( 17, 17, 17 ),
( 34, 34, 34 ), ( 68, 68, 68 ), ( 85, 85, 85 ), ( 119, 119, 119 ),
( 136, 136, 136 ), ( 170, 170, 170 ), ( 187, 187, 187 ), ( 221, 221, 221 ),
( 238, 238, 238 ), ( 192, 192, 192 ), ( 128, 0, 0 ), ( 128, 0, 128 ),
( 0, 128, 0 ), ( 0, 128, 128 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ),
( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ), ( 0, 0, 0 ))
(255, 255, 255), (255, 204, 255), (255, 153, 255), (255, 102, 255),
(255, 51, 255), (255, 0, 255), (255, 255, 204), (255, 204, 204),
(255, 153, 204), (255, 102, 204), (255, 51, 204), (255, 0, 204),
(255, 255, 153), (255, 204, 153), (255, 153, 153), (255, 102, 153),
(255, 51, 153), (255, 0, 153), (204, 255, 255), (204, 204, 255),
(204, 153, 255), (204, 102, 255), (204, 51, 255), (204, 0, 255),
(204, 255, 204), (204, 204, 204), (204, 153, 204), (204, 102, 204),
(204, 51, 204), (204, 0, 204), (204, 255, 153), (204, 204, 153),
(204, 153, 153), (204, 102, 153), (204, 51, 153), (204, 0, 153),
(153, 255, 255), (153, 204, 255), (153, 153, 255), (153, 102, 255),
(153, 51, 255), (153, 0, 255), (153, 255, 204), (153, 204, 204),
(153, 153, 204), (153, 102, 204), (153, 51, 204), (153, 0, 204),
(153, 255, 153), (153, 204, 153), (153, 153, 153), (153, 102, 153),
(153, 51, 153), (153, 0, 153), (102, 255, 255), (102, 204, 255),
(102, 153, 255), (102, 102, 255), (102, 51, 255), (102, 0, 255),
(102, 255, 204), (102, 204, 204), (102, 153, 204), (102, 102, 204),
(102, 51, 204), (102, 0, 204), (102, 255, 153), (102, 204, 153),
(102, 153, 153), (102, 102, 153), (102, 51, 153), (102, 0, 153),
( 51, 255, 255), ( 51, 204, 255), ( 51, 153, 255), ( 51, 102, 255),
( 51, 51, 255), ( 51, 0, 255), ( 51, 255, 204), ( 51, 204, 204),
( 51, 153, 204), ( 51, 102, 204), ( 51, 51, 204), ( 51, 0, 204),
( 51, 255, 153), ( 51, 204, 153), ( 51, 153, 153), ( 51, 102, 153),
( 51, 51, 153), ( 51, 0, 153), ( 0, 255, 255), ( 0, 204, 255),
( 0, 153, 255), ( 0, 102, 255), ( 0, 51, 255), ( 0, 0, 255),
( 0, 255, 204), ( 0, 204, 204), ( 0, 153, 204), ( 0, 102, 204),
( 0, 51, 204), ( 0, 0, 204), ( 0, 255, 153), ( 0, 204, 153),
( 0, 153, 153), ( 0, 102, 153), ( 0, 51, 153), ( 0, 0, 153),
(255, 255, 102), (255, 204, 102), (255, 153, 102), (255, 102, 102),
(255, 51, 102), (255, 0, 102), (255, 255, 51), (255, 204, 51),
(255, 153, 51), (255, 102, 51), (255, 51, 51), (255, 0, 51),
(255, 255, 0), (255, 204, 0), (255, 153, 0), (255, 102, 0),
(255, 51, 0), (255, 0, 0), (204, 255, 102), (204, 204, 102),
(204, 153, 102), (204, 102, 102), (204, 51, 102), (204, 0, 102),
(204, 255, 51), (204, 204, 51), (204, 153, 51), (204, 102, 51),
(204, 51, 51), (204, 0, 51), (204, 255, 0), (204, 204, 0),
(204, 153, 0), (204, 102, 0), (204, 51, 0), (204, 0, 0),
(153, 255, 102), (153, 204, 102), (153, 153, 102), (153, 102, 102),
(153, 51, 102), (153, 0, 102), (153, 255, 51), (153, 204, 51),
(153, 153, 51), (153, 102, 51), (153, 51, 51), (153, 0, 51),
(153, 255, 0), (153, 204, 0), (153, 153, 0), (153, 102, 0),
(153, 51, 0), (153, 0, 0), (102, 255, 102), (102, 204, 102),
(102, 153, 102), (102, 102, 102), (102, 51, 102), (102, 0, 102),
(102, 255, 51), (102, 204, 51), (102, 153, 51), (102, 102, 51),
(102, 51, 51), (102, 0, 51), (102, 255, 0), (102, 204, 0),
(102, 153, 0), (102, 102, 0), (102, 51, 0), (102, 0, 0),
( 51, 255, 102), ( 51, 204, 102), ( 51, 153, 102), ( 51, 102, 102),
( 51, 51, 102), ( 51, 0, 102), ( 51, 255, 51), ( 51, 204, 51),
( 51, 153, 51), ( 51, 102, 51), ( 51, 51, 51), ( 51, 0, 51),
( 51, 255, 0), ( 51, 204, 0), ( 51, 153, 0), ( 51, 102, 0),
( 51, 51, 0), ( 51, 0, 0), ( 0, 255, 102), ( 0, 204, 102),
( 0, 153, 102), ( 0, 102, 102), ( 0, 51, 102), ( 0, 0, 102),
( 0, 255, 51), ( 0, 204, 51), ( 0, 153, 51), ( 0, 102, 51),
( 0, 51, 51), ( 0, 0, 51), ( 0, 255, 0), ( 0, 204, 0),
( 0, 153, 0), ( 0, 102, 0), ( 0, 51, 0), ( 17, 17, 17),
( 34, 34, 34), ( 68, 68, 68), ( 85, 85, 85), (119, 119, 119),
(136, 136, 136), (170, 170, 170), (187, 187, 187), (221, 221, 221),
(238, 238, 238), (192, 192, 192), (128, 0, 0), (128, 0, 128),
( 0, 128, 0), ( 0, 128, 128), ( 0, 0, 0), ( 0, 0, 0),
( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0),
( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0),
( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0),
( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0),
( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0),
( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0), ( 0, 0, 0))
# so build a prototype image to be used for palette resampling
def build_prototype_image():
image = Image.new("L", (1,len(_Palm8BitColormapValues),))
image = Image.new("L", (1, len(_Palm8BitColormapValues),))
image.putdata(list(range(len(_Palm8BitColormapValues))))
palettedata = ()
for i in range(len(_Palm8BitColormapValues)):
@ -91,7 +92,8 @@ def build_prototype_image():
Palm8BitColormapImage = build_prototype_image()
# OK, we now have in Palm8BitColormapImage, a "P"-mode image with the right palette
# OK, we now have in Palm8BitColormapImage,
# a "P"-mode image with the right palette
#
# --------------------------------------------------------------------
@ -110,6 +112,7 @@ _COMPRESSION_TYPES = {
o8 = _binary.o8
o16b = _binary.o16be
#
# --------------------------------------------------------------------
@ -127,12 +130,16 @@ def _save(im, fp, filename, check=0):
bpp = 8
version = 1
elif im.mode == "L" and "bpp" in im.encoderinfo and im.encoderinfo["bpp"] in (1, 2, 4):
elif (im.mode == "L" and
"bpp" in im.encoderinfo and
im.encoderinfo["bpp"] in (1, 2, 4)):
# this is 8-bit grayscale, so we shift it to get the high-order bits, and invert it because
# this is 8-bit grayscale, so we shift it to get the high-order bits,
# and invert it because
# Palm does greyscale from white (0) to black (1)
bpp = im.encoderinfo["bpp"]
im = im.point(lambda x, shift=8-bpp, maxval=(1 << bpp)-1: maxval - (x >> shift))
im = im.point(
lambda x, shift=8-bpp, maxval=(1 << bpp)-1: maxval - (x >> shift))
# we ignore the palette here
im.mode = "P"
rawmode = "P;" + str(bpp)
@ -140,8 +147,9 @@ def _save(im, fp, filename, check=0):
elif im.mode == "L" and "bpp" in im.info and im.info["bpp"] in (1, 2, 4):
# here we assume that even though the inherent mode is 8-bit grayscale, only
# the lower bpp bits are significant. We invert them to match the Palm.
# here we assume that even though the inherent mode is 8-bit grayscale,
# only the lower bpp bits are significant.
# We invert them to match the Palm.
bpp = im.info["bpp"]
im = im.point(lambda x, maxval=(1 << bpp)-1: maxval - (x & maxval))
# we ignore the palette here
@ -172,7 +180,7 @@ def _save(im, fp, filename, check=0):
cols = im.size[0]
rows = im.size[1]
rowbytes = ((cols + (16//bpp - 1)) / (16 // bpp)) * 2
rowbytes = int((cols + (16//bpp - 1)) / (16 // bpp)) * 2
transparent_index = 0
compression_type = _COMPRESSION_TYPES["none"]
@ -205,12 +213,19 @@ def _save(im, fp, filename, check=0):
for i in range(256):
fp.write(o8(i))
if colormapmode == 'RGB':
fp.write(o8(colormap[3 * i]) + o8(colormap[3 * i + 1]) + o8(colormap[3 * i + 2]))
fp.write(
o8(colormap[3 * i]) +
o8(colormap[3 * i + 1]) +
o8(colormap[3 * i + 2]))
elif colormapmode == 'RGBA':
fp.write(o8(colormap[4 * i]) + o8(colormap[4 * i + 1]) + o8(colormap[4 * i + 2]))
fp.write(
o8(colormap[4 * i]) +
o8(colormap[4 * i + 1]) +
o8(colormap[4 * i + 2]))
# now convert data to raw form
ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, rowbytes, 1))])
ImageFile._save(
im, fp, [("raw", (0, 0)+im.size, 0, (rawmode, rowbytes, 1))])
fp.flush()

View File

@ -3,20 +3,25 @@ import os
if bytes is str:
def isStringType(t):
return isinstance(t, basestring)
def isPath(f):
return isinstance(f, basestring)
else:
def isStringType(t):
return isinstance(t, str)
def isPath(f):
return isinstance(f, (bytes, str))
# Checks if an object is a string, and that it points to a directory.
def isDirectory(f):
return isPath(f) and os.path.isdir(f)
class deferred_error(object):
def __init__(self, ex):
self.ex = ex
def __getattr__(self, elt):
raise self.ex

View File

@ -0,0 +1,10 @@
#!/usr/bin/env python
from PIL import Image
import sys
if sys.maxsize < 2**32:
im = Image.new('L', (999999, 999999), 0)

View File

@ -5,22 +5,19 @@ from __future__ import print_function
import sys
import tempfile
import os
import glob
if sys.version_info[:2] <= (2, 6):
import unittest2 as unittest
else:
import unittest
def tearDownModule():
#remove me later
pass
class PillowTestCase(unittest.TestCase):
def __init__(self, *args, **kwargs):
unittest.TestCase.__init__(self, *args, **kwargs)
self.currentResult = None # holds last result object passed to run method
# holds last result object passed to run method:
self.currentResult = None
def run(self, result=None):
self.currentResult = result # remember result for use later
@ -40,7 +37,7 @@ class PillowTestCase(unittest.TestCase):
except OSError:
pass # report?
else:
print("=== orphaned temp file: %s" %path)
print("=== orphaned temp file: %s" % path)
def assert_almost_equal(self, a, b, msg=None, eps=1e-6):
self.assertLess(
@ -123,14 +120,40 @@ class PillowTestCase(unittest.TestCase):
self.assertTrue(found)
return result
def skipKnownBadTest(self, msg=None, platform=None, travis=None):
# Skip if platform/travis matches, and
# PILLOW_RUN_KNOWN_BAD is not true in the environment.
if bool(os.environ.get('PILLOW_RUN_KNOWN_BAD', False)):
print (os.environ.get('PILLOW_RUN_KNOWN_BAD', False))
return
skip = True
if platform is not None:
skip = sys.platform.startswith(platform)
if travis is not None:
skip = skip and (travis == bool(os.environ.get('TRAVIS', False)))
if skip:
self.skipTest(msg or "Known Bad Test")
def tempfile(self, template):
assert template[:5] in ("temp.", "temp_")
(fd, path) = tempfile.mkstemp(template[4:], template[:4])
os.close(fd)
self.addCleanup(self.delete_tempfile, path)
self.addCleanup(self.delete_tempfile, path)
return path
def open_withImagemagick(self, f):
if not imagemagick_available():
raise IOError()
outfile = self.tempfile("temp.png")
if command_succeeds(['convert', f, outfile]):
from PIL import Image
return Image.open(outfile)
raise IOError()
# helpers
import sys
@ -184,14 +207,21 @@ def command_succeeds(cmd):
return False
return True
def djpeg_available():
return command_succeeds(['djpeg', '--help'])
def cjpeg_available():
return command_succeeds(['cjpeg', '--help'])
def netpbm_available():
return command_succeeds(["ppmquant", "--help"]) and \
command_succeeds(["ppmtogif", "--help"])
return (command_succeeds(["ppmquant", "--help"]) and
command_succeeds(["ppmtogif", "--help"]))
def imagemagick_available():
return command_succeeds(['convert', '-version'])
# End of file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
Tests/images/iss634.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
import PIL
import PIL.Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image
import os

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
try:
import cffi

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image
import io

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image, EpsImagePlugin
import io

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena, netpbm_available
from helper import unittest, PillowTestCase, lena, netpbm_available
from PIL import Image
from PIL import GifImagePlugin
@ -106,6 +106,50 @@ class TestFileGif(PillowTestCase):
GifImagePlugin._save_netpbm(img, 0, tempfile)
self.assert_image_similar(img, Image.open(tempfile).convert("L"), 0)
def test_seek(self):
img = Image.open("Tests/images/dispose_none.gif")
framecount = 0
try:
while True:
framecount += 1
img.seek(img.tell() +1)
except EOFError:
self.assertEqual(framecount, 5)
def test_dispose_none(self):
img = Image.open("Tests/images/dispose_none.gif")
try:
while True:
img.seek(img.tell() +1)
self.assertEqual(img.disposal_method, 1)
except EOFError:
pass
def test_dispose_background(self):
img = Image.open("Tests/images/dispose_bgnd.gif")
try:
while True:
img.seek(img.tell() +1)
self.assertEqual(img.disposal_method, 2)
except EOFError:
pass
def test_dispose_previous(self):
img = Image.open("Tests/images/dispose_prev.gif")
try:
while True:
img.seek(img.tell() +1)
self.assertEqual(img.disposal_method, 3)
except EOFError:
pass
def test_iss634(self):
img = Image.open("Tests/images/iss634.gif")
# seek to the second frame
img.seek(img.tell() +1)
# all transparent pixels should be replaced with the color from the first frame
self.assertEqual(img.histogram()[img.info['transparency']], 0)
if __name__ == '__main__':
unittest.main()

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena, py3
from helper import unittest, PillowTestCase, lena, py3
from helper import djpeg_available, cjpeg_available
import random

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image
from io import BytesIO

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena, py3
from helper import unittest, PillowTestCase, lena, py3
import os

View File

@ -1,4 +1,4 @@
from helper import unittest, tearDownModule
from helper import unittest
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

61
Tests/test_file_palm.py Normal file
View File

@ -0,0 +1,61 @@
from helper import unittest, PillowTestCase, lena, imagemagick_available
import os.path
class TestFilePalm(PillowTestCase):
_roundtrip = imagemagick_available()
def helper_save_as_palm(self, mode):
# Arrange
im = lena(mode)
outfile = self.tempfile("temp_" + mode + ".palm")
# Act
im.save(outfile)
# Assert
self.assertTrue(os.path.isfile(outfile))
self.assertGreater(os.path.getsize(outfile), 0)
def roundtrip(self, mode):
if not self._roundtrip:
return
im = lena(mode)
outfile = self.tempfile("temp.palm")
im.save(outfile)
converted = self.open_withImagemagick(outfile)
self.assert_image_equal(converted, im)
def test_monochrome(self):
# Arrange
mode = "1"
# Act / Assert
self.helper_save_as_palm(mode)
self.roundtrip(mode)
def test_p_mode(self):
# Arrange
mode = "P"
# Act / Assert
self.helper_save_as_palm(mode)
self.skipKnownBadTest("Palm P image is wrong")
self.roundtrip(mode)
def test_rgb_ioerror(self):
# Arrange
mode = "RGB"
# Act / Assert
self.assertRaises(IOError, lambda: self.helper_save_as_palm(mode))
if __name__ == '__main__':
unittest.main()
# End of file

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
import os.path

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from io import BytesIO

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image
from PIL import SpiderImagePlugin

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image, TarIO

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena, py3
from helper import unittest, PillowTestCase, lena, py3
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image, TiffImagePlugin, TiffTags

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import FontFile, BdfFontFile

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image, FontFile, PcfFontFile
from PIL import ImageFont, ImageDraw

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image
@ -44,6 +44,17 @@ class TestImage(PillowTestCase):
file = self.tempfile("temp.ppm")
im._dump(file)
def test_comparison_with_other_type(self):
# Arrange
item = Image.new('RGB', (25, 25), '#000')
num = 12
# Act/Assert
# Shouldn't cause AttributeError (#774)
self.assertFalse(item is None)
self.assertFalse(item == None)
self.assertFalse(item == num)
if __name__ == '__main__':
unittest.main()

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, fromstring, tostring
from helper import unittest, PillowTestCase, fromstring, tostring
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image
from PIL import ImageFilter

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
class TestImageGetColors(PillowTestCase):

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
class TestImageGetData(PillowTestCase):

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
class TestImageGetExtrema(PillowTestCase):

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena, py3
from helper import unittest, PillowTestCase, lena, py3
class TestImageGetIm(PillowTestCase):

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
class TestImageGetPalette(PillowTestCase):

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
class TestImageHistogram(PillowTestCase):

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
class TestImageOffset(PillowTestCase):

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
import sys

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
import sys

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import ImagePalette

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
class TestImageResize(PillowTestCase):

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
class TestImageRotate(PillowTestCase):

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
class TestImageThumbnail(PillowTestCase):

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena, fromstring
from helper import unittest, PillowTestCase, lena, fromstring
class TestImageToBitmap(PillowTestCase):

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image
from PIL import ImageChops

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image
from PIL import ImageColor

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image
from PIL import ImageColor

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import Image
from PIL import ImageEnhance

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena, fromstring, tostring
from helper import unittest, PillowTestCase, lena, fromstring, tostring
from io import BytesIO

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena, tostring
from helper import unittest, PillowTestCase, lena, tostring
from PIL import Image
from PIL import ImageFileIO

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import ImageFilter

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image
from PIL import ImageDraw
@ -71,11 +71,25 @@ try:
self.assert_image_equal(img_path, img_filelike)
self._clean()
def test_textsize_equal(self):
im = Image.new(mode='RGB', size=(300, 100))
draw = ImageDraw.Draw(im)
ttf = ImageFont.truetype(font_path, font_size)
txt = "Hello World!"
size = draw.textsize(txt, ttf)
draw.text((10, 10), txt, font=ttf)
draw.rectangle((10, 10, 10 + size[0], 10 + size[1]))
target = 'Tests/images/rectangle_surrounding_text.png'
target_img = Image.open(target)
self.assert_image_equal(im, target_img)
def test_render_multiline(self):
im = Image.new(mode='RGB', size=(300, 100))
draw = ImageDraw.Draw(im)
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
line_spacing = draw.textsize('A', font=ttf)[1] + 8
line_spacing = draw.textsize('A', font=ttf)[1] + 4
lines = ['hey you', 'you are awesome', 'this looks awkward']
y = 0
for line in lines:

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
try:
from PIL import ImageGrab

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image
from PIL import ImageMath

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import ImageMode

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
from PIL import ImageOps

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import Image
from PIL import ImageOps

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import ImagePalette

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule
from helper import unittest, PillowTestCase
from PIL import ImagePath

View File

@ -1,4 +1,4 @@
from helper import unittest, PillowTestCase, tearDownModule, lena
from helper import unittest, PillowTestCase, lena
try:
from PIL import ImageQt

Some files were not shown because too many files have changed in this diff Show More