Pillow/Tests/test_file_png.py

333 lines
9.5 KiB
Python
Raw Normal View History

2014-07-07 21:03:50 +04:00
from helper import unittest, PillowTestCase, lena
2014-06-10 13:10:47 +04:00
from io import BytesIO
from PIL import Image
from PIL import PngImagePlugin
2013-08-20 16:17:17 +04:00
import zlib
codecs = dir(Image.core)
# sample png stream
file = "Tests/images/lena.png"
data = open(file, "rb").read()
# stuff to create inline PNG images
MAGIC = PngImagePlugin._MAGIC
2014-06-10 13:10:47 +04:00
def chunk(cid, *data):
file = BytesIO()
PngImagePlugin.putchunk(*(file, cid) + data)
return file.getvalue()
o32 = PngImagePlugin.o32
IHDR = chunk(b"IHDR", o32(1), o32(1), b'\x08\x02', b'\0\0\0')
IDAT = chunk(b"IDAT")
IEND = chunk(b"IEND")
HEAD = MAGIC + IHDR
TAIL = IDAT + IEND
2014-06-10 13:10:47 +04:00
def load(data):
return Image.open(BytesIO(data))
2014-06-10 13:10:47 +04:00
def roundtrip(im, **options):
out = BytesIO()
im.save(out, "PNG", **options)
out.seek(0)
return Image.open(out)
2014-06-10 13:10:47 +04:00
class TestFilePng(PillowTestCase):
def setUp(self):
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
self.skipTest("zip/deflate support not available")
def test_sanity(self):
2014-06-10 13:10:47 +04:00
# internal version number
self.assertRegexpMatches(
Image.core.zlib_version, "\d+\.\d+\.\d+(\.\d+)?$")
2014-06-10 13:10:47 +04:00
file = self.tempfile("temp.png")
2014-06-10 13:10:47 +04:00
lena("RGB").save(file)
2014-06-10 13:10:47 +04:00
im = Image.open(file)
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "PNG")
2014-06-10 13:10:47 +04:00
lena("1").save(file)
im = Image.open(file)
2014-06-10 13:10:47 +04:00
lena("L").save(file)
im = Image.open(file)
2014-06-10 13:10:47 +04:00
lena("P").save(file)
im = Image.open(file)
2014-06-10 13:10:47 +04:00
lena("RGB").save(file)
im = Image.open(file)
2014-06-10 13:10:47 +04:00
lena("I").save(file)
im = Image.open(file)
2014-06-10 13:10:47 +04:00
def test_broken(self):
# Check reading of totally broken files. In this case, the test
# file was checked into Subversion as a text file.
2014-06-10 13:10:47 +04:00
file = "Tests/images/broken.png"
self.assertRaises(IOError, lambda: Image.open(file))
2014-06-10 13:10:47 +04:00
def test_bad_text(self):
# Make sure PIL can read malformed tEXt chunks (@PIL152)
2014-06-10 13:10:47 +04:00
im = load(HEAD + chunk(b'tEXt') + TAIL)
self.assertEqual(im.info, {})
2014-06-10 13:10:47 +04:00
im = load(HEAD + chunk(b'tEXt', b'spam') + TAIL)
self.assertEqual(im.info, {'spam': ''})
2014-06-10 13:10:47 +04:00
im = load(HEAD + chunk(b'tEXt', b'spam\0') + TAIL)
self.assertEqual(im.info, {'spam': ''})
2014-06-10 13:10:47 +04:00
im = load(HEAD + chunk(b'tEXt', b'spam\0egg') + TAIL)
self.assertEqual(im.info, {'spam': 'egg'})
2014-06-10 13:10:47 +04:00
im = load(HEAD + chunk(b'tEXt', b'spam\0egg\0') + TAIL)
self.assertEqual(im.info, {'spam': 'egg\x00'})
2014-06-10 13:10:47 +04:00
def test_bad_ztxt(self):
# Test reading malformed zTXt chunks (python-pillow/Pillow#318)
2014-06-10 13:10:47 +04:00
im = load(HEAD + chunk(b'zTXt') + TAIL)
self.assertEqual(im.info, {})
2013-08-20 16:17:17 +04:00
2014-06-10 13:10:47 +04:00
im = load(HEAD + chunk(b'zTXt', b'spam') + TAIL)
self.assertEqual(im.info, {'spam': ''})
2013-08-20 16:17:17 +04:00
2014-06-10 13:10:47 +04:00
im = load(HEAD + chunk(b'zTXt', b'spam\0') + TAIL)
self.assertEqual(im.info, {'spam': ''})
2013-08-20 16:17:17 +04:00
2014-06-10 13:10:47 +04:00
im = load(HEAD + chunk(b'zTXt', b'spam\0\0') + TAIL)
self.assertEqual(im.info, {'spam': ''})
2013-08-20 16:17:17 +04:00
2014-06-10 13:10:47 +04:00
im = load(HEAD + chunk(
b'zTXt', b'spam\0\0' + zlib.compress(b'egg')[:1]) + TAIL)
self.assertEqual(im.info, {'spam': ''})
2013-08-20 16:17:17 +04:00
2014-06-10 13:10:47 +04:00
im = load(
HEAD + chunk(b'zTXt', b'spam\0\0' + zlib.compress(b'egg')) + TAIL)
self.assertEqual(im.info, {'spam': 'egg'})
2013-08-20 16:17:17 +04:00
2014-07-23 12:09:06 +04:00
def test_bad_itxt(self):
im = load(HEAD + chunk(b'iTXt') + TAIL)
self.assertEqual(im.info, {})
im = load(HEAD + chunk(b'iTXt', b'spam') + TAIL)
self.assertEqual(im.info, {})
im = load(HEAD + chunk(b'iTXt', b'spam\0') + TAIL)
self.assertEqual(im.info, {})
im = load(HEAD + chunk(b'iTXt', b'spam\0\x02') + TAIL)
self.assertEqual(im.info, {})
im = load(HEAD + chunk(b'iTXt', b'spam\0\0\0foo\0') + TAIL)
self.assertEqual(im.info, {})
im = load(HEAD + chunk(b'iTXt', b'spam\0\0\0en\0Spam\0egg') + TAIL)
self.assertEqual(im.info, {"spam": "egg"})
self.assertEqual(im.info["spam"].lang, "en")
self.assertEqual(im.info["spam"].tkey, "Spam")
im = load(HEAD + chunk(b'iTXt', b'spam\0\1\0en\0Spam\0' + zlib.compress(b"egg")[:1]) + TAIL)
self.assertEqual(im.info, {})
im = load(HEAD + chunk(b'iTXt', b'spam\0\1\1en\0Spam\0' + zlib.compress(b"egg")) + TAIL)
self.assertEqual(im.info, {})
im = load(HEAD + chunk(b'iTXt', b'spam\0\1\0en\0Spam\0' + zlib.compress(b"egg")) + TAIL)
self.assertEqual(im.info, {"spam": "egg"})
self.assertEqual(im.info["spam"].lang, "en")
self.assertEqual(im.info["spam"].tkey, "Spam")
2014-06-10 13:10:47 +04:00
def test_interlace(self):
2013-08-20 16:17:17 +04:00
2014-06-10 13:10:47 +04:00
file = "Tests/images/pil123p.png"
im = Image.open(file)
2014-06-10 13:10:47 +04:00
self.assert_image(im, "P", (162, 150))
self.assertTrue(im.info.get("interlace"))
2014-06-10 13:10:47 +04:00
im.load()
2014-06-10 13:10:47 +04:00
file = "Tests/images/pil123rgba.png"
im = Image.open(file)
2014-06-10 13:10:47 +04:00
self.assert_image(im, "RGBA", (162, 150))
self.assertTrue(im.info.get("interlace"))
2014-06-10 13:10:47 +04:00
im.load()
2014-06-10 13:10:47 +04:00
def test_load_transparent_p(self):
file = "Tests/images/pil123p.png"
im = Image.open(file)
2014-06-10 13:10:47 +04:00
self.assert_image(im, "P", (162, 150))
im = im.convert("RGBA")
self.assert_image(im, "RGBA", (162, 150))
2014-06-10 13:10:47 +04:00
# image has 124 uniqe qlpha values
self.assertEqual(len(im.split()[3].getcolors()), 124)
2014-06-10 13:10:47 +04:00
def test_load_transparent_rgb(self):
file = "Tests/images/rgb_trns.png"
im = Image.open(file)
2014-06-10 13:10:47 +04:00
self.assert_image(im, "RGB", (64, 64))
im = im.convert("RGBA")
self.assert_image(im, "RGBA", (64, 64))
2013-11-23 04:04:51 +04:00
2014-06-10 13:10:47 +04:00
# image has 876 transparent pixels
self.assertEqual(im.split()[3].getcolors()[0][0], 876)
2013-11-23 04:04:51 +04:00
2014-06-10 13:10:47 +04:00
def test_save_p_transparent_palette(self):
in_file = "Tests/images/pil123p.png"
im = Image.open(in_file)
2013-11-23 04:04:51 +04:00
2014-06-10 13:10:47 +04:00
file = self.tempfile("temp.png")
im.save(file)
2014-06-10 13:10:47 +04:00
def test_save_p_single_transparency(self):
in_file = "Tests/images/p_trns_single.png"
im = Image.open(in_file)
2014-06-10 13:10:47 +04:00
file = self.tempfile("temp.png")
im.save(file)
2014-06-10 13:10:47 +04:00
def test_save_l_transparency(self):
in_file = "Tests/images/l_trns.png"
im = Image.open(in_file)
2014-06-10 13:10:47 +04:00
file = self.tempfile("temp.png")
im.save(file)
2014-06-10 13:10:47 +04:00
# There are 559 transparent pixels.
im = im.convert('RGBA')
self.assertEqual(im.split()[3].getcolors()[0][0], 559)
2014-06-10 13:10:47 +04:00
def test_save_rgb_single_transparency(self):
in_file = "Tests/images/caption_6_33_22.png"
im = Image.open(in_file)
2014-06-10 13:10:47 +04:00
file = self.tempfile("temp.png")
im.save(file)
2014-06-10 13:10:47 +04:00
def test_load_verify(self):
# Check open/load/verify exception (@PIL150)
im = Image.open("Tests/images/lena.png")
2014-06-10 13:10:47 +04:00
im.verify()
im = Image.open("Tests/images/lena.png")
2014-06-10 13:10:47 +04:00
im.load()
self.assertRaises(RuntimeError, lambda: im.verify())
2014-06-10 13:10:47 +04:00
def test_roundtrip_dpi(self):
# Check dpi roundtripping
2014-06-10 13:10:47 +04:00
im = Image.open(file)
2014-06-10 13:10:47 +04:00
im = roundtrip(im, dpi=(100, 100))
self.assertEqual(im.info["dpi"], (100, 100))
2014-06-10 13:10:47 +04:00
def test_roundtrip_text(self):
# Check text roundtripping
2014-06-10 13:10:47 +04:00
im = Image.open(file)
2014-06-10 13:10:47 +04:00
info = PngImagePlugin.PngInfo()
info.add_text("TXT", "VALUE")
info.add_text("ZIP", "VALUE", 1)
2014-06-10 13:10:47 +04:00
im = roundtrip(im, pnginfo=info)
self.assertEqual(im.info, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
self.assertEqual(im.text, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
2014-06-10 13:10:47 +04:00
def test_scary(self):
# Check reading of evil PNG file. For information, see:
# http://scary.beasts.org/security/CESA-2004-001.txt
# The first byte is removed from pngtest_bad.png
# to avoid classification as malware.
2014-06-10 13:10:47 +04:00
with open("Tests/images/pngtest_bad.png.bin", 'rb') as fd:
data = b'\x89' + fd.read()
2014-06-10 13:10:47 +04:00
pngfile = BytesIO(data)
self.assertRaises(IOError, lambda: Image.open(pngfile))
2014-06-10 13:10:47 +04:00
def test_trns_rgb(self):
# Check writing and reading of tRNS chunks for RGB images.
# Independent file sample provided by Sebastian Spaeth.
2014-06-10 13:10:47 +04:00
file = "Tests/images/caption_6_33_22.png"
im = Image.open(file)
self.assertEqual(im.info["transparency"], (248, 248, 248))
2014-06-10 13:10:47 +04:00
# check saving transparency by default
im = roundtrip(im)
self.assertEqual(im.info["transparency"], (248, 248, 248))
2014-06-10 13:10:47 +04:00
im = roundtrip(im, transparency=(0, 1, 2))
self.assertEqual(im.info["transparency"], (0, 1, 2))
2014-06-10 13:10:47 +04:00
def test_trns_p(self):
# Check writing a transparency of 0, issue #528
im = lena('P')
im.info['transparency'] = 0
2014-06-10 13:10:47 +04:00
f = self.tempfile("temp.png")
im.save(f)
2014-06-10 13:10:47 +04:00
im2 = Image.open(f)
self.assertIn('transparency', im2.info)
2014-03-01 04:29:34 +04:00
2014-06-10 13:10:47 +04:00
self.assert_image_equal(im2.convert('RGBA'), im.convert('RGBA'))
2014-03-01 04:29:34 +04:00
2014-06-10 13:10:47 +04:00
def test_save_icc_profile_none(self):
# check saving files with an ICC profile set to None (omit profile)
in_file = "Tests/images/icc_profile_none.png"
im = Image.open(in_file)
self.assertEqual(im.info['icc_profile'], None)
2014-06-10 13:10:47 +04:00
im = roundtrip(im)
self.assertNotIn('icc_profile', im.info)
2014-06-10 13:10:47 +04:00
def test_roundtrip_icc_profile(self):
# check that we can roundtrip the icc profile
im = lena('RGB')
2014-06-10 13:10:47 +04:00
jpeg_image = Image.open('Tests/images/flower2.jpg')
expected_icc = jpeg_image.info['icc_profile']
2014-06-10 13:10:47 +04:00
im.info['icc_profile'] = expected_icc
im = roundtrip(im)
self.assertEqual(im.info['icc_profile'], expected_icc)
2014-01-22 08:50:54 +04:00
2014-06-10 13:10:47 +04:00
if __name__ == '__main__':
unittest.main()
2014-06-10 13:10:47 +04:00
# End of file