Pillow/Tests/test_file_libtiff.py

391 lines
12 KiB
Python
Raw Normal View History

from __future__ import print_function
from helper import unittest, PillowTestCase, hopper, py3
2014-06-10 13:10:47 +04:00
2014-11-16 07:38:52 +03:00
import io
import logging
import os
2013-11-22 08:33:43 +04:00
from PIL import Image, TiffImagePlugin
logger = logging.getLogger(__name__)
class LibTiffTestCase(PillowTestCase):
2014-06-10 13:10:47 +04:00
def setUp(self):
codecs = dir(Image.core)
2014-06-10 13:10:47 +04:00
if "libtiff_encoder" not in codecs or "libtiff_decoder" not in codecs:
self.skipTest("tiff support not available")
2014-06-10 13:10:47 +04:00
def _assert_noerr(self, im):
"""Helper tests that assert basic sanity about the g4 tiff reading"""
# 1 bit
self.assertEqual(im.mode, "1")
2014-06-10 13:10:47 +04:00
# Does the data actually load
im.load()
im.getdata()
2014-06-10 13:10:47 +04:00
try:
self.assertEqual(im._compression, 'group4')
except:
print("No _compression")
2015-04-24 02:26:52 +03:00
print(dir(im))
2014-06-10 13:10:47 +04:00
# can we write it back out, in a different form.
out = self.tempfile("temp.png")
im.save(out)
class TestFileLibTiff(LibTiffTestCase):
2014-06-10 13:10:47 +04:00
def test_g4_tiff(self):
"""Test the ordinary file path load path"""
2015-04-02 11:45:24 +03:00
test_file = "Tests/images/hopper_g4_500.tif"
im = Image.open(test_file)
2014-06-10 13:10:47 +04:00
self.assertEqual(im.size, (500, 500))
self._assert_noerr(im)
2014-06-10 13:10:47 +04:00
def test_g4_large(self):
2015-04-24 11:24:52 +03:00
test_file = "Tests/images/pport_g4.tif"
im = Image.open(test_file)
2014-06-10 13:10:47 +04:00
self._assert_noerr(im)
2014-06-10 13:10:47 +04:00
def test_g4_tiff_file(self):
"""Testing the string load path"""
2015-04-02 11:45:24 +03:00
test_file = "Tests/images/hopper_g4_500.tif"
with open(test_file, 'rb') as f:
2014-06-10 13:10:47 +04:00
im = Image.open(f)
self.assertEqual(im.size, (500, 500))
self._assert_noerr(im)
def test_g4_tiff_bytesio(self):
"""Testing the stringio loading code path"""
2015-04-02 11:45:24 +03:00
test_file = "Tests/images/hopper_g4_500.tif"
2014-11-16 07:38:52 +03:00
s = io.BytesIO()
2015-04-02 11:45:24 +03:00
with open(test_file, 'rb') as f:
2014-06-10 13:10:47 +04:00
s.write(f.read())
s.seek(0)
im = Image.open(s)
self.assertEqual(im.size, (500, 500))
self._assert_noerr(im)
def test_g4_eq_png(self):
""" Checking that we're actually getting the data that we expect"""
2014-09-23 17:16:04 +04:00
png = Image.open('Tests/images/hopper_bw_500.png')
g4 = Image.open('Tests/images/hopper_g4_500.tif')
2014-06-10 13:10:47 +04:00
self.assert_image_equal(g4, png)
# see https://github.com/python-pillow/Pillow/issues/279
def test_g4_fillorder_eq_png(self):
""" Checking that we're actually getting the data that we expect"""
png = Image.open('Tests/images/g4-fillorder-test.png')
g4 = Image.open('Tests/images/g4-fillorder-test.tif')
self.assert_image_equal(g4, png)
def test_g4_write(self):
"""Checking to see that the saved image is the same as what we wrote"""
2015-04-02 11:45:24 +03:00
test_file = "Tests/images/hopper_g4_500.tif"
orig = Image.open(test_file)
2014-06-10 13:10:47 +04:00
out = self.tempfile("temp.tif")
rot = orig.transpose(Image.ROTATE_90)
self.assertEqual(rot.size, (500, 500))
rot.save(out)
reread = Image.open(out)
self.assertEqual(reread.size, (500, 500))
self._assert_noerr(reread)
self.assert_image_equal(reread, rot)
self.assertEqual(reread.info['compression'], 'group4')
self.assertEqual(reread.info['compression'], orig.info['compression'])
self.assertNotEqual(orig.tobytes(), reread.tobytes())
def test_adobe_deflate_tiff(self):
2015-04-02 11:45:24 +03:00
test_file = "Tests/images/tiff_adobe_deflate.tif"
im = Image.open(test_file)
2014-06-10 13:10:47 +04:00
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (278, 374))
self.assertEqual(
im.tile[0][:3], ('tiff_adobe_deflate', (0, 0, 278, 374), 0))
im.load()
def test_write_metadata(self):
""" Test metadata writing through libtiff """
2014-09-23 11:57:55 +04:00
img = Image.open('Tests/images/hopper_g4.tif')
2014-06-10 13:10:47 +04:00
f = self.tempfile('temp.tiff')
img.save(f, tiffinfo=img.tag)
loaded = Image.open(f)
original = img.tag.named()
reloaded = loaded.tag.named()
# PhotometricInterpretation is set from SAVE_INFO,
# not the original image.
ignored = [
'StripByteCounts', 'RowsPerStrip',
'PageNumber', 'PhotometricInterpretation']
for tag, value in reloaded.items():
if tag not in ignored:
if tag.endswith('Resolution'):
val = original[tag]
self.assert_almost_equal(
val[0][0]/val[0][1], value[0][0]/value[0][1],
msg="%s didn't roundtrip" % tag)
else:
self.assertEqual(
original[tag], value, "%s didn't roundtrip" % tag)
for tag, value in original.items():
if tag not in ignored:
if tag.endswith('Resolution'):
val = reloaded[tag]
self.assert_almost_equal(
val[0][0]/val[0][1], value[0][0]/value[0][1],
msg="%s didn't roundtrip" % tag)
else:
self.assertEqual(
value, reloaded[tag], "%s didn't roundtrip" % tag)
def test_g3_compression(self):
2014-09-23 17:16:04 +04:00
i = Image.open('Tests/images/hopper_g4_500.tif')
2014-06-10 13:10:47 +04:00
out = self.tempfile("temp.tif")
i.save(out, compression='group3')
reread = Image.open(out)
self.assertEqual(reread.info['compression'], 'group3')
self.assert_image_equal(reread, i)
def test_little_endian(self):
im = Image.open('Tests/images/16bit.deflate.tif')
self.assertEqual(im.getpixel((0, 0)), 480)
self.assertEqual(im.mode, 'I;16')
b = im.tobytes()
# Bytes are in image native order (little endian)
if py3:
self.assertEqual(b[0], ord(b'\xe0'))
self.assertEqual(b[1], ord(b'\x01'))
else:
self.assertEqual(b[0], b'\xe0')
self.assertEqual(b[1], b'\x01')
out = self.tempfile("temp.tif")
# out = "temp.le.tif"
im.save(out)
reread = Image.open(out)
self.assertEqual(reread.info['compression'], im.info['compression'])
self.assertEqual(reread.getpixel((0, 0)), 480)
# UNDONE - libtiff defaults to writing in native endian, so
# on big endian, we'll get back mode = 'I;16B' here.
def test_big_endian(self):
im = Image.open('Tests/images/16bit.MM.deflate.tif')
self.assertEqual(im.getpixel((0, 0)), 480)
self.assertEqual(im.mode, 'I;16B')
b = im.tobytes()
# Bytes are in image native order (big endian)
if py3:
self.assertEqual(b[0], ord(b'\x01'))
self.assertEqual(b[1], ord(b'\xe0'))
else:
self.assertEqual(b[0], b'\x01')
self.assertEqual(b[1], b'\xe0')
out = self.tempfile("temp.tif")
im.save(out)
reread = Image.open(out)
self.assertEqual(reread.info['compression'], im.info['compression'])
self.assertEqual(reread.getpixel((0, 0)), 480)
def test_g4_string_info(self):
"""Tests String data in info directory"""
2015-04-02 11:45:24 +03:00
test_file = "Tests/images/hopper_g4_500.tif"
orig = Image.open(test_file)
2014-06-10 13:10:47 +04:00
out = self.tempfile("temp.tif")
orig.tag[269] = 'temp.tif'
orig.save(out)
reread = Image.open(out)
self.assertEqual('temp.tif', reread.tag[269])
def test_12bit_rawmode(self):
""" Are we generating the same interpretation
of the image as Imagemagick is? """
TiffImagePlugin.READ_LIBTIFF = True
im = Image.open('Tests/images/12bit.cropped.tif')
im.load()
TiffImagePlugin.READ_LIBTIFF = False
# to make the target --
# convert 12bit.cropped.tif -depth 16 tmp.tif
# convert tmp.tif -evaluate RightShift 4 12in16bit2.tif
# imagemagick will auto scale so that a 12bit FFF is 16bit FFF0,
# so we need to unshift so that the integer values are the same.
im2 = Image.open('Tests/images/12in16bit.tif')
logger.debug("%s", [img.getpixel((0, idx))
for img in [im, im2] for idx in range(3)])
2014-06-10 13:10:47 +04:00
self.assert_image_equal(im, im2)
def test_blur(self):
# test case from irc, how to do blur on b/w image
# and save to compressed tif.
from PIL import ImageFilter
out = self.tempfile('temp.tif')
im = Image.open('Tests/images/pport_g4.tif')
im = im.convert('L')
im = im.filter(ImageFilter.GaussianBlur(4))
im.save(out, compression='tiff_adobe_deflate')
2014-06-10 13:10:47 +04:00
im2 = Image.open(out)
im2.load()
2013-10-22 21:09:25 +04:00
2014-06-10 13:10:47 +04:00
self.assert_image_equal(im, im2)
2014-06-10 13:10:47 +04:00
def test_compressions(self):
im = hopper('RGB')
2014-06-10 13:10:47 +04:00
out = self.tempfile('temp.tif')
2014-06-10 13:10:47 +04:00
for compression in ('packbits', 'tiff_lzw'):
im.save(out, compression=compression)
im2 = Image.open(out)
self.assert_image_equal(im, im2)
2013-11-06 08:53:18 +04:00
2014-06-10 13:10:47 +04:00
im.save(out, compression='jpeg')
im2 = Image.open(out)
2014-06-10 13:10:47 +04:00
self.assert_image_similar(im, im2, 30)
2014-06-10 13:10:47 +04:00
def test_cmyk_save(self):
im = hopper('CMYK')
2014-06-10 13:10:47 +04:00
out = self.tempfile('temp.tif')
im.save(out, compression='tiff_adobe_deflate')
im2 = Image.open(out)
self.assert_image_equal(im, im2)
def xtest_bw_compression_w_rgb(self):
2014-06-10 13:10:47 +04:00
""" This test passes, but when running all tests causes a failure due
to output on stderr from the error thrown by libtiff. We need to
capture that but not now"""
im = hopper('RGB')
2014-06-10 13:10:47 +04:00
out = self.tempfile('temp.tif')
2014-06-10 13:10:47 +04:00
self.assertRaises(
IOError, lambda: im.save(out, compression='tiff_ccitt'))
self.assertRaises(IOError, lambda: im.save(out, compression='group3'))
self.assertRaises(IOError, lambda: im.save(out, compression='group4'))
2014-06-10 13:10:47 +04:00
def test_fp_leak(self):
2014-09-23 17:16:04 +04:00
im = Image.open("Tests/images/hopper_g4_500.tif")
2014-06-10 13:10:47 +04:00
fn = im.fp.fileno()
2014-06-10 13:10:47 +04:00
os.fstat(fn)
im.load() # this should close it.
self.assertRaises(OSError, lambda: os.fstat(fn))
im = None # this should force even more closed.
self.assertRaises(OSError, lambda: os.fstat(fn))
self.assertRaises(OSError, lambda: os.close(fn))
2014-08-21 08:43:46 +04:00
def test_multipage(self):
# issue #862
TiffImagePlugin.READ_LIBTIFF = True
im = Image.open('Tests/images/multipage.tiff')
# file is a multipage tiff, 10x10 green, 10x10 red, 20x20 blue
im.seek(0)
self.assertEqual(im.size, (10, 10))
self.assertEqual(im.convert('RGB').getpixel((0, 0)), (0, 128, 0))
2014-08-21 08:43:46 +04:00
self.assertTrue(im.tag.next)
im.seek(1)
self.assertEqual(im.size, (10, 10))
self.assertEqual(im.convert('RGB').getpixel((0, 0)), (255, 0, 0))
2014-08-21 08:43:46 +04:00
self.assertTrue(im.tag.next)
im.seek(2)
self.assertFalse(im.tag.next)
self.assertEqual(im.size, (20, 20))
self.assertEqual(im.convert('RGB').getpixel((0, 0)), (0, 0, 255))
2014-08-21 08:43:46 +04:00
TiffImagePlugin.READ_LIBTIFF = False
def test__next(self):
TiffImagePlugin.READ_LIBTIFF = True
im = Image.open('Tests/images/hopper.tif')
2014-08-21 08:43:46 +04:00
self.assertFalse(im.tag.next)
im.load()
self.assertFalse(im.tag.next)
2014-10-29 21:07:20 +03:00
def test_4bit(self):
# Arrange
test_file = "Tests/images/hopper_gray_4bpp.tif"
original = hopper("L")
# Act
TiffImagePlugin.READ_LIBTIFF = True
im = Image.open(test_file)
TiffImagePlugin.READ_LIBTIFF = False
# Assert
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.mode, "L")
self.assert_image_similar(im, original, 7.3)
2014-11-16 07:38:52 +03:00
def test_save_bytesio(self):
# PR 1011
# Test TIFF saving to io.BytesIO() object.
2014-11-16 07:38:52 +03:00
TiffImagePlugin.WRITE_LIBTIFF = True
TiffImagePlugin.READ_LIBTIFF = True
# Generate test image
pilim = hopper()
def save_bytesio(compression=None):
2014-11-16 07:38:52 +03:00
buffer_io = io.BytesIO()
pilim.save(buffer_io, format="tiff", compression=compression)
buffer_io.seek(0)
pilim_load = Image.open(buffer_io)
self.assert_image_similar(pilim, pilim_load, 0)
2014-11-16 07:38:52 +03:00
# save_bytesio()
save_bytesio('raw')
save_bytesio("packbits")
save_bytesio("tiff_lzw")
2014-11-16 07:38:52 +03:00
TiffImagePlugin.WRITE_LIBTIFF = False
TiffImagePlugin.READ_LIBTIFF = False
2014-10-29 21:07:20 +03:00
2014-06-10 13:10:47 +04:00
if __name__ == '__main__':
unittest.main()
2014-03-28 09:17:27 +04:00
2014-06-10 13:10:47 +04:00
# End of file