Skip to content

Commit

Permalink
merge from master
Browse files Browse the repository at this point in the history
  • Loading branch information
wiredfool committed Jan 31, 2014
2 parents 9e069bf + 09ee0c0 commit 288a563
Show file tree
Hide file tree
Showing 20 changed files with 254 additions and 139 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ install:
- "sudo apt-get -qq install libfreetype6-dev liblcms2-dev libwebp-dev python-qt4 ghostscript libffi-dev"
- "pip install cffi"


script:
- python setup.py clean
- python setup.py build_ext --inplace
Expand Down
12 changes: 12 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ Changelog (Pillow)
2.4.0 (2014-04-01)
------------------

- Minor patch on booleans + Travis
[sciunto]

- Look in multiarch paths in GNU platforms
[pinotree]

- Add arch support for pcc64, s390, s390x, armv7l, aarch64
[manisandro]

- Add arch support for ppc
[wiredfool]

- Correctly quote file names for WindowsViewer command
[cgohlke]

Expand Down
54 changes: 33 additions & 21 deletions PIL/EpsImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,43 +67,48 @@ def Ghostscript(tile, size, fp, scale=1):

import tempfile, os, subprocess

file = tempfile.mktemp()
outfile = tempfile.mktemp()
infile = tempfile.mktemp()

with open(infile, 'wb') as f:
fp.seek(offset)
while length >0:
s = fp.read(100*1024)
if not s:
break
length = length - len(s)
f.write(s)

# Build ghostscript command
command = ["gs",
"-q", # quite mode
"-g%dx%d" % size, # set output geometry (pixels)
"-r%d" % (72*scale), # set input DPI (dots per inch)
"-dNOPAUSE -dSAFER", # don't pause between pages, safe mode
"-sDEVICE=ppmraw", # ppm driver
"-sOutputFile=%s" % file,# output file
"-q", # quiet mode
"-g%dx%d" % size, # set output geometry (pixels)
"-r%d" % (72*scale), # set input DPI (dots per inch)
"-dNOPAUSE -dSAFER", # don't pause between pages, safe mode
"-sDEVICE=ppmraw", # ppm driver
"-sOutputFile=%s" % outfile, # output file
"-c", "%d %d translate" % (-bbox[0], -bbox[1]),
# adjust for image origin
"-f", infile, # input file
]

if gs_windows_binary is not None:
if gs_windows_binary is False:
if not gs_windows_binary:
raise WindowsError('Unable to locate Ghostscript on paths')
command[0] = gs_windows_binary

# push data through ghostscript
try:
gs = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
# adjust for image origin
if bbox[0] != 0 or bbox[1] != 0:
gs.stdin.write(("%d %d translate\n" % (-bbox[0], -bbox[1])).encode('ascii'))
fp.seek(offset)
while length > 0:
s = fp.read(8192)
if not s:
break
length = length - len(s)
gs.stdin.write(s)
gs.stdin.close()
status = gs.wait()
if status:
raise IOError("gs failed (status %d)" % status)
im = Image.core.open_ppm(file)
im = Image.core.open_ppm(outfile)
finally:
try: os.unlink(file)
try:
os.unlink(outfile)
os.unlink(infile)
except: pass

return im
Expand Down Expand Up @@ -320,6 +325,11 @@ def load(self, scale=1):
self.size = self.im.size
self.tile = []

def load_seek(self,*args,**kwargs):
# we can't incrementally load, so force ImageFile.parser to
# use our custom load method by defining this method.
pass

#
# --------------------------------------------------------------------

Expand Down Expand Up @@ -350,7 +360,9 @@ def close(self):
pass

base_fp = fp
fp = io.TextIOWrapper(NoCloseStream(fp), encoding='latin-1')
fp = NoCloseStream(fp)
if sys.version_info[0] > 2:
fp = io.TextIOWrapper(fp, encoding='latin-1')

if eps:
#
Expand Down
4 changes: 3 additions & 1 deletion PIL/Image.py
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,8 @@ def crop(self, box=None):

def draft(self, mode, size):
"""
NYI
Configures the image file loader so it returns a version of the
image that as closely as possible matches the given mode and
size. For example, you can use this method to convert a color
Expand Down Expand Up @@ -1323,7 +1325,7 @@ def resize(self, size, resample=NEAREST):
:param size: The requested size in pixels, as a 2-tuple:
(width, height).
:param filter: An optional resampling filter. This can be
:param resample: An optional resampling filter. This can be
one of :py:attr:`PIL.Image.NEAREST` (use nearest neighbour),
:py:attr:`PIL.Image.BILINEAR` (linear interpolation in a 2x2
environment), :py:attr:`PIL.Image.BICUBIC` (cubic spline
Expand Down
2 changes: 1 addition & 1 deletion PIL/ImageFile.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def load(self):

self.fp = None # might be shared

if (not LOAD_TRUNCATED_IMAGES or t == 0) and not self.map and e < 0:
if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:
# still raised if decoder fails to return anything
raise_ioerror(e)

Expand Down
2 changes: 1 addition & 1 deletion PIL/OleFileIO.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ class OleFileIO:
if entry[1:2] == "Image":
fin = ole.openstream(entry)
fout = open(entry[0:1], "wb")
while 1:
while True:
s = fin.read(8192)
if not s:
break
Expand Down
2 changes: 1 addition & 1 deletion PIL/SpiderImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def tkPhotoImage(self):
# given a list of filenames, return a list of images
def loadImageSeries(filelist=None):
" create a list of Image.images for use in montage "
if filelist == None or len(filelist) < 1:
if filelist is None or len(filelist) < 1:
return

imglist = []
Expand Down
2 changes: 1 addition & 1 deletion PIL/TiffImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,7 @@ def _save(im, fp, filename):
# print (im.mode, compression, a, im.encoderconfig)
e = Image._getencoder(im.mode, 'libtiff', a, im.encoderconfig)
e.setimage(im.im, (0,0)+im.size)
while 1:
while True:
l, s, d = e.encode(16*1024) # undone, change to self.decodermaxblock
if not _fp:
fp.write(d)
Expand Down
6 changes: 4 additions & 2 deletions PIL/WebPImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ class WebPImageFile(ImageFile.ImageFile):
def _open(self):
data, width, height, self.mode, icc_profile, exif = _webp.WebPDecode(self.fp.read())

self.info["icc_profile"] = icc_profile
self.info["exif"] = exif
if icc_profile:
self.info["icc_profile"] = icc_profile
if exif:
self.info["exif"] = exif

self.size = width, height
self.fp = BytesIO(data)
Expand Down
20 changes: 10 additions & 10 deletions Tests/cms_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
#######################################################################
def outputImage(im, funcName = None):
# save or display the image, depending on value of SHOW_IMAGES
if SHOW == True:
if SHOW:
im.show()
else:
im.save(os.path.join(OUTPUTDIR, "%s.tif" %funcName))
Expand All @@ -57,7 +57,7 @@ def outputImage(im, funcName = None):
# The tests themselves
#######################################################################

if TEST_error_catching == True:
if TEST_error_catching:
im = Image.open(IMAGE)
try:
#neither of these proifles exists (unless you make them), so we should
Expand All @@ -70,7 +70,7 @@ def outputImage(im, funcName = None):
print("error catching test completed successfully (if you see the message \
above that we caught the error).")

if TEST_profileToProfile == True:
if TEST_profileToProfile:
# open the image file using the standard PIL function Image.open()
im = Image.open(IMAGE)

Expand All @@ -84,7 +84,7 @@ def outputImage(im, funcName = None):

print("profileToProfile test completed successfully.")

if TEST_profileToProfile_inPlace == True:
if TEST_profileToProfile_inPlace:
# we'll do the same test as profileToProfile, but modify im in place
# instead of getting a new image returned to us
im = Image.open(IMAGE)
Expand All @@ -94,7 +94,7 @@ def outputImage(im, funcName = None):
outputMode = OUTMODE, inPlace = True)

# now that the image is converted, save or display it
if result == None:
if result is None:
# this is the normal result when modifying in-place
outputImage(im, "profileToProfile_inPlace")
else:
Expand All @@ -103,7 +103,7 @@ def outputImage(im, funcName = None):

print("profileToProfile in-place test completed successfully.")

if TEST_buildTransform == True:
if TEST_buildTransform:
# make a transform using the input and output profile path strings
transform = ImageCms.buildTransform(INPUT_PROFILE, OUTPUT_PROFILE, INMODE, \
OUTMODE)
Expand All @@ -126,7 +126,7 @@ def outputImage(im, funcName = None):
# Python should also do this automatically when it goes out of scope.
del(transform)

if TEST_buildTransformFromOpenProfiles == True:
if TEST_buildTransformFromOpenProfiles:
# we'll actually test a couple profile open/creation functions here too

# first, get a handle to an input profile, in this case we'll create
Expand Down Expand Up @@ -160,7 +160,7 @@ def outputImage(im, funcName = None):
del(outputProfile)
del(transform)

if TEST_buildProofTransform == True:
if TEST_buildProofTransform:
# make a transform using the input and output and proof profile path
# strings
# images converted with this transform will simulate the appearance
Expand Down Expand Up @@ -188,7 +188,7 @@ def outputImage(im, funcName = None):
# Python should also do this automatically when it goes out of scope.
del(transform)

if TEST_getProfileInfo == True:
if TEST_getProfileInfo:
# get a profile handle
profile = ImageCms.getOpenProfile(INPUT_PROFILE)

Expand All @@ -212,7 +212,7 @@ def outputImage(im, funcName = None):

print("getProfileInfo test completed successfully.")

if TEST_misc == True:
if TEST_misc:
# test the versions, about, and copyright functions
print("Versions: %s" %str(ImageCms.versions()))
print("About:\n\n%s" %ImageCms.about())
Expand Down
20 changes: 16 additions & 4 deletions Tests/test_file_eps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

from PIL import Image, EpsImagePlugin
import sys
import io

if EpsImagePlugin.gs_windows_binary == False:
# already checked. Not there.
if not EpsImagePlugin.gs_windows_binary:
# already checked. Not there.
skip()

if not sys.platform.startswith('win'):
import subprocess
try:
Expand Down Expand Up @@ -54,6 +55,18 @@ def test_sanity():
assert_equal(image2_scale2.size, (720, 504))
assert_equal(image2_scale2.format, "EPS")

def test_file_object():
#issue 479
image1 = Image.open(file1)
with open(tempfile('temp_file.eps'), 'wb') as fh:
image1.save(fh, 'EPS')

def test_iobase_object():
#issue 479
image1 = Image.open(file1)
with io.open(tempfile('temp_iobase.eps'), 'wb') as fh:
image1.save(fh, 'EPS')

def test_render_scale1():
#We need png support for these render test
codecs = dir(Image.core)
Expand Down Expand Up @@ -93,4 +106,3 @@ def test_render_scale2():
image2_scale2_compare = Image.open(file2_compare_scale2).convert("RGB")
image2_scale2_compare.load()
assert_image_similar(image2_scale2, image2_scale2_compare, 10)

Loading

0 comments on commit 288a563

Please sign in to comment.