2012-10-16 00:26:38 +04:00
|
|
|
from tester import *
|
|
|
|
|
|
|
|
from PIL import Image
|
|
|
|
from PIL import PngImagePlugin
|
2013-08-20 16:17:17 +04:00
|
|
|
import zlib
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
codecs = dir(Image.core)
|
|
|
|
|
|
|
|
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
|
|
|
skip("zip/deflate support not available")
|
|
|
|
|
|
|
|
# sample png stream
|
|
|
|
|
|
|
|
file = "Images/lena.png"
|
|
|
|
data = open(file, "rb").read()
|
|
|
|
|
|
|
|
# stuff to create inline PNG images
|
|
|
|
|
|
|
|
MAGIC = PngImagePlugin._MAGIC
|
|
|
|
|
|
|
|
def chunk(cid, *data):
|
|
|
|
file = BytesIO()
|
|
|
|
PngImagePlugin.putchunk(*(file, cid) + data)
|
|
|
|
return file.getvalue()
|
|
|
|
|
|
|
|
o32 = PngImagePlugin.o32
|
|
|
|
|
2012-10-15 09:55:39 +04:00
|
|
|
IHDR = chunk(b"IHDR", o32(1), o32(1), b'\x08\x02', b'\0\0\0')
|
2012-10-16 00:26:38 +04:00
|
|
|
IDAT = chunk(b"IDAT")
|
|
|
|
IEND = chunk(b"IEND")
|
|
|
|
|
|
|
|
HEAD = MAGIC + IHDR
|
|
|
|
TAIL = IDAT + IEND
|
|
|
|
|
|
|
|
def load(data):
|
|
|
|
return Image.open(BytesIO(data))
|
|
|
|
|
|
|
|
def roundtrip(im, **options):
|
|
|
|
out = BytesIO()
|
|
|
|
im.save(out, "PNG", **options)
|
|
|
|
out.seek(0)
|
|
|
|
return Image.open(out)
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
|
|
|
|
def test_sanity():
|
|
|
|
|
|
|
|
# internal version number
|
|
|
|
assert_match(Image.core.zlib_version, "\d+\.\d+\.\d+(\.\d+)?$")
|
|
|
|
|
|
|
|
file = tempfile("temp.png")
|
|
|
|
|
|
|
|
lena("RGB").save(file)
|
|
|
|
|
|
|
|
im = Image.open(file)
|
|
|
|
im.load()
|
|
|
|
assert_equal(im.mode, "RGB")
|
|
|
|
assert_equal(im.size, (128, 128))
|
|
|
|
assert_equal(im.format, "PNG")
|
|
|
|
|
|
|
|
lena("1").save(file)
|
|
|
|
im = Image.open(file)
|
|
|
|
|
|
|
|
lena("L").save(file)
|
|
|
|
im = Image.open(file)
|
|
|
|
|
|
|
|
lena("P").save(file)
|
|
|
|
im = Image.open(file)
|
|
|
|
|
|
|
|
lena("RGB").save(file)
|
|
|
|
im = Image.open(file)
|
|
|
|
|
|
|
|
lena("I").save(file)
|
|
|
|
im = Image.open(file)
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
|
|
|
|
def test_broken():
|
|
|
|
# Check reading of totally broken files. In this case, the test
|
|
|
|
# file was checked into Subversion as a text file.
|
|
|
|
|
|
|
|
file = "Tests/images/broken.png"
|
|
|
|
assert_exception(IOError, lambda: Image.open(file))
|
|
|
|
|
|
|
|
def test_bad_text():
|
|
|
|
# Make sure PIL can read malformed tEXt chunks (@PIL152)
|
|
|
|
|
|
|
|
im = load(HEAD + chunk(b'tEXt') + TAIL)
|
|
|
|
assert_equal(im.info, {})
|
|
|
|
|
|
|
|
im = load(HEAD + chunk(b'tEXt', b'spam') + TAIL)
|
py3k: The big push
There are two main issues fixed with this commit:
* bytes vs. str: All file, image, and palette data are now handled as
bytes. A new _binary module consolidates the hacks needed to do this
across Python versions. tostring/fromstring methods have been renamed to
tobytes/frombytes, but the Python 2.6/2.7 versions alias them to the old
names for compatibility. Users should move to tobytes/frombytes.
One other potentially-breaking change is that text data in image files
(such as tags, comments) are now explicitly handled with a specific
character encoding in mind. This works well with the Unicode str in
Python 3, but may trip up old code expecting a straight byte-for-byte
translation to a Python string. This also required a change to Gohlke's
tags tests (in Tests/test_file_png.py) to expect Unicode strings from
the code.
* True div vs. floor div: Many division operations used the "/" operator
to do floor division, which is now the "//" operator in Python 3. These
were fixed.
As of this commit, on the first pass, I have one failing test (improper
handling of a slice object in a C module, test_imagepath.py) in Python 3,
and three that that I haven't tried running yet (test_imagegl,
test_imagegrab, and test_imageqt). I also haven't tested anything on
Windows. All but the three skipped tests run flawlessly against Pythons
2.6 and 2.7.
2012-10-21 01:01:53 +04:00
|
|
|
assert_equal(im.info, {'spam': ''})
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
im = load(HEAD + chunk(b'tEXt', b'spam\0') + TAIL)
|
py3k: The big push
There are two main issues fixed with this commit:
* bytes vs. str: All file, image, and palette data are now handled as
bytes. A new _binary module consolidates the hacks needed to do this
across Python versions. tostring/fromstring methods have been renamed to
tobytes/frombytes, but the Python 2.6/2.7 versions alias them to the old
names for compatibility. Users should move to tobytes/frombytes.
One other potentially-breaking change is that text data in image files
(such as tags, comments) are now explicitly handled with a specific
character encoding in mind. This works well with the Unicode str in
Python 3, but may trip up old code expecting a straight byte-for-byte
translation to a Python string. This also required a change to Gohlke's
tags tests (in Tests/test_file_png.py) to expect Unicode strings from
the code.
* True div vs. floor div: Many division operations used the "/" operator
to do floor division, which is now the "//" operator in Python 3. These
were fixed.
As of this commit, on the first pass, I have one failing test (improper
handling of a slice object in a C module, test_imagepath.py) in Python 3,
and three that that I haven't tried running yet (test_imagegl,
test_imagegrab, and test_imageqt). I also haven't tested anything on
Windows. All but the three skipped tests run flawlessly against Pythons
2.6 and 2.7.
2012-10-21 01:01:53 +04:00
|
|
|
assert_equal(im.info, {'spam': ''})
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
im = load(HEAD + chunk(b'tEXt', b'spam\0egg') + TAIL)
|
py3k: The big push
There are two main issues fixed with this commit:
* bytes vs. str: All file, image, and palette data are now handled as
bytes. A new _binary module consolidates the hacks needed to do this
across Python versions. tostring/fromstring methods have been renamed to
tobytes/frombytes, but the Python 2.6/2.7 versions alias them to the old
names for compatibility. Users should move to tobytes/frombytes.
One other potentially-breaking change is that text data in image files
(such as tags, comments) are now explicitly handled with a specific
character encoding in mind. This works well with the Unicode str in
Python 3, but may trip up old code expecting a straight byte-for-byte
translation to a Python string. This also required a change to Gohlke's
tags tests (in Tests/test_file_png.py) to expect Unicode strings from
the code.
* True div vs. floor div: Many division operations used the "/" operator
to do floor division, which is now the "//" operator in Python 3. These
were fixed.
As of this commit, on the first pass, I have one failing test (improper
handling of a slice object in a C module, test_imagepath.py) in Python 3,
and three that that I haven't tried running yet (test_imagegl,
test_imagegrab, and test_imageqt). I also haven't tested anything on
Windows. All but the three skipped tests run flawlessly against Pythons
2.6 and 2.7.
2012-10-21 01:01:53 +04:00
|
|
|
assert_equal(im.info, {'spam': 'egg'})
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
im = load(HEAD + chunk(b'tEXt', b'spam\0egg\0') + TAIL)
|
py3k: The big push
There are two main issues fixed with this commit:
* bytes vs. str: All file, image, and palette data are now handled as
bytes. A new _binary module consolidates the hacks needed to do this
across Python versions. tostring/fromstring methods have been renamed to
tobytes/frombytes, but the Python 2.6/2.7 versions alias them to the old
names for compatibility. Users should move to tobytes/frombytes.
One other potentially-breaking change is that text data in image files
(such as tags, comments) are now explicitly handled with a specific
character encoding in mind. This works well with the Unicode str in
Python 3, but may trip up old code expecting a straight byte-for-byte
translation to a Python string. This also required a change to Gohlke's
tags tests (in Tests/test_file_png.py) to expect Unicode strings from
the code.
* True div vs. floor div: Many division operations used the "/" operator
to do floor division, which is now the "//" operator in Python 3. These
were fixed.
As of this commit, on the first pass, I have one failing test (improper
handling of a slice object in a C module, test_imagepath.py) in Python 3,
and three that that I haven't tried running yet (test_imagegl,
test_imagegrab, and test_imageqt). I also haven't tested anything on
Windows. All but the three skipped tests run flawlessly against Pythons
2.6 and 2.7.
2012-10-21 01:01:53 +04:00
|
|
|
assert_equal(im.info, {'spam': 'egg\x00'})
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2013-08-20 16:17:17 +04:00
|
|
|
def test_bad_ztxt():
|
2014-06-03 14:02:44 +04:00
|
|
|
# Test reading malformed zTXt chunks (python-pillow/Pillow#318)
|
2013-08-20 16:17:17 +04:00
|
|
|
|
|
|
|
im = load(HEAD + chunk(b'zTXt') + TAIL)
|
|
|
|
assert_equal(im.info, {})
|
|
|
|
|
|
|
|
im = load(HEAD + chunk(b'zTXt', b'spam') + TAIL)
|
|
|
|
assert_equal(im.info, {'spam': ''})
|
|
|
|
|
|
|
|
im = load(HEAD + chunk(b'zTXt', b'spam\0') + TAIL)
|
|
|
|
assert_equal(im.info, {'spam': ''})
|
|
|
|
|
|
|
|
im = load(HEAD + chunk(b'zTXt', b'spam\0\0') + TAIL)
|
|
|
|
assert_equal(im.info, {'spam': ''})
|
|
|
|
|
2013-08-20 18:09:22 +04:00
|
|
|
im = load(HEAD + chunk(b'zTXt', b'spam\0\0' + zlib.compress(b'egg')[:1]) + TAIL)
|
2013-08-20 16:17:17 +04:00
|
|
|
assert_equal(im.info, {'spam': ''})
|
|
|
|
|
|
|
|
im = load(HEAD + chunk(b'zTXt', b'spam\0\0' + zlib.compress(b'egg')) + TAIL)
|
|
|
|
assert_equal(im.info, {'spam': 'egg'})
|
|
|
|
|
2012-10-16 00:26:38 +04:00
|
|
|
def test_interlace():
|
|
|
|
|
|
|
|
file = "Tests/images/pil123p.png"
|
|
|
|
im = Image.open(file)
|
|
|
|
|
|
|
|
assert_image(im, "P", (162, 150))
|
|
|
|
assert_true(im.info.get("interlace"))
|
|
|
|
|
|
|
|
assert_no_exception(lambda: im.load())
|
|
|
|
|
|
|
|
file = "Tests/images/pil123rgba.png"
|
|
|
|
im = Image.open(file)
|
|
|
|
|
|
|
|
assert_image(im, "RGBA", (162, 150))
|
|
|
|
assert_true(im.info.get("interlace"))
|
|
|
|
|
|
|
|
assert_no_exception(lambda: im.load())
|
|
|
|
|
2013-03-11 23:33:04 +04:00
|
|
|
def test_load_transparent_p():
|
|
|
|
file = "Tests/images/pil123p.png"
|
|
|
|
im = Image.open(file)
|
|
|
|
|
|
|
|
assert_image(im, "P", (162, 150))
|
|
|
|
im = im.convert("RGBA")
|
|
|
|
assert_image(im, "RGBA", (162, 150))
|
|
|
|
|
|
|
|
# image has 124 uniqe qlpha values
|
|
|
|
assert_equal(len(im.split()[3].getcolors()), 124)
|
|
|
|
|
2013-11-23 04:04:51 +04:00
|
|
|
def test_load_transparent_rgb():
|
|
|
|
file = "Tests/images/rgb_trns.png"
|
|
|
|
im = Image.open(file)
|
|
|
|
|
|
|
|
assert_image(im, "RGB", (64, 64))
|
|
|
|
im = im.convert("RGBA")
|
|
|
|
assert_image(im, "RGBA", (64, 64))
|
|
|
|
|
2013-11-27 00:22:09 +04:00
|
|
|
# image has 876 transparent pixels
|
|
|
|
assert_equal(im.split()[3].getcolors()[0][0], 876)
|
2013-11-23 04:04:51 +04:00
|
|
|
|
2013-03-26 14:24:07 +04:00
|
|
|
def test_save_p_transparent_palette():
|
|
|
|
in_file = "Tests/images/pil123p.png"
|
|
|
|
im = Image.open(in_file)
|
|
|
|
|
|
|
|
file = tempfile("temp.png")
|
|
|
|
assert_no_exception(lambda: im.save(file))
|
|
|
|
|
|
|
|
def test_save_p_single_transparency():
|
|
|
|
in_file = "Tests/images/p_trns_single.png"
|
|
|
|
im = Image.open(in_file)
|
|
|
|
|
|
|
|
file = tempfile("temp.png")
|
|
|
|
assert_no_exception(lambda: im.save(file))
|
|
|
|
|
|
|
|
def test_save_l_transparency():
|
|
|
|
in_file = "Tests/images/l_trns.png"
|
|
|
|
im = Image.open(in_file)
|
|
|
|
|
|
|
|
file = tempfile("temp.png")
|
|
|
|
assert_no_exception(lambda: im.save(file))
|
|
|
|
|
2014-06-03 14:02:44 +04:00
|
|
|
# There are 559 transparent pixels.
|
2013-11-27 01:04:10 +04:00
|
|
|
im = im.convert('RGBA')
|
|
|
|
assert_equal(im.split()[3].getcolors()[0][0], 559)
|
|
|
|
|
2013-03-26 14:24:07 +04:00
|
|
|
def test_save_rgb_single_transparency():
|
|
|
|
in_file = "Tests/images/caption_6_33_22.png"
|
|
|
|
im = Image.open(in_file)
|
|
|
|
|
|
|
|
file = tempfile("temp.png")
|
|
|
|
assert_no_exception(lambda: im.save(file))
|
|
|
|
|
2012-10-16 00:26:38 +04:00
|
|
|
def test_load_verify():
|
|
|
|
# Check open/load/verify exception (@PIL150)
|
|
|
|
|
|
|
|
im = Image.open("Images/lena.png")
|
|
|
|
assert_no_exception(lambda: im.verify())
|
|
|
|
|
|
|
|
im = Image.open("Images/lena.png")
|
|
|
|
im.load()
|
|
|
|
assert_exception(RuntimeError, lambda: im.verify())
|
|
|
|
|
|
|
|
def test_roundtrip_dpi():
|
|
|
|
# Check dpi roundtripping
|
|
|
|
|
|
|
|
im = Image.open(file)
|
|
|
|
|
|
|
|
im = roundtrip(im, dpi=(100, 100))
|
|
|
|
assert_equal(im.info["dpi"], (100, 100))
|
|
|
|
|
|
|
|
def test_roundtrip_text():
|
|
|
|
# Check text roundtripping
|
|
|
|
|
|
|
|
im = Image.open(file)
|
|
|
|
|
|
|
|
info = PngImagePlugin.PngInfo()
|
py3k: The big push
There are two main issues fixed with this commit:
* bytes vs. str: All file, image, and palette data are now handled as
bytes. A new _binary module consolidates the hacks needed to do this
across Python versions. tostring/fromstring methods have been renamed to
tobytes/frombytes, but the Python 2.6/2.7 versions alias them to the old
names for compatibility. Users should move to tobytes/frombytes.
One other potentially-breaking change is that text data in image files
(such as tags, comments) are now explicitly handled with a specific
character encoding in mind. This works well with the Unicode str in
Python 3, but may trip up old code expecting a straight byte-for-byte
translation to a Python string. This also required a change to Gohlke's
tags tests (in Tests/test_file_png.py) to expect Unicode strings from
the code.
* True div vs. floor div: Many division operations used the "/" operator
to do floor division, which is now the "//" operator in Python 3. These
were fixed.
As of this commit, on the first pass, I have one failing test (improper
handling of a slice object in a C module, test_imagepath.py) in Python 3,
and three that that I haven't tried running yet (test_imagegl,
test_imagegrab, and test_imageqt). I also haven't tested anything on
Windows. All but the three skipped tests run flawlessly against Pythons
2.6 and 2.7.
2012-10-21 01:01:53 +04:00
|
|
|
info.add_text("TXT", "VALUE")
|
|
|
|
info.add_text("ZIP", "VALUE", 1)
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
im = roundtrip(im, pnginfo=info)
|
py3k: The big push
There are two main issues fixed with this commit:
* bytes vs. str: All file, image, and palette data are now handled as
bytes. A new _binary module consolidates the hacks needed to do this
across Python versions. tostring/fromstring methods have been renamed to
tobytes/frombytes, but the Python 2.6/2.7 versions alias them to the old
names for compatibility. Users should move to tobytes/frombytes.
One other potentially-breaking change is that text data in image files
(such as tags, comments) are now explicitly handled with a specific
character encoding in mind. This works well with the Unicode str in
Python 3, but may trip up old code expecting a straight byte-for-byte
translation to a Python string. This also required a change to Gohlke's
tags tests (in Tests/test_file_png.py) to expect Unicode strings from
the code.
* True div vs. floor div: Many division operations used the "/" operator
to do floor division, which is now the "//" operator in Python 3. These
were fixed.
As of this commit, on the first pass, I have one failing test (improper
handling of a slice object in a C module, test_imagepath.py) in Python 3,
and three that that I haven't tried running yet (test_imagegl,
test_imagegrab, and test_imageqt). I also haven't tested anything on
Windows. All but the three skipped tests run flawlessly against Pythons
2.6 and 2.7.
2012-10-21 01:01:53 +04:00
|
|
|
assert_equal(im.info, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
|
|
|
|
assert_equal(im.text, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
def test_scary():
|
|
|
|
# Check reading of evil PNG file. For information, see:
|
|
|
|
# http://scary.beasts.org/security/CESA-2004-001.txt
|
2013-09-28 03:55:19 +04:00
|
|
|
# The first byte is removed from pngtest_bad.png
|
|
|
|
# to avoid classification as malware.
|
2012-10-16 00:26:38 +04:00
|
|
|
|
2013-09-28 03:55:19 +04:00
|
|
|
with open("Tests/images/pngtest_bad.png.bin", 'rb') as fd:
|
|
|
|
data = b'\x89' + fd.read()
|
2012-10-15 09:55:39 +04:00
|
|
|
|
2013-09-28 03:55:19 +04:00
|
|
|
pngfile = BytesIO(data)
|
|
|
|
assert_exception(IOError, lambda: Image.open(pngfile))
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
def test_trns_rgb():
|
|
|
|
# Check writing and reading of tRNS chunks for RGB images.
|
|
|
|
# Independent file sample provided by Sebastian Spaeth.
|
|
|
|
|
|
|
|
file = "Tests/images/caption_6_33_22.png"
|
|
|
|
im = Image.open(file)
|
|
|
|
assert_equal(im.info["transparency"], (248, 248, 248))
|
|
|
|
|
2013-11-27 02:59:03 +04:00
|
|
|
# check saving transparency by default
|
|
|
|
im = roundtrip(im)
|
|
|
|
assert_equal(im.info["transparency"], (248, 248, 248))
|
|
|
|
|
2012-10-16 00:26:38 +04:00
|
|
|
im = roundtrip(im, transparency=(0, 1, 2))
|
|
|
|
assert_equal(im.info["transparency"], (0, 1, 2))
|
2014-01-19 19:40:39 +04:00
|
|
|
|
2014-03-01 04:29:34 +04:00
|
|
|
def test_trns_p():
|
|
|
|
# Check writing a transparency of 0, issue #528
|
|
|
|
im = lena('P')
|
|
|
|
im.info['transparency']=0
|
2014-06-03 14:02:44 +04:00
|
|
|
|
2014-03-01 04:29:34 +04:00
|
|
|
f = tempfile("temp.png")
|
|
|
|
im.save(f)
|
|
|
|
|
|
|
|
im2 = Image.open(f)
|
|
|
|
assert_true('transparency' in im2.info)
|
|
|
|
|
|
|
|
assert_image_equal(im2.convert('RGBA'), im.convert('RGBA'))
|
2014-06-03 14:02:44 +04:00
|
|
|
|
|
|
|
|
2014-01-19 19:40:39 +04:00
|
|
|
def test_save_icc_profile_none():
|
2014-01-19 22:09:40 +04:00
|
|
|
# check saving files with an ICC profile set to None (omit profile)
|
2014-01-19 19:40:39 +04:00
|
|
|
in_file = "Tests/images/icc_profile_none.png"
|
|
|
|
im = Image.open(in_file)
|
2014-01-21 01:34:48 +04:00
|
|
|
assert_equal(im.info['icc_profile'], None)
|
2014-01-19 19:40:39 +04:00
|
|
|
|
2014-01-22 08:50:54 +04:00
|
|
|
im = roundtrip(im)
|
2014-01-21 01:34:48 +04:00
|
|
|
assert_false('icc_profile' in im.info)
|
2014-01-19 22:09:40 +04:00
|
|
|
|
2014-01-22 08:50:54 +04:00
|
|
|
def test_roundtrip_icc_profile():
|
|
|
|
# check that we can roundtrip the icc profile
|
|
|
|
im = lena('RGB')
|
2014-01-19 22:09:40 +04:00
|
|
|
|
2014-01-22 08:50:54 +04:00
|
|
|
jpeg_image = Image.open('Tests/images/flower2.jpg')
|
|
|
|
expected_icc = jpeg_image.info['icc_profile']
|
|
|
|
|
|
|
|
im.info['icc_profile'] = expected_icc
|
|
|
|
im = roundtrip(im)
|
|
|
|
assert_equal(im.info['icc_profile'], expected_icc)
|
2014-01-19 22:09:40 +04:00
|
|
|
|