Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Changelog (Pillow)
2.4.0 (unreleased)
------------------

- Fixed opening and saving odd sized .pcx files
[wiredfool]

- Fixed saving mode P image as a PNG with transparency = palette color 0
[d-schmidt]

Expand Down
20 changes: 19 additions & 1 deletion PIL/PcxImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,18 @@ def _open(self):
bbox = i16(s,4), i16(s,6), i16(s,8)+1, i16(s,10)+1
if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]:
raise SyntaxError("bad PCX image size")
if Image.DEBUG:
print ("BBox: %s %s %s %s" % bbox)


# format
version = i8(s[1])
bits = i8(s[3])
planes = i8(s[65])
stride = i16(s,66)
if Image.DEBUG:
print ("PCX version %s, bits %s, planes %s, stride %s" %
(version, bits, planes, stride))

self.info["dpi"] = i16(s,12), i16(s,14)

Expand Down Expand Up @@ -98,7 +104,9 @@ def _open(self):
self.size = bbox[2]-bbox[0], bbox[3]-bbox[1]

bbox = (0, 0) + self.size

if Image.DEBUG:
print ("size: %sx%s" % self.size)

self.tile = [("pcx", bbox, self.fp.tell(), (rawmode, planes * stride))]

# --------------------------------------------------------------------
Expand Down Expand Up @@ -126,6 +134,16 @@ def _save(im, fp, filename, check=0):

# bytes per plane
stride = (im.size[0] * bits + 7) // 8
# stride should be even
stride = stride + (stride % 2)
# Stride needs to be kept in sync with the PcxEncode.c version.
# Ideally it should be passed in in the state, but the bytes value
# gets overwritten.


if Image.DEBUG:
print ("PcxImagePlugin._save: xwidth: %d, bits: %d, stride: %d" % (
im.size[0], bits, stride))

# under windows, we could determine the current screen size with
# "Image.core.display_mode()[1]", but I think that's overkill...
Expand Down
43 changes: 22 additions & 21 deletions Tests/test_file_pcx.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,30 @@

from PIL import Image

def test_sanity():

file = tempfile("temp.pcx")

lena("1").save(file)

im = Image.open(file)
im.load()
assert_equal(im.mode, "1")
assert_equal(im.size, (128, 128))
assert_equal(im.format, "PCX")

lena("1").save(file)
im = Image.open(file)

lena("L").save(file)
im = Image.open(file)

lena("P").save(file)
im = Image.open(file)
def _roundtrip(im):
f = tempfile("temp.pcx")
im.save(f)
im2 = Image.open(f)

lena("RGB").save(file)
im = Image.open(file)
assert_equal(im2.mode, im.mode)
assert_equal(im2.size, im.size)
assert_equal(im2.format, "PCX")
assert_image_equal(im2, im)

def test_sanity():
for mode in ('1', 'L', 'P', 'RGB'):
_roundtrip(lena(mode))

def test_odd():
# see issue #523, odd sized images should have a stride that's even.
# not that imagemagick or gimp write pcx that way.
# we were not handling properly.
for mode in ('1', 'L', 'P', 'RGB'):
# larger, odd sized images are better here to ensure that
# we handle interrupted scan lines properly.
_roundtrip(lena(mode).resize((511,511)))


def test_pil184():
# Check reading of files where xmin/xmax is not zero.
Expand Down
Loading