Merge pull request #808 from wiredfool/xpm_load_image

Fix Scrambled XPM
This commit is contained in:
Hugo 2014-07-19 00:28:02 +03:00
commit eb4f669b34
3 changed files with 40 additions and 22 deletions

View File

@ -133,11 +133,27 @@ class ImageFile(Image.Image):
return pixel return pixel
self.map = None self.map = None
use_mmap = self.filename and len(self.tile) == 1
# As of pypy 2.1.0, memory mapping was failing here.
use_mmap = use_mmap and not hasattr(sys, 'pypy_version_info')
readonly = 0 readonly = 0
if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'): # look for read/seek overrides
# As of pypy 2.1.0, memory mapping was failing here. try:
read = self.load_read
# don't use mmap if there are custom read/seek functions
use_mmap = False
except AttributeError:
read = self.fp.read
try:
seek = self.load_seek
use_mmap = False
except AttributeError:
seek = self.fp.seek
if use_mmap:
# try memory mapping # try memory mapping
d, e, o, a = self.tile[0] d, e, o, a = self.tile[0]
if d == "raw" and a[0] == self.mode and a[0] in Image._MAPMODES: if d == "raw" and a[0] == self.mode and a[0] in Image._MAPMODES:
@ -165,19 +181,7 @@ class ImageFile(Image.Image):
self.load_prepare() self.load_prepare()
# look for read/seek overrides
try:
read = self.load_read
except AttributeError:
read = self.fp.read
try:
seek = self.load_seek
except AttributeError:
seek = self.fp.seek
if not self.map: if not self.map:
# sort tiles in file order # sort tiles in file order
self.tile.sort(key=_tilesort) self.tile.sort(key=_tilesort)

View File

@ -29,6 +29,7 @@ xpm_head = re.compile(b"\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)")
def _accept(prefix): def _accept(prefix):
return prefix[:9] == b"/* XPM */" return prefix[:9] == b"/* XPM */"
## ##
# Image plugin for X11 pixel maps. # Image plugin for X11 pixel maps.
@ -86,9 +87,9 @@ class XpmImageFile(ImageFile.ImageFile):
elif rgb[0:1] == b"#": elif rgb[0:1] == b"#":
# FIXME: handle colour names (see ImagePalette.py) # FIXME: handle colour names (see ImagePalette.py)
rgb = int(rgb[1:], 16) rgb = int(rgb[1:], 16)
palette[c] = o8((rgb >> 16) & 255) +\ palette[c] = (o8((rgb >> 16) & 255) +
o8((rgb >> 8) & 255) +\ o8((rgb >> 8) & 255) +
o8(rgb & 255) o8(rgb & 255))
else: else:
# unknown colour # unknown colour
raise ValueError("cannot read this XPM file") raise ValueError("cannot read this XPM file")

View File

@ -1,21 +1,34 @@
from helper import unittest, PillowTestCase from helper import unittest, PillowTestCase, lena
from PIL import Image from PIL import Image
# sample ppm stream # sample ppm stream
file = "Tests/images/lena.xpm" TEST_FILE = "Tests/images/lena.xpm"
data = open(file, "rb").read()
class TestFileXpm(PillowTestCase): class TestFileXpm(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im = Image.open(file) im = Image.open(TEST_FILE)
im.load() im.load()
self.assertEqual(im.mode, "P") self.assertEqual(im.mode, "P")
self.assertEqual(im.size, (128, 128)) self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "XPM") self.assertEqual(im.format, "XPM")
#large error due to quantization->44 colors.
self.assert_image_similar(im.convert('RGB'), lena('RGB'), 60)
def test_load_read(self):
# Arrange
im = Image.open(TEST_FILE)
dummy_bytes = 1
# Act
data = im.load_read(dummy_bytes)
# Assert
self.assertEqual(len(data), 16384)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()