Format with Black

This commit is contained in:
Hugo 2019-06-13 18:54:46 +03:00
parent 77f946d8bc
commit 5631718a8d
41 changed files with 1586 additions and 1394 deletions

View File

@ -15,7 +15,6 @@ GREY = 128
class TestImageChops(PillowTestCase): class TestImageChops(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im = hopper("L") im = hopper("L")
@ -264,11 +263,12 @@ class TestImageChops(PillowTestCase):
# Assert # Assert
self.assertEqual(new.getbbox(), (0, 45, 100, 96)) self.assertEqual(new.getbbox(), (0, 45, 100, 96))
self.assertEqual(new.getpixel((50, 50)), BLACK) self.assertEqual(new.getpixel((50, 50)), BLACK)
self.assertEqual(new.getpixel((50+xoffset, 50+yoffset)), DARK_GREEN) self.assertEqual(new.getpixel((50 + xoffset, 50 + yoffset)), DARK_GREEN)
# Test no yoffset # Test no yoffset
self.assertEqual(ImageChops.offset(im, xoffset), self.assertEqual(
ImageChops.offset(im, xoffset, xoffset)) ImageChops.offset(im, xoffset), ImageChops.offset(im, xoffset, xoffset)
)
def test_screen(self): def test_screen(self):
# Arrange # Arrange
@ -343,7 +343,6 @@ class TestImageChops(PillowTestCase):
self.assertEqual(new.getpixel((50, 50)), (241, 167, 127)) self.assertEqual(new.getpixel((50, 50)), (241, 167, 127))
def test_logical(self): def test_logical(self):
def table(op, a, b): def table(op, a, b):
out = [] out = []
for x in (a, b): for x in (a, b):
@ -353,23 +352,14 @@ class TestImageChops(PillowTestCase):
out.append(op(imx, imy).getpixel((0, 0))) out.append(op(imx, imy).getpixel((0, 0)))
return tuple(out) return tuple(out)
self.assertEqual( self.assertEqual(table(ImageChops.logical_and, 0, 1), (0, 0, 0, 255))
table(ImageChops.logical_and, 0, 1), (0, 0, 0, 255)) self.assertEqual(table(ImageChops.logical_or, 0, 1), (0, 255, 255, 255))
self.assertEqual( self.assertEqual(table(ImageChops.logical_xor, 0, 1), (0, 255, 255, 0))
table(ImageChops.logical_or, 0, 1), (0, 255, 255, 255))
self.assertEqual(
table(ImageChops.logical_xor, 0, 1), (0, 255, 255, 0))
self.assertEqual( self.assertEqual(table(ImageChops.logical_and, 0, 128), (0, 0, 0, 255))
table(ImageChops.logical_and, 0, 128), (0, 0, 0, 255)) self.assertEqual(table(ImageChops.logical_or, 0, 128), (0, 255, 255, 255))
self.assertEqual( self.assertEqual(table(ImageChops.logical_xor, 0, 128), (0, 255, 255, 0))
table(ImageChops.logical_or, 0, 128), (0, 255, 255, 255))
self.assertEqual(
table(ImageChops.logical_xor, 0, 128), (0, 255, 255, 0))
self.assertEqual( self.assertEqual(table(ImageChops.logical_and, 0, 255), (0, 0, 0, 255))
table(ImageChops.logical_and, 0, 255), (0, 0, 0, 255)) self.assertEqual(table(ImageChops.logical_or, 0, 255), (0, 255, 255, 255))
self.assertEqual( self.assertEqual(table(ImageChops.logical_xor, 0, 255), (0, 255, 255, 0))
table(ImageChops.logical_or, 0, 255), (0, 255, 255, 255))
self.assertEqual(
table(ImageChops.logical_xor, 0, 255), (0, 255, 255, 0))

View File

@ -9,6 +9,7 @@ import os
try: try:
from PIL import ImageCms from PIL import ImageCms
from PIL.ImageCms import ImageCmsProfile from PIL.ImageCms import ImageCmsProfile
ImageCms.core.profile_open ImageCms.core.profile_open
except ImportError: except ImportError:
# Skipped via setUp() # Skipped via setUp()
@ -20,10 +21,10 @@ HAVE_PROFILE = os.path.exists(SRGB)
class TestImageCms(PillowTestCase): class TestImageCms(PillowTestCase):
def setUp(self): def setUp(self):
try: try:
from PIL import ImageCms from PIL import ImageCms
# need to hit getattr to trigger the delayed import error # need to hit getattr to trigger the delayed import error
ImageCms.core.profile_open ImageCms.core.profile_open
except ImportError as v: except ImportError as v:
@ -39,7 +40,7 @@ class TestImageCms(PillowTestCase):
# this mostly follows the cms_test outline. # this mostly follows the cms_test outline.
v = ImageCms.versions() # should return four strings v = ImageCms.versions() # should return four strings
self.assertEqual(v[0], '1.0.0 pil') self.assertEqual(v[0], "1.0.0 pil")
self.assertEqual(list(map(type, v)), [str, str, str, str]) self.assertEqual(list(map(type, v)), [str, str, str, str])
# internal version number # internal version number
@ -82,45 +83,55 @@ class TestImageCms(PillowTestCase):
# get profile information for file # get profile information for file
self.assertEqual( self.assertEqual(
ImageCms.getProfileName(SRGB).strip(), ImageCms.getProfileName(SRGB).strip(),
'IEC 61966-2-1 Default RGB Colour Space - sRGB') "IEC 61966-2-1 Default RGB Colour Space - sRGB",
)
def test_info(self): def test_info(self):
self.skip_missing() self.skip_missing()
self.assertEqual( self.assertEqual(
ImageCms.getProfileInfo(SRGB).splitlines(), [ ImageCms.getProfileInfo(SRGB).splitlines(),
'sRGB IEC61966-2-1 black scaled', '', [
'Copyright International Color Consortium, 2009', '']) "sRGB IEC61966-2-1 black scaled",
"",
"Copyright International Color Consortium, 2009",
"",
],
)
def test_copyright(self): def test_copyright(self):
self.skip_missing() self.skip_missing()
self.assertEqual( self.assertEqual(
ImageCms.getProfileCopyright(SRGB).strip(), ImageCms.getProfileCopyright(SRGB).strip(),
'Copyright International Color Consortium, 2009') "Copyright International Color Consortium, 2009",
)
def test_manufacturer(self): def test_manufacturer(self):
self.skip_missing() self.skip_missing()
self.assertEqual( self.assertEqual(ImageCms.getProfileManufacturer(SRGB).strip(), "")
ImageCms.getProfileManufacturer(SRGB).strip(),
'')
def test_model(self): def test_model(self):
self.skip_missing() self.skip_missing()
self.assertEqual( self.assertEqual(
ImageCms.getProfileModel(SRGB).strip(), ImageCms.getProfileModel(SRGB).strip(),
'IEC 61966-2-1 Default RGB Colour Space - sRGB') "IEC 61966-2-1 Default RGB Colour Space - sRGB",
)
def test_description(self): def test_description(self):
self.skip_missing() self.skip_missing()
self.assertEqual( self.assertEqual(
ImageCms.getProfileDescription(SRGB).strip(), ImageCms.getProfileDescription(SRGB).strip(),
'sRGB IEC61966-2-1 black scaled') "sRGB IEC61966-2-1 black scaled",
)
def test_intent(self): def test_intent(self):
self.skip_missing() self.skip_missing()
self.assertEqual(ImageCms.getDefaultIntent(SRGB), 0) self.assertEqual(ImageCms.getDefaultIntent(SRGB), 0)
self.assertEqual(ImageCms.isIntentSupported( self.assertEqual(
SRGB, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.isIntentSupported(
ImageCms.DIRECTION_INPUT), 1) SRGB, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.DIRECTION_INPUT
),
1,
)
def test_profile_object(self): def test_profile_object(self):
# same, using profile object # same, using profile object
@ -130,9 +141,12 @@ class TestImageCms(PillowTestCase):
# self.assertEqual(ImageCms.getProfileInfo(p).splitlines(), # self.assertEqual(ImageCms.getProfileInfo(p).splitlines(),
# ['sRGB built-in', '', 'WhitePoint : D65 (daylight)', '', '']) # ['sRGB built-in', '', 'WhitePoint : D65 (daylight)', '', ''])
self.assertEqual(ImageCms.getDefaultIntent(p), 0) self.assertEqual(ImageCms.getDefaultIntent(p), 0)
self.assertEqual(ImageCms.isIntentSupported( self.assertEqual(
p, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.isIntentSupported(
ImageCms.DIRECTION_INPUT), 1) p, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.DIRECTION_INPUT
),
1,
)
def test_extensions(self): def test_extensions(self):
# extensions # extensions
@ -141,7 +155,8 @@ class TestImageCms(PillowTestCase):
p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"])) p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"]))
self.assertEqual( self.assertEqual(
ImageCms.getProfileName(p).strip(), ImageCms.getProfileName(p).strip(),
'IEC 61966-2.1 Default RGB colour space - sRGB') "IEC 61966-2.1 Default RGB colour space - sRGB",
)
def test_exceptions(self): def test_exceptions(self):
# Test mode mismatch # Test mode mismatch
@ -152,18 +167,16 @@ class TestImageCms(PillowTestCase):
# the procedural pyCMS API uses PyCMSError for all sorts of errors # the procedural pyCMS API uses PyCMSError for all sorts of errors
self.assertRaises( self.assertRaises(
ImageCms.PyCMSError, ImageCms.PyCMSError, ImageCms.profileToProfile, hopper(), "foo", "bar"
ImageCms.profileToProfile, hopper(), "foo", "bar") )
self.assertRaises( self.assertRaises(
ImageCms.PyCMSError, ImageCms.PyCMSError, ImageCms.buildTransform, "foo", "bar", "RGB", "RGB"
ImageCms.buildTransform, "foo", "bar", "RGB", "RGB") )
self.assertRaises( self.assertRaises(ImageCms.PyCMSError, ImageCms.getProfileName, None)
ImageCms.PyCMSError,
ImageCms.getProfileName, None)
self.skip_missing() self.skip_missing()
self.assertRaises( self.assertRaises(
ImageCms.PyCMSError, ImageCms.PyCMSError, ImageCms.isIntentSupported, SRGB, None, None
ImageCms.isIntentSupported, SRGB, None, None) )
def test_display_profile(self): def test_display_profile(self):
# try fetching the profile for the current display device # try fetching the profile for the current display device
@ -174,15 +187,13 @@ class TestImageCms(PillowTestCase):
ImageCms.createProfile("LAB", 6500) ImageCms.createProfile("LAB", 6500)
def test_unsupported_color_space(self): def test_unsupported_color_space(self):
self.assertRaises(ImageCms.PyCMSError, self.assertRaises(ImageCms.PyCMSError, ImageCms.createProfile, "unsupported")
ImageCms.createProfile, "unsupported")
def test_invalid_color_temperature(self): def test_invalid_color_temperature(self):
self.assertRaises(ImageCms.PyCMSError, self.assertRaises(ImageCms.PyCMSError, ImageCms.createProfile, "LAB", "invalid")
ImageCms.createProfile, "LAB", "invalid")
def test_simple_lab(self): def test_simple_lab(self):
i = Image.new('RGB', (10, 10), (128, 128, 128)) i = Image.new("RGB", (10, 10), (128, 128, 128))
psRGB = ImageCms.createProfile("sRGB") psRGB = ImageCms.createProfile("sRGB")
pLab = ImageCms.createProfile("LAB") pLab = ImageCms.createProfile("LAB")
@ -190,7 +201,7 @@ class TestImageCms(PillowTestCase):
i_lab = ImageCms.applyTransform(i, t) i_lab = ImageCms.applyTransform(i, t)
self.assertEqual(i_lab.mode, 'LAB') self.assertEqual(i_lab.mode, "LAB")
k = i_lab.getpixel((0, 0)) k = i_lab.getpixel((0, 0))
# not a linear luminance map. so L != 128: # not a linear luminance map. so L != 128:
@ -217,7 +228,7 @@ class TestImageCms(PillowTestCase):
# i.save('temp.lab.tif') # visually verified vs PS. # i.save('temp.lab.tif') # visually verified vs PS.
target = Image.open('Tests/images/hopper.Lab.tif') target = Image.open("Tests/images/hopper.Lab.tif")
self.assert_image_similar(i, target, 3.5) self.assert_image_similar(i, target, 3.5)
@ -226,17 +237,17 @@ class TestImageCms(PillowTestCase):
pLab = ImageCms.createProfile("LAB") pLab = ImageCms.createProfile("LAB")
t = ImageCms.buildTransform(pLab, psRGB, "LAB", "RGB") t = ImageCms.buildTransform(pLab, psRGB, "LAB", "RGB")
img = Image.open('Tests/images/hopper.Lab.tif') img = Image.open("Tests/images/hopper.Lab.tif")
img_srgb = ImageCms.applyTransform(img, t) img_srgb = ImageCms.applyTransform(img, t)
# img_srgb.save('temp.srgb.tif') # visually verified vs ps. # img_srgb.save('temp.srgb.tif') # visually verified vs ps.
self.assert_image_similar(hopper(), img_srgb, 30) self.assert_image_similar(hopper(), img_srgb, 30)
self.assertTrue(img_srgb.info['icc_profile']) self.assertTrue(img_srgb.info["icc_profile"])
profile = ImageCmsProfile(BytesIO(img_srgb.info['icc_profile'])) profile = ImageCmsProfile(BytesIO(img_srgb.info["icc_profile"]))
self.assertIn('sRGB', ImageCms.getProfileDescription(profile)) self.assertIn("sRGB", ImageCms.getProfileDescription(profile))
def test_lab_roundtrip(self): def test_lab_roundtrip(self):
# check to see if we're at least internally consistent. # check to see if we're at least internally consistent.
@ -248,8 +259,7 @@ class TestImageCms(PillowTestCase):
i = ImageCms.applyTransform(hopper(), t) i = ImageCms.applyTransform(hopper(), t)
self.assertEqual(i.info['icc_profile'], self.assertEqual(i.info["icc_profile"], ImageCmsProfile(pLab).tobytes())
ImageCmsProfile(pLab).tobytes())
out = ImageCms.applyTransform(i, t2) out = ImageCms.applyTransform(i, t2)
@ -264,10 +274,10 @@ class TestImageCms(PillowTestCase):
# not the same bytes as the original icc_profile, # not the same bytes as the original icc_profile,
# but it does roundtrip # but it does roundtrip
self.assertEqual(p.tobytes(), p2.tobytes()) self.assertEqual(p.tobytes(), p2.tobytes())
self.assertEqual(ImageCms.getProfileName(p), self.assertEqual(ImageCms.getProfileName(p), ImageCms.getProfileName(p2))
ImageCms.getProfileName(p2)) self.assertEqual(
self.assertEqual(ImageCms.getProfileDescription(p), ImageCms.getProfileDescription(p), ImageCms.getProfileDescription(p2)
ImageCms.getProfileDescription(p2)) )
def test_extended_information(self): def test_extended_information(self):
self.skip_missing() self.skip_missing()
@ -281,110 +291,150 @@ class TestImageCms(PillowTestCase):
def truncate_tuple(tuple_or_float): def truncate_tuple(tuple_or_float):
return tuple( return tuple(
truncate_tuple(val) if isinstance(val, tuple) truncate_tuple(val)
else int(val * power) / power for val in tuple_or_float) if isinstance(val, tuple)
else int(val * power) / power
for val in tuple_or_float
)
self.assertEqual(truncate_tuple(tup1), truncate_tuple(tup2)) self.assertEqual(truncate_tuple(tup1), truncate_tuple(tup2))
self.assertEqual(p.attributes, 4294967296) self.assertEqual(p.attributes, 4294967296)
assert_truncated_tuple_equal( assert_truncated_tuple_equal(
p.blue_colorant, p.blue_colorant,
((0.14306640625, 0.06060791015625, 0.7140960693359375), (
(0.1558847490315394, 0.06603820639433387, 0.06060791015625))) (0.14306640625, 0.06060791015625, 0.7140960693359375),
(0.1558847490315394, 0.06603820639433387, 0.06060791015625),
),
)
assert_truncated_tuple_equal( assert_truncated_tuple_equal(
p.blue_primary, p.blue_primary,
((0.14306641366715667, 0.06060790921083026, 0.7140960805782015), (
(0.15588475410450106, 0.06603820408959558, 0.06060790921083026))) (0.14306641366715667, 0.06060790921083026, 0.7140960805782015),
(0.15588475410450106, 0.06603820408959558, 0.06060790921083026),
),
)
assert_truncated_tuple_equal( assert_truncated_tuple_equal(
p.chromatic_adaptation, p.chromatic_adaptation,
(((1.04791259765625, 0.0229339599609375, -0.050201416015625), (
(
(1.04791259765625, 0.0229339599609375, -0.050201416015625),
(0.02960205078125, 0.9904632568359375, -0.0170745849609375), (0.02960205078125, 0.9904632568359375, -0.0170745849609375),
(-0.009246826171875, 0.0150604248046875, 0.7517852783203125)), (-0.009246826171875, 0.0150604248046875, 0.7517852783203125),
((1.0267159024652783, 0.022470062342089134, 0.0229339599609375), ),
(
(1.0267159024652783, 0.022470062342089134, 0.0229339599609375),
(0.02951378324103937, 0.9875098886387147, 0.9904632568359375), (0.02951378324103937, 0.9875098886387147, 0.9904632568359375),
(-0.012205438066465256, 0.01987915407854985, 0.0150604248046875)))) (-0.012205438066465256, 0.01987915407854985, 0.0150604248046875),
),
),
)
self.assertIsNone(p.chromaticity) self.assertIsNone(p.chromaticity)
self.assertEqual(p.clut, { self.assertEqual(
p.clut,
{
0: (False, False, True), 0: (False, False, True),
1: (False, False, True), 1: (False, False, True),
2: (False, False, True), 2: (False, False, True),
3: (False, False, True) 3: (False, False, True),
}) },
)
self.assertIsNone(p.colorant_table) self.assertIsNone(p.colorant_table)
self.assertIsNone(p.colorant_table_out) self.assertIsNone(p.colorant_table_out)
self.assertIsNone(p.colorimetric_intent) self.assertIsNone(p.colorimetric_intent)
self.assertEqual(p.connection_space, 'XYZ ') self.assertEqual(p.connection_space, "XYZ ")
self.assertEqual(p.copyright, self.assertEqual(p.copyright, "Copyright International Color Consortium, 2009")
'Copyright International Color Consortium, 2009') self.assertEqual(p.creation_date, datetime.datetime(2009, 2, 27, 21, 36, 31))
self.assertEqual(p.creation_date, self.assertEqual(p.device_class, "mntr")
datetime.datetime(2009, 2, 27, 21, 36, 31))
self.assertEqual(p.device_class, 'mntr')
assert_truncated_tuple_equal( assert_truncated_tuple_equal(
p.green_colorant, p.green_colorant,
((0.3851470947265625, 0.7168731689453125, 0.097076416015625), (
(0.32119769927720654, 0.5978443449048152, 0.7168731689453125))) (0.3851470947265625, 0.7168731689453125, 0.097076416015625),
(0.32119769927720654, 0.5978443449048152, 0.7168731689453125),
),
)
assert_truncated_tuple_equal( assert_truncated_tuple_equal(
p.green_primary, p.green_primary,
((0.3851470888162112, 0.7168731974161346, 0.09707641738998518), (
(0.32119768793686687, 0.5978443567149709, 0.7168731974161346))) (0.3851470888162112, 0.7168731974161346, 0.09707641738998518),
(0.32119768793686687, 0.5978443567149709, 0.7168731974161346),
),
)
self.assertEqual(p.header_flags, 0) self.assertEqual(p.header_flags, 0)
self.assertEqual(p.header_manufacturer, '\x00\x00\x00\x00') self.assertEqual(p.header_manufacturer, "\x00\x00\x00\x00")
self.assertEqual(p.header_model, '\x00\x00\x00\x00') self.assertEqual(p.header_model, "\x00\x00\x00\x00")
self.assertEqual(p.icc_measurement_condition, { self.assertEqual(
'backing': (0.0, 0.0, 0.0), p.icc_measurement_condition,
'flare': 0.0, {
'geo': 'unknown', "backing": (0.0, 0.0, 0.0),
'observer': 1, "flare": 0.0,
'illuminant_type': 'D65' "geo": "unknown",
}) "observer": 1,
"illuminant_type": "D65",
},
)
self.assertEqual(p.icc_version, 33554432) self.assertEqual(p.icc_version, 33554432)
self.assertIsNone(p.icc_viewing_condition) self.assertIsNone(p.icc_viewing_condition)
self.assertEqual(p.intent_supported, { self.assertEqual(
p.intent_supported,
{
0: (True, True, True), 0: (True, True, True),
1: (True, True, True), 1: (True, True, True),
2: (True, True, True), 2: (True, True, True),
3: (True, True, True) 3: (True, True, True),
}) },
)
self.assertTrue(p.is_matrix_shaper) self.assertTrue(p.is_matrix_shaper)
self.assertEqual(p.luminance, ((0.0, 80.0, 0.0), (0.0, 1.0, 80.0))) self.assertEqual(p.luminance, ((0.0, 80.0, 0.0), (0.0, 1.0, 80.0)))
self.assertIsNone(p.manufacturer) self.assertIsNone(p.manufacturer)
assert_truncated_tuple_equal( assert_truncated_tuple_equal(
p.media_black_point, p.media_black_point,
((0.012054443359375, 0.0124969482421875, 0.01031494140625), (
(0.34573304157549234, 0.35842450765864337, 0.0124969482421875))) (0.012054443359375, 0.0124969482421875, 0.01031494140625),
(0.34573304157549234, 0.35842450765864337, 0.0124969482421875),
),
)
assert_truncated_tuple_equal( assert_truncated_tuple_equal(
p.media_white_point, p.media_white_point,
((0.964202880859375, 1.0, 0.8249053955078125), (
(0.3457029219802284, 0.3585375327567059, 1.0))) (0.964202880859375, 1.0, 0.8249053955078125),
(0.3457029219802284, 0.3585375327567059, 1.0),
),
)
assert_truncated_tuple_equal( assert_truncated_tuple_equal(
(p.media_white_point_temperature,), (p.media_white_point_temperature,), (5000.722328847392,)
(5000.722328847392,)) )
self.assertEqual(p.model, self.assertEqual(p.model, "IEC 61966-2-1 Default RGB Colour Space - sRGB")
'IEC 61966-2-1 Default RGB Colour Space - sRGB')
self.assertIsNone(p.perceptual_rendering_intent_gamut) self.assertIsNone(p.perceptual_rendering_intent_gamut)
self.assertEqual( self.assertEqual(p.profile_description, "sRGB IEC61966-2-1 black scaled")
p.profile_description, 'sRGB IEC61966-2-1 black scaled') self.assertEqual(p.profile_id, b")\xf8=\xde\xaf\xf2U\xaexB\xfa\xe4\xca\x839\r")
self.assertEqual(
p.profile_id, b')\xf8=\xde\xaf\xf2U\xaexB\xfa\xe4\xca\x839\r')
assert_truncated_tuple_equal( assert_truncated_tuple_equal(
p.red_colorant, p.red_colorant,
((0.436065673828125, 0.2224884033203125, 0.013916015625), (
(0.6484536316398539, 0.3308524880306778, 0.2224884033203125))) (0.436065673828125, 0.2224884033203125, 0.013916015625),
(0.6484536316398539, 0.3308524880306778, 0.2224884033203125),
),
)
assert_truncated_tuple_equal( assert_truncated_tuple_equal(
p.red_primary, p.red_primary,
((0.43606566581047446, 0.22248840582960838, 0.013916015621759925), (
(0.6484536250319214, 0.3308524944738204, 0.22248840582960838))) (0.43606566581047446, 0.22248840582960838, 0.013916015621759925),
(0.6484536250319214, 0.3308524944738204, 0.22248840582960838),
),
)
self.assertEqual(p.rendering_intent, 0) self.assertEqual(p.rendering_intent, 0)
self.assertIsNone(p.saturation_rendering_intent_gamut) self.assertIsNone(p.saturation_rendering_intent_gamut)
self.assertIsNone(p.screening_description) self.assertIsNone(p.screening_description)
self.assertIsNone(p.target) self.assertIsNone(p.target)
self.assertEqual(p.technology, 'CRT ') self.assertEqual(p.technology, "CRT ")
self.assertEqual(p.version, 2.0) self.assertEqual(p.version, 2.0)
self.assertEqual(p.viewing_condition, self.assertEqual(
'Reference Viewing Condition in IEC 61966-2-1') p.viewing_condition, "Reference Viewing Condition in IEC 61966-2-1"
self.assertEqual(p.xcolor_space, 'RGB ') )
self.assertEqual(p.xcolor_space, "RGB ")
def test_deprecations(self): def test_deprecations(self):
self.skip_missing() self.skip_missing()
@ -431,34 +481,36 @@ class TestImageCms(PillowTestCase):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
ImageCms.ImageCmsProfile(1).tobytes() ImageCms.ImageCmsProfile(1).tobytes()
def assert_aux_channel_preserved(self, mode, def assert_aux_channel_preserved(self, mode, transform_in_place, preserved_channel):
transform_in_place, preserved_channel):
def create_test_image(): def create_test_image():
# set up test image with something interesting in the tested aux # set up test image with something interesting in the tested aux channel.
# channel. # fmt: off
nine_grid_deltas = [ # noqa: E128 nine_grid_deltas = [ # noqa: E131
(-1, -1), (-1, 0), (-1, 1), (-1, -1), (-1, 0), (-1, 1),
(0, -1), (0, 0), (0, 1), (0, -1), (0, 0), (0, 1),
(1, -1), (1, 0), (1, 1), (1, -1), (1, 0), (1, 1),
] ]
# fmt: on
chans = [] chans = []
bands = ImageMode.getmode(mode).bands bands = ImageMode.getmode(mode).bands
for band_ndx in range(len(bands)): for band_ndx in range(len(bands)):
channel_type = 'L' # 8-bit unorm channel_type = "L" # 8-bit unorm
channel_pattern = hopper(channel_type) channel_pattern = hopper(channel_type)
# paste pattern with varying offsets to avoid correlation # paste pattern with varying offsets to avoid correlation
# potentially hiding some bugs (like channels getting mixed). # potentially hiding some bugs (like channels getting mixed).
paste_offset = ( paste_offset = (
int(band_ndx / float(len(bands)) * channel_pattern.size[0]), int(band_ndx / float(len(bands)) * channel_pattern.size[0]),
int(band_ndx / float(len(bands) * 2) * channel_pattern.size[1]) int(band_ndx / float(len(bands) * 2) * channel_pattern.size[1]),
) )
channel_data = Image.new(channel_type, channel_pattern.size) channel_data = Image.new(channel_type, channel_pattern.size)
for delta in nine_grid_deltas: for delta in nine_grid_deltas:
channel_data.paste( channel_data.paste(
channel_pattern, channel_pattern,
tuple(paste_offset[c] + delta[c] * channel_pattern.size[c] tuple(
for c in range(2)), paste_offset[c] + delta[c] * channel_pattern.size[c]
for c in range(2)
),
) )
chans.append(channel_data) chans.append(channel_data)
return Image.merge(mode, chans) return Image.merge(mode, chans)
@ -470,42 +522,46 @@ class TestImageCms(PillowTestCase):
source_profile = ImageCms.createProfile("sRGB") source_profile = ImageCms.createProfile("sRGB")
destination_profile = ImageCms.createProfile("sRGB") destination_profile = ImageCms.createProfile("sRGB")
t = ImageCms.buildTransform( t = ImageCms.buildTransform(
source_profile, destination_profile, inMode=mode, outMode=mode) source_profile, destination_profile, inMode=mode, outMode=mode
)
# apply transform # apply transform
if transform_in_place: if transform_in_place:
ImageCms.applyTransform(source_image, t, inPlace=True) ImageCms.applyTransform(source_image, t, inPlace=True)
result_image = source_image result_image = source_image
else: else:
result_image = ImageCms.applyTransform( result_image = ImageCms.applyTransform(source_image, t, inPlace=False)
source_image, t, inPlace=False)
result_image_aux = result_image.getchannel(preserved_channel) result_image_aux = result_image.getchannel(preserved_channel)
self.assert_image_equal(source_image_aux, result_image_aux) self.assert_image_equal(source_image_aux, result_image_aux)
def test_preserve_auxiliary_channels_rgba(self): def test_preserve_auxiliary_channels_rgba(self):
self.assert_aux_channel_preserved( self.assert_aux_channel_preserved(
mode='RGBA', transform_in_place=False, preserved_channel='A') mode="RGBA", transform_in_place=False, preserved_channel="A"
)
def test_preserve_auxiliary_channels_rgba_in_place(self): def test_preserve_auxiliary_channels_rgba_in_place(self):
self.assert_aux_channel_preserved( self.assert_aux_channel_preserved(
mode='RGBA', transform_in_place=True, preserved_channel='A') mode="RGBA", transform_in_place=True, preserved_channel="A"
)
def test_preserve_auxiliary_channels_rgbx(self): def test_preserve_auxiliary_channels_rgbx(self):
self.assert_aux_channel_preserved( self.assert_aux_channel_preserved(
mode='RGBX', transform_in_place=False, preserved_channel='X') mode="RGBX", transform_in_place=False, preserved_channel="X"
)
def test_preserve_auxiliary_channels_rgbx_in_place(self): def test_preserve_auxiliary_channels_rgbx_in_place(self):
self.assert_aux_channel_preserved( self.assert_aux_channel_preserved(
mode='RGBX', transform_in_place=True, preserved_channel='X') mode="RGBX", transform_in_place=True, preserved_channel="X"
)
def test_auxiliary_channels_isolated(self): def test_auxiliary_channels_isolated(self):
# test data in aux channels does not affect non-aux channels # test data in aux channels does not affect non-aux channels
aux_channel_formats = [ aux_channel_formats = [
# format, profile, color-only format, source test image # format, profile, color-only format, source test image
('RGBA', 'sRGB', 'RGB', hopper('RGBA')), ("RGBA", "sRGB", "RGB", hopper("RGBA")),
('RGBX', 'sRGB', 'RGB', hopper('RGBX')), ("RGBX", "sRGB", "RGB", hopper("RGBX")),
('LAB', 'LAB', 'LAB', Image.open('Tests/images/hopper.Lab.tif')), ("LAB", "LAB", "LAB", Image.open("Tests/images/hopper.Lab.tif")),
] ]
for src_format in aux_channel_formats: for src_format in aux_channel_formats:
for dst_format in aux_channel_formats: for dst_format in aux_channel_formats:
@ -519,25 +575,34 @@ class TestImageCms(PillowTestCase):
destination_profile = ImageCms.createProfile(dst_format[1]) destination_profile = ImageCms.createProfile(dst_format[1])
source_image = src_format[3] source_image = src_format[3]
test_transform = ImageCms.buildTransform( test_transform = ImageCms.buildTransform(
source_profile, destination_profile, source_profile,
inMode=src_format[0], outMode=dst_format[0]) destination_profile,
inMode=src_format[0],
outMode=dst_format[0],
)
# test conversion from aux-ful source # test conversion from aux-ful source
if transform_in_place: if transform_in_place:
test_image = source_image.copy() test_image = source_image.copy()
ImageCms.applyTransform( ImageCms.applyTransform(
test_image, test_transform, inPlace=True) test_image, test_transform, inPlace=True
)
else: else:
test_image = ImageCms.applyTransform( test_image = ImageCms.applyTransform(
source_image, test_transform, inPlace=False) source_image, test_transform, inPlace=False
)
# reference conversion from aux-less source # reference conversion from aux-less source
reference_transform = ImageCms.buildTransform( reference_transform = ImageCms.buildTransform(
source_profile, destination_profile, source_profile,
inMode=src_format[2], outMode=dst_format[2]) destination_profile,
inMode=src_format[2],
outMode=dst_format[2],
)
reference_image = ImageCms.applyTransform( reference_image = ImageCms.applyTransform(
source_image.convert(src_format[2]), source_image.convert(src_format[2]), reference_transform
reference_transform) )
self.assert_image_equal(test_image.convert(dst_format[2]), self.assert_image_equal(
reference_image) test_image.convert(dst_format[2]), reference_image
)

View File

@ -5,7 +5,6 @@ from PIL import ImageColor
class TestImageColor(PillowTestCase): class TestImageColor(PillowTestCase):
def test_hash(self): def test_hash(self):
# short 3 components # short 3 components
self.assertEqual((255, 0, 0), ImageColor.getrgb("#f00")) self.assertEqual((255, 0, 0), ImageColor.getrgb("#f00"))
@ -31,12 +30,9 @@ class TestImageColor(PillowTestCase):
# case insensitivity # case insensitivity
self.assertEqual(ImageColor.getrgb("#DEF"), ImageColor.getrgb("#def")) self.assertEqual(ImageColor.getrgb("#DEF"), ImageColor.getrgb("#def"))
self.assertEqual(ImageColor.getrgb("#CDEF"), self.assertEqual(ImageColor.getrgb("#CDEF"), ImageColor.getrgb("#cdef"))
ImageColor.getrgb("#cdef")) self.assertEqual(ImageColor.getrgb("#DEFDEF"), ImageColor.getrgb("#defdef"))
self.assertEqual(ImageColor.getrgb("#DEFDEF"), self.assertEqual(ImageColor.getrgb("#CDEFCDEF"), ImageColor.getrgb("#cdefcdef"))
ImageColor.getrgb("#defdef"))
self.assertEqual(ImageColor.getrgb("#CDEFCDEF"),
ImageColor.getrgb("#cdefcdef"))
# not a number # not a number
self.assertRaises(ValueError, ImageColor.getrgb, "#fo0") self.assertRaises(ValueError, ImageColor.getrgb, "#fo0")
@ -81,49 +77,48 @@ class TestImageColor(PillowTestCase):
self.assertEqual((255, 0, 0), ImageColor.getrgb("hsv(0,100%,100%)")) self.assertEqual((255, 0, 0), ImageColor.getrgb("hsv(0,100%,100%)"))
self.assertEqual((255, 0, 0), ImageColor.getrgb("hsv(360,100%,100%)")) self.assertEqual((255, 0, 0), ImageColor.getrgb("hsv(360,100%,100%)"))
self.assertEqual((0, 255, 255), self.assertEqual((0, 255, 255), ImageColor.getrgb("hsv(180,100%,100%)"))
ImageColor.getrgb("hsv(180,100%,100%)"))
# alternate format # alternate format
self.assertEqual(ImageColor.getrgb("hsb(0,100%,50%)"), self.assertEqual(
ImageColor.getrgb("hsv(0,100%,50%)")) ImageColor.getrgb("hsb(0,100%,50%)"), ImageColor.getrgb("hsv(0,100%,50%)")
)
# floats # floats
self.assertEqual((254, 3, 3), self.assertEqual((254, 3, 3), ImageColor.getrgb("hsl(0.1,99.2%,50.3%)"))
ImageColor.getrgb("hsl(0.1,99.2%,50.3%)")) self.assertEqual((255, 0, 0), ImageColor.getrgb("hsl(360.,100.0%,50%)"))
self.assertEqual((255, 0, 0),
ImageColor.getrgb("hsl(360.,100.0%,50%)"))
self.assertEqual((253, 2, 2), self.assertEqual((253, 2, 2), ImageColor.getrgb("hsv(0.1,99.2%,99.3%)"))
ImageColor.getrgb("hsv(0.1,99.2%,99.3%)")) self.assertEqual((255, 0, 0), ImageColor.getrgb("hsv(360.,100.0%,100%)"))
self.assertEqual((255, 0, 0),
ImageColor.getrgb("hsv(360.,100.0%,100%)"))
# case insensitivity # case insensitivity
self.assertEqual(ImageColor.getrgb("RGB(255,0,0)"), self.assertEqual(
ImageColor.getrgb("rgb(255,0,0)")) ImageColor.getrgb("RGB(255,0,0)"), ImageColor.getrgb("rgb(255,0,0)")
self.assertEqual(ImageColor.getrgb("RGB(100%,0%,0%)"), )
ImageColor.getrgb("rgb(100%,0%,0%)")) self.assertEqual(
self.assertEqual(ImageColor.getrgb("RGBA(255,0,0,0)"), ImageColor.getrgb("RGB(100%,0%,0%)"), ImageColor.getrgb("rgb(100%,0%,0%)")
ImageColor.getrgb("rgba(255,0,0,0)")) )
self.assertEqual(ImageColor.getrgb("HSL(0,100%,50%)"), self.assertEqual(
ImageColor.getrgb("hsl(0,100%,50%)")) ImageColor.getrgb("RGBA(255,0,0,0)"), ImageColor.getrgb("rgba(255,0,0,0)")
self.assertEqual(ImageColor.getrgb("HSV(0,100%,50%)"), )
ImageColor.getrgb("hsv(0,100%,50%)")) self.assertEqual(
self.assertEqual(ImageColor.getrgb("HSB(0,100%,50%)"), ImageColor.getrgb("HSL(0,100%,50%)"), ImageColor.getrgb("hsl(0,100%,50%)")
ImageColor.getrgb("hsb(0,100%,50%)")) )
self.assertEqual(
ImageColor.getrgb("HSV(0,100%,50%)"), ImageColor.getrgb("hsv(0,100%,50%)")
)
self.assertEqual(
ImageColor.getrgb("HSB(0,100%,50%)"), ImageColor.getrgb("hsb(0,100%,50%)")
)
# space agnosticism # space agnosticism
self.assertEqual((255, 0, 0), self.assertEqual((255, 0, 0), ImageColor.getrgb("rgb( 255 , 0 , 0 )"))
ImageColor.getrgb("rgb( 255 , 0 , 0 )")) self.assertEqual((255, 0, 0), ImageColor.getrgb("rgb( 100% , 0% , 0% )"))
self.assertEqual((255, 0, 0), self.assertEqual(
ImageColor.getrgb("rgb( 100% , 0% , 0% )")) (255, 0, 0, 0), ImageColor.getrgb("rgba( 255 , 0 , 0 , 0 )")
self.assertEqual((255, 0, 0, 0), )
ImageColor.getrgb("rgba( 255 , 0 , 0 , 0 )")) self.assertEqual((255, 0, 0), ImageColor.getrgb("hsl( 0 , 100% , 50% )"))
self.assertEqual((255, 0, 0), self.assertEqual((255, 0, 0), ImageColor.getrgb("hsv( 0 , 100% , 100% )"))
ImageColor.getrgb("hsl( 0 , 100% , 50% )"))
self.assertEqual((255, 0, 0),
ImageColor.getrgb("hsv( 0 , 100% , 100% )"))
# wrong number of components # wrong number of components
self.assertRaises(ValueError, ImageColor.getrgb, "rgb(255,0)") self.assertRaises(ValueError, ImageColor.getrgb, "rgb(255,0)")
@ -153,35 +148,32 @@ class TestImageColor(PillowTestCase):
def test_rounding_errors(self): def test_rounding_errors(self):
for color in ImageColor.colormap: for color in ImageColor.colormap:
expected = Image.new( expected = Image.new("RGB", (1, 1), color).convert("L").getpixel((0, 0))
"RGB", (1, 1), color).convert("L").getpixel((0, 0)) actual = ImageColor.getcolor(color, "L")
actual = ImageColor.getcolor(color, 'L')
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
self.assertEqual( self.assertEqual(
(0, 255, 115), ImageColor.getcolor("rgba(0, 255, 115, 33)", "RGB")) (0, 255, 115), ImageColor.getcolor("rgba(0, 255, 115, 33)", "RGB")
)
Image.new("RGB", (1, 1), "white") Image.new("RGB", (1, 1), "white")
self.assertEqual((0, 0, 0, 255), ImageColor.getcolor("black", "RGBA")) self.assertEqual((0, 0, 0, 255), ImageColor.getcolor("black", "RGBA"))
self.assertEqual((255, 255, 255, 255), ImageColor.getcolor("white", "RGBA"))
self.assertEqual( self.assertEqual(
(255, 255, 255, 255), ImageColor.getcolor("white", "RGBA")) (0, 255, 115, 33), ImageColor.getcolor("rgba(0, 255, 115, 33)", "RGBA")
self.assertEqual( )
(0, 255, 115, 33),
ImageColor.getcolor("rgba(0, 255, 115, 33)", "RGBA"))
Image.new("RGBA", (1, 1), "white") Image.new("RGBA", (1, 1), "white")
self.assertEqual(0, ImageColor.getcolor("black", "L")) self.assertEqual(0, ImageColor.getcolor("black", "L"))
self.assertEqual(255, ImageColor.getcolor("white", "L")) self.assertEqual(255, ImageColor.getcolor("white", "L"))
self.assertEqual(162, self.assertEqual(162, ImageColor.getcolor("rgba(0, 255, 115, 33)", "L"))
ImageColor.getcolor("rgba(0, 255, 115, 33)", "L"))
Image.new("L", (1, 1), "white") Image.new("L", (1, 1), "white")
self.assertEqual(0, ImageColor.getcolor("black", "1")) self.assertEqual(0, ImageColor.getcolor("black", "1"))
self.assertEqual(255, ImageColor.getcolor("white", "1")) self.assertEqual(255, ImageColor.getcolor("white", "1"))
# The following test is wrong, but is current behavior # The following test is wrong, but is current behavior
# The correct result should be 255 due to the mode 1 # The correct result should be 255 due to the mode 1
self.assertEqual( self.assertEqual(162, ImageColor.getcolor("rgba(0, 255, 115, 33)", "1"))
162, ImageColor.getcolor("rgba(0, 255, 115, 33)", "1"))
# Correct behavior # Correct behavior
# self.assertEqual( # self.assertEqual(
# 255, ImageColor.getcolor("rgba(0, 255, 115, 33)", "1")) # 255, ImageColor.getcolor("rgba(0, 255, 115, 33)", "1"))
@ -189,6 +181,5 @@ class TestImageColor(PillowTestCase):
self.assertEqual((0, 255), ImageColor.getcolor("black", "LA")) self.assertEqual((0, 255), ImageColor.getcolor("black", "LA"))
self.assertEqual((255, 255), ImageColor.getcolor("white", "LA")) self.assertEqual((255, 255), ImageColor.getcolor("white", "LA"))
self.assertEqual( self.assertEqual((162, 33), ImageColor.getcolor("rgba(0, 255, 115, 33)", "LA"))
(162, 33), ImageColor.getcolor("rgba(0, 255, 115, 33)", "LA"))
Image.new("LA", (1, 1), "white") Image.new("LA", (1, 1), "white")

View File

@ -6,8 +6,8 @@ from PIL import Image, ImageColor, ImageDraw
BLACK = (0, 0, 0) BLACK = (0, 0, 0)
WHITE = (255, 255, 255) WHITE = (255, 255, 255)
GRAY = (190, 190, 190) GRAY = (190, 190, 190)
DEFAULT_MODE = 'RGB' DEFAULT_MODE = "RGB"
IMAGES_PATH = os.path.join('Tests', 'images', 'imagedraw') IMAGES_PATH = os.path.join("Tests", "images", "imagedraw")
# Image size # Image size
W, H = 100, 100 W, H = 100, 100
@ -30,7 +30,6 @@ KITE_POINTS = [(10, 50), (70, 10), (90, 50), (70, 90), (10, 50)]
class TestImageDraw(PillowTestCase): class TestImageDraw(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im = hopper("RGB").copy() im = hopper("RGB").copy()
@ -62,8 +61,7 @@ class TestImageDraw(PillowTestCase):
draw.arc(bbox, start, end) draw.arc(bbox, start, end)
# Assert # Assert
self.assert_image_similar( self.assert_image_similar(im, Image.open("Tests/images/imagedraw_arc.png"), 1)
im, Image.open("Tests/images/imagedraw_arc.png"), 1)
def test_arc1(self): def test_arc1(self):
self.helper_arc(BBOX1, 0, 180) self.helper_arc(BBOX1, 0, 180)
@ -85,7 +83,8 @@ class TestImageDraw(PillowTestCase):
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(
im, Image.open("Tests/images/imagedraw_arc_end_le_start.png")) im, Image.open("Tests/images/imagedraw_arc_end_le_start.png")
)
def test_arc_no_loops(self): def test_arc_no_loops(self):
# No need to go in loops # No need to go in loops
@ -100,7 +99,8 @@ class TestImageDraw(PillowTestCase):
# Assert # Assert
self.assert_image_similar( self.assert_image_similar(
im, Image.open("Tests/images/imagedraw_arc_no_loops.png"), 1) im, Image.open("Tests/images/imagedraw_arc_no_loops.png"), 1
)
def test_arc_width(self): def test_arc_width(self):
# Arrange # Arrange
@ -149,8 +149,7 @@ class TestImageDraw(PillowTestCase):
draw.bitmap((10, 10), small) draw.bitmap((10, 10), small)
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_bitmap.png"))
im, Image.open("Tests/images/imagedraw_bitmap.png"))
def helper_chord(self, mode, bbox, start, end): def helper_chord(self, mode, bbox, start, end):
# Arrange # Arrange
@ -224,17 +223,15 @@ class TestImageDraw(PillowTestCase):
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
# Act # Act
draw.ellipse(((0, 0), (W-1, H)), fill="white") draw.ellipse(((0, 0), (W - 1, H)), fill="white")
# Assert # Assert
self.assert_image_similar( self.assert_image_similar(
im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1) im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1
)
def test_ellipse_symmetric(self): def test_ellipse_symmetric(self):
for bbox in [ for bbox in [(25, 25, 76, 76), (25, 25, 75, 75)]:
(25, 25, 76, 76),
(25, 25, 75, 75)
]:
im = Image.new("RGB", (101, 101)) im = Image.new("RGB", (101, 101))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.ellipse(bbox, fill="green", outline="blue") draw.ellipse(bbox, fill="green", outline="blue")
@ -285,8 +282,7 @@ class TestImageDraw(PillowTestCase):
draw.line(points, fill="yellow", width=2) draw.line(points, fill="yellow", width=2)
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png"))
im, Image.open("Tests/images/imagedraw_line.png"))
def test_line1(self): def test_line1(self):
self.helper_line(POINTS1) self.helper_line(POINTS1)
@ -312,8 +308,7 @@ class TestImageDraw(PillowTestCase):
draw.shape(s, fill=1) draw.shape(s, fill=1)
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_shape1.png"))
im, Image.open("Tests/images/imagedraw_shape1.png"))
def test_shape2(self): def test_shape2(self):
# Arrange # Arrange
@ -333,8 +328,7 @@ class TestImageDraw(PillowTestCase):
draw.shape(s, outline="blue") draw.shape(s, outline="blue")
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_shape2.png"))
im, Image.open("Tests/images/imagedraw_shape2.png"))
def helper_pieslice(self, bbox, start, end): def helper_pieslice(self, bbox, start, end):
# Arrange # Arrange
@ -346,7 +340,8 @@ class TestImageDraw(PillowTestCase):
# Assert # Assert
self.assert_image_similar( self.assert_image_similar(
im, Image.open("Tests/images/imagedraw_pieslice.png"), 1) im, Image.open("Tests/images/imagedraw_pieslice.png"), 1
)
def test_pieslice1(self): def test_pieslice1(self):
self.helper_pieslice(BBOX1, -90, 45) self.helper_pieslice(BBOX1, -90, 45)
@ -389,8 +384,7 @@ class TestImageDraw(PillowTestCase):
draw.point(points, fill="yellow") draw.point(points, fill="yellow")
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_point.png"))
im, Image.open("Tests/images/imagedraw_point.png"))
def test_point1(self): def test_point1(self):
self.helper_point(POINTS1) self.helper_point(POINTS1)
@ -407,8 +401,7 @@ class TestImageDraw(PillowTestCase):
draw.polygon(points, fill="red", outline="blue") draw.polygon(points, fill="red", outline="blue")
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_polygon.png"))
im, Image.open("Tests/images/imagedraw_polygon.png"))
def test_polygon1(self): def test_polygon1(self):
self.helper_polygon(POINTS1) self.helper_polygon(POINTS1)
@ -423,8 +416,7 @@ class TestImageDraw(PillowTestCase):
# Arrange # Arrange
im = Image.new(mode, (W, H)) im = Image.new(mode, (W, H))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_polygon_kite_{}.png".format( expected = "Tests/images/imagedraw_polygon_kite_{}.png".format(mode)
mode)
# Act # Act
draw.polygon(KITE_POINTS, fill="blue", outline="yellow") draw.polygon(KITE_POINTS, fill="blue", outline="yellow")
@ -441,8 +433,7 @@ class TestImageDraw(PillowTestCase):
draw.rectangle(bbox, fill="black", outline="green") draw.rectangle(bbox, fill="black", outline="green")
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_rectangle.png"))
im, Image.open("Tests/images/imagedraw_rectangle.png"))
def test_rectangle1(self): def test_rectangle1(self):
self.helper_rectangle(BBOX1) self.helper_rectangle(BBOX1)
@ -454,7 +445,7 @@ class TestImageDraw(PillowTestCase):
# Test drawing a rectangle bigger than the image # Test drawing a rectangle bigger than the image
# Arrange # Arrange
im = Image.new("RGB", (W, H)) im = Image.new("RGB", (W, H))
bbox = [(-1, -1), (W+1, H+1)] bbox = [(-1, -1), (W + 1, H + 1)]
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_big_rectangle.png" expected = "Tests/images/imagedraw_big_rectangle.png"
@ -491,22 +482,18 @@ class TestImageDraw(PillowTestCase):
def test_floodfill(self): def test_floodfill(self):
red = ImageColor.getrgb("red") red = ImageColor.getrgb("red")
for mode, value in [ for mode, value in [("L", 1), ("RGBA", (255, 0, 0, 0)), ("RGB", red)]:
("L", 1),
("RGBA", (255, 0, 0, 0)),
("RGB", red)
]:
# Arrange # Arrange
im = Image.new(mode, (W, H)) im = Image.new(mode, (W, H))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.rectangle(BBOX2, outline="yellow", fill="green") draw.rectangle(BBOX2, outline="yellow", fill="green")
centre_point = (int(W/2), int(H/2)) centre_point = (int(W / 2), int(H / 2))
# Act # Act
ImageDraw.floodfill(im, centre_point, value) ImageDraw.floodfill(im, centre_point, value)
# Assert # Assert
expected = "Tests/images/imagedraw_floodfill_"+mode+".png" expected = "Tests/images/imagedraw_floodfill_" + mode + ".png"
im_floodfill = Image.open(expected) im_floodfill = Image.open(expected)
self.assert_image_equal(im, im_floodfill) self.assert_image_equal(im, im_floodfill)
@ -530,16 +517,18 @@ class TestImageDraw(PillowTestCase):
im = Image.new("RGB", (W, H)) im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.rectangle(BBOX2, outline="yellow", fill="green") draw.rectangle(BBOX2, outline="yellow", fill="green")
centre_point = (int(W/2), int(H/2)) centre_point = (int(W / 2), int(H / 2))
# Act # Act
ImageDraw.floodfill( ImageDraw.floodfill(
im, centre_point, ImageColor.getrgb("red"), im,
border=ImageColor.getrgb("black")) centre_point,
ImageColor.getrgb("red"),
border=ImageColor.getrgb("black"),
)
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_floodfill2.png"))
im, Image.open("Tests/images/imagedraw_floodfill2.png"))
def test_floodfill_thresh(self): def test_floodfill_thresh(self):
# floodfill() is experimental # floodfill() is experimental
@ -548,21 +537,17 @@ class TestImageDraw(PillowTestCase):
im = Image.new("RGB", (W, H)) im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.rectangle(BBOX2, outline="darkgreen", fill="green") draw.rectangle(BBOX2, outline="darkgreen", fill="green")
centre_point = (int(W/2), int(H/2)) centre_point = (int(W / 2), int(H / 2))
# Act # Act
ImageDraw.floodfill( ImageDraw.floodfill(im, centre_point, ImageColor.getrgb("red"), thresh=30)
im, centre_point, ImageColor.getrgb("red"),
thresh=30)
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_floodfill2.png"))
im, Image.open("Tests/images/imagedraw_floodfill2.png"))
def create_base_image_draw(self, size, def create_base_image_draw(
mode=DEFAULT_MODE, self, size, mode=DEFAULT_MODE, background1=WHITE, background2=GRAY
background1=WHITE, ):
background2=GRAY):
img = Image.new(mode, size, background1) img = Image.new(mode, size, background1)
for x in range(0, size[0]): for x in range(0, size[0]):
for y in range(0, size[1]): for y in range(0, size[1]):
@ -571,140 +556,152 @@ class TestImageDraw(PillowTestCase):
return img, ImageDraw.Draw(img) return img, ImageDraw.Draw(img)
def test_square(self): def test_square(self):
expected = Image.open(os.path.join(IMAGES_PATH, 'square.png')) expected = Image.open(os.path.join(IMAGES_PATH, "square.png"))
expected.load() expected.load()
img, draw = self.create_base_image_draw((10, 10)) img, draw = self.create_base_image_draw((10, 10))
draw.polygon([(2, 2), (2, 7), (7, 7), (7, 2)], BLACK) draw.polygon([(2, 2), (2, 7), (7, 7), (7, 2)], BLACK)
self.assert_image_equal(img, expected, self.assert_image_equal(img, expected, "square as normal polygon failed")
'square as normal polygon failed')
img, draw = self.create_base_image_draw((10, 10)) img, draw = self.create_base_image_draw((10, 10))
draw.polygon([(7, 7), (7, 2), (2, 2), (2, 7)], BLACK) draw.polygon([(7, 7), (7, 2), (2, 2), (2, 7)], BLACK)
self.assert_image_equal(img, expected, self.assert_image_equal(img, expected, "square as inverted polygon failed")
'square as inverted polygon failed')
img, draw = self.create_base_image_draw((10, 10)) img, draw = self.create_base_image_draw((10, 10))
draw.rectangle((2, 2, 7, 7), BLACK) draw.rectangle((2, 2, 7, 7), BLACK)
self.assert_image_equal(img, expected, self.assert_image_equal(img, expected, "square as normal rectangle failed")
'square as normal rectangle failed')
img, draw = self.create_base_image_draw((10, 10)) img, draw = self.create_base_image_draw((10, 10))
draw.rectangle((7, 7, 2, 2), BLACK) draw.rectangle((7, 7, 2, 2), BLACK)
self.assert_image_equal( self.assert_image_equal(img, expected, "square as inverted rectangle failed")
img, expected, 'square as inverted rectangle failed')
def test_triangle_right(self): def test_triangle_right(self):
expected = Image.open(os.path.join(IMAGES_PATH, 'triangle_right.png')) expected = Image.open(os.path.join(IMAGES_PATH, "triangle_right.png"))
expected.load() expected.load()
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.polygon([(3, 5), (17, 5), (10, 12)], BLACK) draw.polygon([(3, 5), (17, 5), (10, 12)], BLACK)
self.assert_image_equal(img, expected, 'triangle right failed') self.assert_image_equal(img, expected, "triangle right failed")
def test_line_horizontal(self): def test_line_horizontal(self):
expected = Image.open(os.path.join(IMAGES_PATH, expected = Image.open(
'line_horizontal_w2px_normal.png')) os.path.join(IMAGES_PATH, "line_horizontal_w2px_normal.png")
)
expected.load() expected.load()
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 5), BLACK, 2) draw.line((5, 5, 14, 5), BLACK, 2)
self.assert_image_equal( self.assert_image_equal(
img, expected, 'line straight horizontal normal 2px wide failed') img, expected, "line straight horizontal normal 2px wide failed"
expected = Image.open(os.path.join(IMAGES_PATH, )
'line_horizontal_w2px_inverted.png')) expected = Image.open(
os.path.join(IMAGES_PATH, "line_horizontal_w2px_inverted.png")
)
expected.load() expected.load()
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 5, 5, 5), BLACK, 2) draw.line((14, 5, 5, 5), BLACK, 2)
self.assert_image_equal( self.assert_image_equal(
img, expected, 'line straight horizontal inverted 2px wide failed') img, expected, "line straight horizontal inverted 2px wide failed"
expected = Image.open(os.path.join(IMAGES_PATH, )
'line_horizontal_w3px.png')) expected = Image.open(os.path.join(IMAGES_PATH, "line_horizontal_w3px.png"))
expected.load() expected.load()
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 5), BLACK, 3) draw.line((5, 5, 14, 5), BLACK, 3)
self.assert_image_equal( self.assert_image_equal(
img, expected, 'line straight horizontal normal 3px wide failed') img, expected, "line straight horizontal normal 3px wide failed"
)
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 5, 5, 5), BLACK, 3) draw.line((14, 5, 5, 5), BLACK, 3)
self.assert_image_equal( self.assert_image_equal(
img, expected, 'line straight horizontal inverted 3px wide failed') img, expected, "line straight horizontal inverted 3px wide failed"
expected = Image.open(os.path.join(IMAGES_PATH, )
'line_horizontal_w101px.png')) expected = Image.open(os.path.join(IMAGES_PATH, "line_horizontal_w101px.png"))
expected.load() expected.load()
img, draw = self.create_base_image_draw((200, 110)) img, draw = self.create_base_image_draw((200, 110))
draw.line((5, 55, 195, 55), BLACK, 101) draw.line((5, 55, 195, 55), BLACK, 101)
self.assert_image_equal( self.assert_image_equal(
img, expected, 'line straight horizontal 101px wide failed') img, expected, "line straight horizontal 101px wide failed"
)
def test_line_h_s1_w2(self): def test_line_h_s1_w2(self):
self.skipTest('failing') self.skipTest("failing")
expected = Image.open(os.path.join(IMAGES_PATH, expected = Image.open(
'line_horizontal_slope1px_w2px.png')) os.path.join(IMAGES_PATH, "line_horizontal_slope1px_w2px.png")
)
expected.load() expected.load()
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 6), BLACK, 2) draw.line((5, 5, 14, 6), BLACK, 2)
self.assert_image_equal( self.assert_image_equal(
img, expected, 'line horizontal 1px slope 2px wide failed') img, expected, "line horizontal 1px slope 2px wide failed"
)
def test_line_vertical(self): def test_line_vertical(self):
expected = Image.open(os.path.join(IMAGES_PATH, expected = Image.open(
'line_vertical_w2px_normal.png')) os.path.join(IMAGES_PATH, "line_vertical_w2px_normal.png")
)
expected.load() expected.load()
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 5, 14), BLACK, 2) draw.line((5, 5, 5, 14), BLACK, 2)
self.assert_image_equal( self.assert_image_equal(
img, expected, 'line straight vertical normal 2px wide failed') img, expected, "line straight vertical normal 2px wide failed"
expected = Image.open(os.path.join(IMAGES_PATH, )
'line_vertical_w2px_inverted.png')) expected = Image.open(
os.path.join(IMAGES_PATH, "line_vertical_w2px_inverted.png")
)
expected.load() expected.load()
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 14, 5, 5), BLACK, 2) draw.line((5, 14, 5, 5), BLACK, 2)
self.assert_image_equal( self.assert_image_equal(
img, expected, 'line straight vertical inverted 2px wide failed') img, expected, "line straight vertical inverted 2px wide failed"
expected = Image.open(os.path.join(IMAGES_PATH, )
'line_vertical_w3px.png')) expected = Image.open(os.path.join(IMAGES_PATH, "line_vertical_w3px.png"))
expected.load() expected.load()
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 5, 14), BLACK, 3) draw.line((5, 5, 5, 14), BLACK, 3)
self.assert_image_equal( self.assert_image_equal(
img, expected, 'line straight vertical normal 3px wide failed') img, expected, "line straight vertical normal 3px wide failed"
)
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 14, 5, 5), BLACK, 3) draw.line((5, 14, 5, 5), BLACK, 3)
self.assert_image_equal( self.assert_image_equal(
img, expected, 'line straight vertical inverted 3px wide failed') img, expected, "line straight vertical inverted 3px wide failed"
expected = Image.open(os.path.join(IMAGES_PATH, )
'line_vertical_w101px.png')) expected = Image.open(os.path.join(IMAGES_PATH, "line_vertical_w101px.png"))
expected.load() expected.load()
img, draw = self.create_base_image_draw((110, 200)) img, draw = self.create_base_image_draw((110, 200))
draw.line((55, 5, 55, 195), BLACK, 101) draw.line((55, 5, 55, 195), BLACK, 101)
self.assert_image_equal(img, expected, self.assert_image_equal(
'line straight vertical 101px wide failed') img, expected, "line straight vertical 101px wide failed"
expected = Image.open(os.path.join(IMAGES_PATH, )
'line_vertical_slope1px_w2px.png')) expected = Image.open(
os.path.join(IMAGES_PATH, "line_vertical_slope1px_w2px.png")
)
expected.load() expected.load()
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 6, 14), BLACK, 2) draw.line((5, 5, 6, 14), BLACK, 2)
self.assert_image_equal(img, expected, self.assert_image_equal(
'line vertical 1px slope 2px wide failed') img, expected, "line vertical 1px slope 2px wide failed"
)
def test_line_oblique_45(self): def test_line_oblique_45(self):
expected = Image.open(os.path.join(IMAGES_PATH, expected = Image.open(os.path.join(IMAGES_PATH, "line_oblique_45_w3px_a.png"))
'line_oblique_45_w3px_a.png'))
expected.load() expected.load()
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 14), BLACK, 3) draw.line((5, 5, 14, 14), BLACK, 3)
self.assert_image_equal(img, expected, self.assert_image_equal(
'line oblique 45 normal 3px wide A failed') img, expected, "line oblique 45 normal 3px wide A failed"
)
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 14, 5, 5), BLACK, 3) draw.line((14, 14, 5, 5), BLACK, 3)
self.assert_image_equal(img, expected, self.assert_image_equal(
'line oblique 45 inverted 3px wide A failed') img, expected, "line oblique 45 inverted 3px wide A failed"
expected = Image.open(os.path.join(IMAGES_PATH, )
'line_oblique_45_w3px_b.png')) expected = Image.open(os.path.join(IMAGES_PATH, "line_oblique_45_w3px_b.png"))
expected.load() expected.load()
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 5, 5, 14), BLACK, 3) draw.line((14, 5, 5, 14), BLACK, 3)
self.assert_image_equal(img, expected, self.assert_image_equal(
'line oblique 45 normal 3px wide B failed') img, expected, "line oblique 45 normal 3px wide B failed"
)
img, draw = self.create_base_image_draw((20, 20)) img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 14, 14, 5), BLACK, 3) draw.line((5, 14, 14, 5), BLACK, 3)
self.assert_image_equal(img, expected, self.assert_image_equal(
'line oblique 45 inverted 3px wide B failed') img, expected, "line oblique 45 inverted 3px wide B failed"
)
def test_wide_line_dot(self): def test_wide_line_dot(self):
# Test drawing a wide "line" from one point to another just draws # Test drawing a wide "line" from one point to another just draws
@ -726,9 +723,22 @@ class TestImageDraw(PillowTestCase):
expected = "Tests/images/imagedraw_line_joint_curve.png" expected = "Tests/images/imagedraw_line_joint_curve.png"
# Act # Act
xy = [(400, 280), (380, 280), (450, 280), (440, 120), (350, 200), xy = [
(310, 280), (300, 280), (250, 280), (250, 200), (150, 200), (400, 280),
(150, 260), (50, 200), (150, 50), (250, 100)] (380, 280),
(450, 280),
(440, 120),
(350, 200),
(310, 280),
(300, 280),
(250, 280),
(250, 200),
(150, 200),
(150, 260),
(50, 200),
(150, 50),
(250, 100),
]
draw.line(xy, GRAY, 50, "curve") draw.line(xy, GRAY, 50, "curve")
# Assert # Assert
@ -761,18 +771,14 @@ class TestImageDraw(PillowTestCase):
# Begin # Begin
for mode in ["RGB", "L"]: for mode in ["RGB", "L"]:
for fill, outline in [ for fill, outline in [["red", None], ["red", "red"], ["red", "#f00"]]:
["red", None],
["red", "red"],
["red", "#f00"]
]:
for operation, args in { for operation, args in {
'chord': [BBOX1, 0, 180], "chord": [BBOX1, 0, 180],
'ellipse': [BBOX1], "ellipse": [BBOX1],
'shape': [s], "shape": [s],
'pieslice': [BBOX1, -90, 45], "pieslice": [BBOX1, -90, 45],
'polygon': [[(18, 30), (85, 30), (60, 72)]], "polygon": [[(18, 30), (85, 30), (60, 72)]],
'rectangle': [BBOX1] "rectangle": [BBOX1],
}.items(): }.items():
# Arrange # Arrange
im = Image.new(mode, (W, H)) im = Image.new(mode, (W, H))
@ -784,6 +790,7 @@ class TestImageDraw(PillowTestCase):
draw_method(*args) draw_method(*args)
# Assert # Assert
expected = ("Tests/images/imagedraw_outline" expected = "Tests/images/imagedraw_outline_{}_{}.png".format(
"_{}_{}.png".format(operation, mode)) operation, mode
)
self.assert_image_similar(im, Image.open(expected), 1) self.assert_image_similar(im, Image.open(expected), 1)

View File

@ -33,7 +33,6 @@ FONT_PATH = "Tests/fonts/FreeMono.ttf"
class TestImageDraw(PillowTestCase): class TestImageDraw(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im = hopper("RGB").copy() im = hopper("RGB").copy()
@ -74,11 +73,12 @@ class TestImageDraw(PillowTestCase):
brush = ImageDraw2.Brush("white") brush = ImageDraw2.Brush("white")
# Act # Act
draw.ellipse(((0, 0), (W-1, H)), brush) draw.ellipse(((0, 0), (W - 1, H)), brush)
# Assert # Assert
self.assert_image_similar( self.assert_image_similar(
im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1) im, Image.open("Tests/images/imagedraw_ellipse_edge.png"), 1
)
def helper_line(self, points): def helper_line(self, points):
# Arrange # Arrange
@ -90,8 +90,7 @@ class TestImageDraw(PillowTestCase):
draw.line(points, pen) draw.line(points, pen)
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png"))
im, Image.open("Tests/images/imagedraw_line.png"))
def test_line1_pen(self): def test_line1_pen(self):
self.helper_line(POINTS1) self.helper_line(POINTS1)
@ -111,8 +110,7 @@ class TestImageDraw(PillowTestCase):
draw.line(POINTS1, pen, brush) draw.line(POINTS1, pen, brush)
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png"))
im, Image.open("Tests/images/imagedraw_line.png"))
def helper_polygon(self, points): def helper_polygon(self, points):
# Arrange # Arrange
@ -125,8 +123,7 @@ class TestImageDraw(PillowTestCase):
draw.polygon(points, pen, brush) draw.polygon(points, pen, brush)
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_polygon.png"))
im, Image.open("Tests/images/imagedraw_polygon.png"))
def test_polygon1(self): def test_polygon1(self):
self.helper_polygon(POINTS1) self.helper_polygon(POINTS1)
@ -145,8 +142,7 @@ class TestImageDraw(PillowTestCase):
draw.rectangle(bbox, pen, brush) draw.rectangle(bbox, pen, brush)
# Assert # Assert
self.assert_image_equal( self.assert_image_equal(im, Image.open("Tests/images/imagedraw_rectangle.png"))
im, Image.open("Tests/images/imagedraw_rectangle.png"))
def test_rectangle1(self): def test_rectangle1(self):
self.helper_rectangle(BBOX1) self.helper_rectangle(BBOX1)

View File

@ -5,7 +5,6 @@ from PIL import ImageEnhance
class TestImageEnhance(PillowTestCase): class TestImageEnhance(PillowTestCase):
def test_sanity(self): def test_sanity(self):
# FIXME: assert_image # FIXME: assert_image
@ -23,10 +22,10 @@ class TestImageEnhance(PillowTestCase):
def _half_transparent_image(self): def _half_transparent_image(self):
# returns an image, half transparent, half solid # returns an image, half transparent, half solid
im = hopper('RGB') im = hopper("RGB")
transparent = Image.new('L', im.size, 0) transparent = Image.new("L", im.size, 0)
solid = Image.new('L', (im.size[0]//2, im.size[1]), 255) solid = Image.new("L", (im.size[0] // 2, im.size[1]), 255)
transparent.paste(solid, (0, 0)) transparent.paste(solid, (0, 0))
im.putalpha(transparent) im.putalpha(transparent)
@ -34,8 +33,11 @@ class TestImageEnhance(PillowTestCase):
def _check_alpha(self, im, original, op, amount): def _check_alpha(self, im, original, op, amount):
self.assertEqual(im.getbands(), original.getbands()) self.assertEqual(im.getbands(), original.getbands())
self.assert_image_equal(im.getchannel('A'), original.getchannel('A'), self.assert_image_equal(
"Diff on %s: %s" % (op, amount)) im.getchannel("A"),
original.getchannel("A"),
"Diff on %s: %s" % (op, amount),
)
def test_alpha(self): def test_alpha(self):
# Issue https://github.com/python-pillow/Pillow/issues/899 # Issue https://github.com/python-pillow/Pillow/issues/899
@ -43,8 +45,11 @@ class TestImageEnhance(PillowTestCase):
original = self._half_transparent_image() original = self._half_transparent_image()
for op in ['Color', 'Brightness', 'Contrast', 'Sharpness']: for op in ["Color", "Brightness", "Contrast", "Sharpness"]:
for amount in [0, 0.5, 1.0]: for amount in [0, 0.5, 1.0]:
self._check_alpha( self._check_alpha(
getattr(ImageEnhance, op)(original).enhance(amount), getattr(ImageEnhance, op)(original).enhance(amount),
original, op, amount) original,
op,
amount,
)

View File

@ -8,6 +8,7 @@ from PIL import EpsImagePlugin
try: try:
from PIL import _webp from PIL import _webp
HAVE_WEBP = True HAVE_WEBP = True
except ImportError: except ImportError:
HAVE_WEBP = False HAVE_WEBP = False
@ -21,9 +22,7 @@ SAFEBLOCK = ImageFile.SAFEBLOCK
class TestImageFile(PillowTestCase): class TestImageFile(PillowTestCase):
def test_parser(self): def test_parser(self):
def roundtrip(format): def roundtrip(format):
im = hopper("L").resize((1000, 1000)) im = hopper("L").resize((1000, 1000))
@ -44,7 +43,7 @@ class TestImageFile(PillowTestCase):
self.assert_image_equal(*roundtrip("BMP")) self.assert_image_equal(*roundtrip("BMP"))
im1, im2 = roundtrip("GIF") im1, im2 = roundtrip("GIF")
self.assert_image_similar(im1.convert('P'), im2, 1) self.assert_image_similar(im1.convert("P"), im2, 1)
self.assert_image_equal(*roundtrip("IM")) self.assert_image_equal(*roundtrip("IM"))
self.assert_image_equal(*roundtrip("MSP")) self.assert_image_equal(*roundtrip("MSP"))
if "zip_encoder" in codecs: if "zip_encoder" in codecs:
@ -69,7 +68,7 @@ class TestImageFile(PillowTestCase):
# md5sum: ba974835ff2d6f3f2fd0053a23521d4a # md5sum: ba974835ff2d6f3f2fd0053a23521d4a
# EPS comes back in RGB: # EPS comes back in RGB:
self.assert_image_similar(im1, im2.convert('L'), 20) self.assert_image_similar(im1, im2.convert("L"), 20)
if "jpeg_encoder" in codecs: if "jpeg_encoder" in codecs:
im1, im2 = roundtrip("JPEG") # lossy compression im1, im2 = roundtrip("JPEG") # lossy compression
@ -78,7 +77,7 @@ class TestImageFile(PillowTestCase):
self.assertRaises(IOError, roundtrip, "PDF") self.assertRaises(IOError, roundtrip, "PDF")
def test_ico(self): def test_ico(self):
with open('Tests/images/python.ico', 'rb') as f: with open("Tests/images/python.ico", "rb") as f:
data = f.read() data = f.read()
with ImageFile.Parser() as p: with ImageFile.Parser() as p:
p.feed(data) p.feed(data)
@ -158,14 +157,13 @@ xoff, yoff, xsize, ysize = 10, 20, 100, 100
class MockImageFile(ImageFile.ImageFile): class MockImageFile(ImageFile.ImageFile):
def _open(self): def _open(self):
self.rawmode = 'RGBA' self.rawmode = "RGBA"
self.mode = 'RGBA' self.mode = "RGBA"
self._size = (200, 200) self._size = (200, 200)
self.tile = [("MOCK", (xoff, yoff, xoff+xsize, yoff+ysize), 32, None)] self.tile = [("MOCK", (xoff, yoff, xoff + xsize, yoff + ysize), 32, None)]
class TestPyDecoder(PillowTestCase): class TestPyDecoder(PillowTestCase):
def get_decoder(self): def get_decoder(self):
decoder = MockPyDecoder(None) decoder = MockPyDecoder(None)
@ -173,11 +171,11 @@ class TestPyDecoder(PillowTestCase):
decoder.__init__(mode, *args) decoder.__init__(mode, *args)
return decoder return decoder
Image.register_decoder('MOCK', closure) Image.register_decoder("MOCK", closure)
return decoder return decoder
def test_setimage(self): def test_setimage(self):
buf = BytesIO(b'\x00'*255) buf = BytesIO(b"\x00" * 255)
im = MockImageFile(buf) im = MockImageFile(buf)
d = self.get_decoder() d = self.get_decoder()
@ -189,10 +187,10 @@ class TestPyDecoder(PillowTestCase):
self.assertEqual(d.state.xsize, xsize) self.assertEqual(d.state.xsize, xsize)
self.assertEqual(d.state.ysize, ysize) self.assertEqual(d.state.ysize, ysize)
self.assertRaises(ValueError, d.set_as_raw, b'\x00') self.assertRaises(ValueError, d.set_as_raw, b"\x00")
def test_extents_none(self): def test_extents_none(self):
buf = BytesIO(b'\x00'*255) buf = BytesIO(b"\x00" * 255)
im = MockImageFile(buf) im = MockImageFile(buf)
im.tile = [("MOCK", None, 32, None)] im.tile = [("MOCK", None, 32, None)]
@ -206,35 +204,31 @@ class TestPyDecoder(PillowTestCase):
self.assertEqual(d.state.ysize, 200) self.assertEqual(d.state.ysize, 200)
def test_negsize(self): def test_negsize(self):
buf = BytesIO(b'\x00'*255) buf = BytesIO(b"\x00" * 255)
im = MockImageFile(buf) im = MockImageFile(buf)
im.tile = [("MOCK", (xoff, yoff, -10, yoff+ysize), 32, None)] im.tile = [("MOCK", (xoff, yoff, -10, yoff + ysize), 32, None)]
self.get_decoder() self.get_decoder()
self.assertRaises(ValueError, im.load) self.assertRaises(ValueError, im.load)
im.tile = [("MOCK", (xoff, yoff, xoff+xsize, -10), 32, None)] im.tile = [("MOCK", (xoff, yoff, xoff + xsize, -10), 32, None)]
self.assertRaises(ValueError, im.load) self.assertRaises(ValueError, im.load)
def test_oversize(self): def test_oversize(self):
buf = BytesIO(b'\x00'*255) buf = BytesIO(b"\x00" * 255)
im = MockImageFile(buf) im = MockImageFile(buf)
im.tile = [ im.tile = [("MOCK", (xoff, yoff, xoff + xsize + 100, yoff + ysize), 32, None)]
("MOCK", (xoff, yoff, xoff+xsize + 100, yoff+ysize), 32, None)
]
self.get_decoder() self.get_decoder()
self.assertRaises(ValueError, im.load) self.assertRaises(ValueError, im.load)
im.tile = [ im.tile = [("MOCK", (xoff, yoff, xoff + xsize, yoff + ysize + 100), 32, None)]
("MOCK", (xoff, yoff, xoff+xsize, yoff+ysize + 100), 32, None)
]
self.assertRaises(ValueError, im.load) self.assertRaises(ValueError, im.load)
def test_no_format(self): def test_no_format(self):
buf = BytesIO(b'\x00'*255) buf = BytesIO(b"\x00" * 255)
im = MockImageFile(buf) im = MockImageFile(buf)
self.assertIsNone(im.format) self.assertIsNone(im.format)
@ -248,7 +242,7 @@ class TestPyDecoder(PillowTestCase):
self.assertEqual(exif[40963], 450) self.assertEqual(exif[40963], 450)
self.assertEqual(exif[11], "gThumb 3.0.1") self.assertEqual(exif[11], "gThumb 3.0.1")
out = self.tempfile('temp.jpg') out = self.tempfile("temp.jpg")
exif[258] = 8 exif[258] = 8
del exif[40960] del exif[40960]
exif[40963] = 455 exif[40963] = 455
@ -268,7 +262,7 @@ class TestPyDecoder(PillowTestCase):
self.assertEqual(exif[40963], 200) self.assertEqual(exif[40963], 200)
self.assertEqual(exif[305], "Adobe Photoshop CC 2017 (Macintosh)") self.assertEqual(exif[305], "Adobe Photoshop CC 2017 (Macintosh)")
out = self.tempfile('temp.jpg') out = self.tempfile("temp.jpg")
exif[258] = 8 exif[258] = 8
del exif[34665] del exif[34665]
exif[40963] = 455 exif[40963] = 455
@ -281,14 +275,16 @@ class TestPyDecoder(PillowTestCase):
self.assertEqual(reloaded_exif[40963], 455) self.assertEqual(reloaded_exif[40963], 455)
self.assertEqual(exif[305], "Pillow test") self.assertEqual(exif[305], "Pillow test")
@unittest.skipIf(not HAVE_WEBP or not _webp.HAVE_WEBPANIM, @unittest.skipIf(
"WebP support not installed with animation") not HAVE_WEBP or not _webp.HAVE_WEBPANIM,
"WebP support not installed with animation",
)
def test_exif_webp(self): def test_exif_webp(self):
im = Image.open("Tests/images/hopper.webp") im = Image.open("Tests/images/hopper.webp")
exif = im.getexif() exif = im.getexif()
self.assertEqual(exif, {}) self.assertEqual(exif, {})
out = self.tempfile('temp.webp') out = self.tempfile("temp.webp")
exif[258] = 8 exif[258] = 8
exif[40963] = 455 exif[40963] = 455
exif[305] = "Pillow test" exif[305] = "Pillow test"
@ -299,6 +295,7 @@ class TestPyDecoder(PillowTestCase):
self.assertEqual(reloaded_exif[258], 8) self.assertEqual(reloaded_exif[258], 8)
self.assertEqual(reloaded_exif[40963], 455) self.assertEqual(reloaded_exif[40963], 455)
self.assertEqual(exif[305], "Pillow test") self.assertEqual(exif[305], "Pillow test")
im.save(out, exif=exif) im.save(out, exif=exif)
check_exif() check_exif()
im.save(out, exif=exif, save_all=True) im.save(out, exif=exif, save_all=True)
@ -309,7 +306,7 @@ class TestPyDecoder(PillowTestCase):
exif = im.getexif() exif = im.getexif()
self.assertEqual(exif, {274: 1}) self.assertEqual(exif, {274: 1})
out = self.tempfile('temp.png') out = self.tempfile("temp.png")
exif[258] = 8 exif[258] = 8
del exif[274] del exif[274]
exif[40963] = 455 exif[40963] = 455
@ -318,18 +315,11 @@ class TestPyDecoder(PillowTestCase):
reloaded = Image.open(out) reloaded = Image.open(out)
reloaded_exif = reloaded.getexif() reloaded_exif = reloaded.getexif()
self.assertEqual(reloaded_exif, { self.assertEqual(reloaded_exif, {258: 8, 40963: 455, 305: "Pillow test"})
258: 8,
40963: 455,
305: 'Pillow test',
})
def test_exif_interop(self): def test_exif_interop(self):
im = Image.open("Tests/images/flower.jpg") im = Image.open("Tests/images/flower.jpg")
exif = im.getexif() exif = im.getexif()
self.assertEqual(exif.get_ifd(0xa005), { self.assertEqual(
1: 'R98', exif.get_ifd(0xA005), {1: "R98", 2: b"0100", 4097: 2272, 4098: 1704}
2: b'0100', )
4097: 2272,
4098: 1704,
})

View File

@ -15,8 +15,8 @@ FONT_SIZE = 20
TEST_TEXT = "hey you\nyou are awesome\nthis looks awkward" TEST_TEXT = "hey you\nyou are awesome\nthis looks awkward"
HAS_FREETYPE = features.check('freetype2') HAS_FREETYPE = features.check("freetype2")
HAS_RAQM = features.check('raqm') HAS_RAQM = features.check("raqm")
class SimplePatcher(object): class SimplePatcher(object):
@ -52,32 +52,24 @@ class TestImageFont(PillowTestCase):
# Freetype has different metrics depending on the version. # Freetype has different metrics depending on the version.
# (and, other things, but first things first) # (and, other things, but first things first)
METRICS = { METRICS = {
('>=2.3', '<2.4'): { (">=2.3", "<2.4"): {"multiline": 30, "textsize": 12, "getters": (13, 16)},
'multiline': 30, (">=2.7",): {"multiline": 6.2, "textsize": 2.5, "getters": (12, 16)},
'textsize': 12, "Default": {"multiline": 0.5, "textsize": 0.5, "getters": (12, 16)},
'getters': (13, 16)},
('>=2.7',): {
'multiline': 6.2,
'textsize': 2.5,
'getters': (12, 16)},
'Default': {
'multiline': 0.5,
'textsize': 0.5,
'getters': (12, 16)},
} }
def setUp(self): def setUp(self):
freetype = distutils.version.StrictVersion(ImageFont.core.freetype2_version) freetype = distutils.version.StrictVersion(ImageFont.core.freetype2_version)
self.metrics = self.METRICS['Default'] self.metrics = self.METRICS["Default"]
for conditions, metrics in self.METRICS.items(): for conditions, metrics in self.METRICS.items():
if not isinstance(conditions, tuple): if not isinstance(conditions, tuple):
continue continue
for condition in conditions: for condition in conditions:
version = re.sub('[<=>]', '', condition) version = re.sub("[<=>]", "", condition)
if (condition.startswith('>=') and freetype >= version) or \ if (condition.startswith(">=") and freetype >= version) or (
(condition.startswith('<') and freetype < version): condition.startswith("<") and freetype < version
):
# Condition was met # Condition was met
continue continue
@ -88,8 +80,9 @@ class TestImageFont(PillowTestCase):
self.metrics = metrics self.metrics = metrics
def get_font(self): def get_font(self):
return ImageFont.truetype(FONT_PATH, FONT_SIZE, return ImageFont.truetype(
layout_engine=self.LAYOUT_ENGINE) FONT_PATH, FONT_SIZE, layout_engine=self.LAYOUT_ENGINE
)
def test_sanity(self): def test_sanity(self):
self.assertRegex(ImageFont.core.freetype2_version, r"\d+\.\d+\.\d+$") self.assertRegex(ImageFont.core.freetype2_version, r"\d+\.\d+\.\d+$")
@ -103,8 +96,8 @@ class TestImageFont(PillowTestCase):
self.assertEqual(ttf_copy.path, FONT_PATH) self.assertEqual(ttf_copy.path, FONT_PATH)
self.assertEqual(ttf_copy.size, FONT_SIZE) self.assertEqual(ttf_copy.size, FONT_SIZE)
ttf_copy = ttf.font_variant(size=FONT_SIZE+1) ttf_copy = ttf.font_variant(size=FONT_SIZE + 1)
self.assertEqual(ttf_copy.size, FONT_SIZE+1) self.assertEqual(ttf_copy.size, FONT_SIZE + 1)
second_font_path = "Tests/fonts/DejaVuSans.ttf" second_font_path = "Tests/fonts/DejaVuSans.ttf"
ttf_copy = ttf.font_variant(font=second_font_path) ttf_copy = ttf.font_variant(font=second_font_path)
@ -115,13 +108,14 @@ class TestImageFont(PillowTestCase):
self._render(FONT_PATH) self._render(FONT_PATH)
def _font_as_bytes(self): def _font_as_bytes(self):
with open(FONT_PATH, 'rb') as f: with open(FONT_PATH, "rb") as f:
font_bytes = BytesIO(f.read()) font_bytes = BytesIO(f.read())
return font_bytes return font_bytes
def test_font_with_filelike(self): def test_font_with_filelike(self):
ImageFont.truetype(self._font_as_bytes(), FONT_SIZE, ImageFont.truetype(
layout_engine=self.LAYOUT_ENGINE) self._font_as_bytes(), FONT_SIZE, layout_engine=self.LAYOUT_ENGINE
)
self._render(self._font_as_bytes()) self._render(self._font_as_bytes())
# Usage note: making two fonts from the same buffer fails. # Usage note: making two fonts from the same buffer fails.
# shared_bytes = self._font_as_bytes() # shared_bytes = self._font_as_bytes()
@ -129,12 +123,12 @@ class TestImageFont(PillowTestCase):
# self.assertRaises(Exception, _render, shared_bytes) # self.assertRaises(Exception, _render, shared_bytes)
def test_font_with_open_file(self): def test_font_with_open_file(self):
with open(FONT_PATH, 'rb') as f: with open(FONT_PATH, "rb") as f:
self._render(f) self._render(f)
def test_non_unicode_path(self): def test_non_unicode_path(self):
try: try:
tempfile = self.tempfile("temp_"+chr(128)+".ttf") tempfile = self.tempfile("temp_" + chr(128) + ".ttf")
except UnicodeEncodeError: except UnicodeEncodeError:
self.skipTest("Unicode path could not be created") self.skipTest("Unicode path could not be created")
shutil.copy(FONT_PATH, tempfile) shutil.copy(FONT_PATH, tempfile)
@ -146,8 +140,9 @@ class TestImageFont(PillowTestCase):
ImageFont.core.HAVE_RAQM = False ImageFont.core.HAVE_RAQM = False
try: try:
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE, ttf = ImageFont.truetype(
layout_engine=ImageFont.LAYOUT_RAQM) FONT_PATH, FONT_SIZE, layout_engine=ImageFont.LAYOUT_RAQM
)
finally: finally:
ImageFont.core.HAVE_RAQM = have_raqm ImageFont.core.HAVE_RAQM = have_raqm
@ -155,26 +150,25 @@ class TestImageFont(PillowTestCase):
def _render(self, font): def _render(self, font):
txt = "Hello World!" txt = "Hello World!"
ttf = ImageFont.truetype(font, FONT_SIZE, ttf = ImageFont.truetype(font, FONT_SIZE, layout_engine=self.LAYOUT_ENGINE)
layout_engine=self.LAYOUT_ENGINE)
ttf.getsize(txt) ttf.getsize(txt)
img = Image.new("RGB", (256, 64), "white") img = Image.new("RGB", (256, 64), "white")
d = ImageDraw.Draw(img) d = ImageDraw.Draw(img)
d.text((10, 10), txt, font=ttf, fill='black') d.text((10, 10), txt, font=ttf, fill="black")
return img return img
def test_render_equal(self): def test_render_equal(self):
img_path = self._render(FONT_PATH) img_path = self._render(FONT_PATH)
with open(FONT_PATH, 'rb') as f: with open(FONT_PATH, "rb") as f:
font_filelike = BytesIO(f.read()) font_filelike = BytesIO(f.read())
img_filelike = self._render(font_filelike) img_filelike = self._render(font_filelike)
self.assert_image_equal(img_path, img_filelike) self.assert_image_equal(img_path, img_filelike)
def test_textsize_equal(self): def test_textsize_equal(self):
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
ttf = self.get_font() ttf = self.get_font()
@ -183,96 +177,101 @@ class TestImageFont(PillowTestCase):
draw.text((10, 10), txt, font=ttf) draw.text((10, 10), txt, font=ttf)
draw.rectangle((10, 10, 10 + size[0], 10 + size[1])) draw.rectangle((10, 10, 10 + size[0], 10 + size[1]))
target = 'Tests/images/rectangle_surrounding_text.png' target = "Tests/images/rectangle_surrounding_text.png"
target_img = Image.open(target) target_img = Image.open(target)
# Epsilon ~.5 fails with FreeType 2.7 # Epsilon ~.5 fails with FreeType 2.7
self.assert_image_similar(im, target_img, self.metrics['textsize']) self.assert_image_similar(im, target_img, self.metrics["textsize"])
def test_render_multiline(self): def test_render_multiline(self):
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
ttf = self.get_font() ttf = self.get_font()
line_spacing = draw.textsize('A', font=ttf)[1] + 4 line_spacing = draw.textsize("A", font=ttf)[1] + 4
lines = TEST_TEXT.split("\n") lines = TEST_TEXT.split("\n")
y = 0 y = 0
for line in lines: for line in lines:
draw.text((0, y), line, font=ttf) draw.text((0, y), line, font=ttf)
y += line_spacing y += line_spacing
target = 'Tests/images/multiline_text.png' target = "Tests/images/multiline_text.png"
target_img = Image.open(target) target_img = Image.open(target)
# some versions of freetype have different horizontal spacing. # some versions of freetype have different horizontal spacing.
# setting a tight epsilon, I'm showing the original test failure # setting a tight epsilon, I'm showing the original test failure
# at epsilon = ~38. # at epsilon = ~38.
self.assert_image_similar(im, target_img, self.metrics['multiline']) self.assert_image_similar(im, target_img, self.metrics["multiline"])
def test_render_multiline_text(self): def test_render_multiline_text(self):
ttf = self.get_font() ttf = self.get_font()
# Test that text() correctly connects to multiline_text() # Test that text() correctly connects to multiline_text()
# and that align defaults to left # and that align defaults to left
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), TEST_TEXT, font=ttf) draw.text((0, 0), TEST_TEXT, font=ttf)
target = 'Tests/images/multiline_text.png' target = "Tests/images/multiline_text.png"
target_img = Image.open(target) target_img = Image.open(target)
# Epsilon ~.5 fails with FreeType 2.7 # Epsilon ~.5 fails with FreeType 2.7
self.assert_image_similar(im, target_img, self.metrics['multiline']) self.assert_image_similar(im, target_img, self.metrics["multiline"])
# Test that text() can pass on additional arguments # Test that text() can pass on additional arguments
# to multiline_text() # to multiline_text()
draw.text((0, 0), TEST_TEXT, fill=None, font=ttf, anchor=None, draw.text(
spacing=4, align="left") (0, 0), TEST_TEXT, fill=None, font=ttf, anchor=None, spacing=4, align="left"
)
draw.text((0, 0), TEST_TEXT, None, ttf, None, 4, "left") draw.text((0, 0), TEST_TEXT, None, ttf, None, 4, "left")
# Test align center and right # Test align center and right
for align, ext in {"center": "_center", for align, ext in {"center": "_center", "right": "_right"}.items():
"right": "_right"}.items(): im = Image.new(mode="RGB", size=(300, 100))
im = Image.new(mode='RGB', size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.multiline_text((0, 0), TEST_TEXT, font=ttf, align=align) draw.multiline_text((0, 0), TEST_TEXT, font=ttf, align=align)
target = 'Tests/images/multiline_text'+ext+'.png' target = "Tests/images/multiline_text" + ext + ".png"
target_img = Image.open(target) target_img = Image.open(target)
# Epsilon ~.5 fails with FreeType 2.7 # Epsilon ~.5 fails with FreeType 2.7
self.assert_image_similar(im, target_img, self.assert_image_similar(im, target_img, self.metrics["multiline"])
self.metrics['multiline'])
def test_unknown_align(self): def test_unknown_align(self):
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
ttf = self.get_font() ttf = self.get_font()
# Act/Assert # Act/Assert
self.assertRaises( self.assertRaises(
ValueError, ValueError,
draw.multiline_text, (0, 0), TEST_TEXT, font=ttf, align="unknown") draw.multiline_text,
(0, 0),
TEST_TEXT,
font=ttf,
align="unknown",
)
def test_draw_align(self): def test_draw_align(self):
im = Image.new('RGB', (300, 100), 'white') im = Image.new("RGB", (300, 100), "white")
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
ttf = self.get_font() ttf = self.get_font()
line = "some text" line = "some text"
draw.text((100, 40), line, (0, 0, 0), font=ttf, align='left') draw.text((100, 40), line, (0, 0, 0), font=ttf, align="left")
def test_multiline_size(self): def test_multiline_size(self):
ttf = self.get_font() ttf = self.get_font()
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
# Test that textsize() correctly connects to multiline_textsize() # Test that textsize() correctly connects to multiline_textsize()
self.assertEqual(draw.textsize(TEST_TEXT, font=ttf), self.assertEqual(
draw.multiline_textsize(TEST_TEXT, font=ttf)) draw.textsize(TEST_TEXT, font=ttf),
draw.multiline_textsize(TEST_TEXT, font=ttf),
)
# Test that multiline_textsize corresponds to ImageFont.textsize() # Test that multiline_textsize corresponds to ImageFont.textsize()
# for single line text # for single line text
self.assertEqual(ttf.getsize('A'), self.assertEqual(ttf.getsize("A"), draw.multiline_textsize("A", font=ttf))
draw.multiline_textsize('A', font=ttf))
# Test that textsize() can pass on additional arguments # Test that textsize() can pass on additional arguments
# to multiline_textsize() # to multiline_textsize()
@ -281,25 +280,26 @@ class TestImageFont(PillowTestCase):
def test_multiline_width(self): def test_multiline_width(self):
ttf = self.get_font() ttf = self.get_font()
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
self.assertEqual(draw.textsize("longest line", font=ttf)[0], self.assertEqual(
draw.multiline_textsize("longest line\nline", draw.textsize("longest line", font=ttf)[0],
font=ttf)[0]) draw.multiline_textsize("longest line\nline", font=ttf)[0],
)
def test_multiline_spacing(self): def test_multiline_spacing(self):
ttf = self.get_font() ttf = self.get_font()
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.multiline_text((0, 0), TEST_TEXT, font=ttf, spacing=10) draw.multiline_text((0, 0), TEST_TEXT, font=ttf, spacing=10)
target = 'Tests/images/multiline_text_spacing.png' target = "Tests/images/multiline_text_spacing.png"
target_img = Image.open(target) target_img = Image.open(target)
# Epsilon ~.5 fails with FreeType 2.7 # Epsilon ~.5 fails with FreeType 2.7
self.assert_image_similar(im, target_img, self.metrics['multiline']) self.assert_image_similar(im, target_img, self.metrics["multiline"])
def test_rotated_transposed_font(self): def test_rotated_transposed_font(self):
img_grey = Image.new("L", (100, 100)) img_grey = Image.new("L", (100, 100))
@ -308,8 +308,7 @@ class TestImageFont(PillowTestCase):
font = self.get_font() font = self.get_font()
orientation = Image.ROTATE_90 orientation = Image.ROTATE_90
transposed_font = ImageFont.TransposedFont( transposed_font = ImageFont.TransposedFont(font, orientation=orientation)
font, orientation=orientation)
# Original font # Original font
draw.font = font draw.font = font
@ -330,8 +329,7 @@ class TestImageFont(PillowTestCase):
font = self.get_font() font = self.get_font()
orientation = None orientation = None
transposed_font = ImageFont.TransposedFont( transposed_font = ImageFont.TransposedFont(font, orientation=orientation)
font, orientation=orientation)
# Original font # Original font
draw.font = font draw.font = font
@ -349,8 +347,7 @@ class TestImageFont(PillowTestCase):
text = "mask this" text = "mask this"
font = self.get_font() font = self.get_font()
orientation = Image.ROTATE_90 orientation = Image.ROTATE_90
transposed_font = ImageFont.TransposedFont( transposed_font = ImageFont.TransposedFont(font, orientation=orientation)
font, orientation=orientation)
# Act # Act
mask = transposed_font.getmask(text) mask = transposed_font.getmask(text)
@ -363,8 +360,7 @@ class TestImageFont(PillowTestCase):
text = "mask this" text = "mask this"
font = self.get_font() font = self.get_font()
orientation = None orientation = None
transposed_font = ImageFont.TransposedFont( transposed_font = ImageFont.TransposedFont(font, orientation=orientation)
font, orientation=orientation)
# Act # Act
mask = transposed_font.getmask(text) mask = transposed_font.getmask(text)
@ -380,7 +376,7 @@ class TestImageFont(PillowTestCase):
name = font.getname() name = font.getname()
# Assert # Assert
self.assertEqual(('FreeMono', 'Regular'), name) self.assertEqual(("FreeMono", "Regular"), name)
def test_free_type_font_get_metrics(self): def test_free_type_font_get_metrics(self):
# Arrange # Arrange
@ -427,10 +423,10 @@ class TestImageFont(PillowTestCase):
def test_default_font(self): def test_default_font(self):
# Arrange # Arrange
txt = 'This is a "better than nothing" default font.' txt = 'This is a "better than nothing" default font.'
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
target = 'Tests/images/default_font.png' target = "Tests/images/default_font.png"
target_img = Image.open(target) target_img = Image.open(target)
# Act # Act
@ -444,16 +440,16 @@ class TestImageFont(PillowTestCase):
# issue #2614 # issue #2614
font = self.get_font() font = self.get_font()
# should not crash. # should not crash.
self.assertEqual((0, 0), font.getsize('')) self.assertEqual((0, 0), font.getsize(""))
def test_render_empty(self): def test_render_empty(self):
# issue 2666 # issue 2666
font = self.get_font() font = self.get_font()
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
target = im.copy() target = im.copy()
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
# should not crash here. # should not crash here.
draw.text((10, 10), '', font=font) draw.text((10, 10), "", font=font)
self.assert_image_equal(im, target) self.assert_image_equal(im, target)
def test_unicode_pilfont(self): def test_unicode_pilfont(self):
@ -466,76 +462,99 @@ class TestImageFont(PillowTestCase):
def _test_fake_loading_font(self, path_to_fake, fontname): def _test_fake_loading_font(self, path_to_fake, fontname):
# Make a copy of FreeTypeFont so we can patch the original # Make a copy of FreeTypeFont so we can patch the original
free_type_font = copy.deepcopy(ImageFont.FreeTypeFont) free_type_font = copy.deepcopy(ImageFont.FreeTypeFont)
with SimplePatcher(ImageFont, '_FreeTypeFont', free_type_font): with SimplePatcher(ImageFont, "_FreeTypeFont", free_type_font):
def loadable_font(filepath, size, index, encoding,
*args, **kwargs): def loadable_font(filepath, size, index, encoding, *args, **kwargs):
if filepath == path_to_fake: if filepath == path_to_fake:
return ImageFont._FreeTypeFont(FONT_PATH, size, index, return ImageFont._FreeTypeFont(
encoding, *args, **kwargs) FONT_PATH, size, index, encoding, *args, **kwargs
return ImageFont._FreeTypeFont(filepath, size, index, )
encoding, *args, **kwargs) return ImageFont._FreeTypeFont(
with SimplePatcher(ImageFont, 'FreeTypeFont', loadable_font): filepath, size, index, encoding, *args, **kwargs
)
with SimplePatcher(ImageFont, "FreeTypeFont", loadable_font):
font = ImageFont.truetype(fontname) font = ImageFont.truetype(fontname)
# Make sure it's loaded # Make sure it's loaded
name = font.getname() name = font.getname()
self.assertEqual(('FreeMono', 'Regular'), name) self.assertEqual(("FreeMono", "Regular"), name)
@unittest.skipIf(sys.platform.startswith('win32'), @unittest.skipIf(sys.platform.startswith("win32"), "requires Unix or macOS")
"requires Unix or macOS")
def test_find_linux_font(self): def test_find_linux_font(self):
# A lot of mocking here - this is more for hitting code and # A lot of mocking here - this is more for hitting code and
# catching syntax like errors # catching syntax like errors
font_directory = '/usr/local/share/fonts' font_directory = "/usr/local/share/fonts"
with SimplePatcher(sys, 'platform', 'linux'): with SimplePatcher(sys, "platform", "linux"):
patched_env = copy.deepcopy(os.environ) patched_env = copy.deepcopy(os.environ)
patched_env['XDG_DATA_DIRS'] = '/usr/share/:/usr/local/share/' patched_env["XDG_DATA_DIRS"] = "/usr/share/:/usr/local/share/"
with SimplePatcher(os, 'environ', patched_env): with SimplePatcher(os, "environ", patched_env):
def fake_walker(path): def fake_walker(path):
if path == font_directory: if path == font_directory:
return [(path, [], [ return [
'Arial.ttf', 'Single.otf', 'Duplicate.otf', (
'Duplicate.ttf'], )] path,
return [(path, [], ['some_random_font.ttf'], )] [],
with SimplePatcher(os, 'walk', fake_walker): [
"Arial.ttf",
"Single.otf",
"Duplicate.otf",
"Duplicate.ttf",
],
)
]
return [(path, [], ["some_random_font.ttf"])]
with SimplePatcher(os, "walk", fake_walker):
# Test that the font loads both with and without the # Test that the font loads both with and without the
# extension # extension
self._test_fake_loading_font( self._test_fake_loading_font(
font_directory+'/Arial.ttf', 'Arial.ttf') font_directory + "/Arial.ttf", "Arial.ttf"
self._test_fake_loading_font( )
font_directory+'/Arial.ttf', 'Arial') self._test_fake_loading_font(font_directory + "/Arial.ttf", "Arial")
# Test that non-ttf fonts can be found without the # Test that non-ttf fonts can be found without the
# extension # extension
self._test_fake_loading_font( self._test_fake_loading_font(
font_directory+'/Single.otf', 'Single') font_directory + "/Single.otf", "Single"
)
# Test that ttf fonts are preferred if the extension is # Test that ttf fonts are preferred if the extension is
# not specified # not specified
self._test_fake_loading_font( self._test_fake_loading_font(
font_directory+'/Duplicate.ttf', 'Duplicate') font_directory + "/Duplicate.ttf", "Duplicate"
)
@unittest.skipIf(sys.platform.startswith('win32'), @unittest.skipIf(sys.platform.startswith("win32"), "requires Unix or macOS")
"requires Unix or macOS")
def test_find_macos_font(self): def test_find_macos_font(self):
# Like the linux test, more cover hitting code rather than testing # Like the linux test, more cover hitting code rather than testing
# correctness. # correctness.
font_directory = '/System/Library/Fonts' font_directory = "/System/Library/Fonts"
with SimplePatcher(sys, 'platform', 'darwin'): with SimplePatcher(sys, "platform", "darwin"):
def fake_walker(path): def fake_walker(path):
if path == font_directory: if path == font_directory:
return [(path, [], return [
['Arial.ttf', 'Single.otf', (
'Duplicate.otf', 'Duplicate.ttf'], )] path,
return [(path, [], ['some_random_font.ttf'], )] [],
with SimplePatcher(os, 'walk', fake_walker): [
"Arial.ttf",
"Single.otf",
"Duplicate.otf",
"Duplicate.ttf",
],
)
]
return [(path, [], ["some_random_font.ttf"])]
with SimplePatcher(os, "walk", fake_walker):
self._test_fake_loading_font(font_directory + "/Arial.ttf", "Arial.ttf")
self._test_fake_loading_font(font_directory + "/Arial.ttf", "Arial")
self._test_fake_loading_font(font_directory + "/Single.otf", "Single")
self._test_fake_loading_font( self._test_fake_loading_font(
font_directory+'/Arial.ttf', 'Arial.ttf') font_directory + "/Duplicate.ttf", "Duplicate"
self._test_fake_loading_font( )
font_directory+'/Arial.ttf', 'Arial')
self._test_fake_loading_font(
font_directory+'/Single.otf', 'Single')
self._test_fake_loading_font(
font_directory+'/Duplicate.ttf', 'Duplicate')
def test_imagefont_getters(self): def test_imagefont_getters(self):
# Arrange # Arrange
@ -549,26 +568,26 @@ class TestImageFont(PillowTestCase):
self.assertEqual(t.font.x_ppem, 20) self.assertEqual(t.font.x_ppem, 20)
self.assertEqual(t.font.y_ppem, 20) self.assertEqual(t.font.y_ppem, 20)
self.assertEqual(t.font.glyphs, 4177) self.assertEqual(t.font.glyphs, 4177)
self.assertEqual(t.getsize('A'), (12, 16)) self.assertEqual(t.getsize("A"), (12, 16))
self.assertEqual(t.getsize('AB'), (24, 16)) self.assertEqual(t.getsize("AB"), (24, 16))
self.assertEqual(t.getsize('M'), self.metrics['getters']) self.assertEqual(t.getsize("M"), self.metrics["getters"])
self.assertEqual(t.getsize('y'), (12, 20)) self.assertEqual(t.getsize("y"), (12, 20))
self.assertEqual(t.getsize('a'), (12, 16)) self.assertEqual(t.getsize("a"), (12, 16))
self.assertEqual(t.getsize_multiline('A'), (12, 16)) self.assertEqual(t.getsize_multiline("A"), (12, 16))
self.assertEqual(t.getsize_multiline('AB'), (24, 16)) self.assertEqual(t.getsize_multiline("AB"), (24, 16))
self.assertEqual(t.getsize_multiline('a'), (12, 16)) self.assertEqual(t.getsize_multiline("a"), (12, 16))
self.assertEqual(t.getsize_multiline('ABC\n'), (36, 36)) self.assertEqual(t.getsize_multiline("ABC\n"), (36, 36))
self.assertEqual(t.getsize_multiline('ABC\nA'), (36, 36)) self.assertEqual(t.getsize_multiline("ABC\nA"), (36, 36))
self.assertEqual(t.getsize_multiline('ABC\nAaaa'), (48, 36)) self.assertEqual(t.getsize_multiline("ABC\nAaaa"), (48, 36))
def test_complex_font_settings(self): def test_complex_font_settings(self):
# Arrange # Arrange
t = self.get_font() t = self.get_font()
# Act / Assert # Act / Assert
if t.layout_engine == ImageFont.LAYOUT_BASIC: if t.layout_engine == ImageFont.LAYOUT_BASIC:
self.assertRaises(KeyError, t.getmask, 'абвг', direction='rtl') self.assertRaises(KeyError, t.getmask, "абвг", direction="rtl")
self.assertRaises(KeyError, t.getmask, 'абвг', features=['-kern']) self.assertRaises(KeyError, t.getmask, "абвг", features=["-kern"])
self.assertRaises(KeyError, t.getmask, 'абвг', language='sr') self.assertRaises(KeyError, t.getmask, "абвг", language="sr")
@unittest.skipUnless(HAS_RAQM, "Raqm not Available") @unittest.skipUnless(HAS_RAQM, "Raqm not Available")

View File

@ -12,16 +12,18 @@ except ImportError:
@unittest.skipIf(not image_font_installed, "image font not installed") @unittest.skipIf(not image_font_installed, "image font not installed")
class TestImageFontBitmap(PillowTestCase): class TestImageFontBitmap(PillowTestCase):
def test_similar(self): def test_similar(self):
text = 'EmbeddedBitmap' text = "EmbeddedBitmap"
font_outline = ImageFont.truetype( font_outline = ImageFont.truetype(font="Tests/fonts/DejaVuSans.ttf", size=24)
font='Tests/fonts/DejaVuSans.ttf', size=24)
font_bitmap = ImageFont.truetype( font_bitmap = ImageFont.truetype(
font='Tests/fonts/DejaVuSans-bitmap.ttf', size=24) font="Tests/fonts/DejaVuSans-bitmap.ttf", size=24
)
size_outline = font_outline.getsize(text) size_outline = font_outline.getsize(text)
size_bitmap = font_bitmap.getsize(text) size_bitmap = font_bitmap.getsize(text)
size_final = (max(size_outline[0], size_bitmap[0]), size_final = (
max(size_outline[1], size_bitmap[1])) max(size_outline[0], size_bitmap[0]),
im_bitmap = Image.new('RGB', size_final, (255, 255, 255)) max(size_outline[1], size_bitmap[1]),
)
im_bitmap = Image.new("RGB", size_final, (255, 255, 255))
im_outline = im_bitmap.copy() im_outline = im_bitmap.copy()
draw_bitmap = ImageDraw.Draw(im_bitmap) draw_bitmap = ImageDraw.Draw(im_bitmap)
draw_outline = ImageDraw.Draw(im_outline) draw_outline = ImageDraw.Draw(im_outline)
@ -29,8 +31,13 @@ class TestImageFontBitmap(PillowTestCase):
# Metrics are different on the bitmap and ttf fonts, # Metrics are different on the bitmap and ttf fonts,
# more so on some platforms and versions of freetype than others. # more so on some platforms and versions of freetype than others.
# Mac has a 1px difference, linux doesn't. # Mac has a 1px difference, linux doesn't.
draw_bitmap.text((0, size_final[1] - size_bitmap[1]), draw_bitmap.text(
text, fill=(0, 0, 0), font=font_bitmap) (0, size_final[1] - size_bitmap[1]), text, fill=(0, 0, 0), font=font_bitmap
draw_outline.text((0, size_final[1] - size_outline[1]), )
text, fill=(0, 0, 0), font=font_outline) draw_outline.text(
(0, size_final[1] - size_outline[1]),
text,
fill=(0, 0, 0),
font=font_outline,
)
self.assert_image_similar(im_bitmap, im_outline, 20) self.assert_image_similar(im_bitmap, im_outline, 20)

View File

@ -7,37 +7,35 @@ FONT_SIZE = 20
FONT_PATH = "Tests/fonts/DejaVuSans.ttf" FONT_PATH = "Tests/fonts/DejaVuSans.ttf"
@unittest.skipUnless(features.check('raqm'), "Raqm Library is not installed.") @unittest.skipUnless(features.check("raqm"), "Raqm Library is not installed.")
class TestImagecomplextext(PillowTestCase): class TestImagecomplextext(PillowTestCase):
def test_english(self): def test_english(self):
# smoke test, this should not fail # smoke test, this should not fail
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'TEST', font=ttf, fill=500, direction='ltr') draw.text((0, 0), "TEST", font=ttf, fill=500, direction="ltr")
def test_complex_text(self): def test_complex_text(self):
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'اهلا عمان', font=ttf, fill=500) draw.text((0, 0), "اهلا عمان", font=ttf, fill=500)
target = 'Tests/images/test_text.png' target = "Tests/images/test_text.png"
target_img = Image.open(target) target_img = Image.open(target)
self.assert_image_similar(im, target_img, .5) self.assert_image_similar(im, target_img, 0.5)
def test_y_offset(self): def test_y_offset(self):
ttf = ImageFont.truetype("Tests/fonts/NotoNastaliqUrdu-Regular.ttf", ttf = ImageFont.truetype("Tests/fonts/NotoNastaliqUrdu-Regular.ttf", FONT_SIZE)
FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'العالم العربي', font=ttf, fill=500) draw.text((0, 0), "العالم العربي", font=ttf, fill=500)
target = 'Tests/images/test_y_offset.png' target = "Tests/images/test_y_offset.png"
target_img = Image.open(target) target_img = Image.open(target)
self.assert_image_similar(im, target_img, 1.7) self.assert_image_similar(im, target_img, 1.7)
@ -45,23 +43,22 @@ class TestImagecomplextext(PillowTestCase):
def test_complex_unicode_text(self): def test_complex_unicode_text(self):
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'السلام عليكم', font=ttf, fill=500) draw.text((0, 0), "السلام عليكم", font=ttf, fill=500)
target = 'Tests/images/test_complex_unicode_text.png' target = "Tests/images/test_complex_unicode_text.png"
target_img = Image.open(target) target_img = Image.open(target)
self.assert_image_similar(im, target_img, .5) self.assert_image_similar(im, target_img, 0.5)
ttf = ImageFont.truetype("Tests/fonts/KhmerOSBattambang-Regular.ttf", ttf = ImageFont.truetype("Tests/fonts/KhmerOSBattambang-Regular.ttf", FONT_SIZE)
FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'លោកុប្បត្តិ', font=ttf, fill=500) draw.text((0, 0), "លោកុប្បត្តិ", font=ttf, fill=500)
target = 'Tests/images/test_complex_unicode_text2.png' target = "Tests/images/test_complex_unicode_text2.png"
target_img = Image.open(target) target_img = Image.open(target)
self.assert_image_similar(im, target_img, 2.3) self.assert_image_similar(im, target_img, 2.3)
@ -69,89 +66,91 @@ class TestImagecomplextext(PillowTestCase):
def test_text_direction_rtl(self): def test_text_direction_rtl(self):
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'English عربي', font=ttf, fill=500, direction='rtl') draw.text((0, 0), "English عربي", font=ttf, fill=500, direction="rtl")
target = 'Tests/images/test_direction_rtl.png' target = "Tests/images/test_direction_rtl.png"
target_img = Image.open(target) target_img = Image.open(target)
self.assert_image_similar(im, target_img, .5) self.assert_image_similar(im, target_img, 0.5)
def test_text_direction_ltr(self): def test_text_direction_ltr(self):
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'سلطنة عمان Oman', draw.text((0, 0), "سلطنة عمان Oman", font=ttf, fill=500, direction="ltr")
font=ttf, fill=500, direction='ltr')
target = 'Tests/images/test_direction_ltr.png' target = "Tests/images/test_direction_ltr.png"
target_img = Image.open(target) target_img = Image.open(target)
self.assert_image_similar(im, target_img, .5) self.assert_image_similar(im, target_img, 0.5)
def test_text_direction_rtl2(self): def test_text_direction_rtl2(self):
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'Oman سلطنة عمان', draw.text((0, 0), "Oman سلطنة عمان", font=ttf, fill=500, direction="rtl")
font=ttf, fill=500, direction='rtl')
target = 'Tests/images/test_direction_ltr.png' target = "Tests/images/test_direction_ltr.png"
target_img = Image.open(target) target_img = Image.open(target)
self.assert_image_similar(im, target_img, .5) self.assert_image_similar(im, target_img, 0.5)
def test_ligature_features(self): def test_ligature_features(self):
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'filling', font=ttf, fill=500, features=['-liga']) draw.text((0, 0), "filling", font=ttf, fill=500, features=["-liga"])
target = 'Tests/images/test_ligature_features.png' target = "Tests/images/test_ligature_features.png"
target_img = Image.open(target) target_img = Image.open(target)
self.assert_image_similar(im, target_img, .5) self.assert_image_similar(im, target_img, 0.5)
liga_size = ttf.getsize('fi', features=['-liga']) liga_size = ttf.getsize("fi", features=["-liga"])
self.assertEqual(liga_size, (13, 19)) self.assertEqual(liga_size, (13, 19))
def test_kerning_features(self): def test_kerning_features(self):
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'TeToAV', font=ttf, fill=500, features=['-kern']) draw.text((0, 0), "TeToAV", font=ttf, fill=500, features=["-kern"])
target = 'Tests/images/test_kerning_features.png' target = "Tests/images/test_kerning_features.png"
target_img = Image.open(target) target_img = Image.open(target)
self.assert_image_similar(im, target_img, .5) self.assert_image_similar(im, target_img, 0.5)
def test_arabictext_features(self): def test_arabictext_features(self):
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'اللغة العربية', font=ttf, fill=500, draw.text(
features=['-fina', '-init', '-medi']) (0, 0),
"اللغة العربية",
font=ttf,
fill=500,
features=["-fina", "-init", "-medi"],
)
target = 'Tests/images/test_arabictext_features.png' target = "Tests/images/test_arabictext_features.png"
target_img = Image.open(target) target_img = Image.open(target)
self.assert_image_similar(im, target_img, .5) self.assert_image_similar(im, target_img, 0.5)
def test_language(self): def test_language(self):
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode='RGB', size=(300, 100)) im = Image.new(mode="RGB", size=(300, 100))
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), 'абвг', font=ttf, fill=500, draw.text((0, 0), "абвг", font=ttf, fill=500, language="sr")
language='sr')
target = 'Tests/images/test_language.png' target = "Tests/images/test_language.png"
target_img = Image.open(target) target_img = Image.open(target)
self.assert_image_similar(im, target_img, .5) self.assert_image_similar(im, target_img, 0.5)

View File

@ -7,37 +7,37 @@ try:
from PIL import ImageGrab from PIL import ImageGrab
class TestImageGrab(PillowTestCase): class TestImageGrab(PillowTestCase):
def test_grab(self): def test_grab(self):
for im in [ for im in [ImageGrab.grab(), ImageGrab.grab(include_layered_windows=True)]:
ImageGrab.grab(),
ImageGrab.grab(include_layered_windows=True)
]:
self.assert_image(im, im.mode, im.size) self.assert_image(im, im.mode, im.size)
def test_grabclipboard(self): def test_grabclipboard(self):
if sys.platform == "darwin": if sys.platform == "darwin":
subprocess.call(['screencapture', '-cx']) subprocess.call(["screencapture", "-cx"])
else: else:
p = subprocess.Popen(['powershell', '-command', '-'], p = subprocess.Popen(
stdin=subprocess.PIPE) ["powershell", "-command", "-"], stdin=subprocess.PIPE
p.stdin.write(b'''[Reflection.Assembly]::LoadWithPartialName("System.Drawing") )
p.stdin.write(
b"""[Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$bmp = New-Object Drawing.Bitmap 200, 200 $bmp = New-Object Drawing.Bitmap 200, 200
[Windows.Forms.Clipboard]::SetImage($bmp)''') [Windows.Forms.Clipboard]::SetImage($bmp)"""
)
p.communicate() p.communicate()
im = ImageGrab.grabclipboard() im = ImageGrab.grabclipboard()
self.assert_image(im, im.mode, im.size) self.assert_image(im, im.mode, im.size)
except ImportError: except ImportError:
class TestImageGrab(PillowTestCase): class TestImageGrab(PillowTestCase):
def test_skip(self): def test_skip(self):
self.skipTest("ImportError") self.skipTest("ImportError")
class TestImageGrabImport(PillowTestCase): class TestImageGrabImport(PillowTestCase):
def test_import(self): def test_import(self):
# Arrange # Arrange
exception = None exception = None
@ -45,6 +45,7 @@ class TestImageGrabImport(PillowTestCase):
# Act # Act
try: try:
from PIL import ImageGrab from PIL import ImageGrab
ImageGrab.__name__ # dummy to prevent Pyflakes warning ImageGrab.__name__ # dummy to prevent Pyflakes warning
except Exception as e: except Exception as e:
exception = e exception = e
@ -54,5 +55,4 @@ class TestImageGrabImport(PillowTestCase):
self.assertIsNone(exception) self.assertIsNone(exception)
else: else:
self.assertIsInstance(exception, ImportError) self.assertIsInstance(exception, ImportError)
self.assertEqual(str(exception), self.assertEqual(str(exception), "ImageGrab is macOS and Windows only")
"ImageGrab is macOS and Windows only")

View File

@ -27,15 +27,13 @@ images = {"A": A, "B": B, "F": F, "I": I}
class TestImageMath(PillowTestCase): class TestImageMath(PillowTestCase):
def test_sanity(self): def test_sanity(self):
self.assertEqual(ImageMath.eval("1"), 1) self.assertEqual(ImageMath.eval("1"), 1)
self.assertEqual(ImageMath.eval("1+A", A=2), 3) self.assertEqual(ImageMath.eval("1+A", A=2), 3)
self.assertEqual(pixel(ImageMath.eval("A+B", A=A, B=B)), "I 3") self.assertEqual(pixel(ImageMath.eval("A+B", A=A, B=B)), "I 3")
self.assertEqual(pixel(ImageMath.eval("A+B", images)), "I 3") self.assertEqual(pixel(ImageMath.eval("A+B", images)), "I 3")
self.assertEqual(pixel(ImageMath.eval("float(A)+B", images)), "F 3.0") self.assertEqual(pixel(ImageMath.eval("float(A)+B", images)), "F 3.0")
self.assertEqual(pixel( self.assertEqual(pixel(ImageMath.eval("int(float(A)+B)", images)), "I 3")
ImageMath.eval("int(float(A)+B)", images)), "I 3")
def test_ops(self): def test_ops(self):
@ -47,16 +45,16 @@ class TestImageMath(PillowTestCase):
self.assertEqual(pixel(ImageMath.eval("A*B", images)), "I 2") self.assertEqual(pixel(ImageMath.eval("A*B", images)), "I 2")
self.assertEqual(pixel(ImageMath.eval("A/B", images)), "I 0") self.assertEqual(pixel(ImageMath.eval("A/B", images)), "I 0")
self.assertEqual(pixel(ImageMath.eval("B**2", images)), "I 4") self.assertEqual(pixel(ImageMath.eval("B**2", images)), "I 4")
self.assertEqual(pixel( self.assertEqual(pixel(ImageMath.eval("B**33", images)), "I 2147483647")
ImageMath.eval("B**33", images)), "I 2147483647")
self.assertEqual(pixel(ImageMath.eval("float(A)+B", images)), "F 3.0") self.assertEqual(pixel(ImageMath.eval("float(A)+B", images)), "F 3.0")
self.assertEqual(pixel(ImageMath.eval("float(A)-B", images)), "F -1.0") self.assertEqual(pixel(ImageMath.eval("float(A)-B", images)), "F -1.0")
self.assertEqual(pixel(ImageMath.eval("float(A)*B", images)), "F 2.0") self.assertEqual(pixel(ImageMath.eval("float(A)*B", images)), "F 2.0")
self.assertEqual(pixel(ImageMath.eval("float(A)/B", images)), "F 0.5") self.assertEqual(pixel(ImageMath.eval("float(A)/B", images)), "F 0.5")
self.assertEqual(pixel(ImageMath.eval("float(B)**2", images)), "F 4.0") self.assertEqual(pixel(ImageMath.eval("float(B)**2", images)), "F 4.0")
self.assertEqual(pixel( self.assertEqual(
ImageMath.eval("float(B)**33", images)), "F 8589934592.0") pixel(ImageMath.eval("float(B)**33", images)), "F 8589934592.0"
)
def test_logical(self): def test_logical(self):
self.assertEqual(pixel(ImageMath.eval("not A", images)), 0) self.assertEqual(pixel(ImageMath.eval("not A", images)), 0)
@ -64,12 +62,11 @@ class TestImageMath(PillowTestCase):
self.assertEqual(pixel(ImageMath.eval("A or B", images)), "L 1") self.assertEqual(pixel(ImageMath.eval("A or B", images)), "L 1")
def test_convert(self): def test_convert(self):
self.assertEqual(pixel( self.assertEqual(pixel(ImageMath.eval("convert(A+B, 'L')", images)), "L 3")
ImageMath.eval("convert(A+B, 'L')", images)), "L 3") self.assertEqual(pixel(ImageMath.eval("convert(A+B, '1')", images)), "1 0")
self.assertEqual(pixel( self.assertEqual(
ImageMath.eval("convert(A+B, '1')", images)), "1 0") pixel(ImageMath.eval("convert(A+B, 'RGB')", images)), "RGB (3, 3, 3)"
self.assertEqual(pixel( )
ImageMath.eval("convert(A+B, 'RGB')", images)), "RGB (3, 3, 3)")
def test_compare(self): def test_compare(self):
self.assertEqual(pixel(ImageMath.eval("min(A, B)", images)), "I 1") self.assertEqual(pixel(ImageMath.eval("min(A, B)", images)), "I 1")
@ -176,9 +173,6 @@ class TestImageMath(PillowTestCase):
self.assertEqual(pixel(ImageMath.eval("notequal(A, A)", A=A)), "I 0") self.assertEqual(pixel(ImageMath.eval("notequal(A, A)", A=A)), "I 0")
self.assertEqual(pixel(ImageMath.eval("notequal(B, B)", B=B)), "I 0") self.assertEqual(pixel(ImageMath.eval("notequal(B, B)", B=B)), "I 0")
self.assertEqual(pixel(ImageMath.eval("notequal(Z, Z)", Z=Z)), "I 0") self.assertEqual(pixel(ImageMath.eval("notequal(Z, Z)", Z=Z)), "I 0")
self.assertEqual( self.assertEqual(pixel(ImageMath.eval("notequal(A, B)", A=A, B=B)), "I 1")
pixel(ImageMath.eval("notequal(A, B)", A=A, B=B)), "I 1") self.assertEqual(pixel(ImageMath.eval("notequal(B, A)", A=A, B=B)), "I 1")
self.assertEqual( self.assertEqual(pixel(ImageMath.eval("notequal(A, Z)", A=A, Z=Z)), "I 1")
pixel(ImageMath.eval("notequal(B, A)", A=A, B=B)), "I 1")
self.assertEqual(
pixel(ImageMath.eval("notequal(A, Z)", A=A, Z=Z)), "I 1")

View File

@ -5,7 +5,6 @@ from PIL import Image, ImageMorph, _imagingmorph
class MorphTests(PillowTestCase): class MorphTests(PillowTestCase):
def setUp(self): def setUp(self):
self.A = self.string_to_img( self.A = self.string_to_img(
""" """
@ -21,23 +20,23 @@ class MorphTests(PillowTestCase):
def img_to_string(self, im): def img_to_string(self, im):
"""Turn a (small) binary image into a string representation""" """Turn a (small) binary image into a string representation"""
chars = '.1' chars = ".1"
width, height = im.size width, height = im.size
return '\n'.join( return "\n".join(
''.join(chars[im.getpixel((c, r)) > 0] for c in range(width)) "".join(chars[im.getpixel((c, r)) > 0] for c in range(width))
for r in range(height)) for r in range(height)
)
def string_to_img(self, image_string): def string_to_img(self, image_string):
"""Turn a string image representation into a binary image""" """Turn a string image representation into a binary image"""
rows = [s for s in image_string.replace(' ', '').split('\n') rows = [s for s in image_string.replace(" ", "").split("\n") if len(s)]
if len(s)]
height = len(rows) height = len(rows)
width = len(rows[0]) width = len(rows[0])
im = Image.new('L', (width, height)) im = Image.new("L", (width, height))
for i in range(width): for i in range(width):
for j in range(height): for j in range(height):
c = rows[j][i] c = rows[j][i]
v = c in 'X1' v = c in "X1"
im.putpixel((i, j), v) im.putpixel((i, j), v)
return im return im
@ -49,54 +48,49 @@ class MorphTests(PillowTestCase):
self.assertEqual(self.img_to_string(A), self.img_to_string(B)) self.assertEqual(self.img_to_string(A), self.img_to_string(B))
def assert_img_equal_img_string(self, A, Bstring): def assert_img_equal_img_string(self, A, Bstring):
self.assertEqual( self.assertEqual(self.img_to_string(A), self.img_string_normalize(Bstring))
self.img_to_string(A),
self.img_string_normalize(Bstring))
def test_str_to_img(self): def test_str_to_img(self):
im = Image.open('Tests/images/morph_a.png') im = Image.open("Tests/images/morph_a.png")
self.assert_image_equal(self.A, im) self.assert_image_equal(self.A, im)
def create_lut(self): def create_lut(self):
for op in ( for op in ("corner", "dilation4", "dilation8", "erosion4", "erosion8", "edge"):
'corner', 'dilation4', 'dilation8',
'erosion4', 'erosion8', 'edge'):
lb = ImageMorph.LutBuilder(op_name=op) lb = ImageMorph.LutBuilder(op_name=op)
lut = lb.build_lut() lut = lb.build_lut()
with open('Tests/images/%s.lut' % op, 'wb') as f: with open("Tests/images/%s.lut" % op, "wb") as f:
f.write(lut) f.write(lut)
# create_lut() # create_lut()
def test_lut(self): def test_lut(self):
for op in ( for op in ("corner", "dilation4", "dilation8", "erosion4", "erosion8", "edge"):
'corner', 'dilation4', 'dilation8',
'erosion4', 'erosion8', 'edge'):
lb = ImageMorph.LutBuilder(op_name=op) lb = ImageMorph.LutBuilder(op_name=op)
self.assertIsNone(lb.get_lut()) self.assertIsNone(lb.get_lut())
lut = lb.build_lut() lut = lb.build_lut()
with open('Tests/images/%s.lut' % op, 'rb') as f: with open("Tests/images/%s.lut" % op, "rb") as f:
self.assertEqual(lut, bytearray(f.read())) self.assertEqual(lut, bytearray(f.read()))
def test_no_operator_loaded(self): def test_no_operator_loaded(self):
mop = ImageMorph.MorphOp() mop = ImageMorph.MorphOp()
with self.assertRaises(Exception) as e: with self.assertRaises(Exception) as e:
mop.apply(None) mop.apply(None)
self.assertEqual(str(e.exception), 'No operator loaded') self.assertEqual(str(e.exception), "No operator loaded")
with self.assertRaises(Exception) as e: with self.assertRaises(Exception) as e:
mop.match(None) mop.match(None)
self.assertEqual(str(e.exception), 'No operator loaded') self.assertEqual(str(e.exception), "No operator loaded")
with self.assertRaises(Exception) as e: with self.assertRaises(Exception) as e:
mop.save_lut(None) mop.save_lut(None)
self.assertEqual(str(e.exception), 'No operator loaded') self.assertEqual(str(e.exception), "No operator loaded")
# Test the named patterns # Test the named patterns
def test_erosion8(self): def test_erosion8(self):
# erosion8 # erosion8
mop = ImageMorph.MorphOp(op_name='erosion8') mop = ImageMorph.MorphOp(op_name="erosion8")
count, Aout = mop.apply(self.A) count, Aout = mop.apply(self.A)
self.assertEqual(count, 8) self.assertEqual(count, 8)
self.assert_img_equal_img_string(Aout, self.assert_img_equal_img_string(
Aout,
""" """
....... .......
....... .......
@ -105,14 +99,16 @@ class MorphTests(PillowTestCase):
....... .......
....... .......
....... .......
""") """,
)
def test_dialation8(self): def test_dialation8(self):
# dialation8 # dialation8
mop = ImageMorph.MorphOp(op_name='dilation8') mop = ImageMorph.MorphOp(op_name="dilation8")
count, Aout = mop.apply(self.A) count, Aout = mop.apply(self.A)
self.assertEqual(count, 16) self.assertEqual(count, 16)
self.assert_img_equal_img_string(Aout, self.assert_img_equal_img_string(
Aout,
""" """
....... .......
.11111. .11111.
@ -121,14 +117,16 @@ class MorphTests(PillowTestCase):
.11111. .11111.
.11111. .11111.
....... .......
""") """,
)
def test_erosion4(self): def test_erosion4(self):
# erosion4 # erosion4
mop = ImageMorph.MorphOp(op_name='dilation4') mop = ImageMorph.MorphOp(op_name="dilation4")
count, Aout = mop.apply(self.A) count, Aout = mop.apply(self.A)
self.assertEqual(count, 12) self.assertEqual(count, 12)
self.assert_img_equal_img_string(Aout, self.assert_img_equal_img_string(
Aout,
""" """
....... .......
..111.. ..111..
@ -137,14 +135,16 @@ class MorphTests(PillowTestCase):
.11111. .11111.
..111.. ..111..
....... .......
""") """,
)
def test_edge(self): def test_edge(self):
# edge # edge
mop = ImageMorph.MorphOp(op_name='edge') mop = ImageMorph.MorphOp(op_name="edge")
count, Aout = mop.apply(self.A) count, Aout = mop.apply(self.A)
self.assertEqual(count, 1) self.assertEqual(count, 1)
self.assert_img_equal_img_string(Aout, self.assert_img_equal_img_string(
Aout,
""" """
....... .......
....... .......
@ -153,15 +153,16 @@ class MorphTests(PillowTestCase):
..111.. ..111..
....... .......
....... .......
""") """,
)
def test_corner(self): def test_corner(self):
# Create a corner detector pattern # Create a corner detector pattern
mop = ImageMorph.MorphOp(patterns=['1:(... ... ...)->0', mop = ImageMorph.MorphOp(patterns=["1:(... ... ...)->0", "4:(00. 01. ...)->1"])
'4:(00. 01. ...)->1'])
count, Aout = mop.apply(self.A) count, Aout = mop.apply(self.A)
self.assertEqual(count, 5) self.assertEqual(count, 5)
self.assert_img_equal_img_string(Aout, self.assert_img_equal_img_string(
Aout,
""" """
....... .......
....... .......
@ -170,7 +171,8 @@ class MorphTests(PillowTestCase):
..1.1.. ..1.1..
....... .......
....... .......
""") """,
)
# Test the coordinate counting with the same operator # Test the coordinate counting with the same operator
coords = mop.match(self.A) coords = mop.match(self.A)
@ -183,11 +185,11 @@ class MorphTests(PillowTestCase):
def test_mirroring(self): def test_mirroring(self):
# Test 'M' for mirroring # Test 'M' for mirroring
mop = ImageMorph.MorphOp(patterns=['1:(... ... ...)->0', mop = ImageMorph.MorphOp(patterns=["1:(... ... ...)->0", "M:(00. 01. ...)->1"])
'M:(00. 01. ...)->1'])
count, Aout = mop.apply(self.A) count, Aout = mop.apply(self.A)
self.assertEqual(count, 7) self.assertEqual(count, 7)
self.assert_img_equal_img_string(Aout, self.assert_img_equal_img_string(
Aout,
""" """
....... .......
....... .......
@ -196,15 +198,16 @@ class MorphTests(PillowTestCase):
....... .......
....... .......
....... .......
""") """,
)
def test_negate(self): def test_negate(self):
# Test 'N' for negate # Test 'N' for negate
mop = ImageMorph.MorphOp(patterns=['1:(... ... ...)->0', mop = ImageMorph.MorphOp(patterns=["1:(... ... ...)->0", "N:(00. 01. ...)->1"])
'N:(00. 01. ...)->1'])
count, Aout = mop.apply(self.A) count, Aout = mop.apply(self.A)
self.assertEqual(count, 8) self.assertEqual(count, 8)
self.assert_img_equal_img_string(Aout, self.assert_img_equal_img_string(
Aout,
""" """
....... .......
....... .......
@ -213,32 +216,34 @@ class MorphTests(PillowTestCase):
....... .......
....... .......
....... .......
""") """,
)
def test_non_binary_images(self): def test_non_binary_images(self):
im = hopper('RGB') im = hopper("RGB")
mop = ImageMorph.MorphOp(op_name="erosion8") mop = ImageMorph.MorphOp(op_name="erosion8")
with self.assertRaises(Exception) as e: with self.assertRaises(Exception) as e:
mop.apply(im) mop.apply(im)
self.assertEqual(str(e.exception), self.assertEqual(
'Image must be binary, meaning it must use mode L') str(e.exception), "Image must be binary, meaning it must use mode L"
)
with self.assertRaises(Exception) as e: with self.assertRaises(Exception) as e:
mop.match(im) mop.match(im)
self.assertEqual(str(e.exception), self.assertEqual(
'Image must be binary, meaning it must use mode L') str(e.exception), "Image must be binary, meaning it must use mode L"
)
with self.assertRaises(Exception) as e: with self.assertRaises(Exception) as e:
mop.get_on_pixels(im) mop.get_on_pixels(im)
self.assertEqual(str(e.exception), self.assertEqual(
'Image must be binary, meaning it must use mode L') str(e.exception), "Image must be binary, meaning it must use mode L"
)
def test_add_patterns(self): def test_add_patterns(self):
# Arrange # Arrange
lb = ImageMorph.LutBuilder(op_name='corner') lb = ImageMorph.LutBuilder(op_name="corner")
self.assertEqual(lb.patterns, ['1:(... ... ...)->0', self.assertEqual(lb.patterns, ["1:(... ... ...)->0", "4:(00. 01. ...)->1"])
'4:(00. 01. ...)->1']) new_patterns = ["M:(00. 01. ...)->1", "N:(00. 01. ...)->1"]
new_patterns = ['M:(00. 01. ...)->1',
'N:(00. 01. ...)->1']
# Act # Act
lb.add_patterns(new_patterns) lb.add_patterns(new_patterns)
@ -246,44 +251,44 @@ class MorphTests(PillowTestCase):
# Assert # Assert
self.assertEqual( self.assertEqual(
lb.patterns, lb.patterns,
['1:(... ... ...)->0', [
'4:(00. 01. ...)->1', "1:(... ... ...)->0",
'M:(00. 01. ...)->1', "4:(00. 01. ...)->1",
'N:(00. 01. ...)->1']) "M:(00. 01. ...)->1",
"N:(00. 01. ...)->1",
],
)
def test_unknown_pattern(self): def test_unknown_pattern(self):
self.assertRaises( self.assertRaises(Exception, ImageMorph.LutBuilder, op_name="unknown")
Exception,
ImageMorph.LutBuilder, op_name='unknown')
def test_pattern_syntax_error(self): def test_pattern_syntax_error(self):
# Arrange # Arrange
lb = ImageMorph.LutBuilder(op_name='corner') lb = ImageMorph.LutBuilder(op_name="corner")
new_patterns = ['a pattern with a syntax error'] new_patterns = ["a pattern with a syntax error"]
lb.add_patterns(new_patterns) lb.add_patterns(new_patterns)
# Act / Assert # Act / Assert
with self.assertRaises(Exception) as e: with self.assertRaises(Exception) as e:
lb.build_lut() lb.build_lut()
self.assertEqual( self.assertEqual(
str(e.exception), str(e.exception), 'Syntax error in pattern "a pattern with a syntax error"'
'Syntax error in pattern "a pattern with a syntax error"') )
def test_load_invalid_mrl(self): def test_load_invalid_mrl(self):
# Arrange # Arrange
invalid_mrl = 'Tests/images/hopper.png' invalid_mrl = "Tests/images/hopper.png"
mop = ImageMorph.MorphOp() mop = ImageMorph.MorphOp()
# Act / Assert # Act / Assert
with self.assertRaises(Exception) as e: with self.assertRaises(Exception) as e:
mop.load_lut(invalid_mrl) mop.load_lut(invalid_mrl)
self.assertEqual(str(e.exception), self.assertEqual(str(e.exception), "Wrong size operator file!")
'Wrong size operator file!')
def test_roundtrip_mrl(self): def test_roundtrip_mrl(self):
# Arrange # Arrange
tempfile = self.tempfile('temp.mrl') tempfile = self.tempfile("temp.mrl")
mop = ImageMorph.MorphOp(op_name='corner') mop = ImageMorph.MorphOp(op_name="corner")
initial_lut = mop.lut initial_lut = mop.lut
# Act # Act
@ -295,7 +300,7 @@ class MorphTests(PillowTestCase):
def test_set_lut(self): def test_set_lut(self):
# Arrange # Arrange
lb = ImageMorph.LutBuilder(op_name='corner') lb = ImageMorph.LutBuilder(op_name="corner")
lut = lb.build_lut() lut = lb.build_lut()
mop = ImageMorph.MorphOp() mop = ImageMorph.MorphOp()
@ -306,9 +311,9 @@ class MorphTests(PillowTestCase):
self.assertEqual(mop.lut, lut) self.assertEqual(mop.lut, lut)
def test_wrong_mode(self): def test_wrong_mode(self):
lut = ImageMorph.LutBuilder(op_name='corner').build_lut() lut = ImageMorph.LutBuilder(op_name="corner").build_lut()
imrgb = Image.new('RGB', (10, 10)) imrgb = Image.new("RGB", (10, 10))
iml = Image.new('L', (10, 10)) iml = Image.new("L", (10, 10))
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
_imagingmorph.apply(bytes(lut), imrgb.im.id, iml.im.id) _imagingmorph.apply(bytes(lut), imrgb.im.id, iml.im.id)

View File

@ -5,13 +5,13 @@ from PIL import ImageOps
try: try:
from PIL import _webp from PIL import _webp
HAVE_WEBP = True HAVE_WEBP = True
except ImportError: except ImportError:
HAVE_WEBP = False HAVE_WEBP = False
class TestImageOps(PillowTestCase): class TestImageOps(PillowTestCase):
class Deformer(object): class Deformer(object):
def getmesh(self, im): def getmesh(self, im):
x, y = im.size x, y = im.size
@ -91,15 +91,15 @@ class TestImageOps(PillowTestCase):
for label, color, new_size in [ for label, color, new_size in [
("h", None, (im.width * 4, im.height * 2)), ("h", None, (im.width * 4, im.height * 2)),
("v", "#f00", (im.width * 2, im.height * 4)) ("v", "#f00", (im.width * 2, im.height * 4)),
]: ]:
for i, centering in enumerate([(0, 0), (0.5, 0.5), (1, 1)]): for i, centering in enumerate([(0, 0), (0.5, 0.5), (1, 1)]):
new_im = ImageOps.pad(im, new_size, new_im = ImageOps.pad(im, new_size, color=color, centering=centering)
color=color, centering=centering)
self.assertEqual(new_im.size, new_size) self.assertEqual(new_im.size, new_size)
target = Image.open( target = Image.open(
"Tests/images/imageops_pad_"+label+"_"+str(i)+".jpg") "Tests/images/imageops_pad_" + label + "_" + str(i) + ".jpg"
)
self.assert_image_similar(new_im, target, 6) self.assert_image_similar(new_im, target, 6)
def test_pil163(self): def test_pil163(self):
@ -135,24 +135,30 @@ class TestImageOps(PillowTestCase):
im = im.convert("L") im = im.convert("L")
# Create image with original 2-color functionality # Create image with original 2-color functionality
im_test = ImageOps.colorize(im, 'red', 'green') im_test = ImageOps.colorize(im, "red", "green")
# Test output image (2-color) # Test output image (2-color)
left = (0, 1) left = (0, 1)
middle = (127, 1) middle = (127, 1)
right = (255, 1) right = (255, 1)
self.assert_tuple_approx_equal(im_test.getpixel(left), self.assert_tuple_approx_equal(
im_test.getpixel(left),
(255, 0, 0), (255, 0, 0),
threshold=1, threshold=1,
msg='black test pixel incorrect') msg="black test pixel incorrect",
self.assert_tuple_approx_equal(im_test.getpixel(middle), )
self.assert_tuple_approx_equal(
im_test.getpixel(middle),
(127, 63, 0), (127, 63, 0),
threshold=1, threshold=1,
msg='mid test pixel incorrect') msg="mid test pixel incorrect",
self.assert_tuple_approx_equal(im_test.getpixel(right), )
self.assert_tuple_approx_equal(
im_test.getpixel(right),
(0, 127, 0), (0, 127, 0),
threshold=1, threshold=1,
msg='white test pixel incorrect') msg="white test pixel incorrect",
)
def test_colorize_2color_offset(self): def test_colorize_2color_offset(self):
# Test the colorizing function with 2-color functionality and offset # Test the colorizing function with 2-color functionality and offset
@ -162,28 +168,32 @@ class TestImageOps(PillowTestCase):
im = im.convert("L") im = im.convert("L")
# Create image with original 2-color functionality with offsets # Create image with original 2-color functionality with offsets
im_test = ImageOps.colorize(im, im_test = ImageOps.colorize(
black='red', im, black="red", white="green", blackpoint=50, whitepoint=100
white='green', )
blackpoint=50,
whitepoint=100)
# Test output image (2-color) with offsets # Test output image (2-color) with offsets
left = (25, 1) left = (25, 1)
middle = (75, 1) middle = (75, 1)
right = (125, 1) right = (125, 1)
self.assert_tuple_approx_equal(im_test.getpixel(left), self.assert_tuple_approx_equal(
im_test.getpixel(left),
(255, 0, 0), (255, 0, 0),
threshold=1, threshold=1,
msg='black test pixel incorrect') msg="black test pixel incorrect",
self.assert_tuple_approx_equal(im_test.getpixel(middle), )
self.assert_tuple_approx_equal(
im_test.getpixel(middle),
(127, 63, 0), (127, 63, 0),
threshold=1, threshold=1,
msg='mid test pixel incorrect') msg="mid test pixel incorrect",
self.assert_tuple_approx_equal(im_test.getpixel(right), )
self.assert_tuple_approx_equal(
im_test.getpixel(right),
(0, 127, 0), (0, 127, 0),
threshold=1, threshold=1,
msg='white test pixel incorrect') msg="white test pixel incorrect",
)
def test_colorize_3color_offset(self): def test_colorize_3color_offset(self):
# Test the colorizing function with 3-color functionality and offset # Test the colorizing function with 3-color functionality and offset
@ -193,13 +203,15 @@ class TestImageOps(PillowTestCase):
im = im.convert("L") im = im.convert("L")
# Create image with new three color functionality with offsets # Create image with new three color functionality with offsets
im_test = ImageOps.colorize(im, im_test = ImageOps.colorize(
black='red', im,
white='green', black="red",
mid='blue', white="green",
mid="blue",
blackpoint=50, blackpoint=50,
whitepoint=200, whitepoint=200,
midpoint=100) midpoint=100,
)
# Test output image (3-color) with offsets # Test output image (3-color) with offsets
left = (25, 1) left = (25, 1)
@ -207,43 +219,47 @@ class TestImageOps(PillowTestCase):
middle = (100, 1) middle = (100, 1)
right_middle = (150, 1) right_middle = (150, 1)
right = (225, 1) right = (225, 1)
self.assert_tuple_approx_equal(im_test.getpixel(left), self.assert_tuple_approx_equal(
im_test.getpixel(left),
(255, 0, 0), (255, 0, 0),
threshold=1, threshold=1,
msg='black test pixel incorrect') msg="black test pixel incorrect",
self.assert_tuple_approx_equal(im_test.getpixel(left_middle), )
self.assert_tuple_approx_equal(
im_test.getpixel(left_middle),
(127, 0, 127), (127, 0, 127),
threshold=1, threshold=1,
msg='low-mid test pixel incorrect') msg="low-mid test pixel incorrect",
self.assert_tuple_approx_equal(im_test.getpixel(middle), )
(0, 0, 255), self.assert_tuple_approx_equal(
threshold=1, im_test.getpixel(middle), (0, 0, 255), threshold=1, msg="mid incorrect"
msg='mid incorrect') )
self.assert_tuple_approx_equal(im_test.getpixel(right_middle), self.assert_tuple_approx_equal(
im_test.getpixel(right_middle),
(0, 63, 127), (0, 63, 127),
threshold=1, threshold=1,
msg='high-mid test pixel incorrect') msg="high-mid test pixel incorrect",
self.assert_tuple_approx_equal(im_test.getpixel(right), )
self.assert_tuple_approx_equal(
im_test.getpixel(right),
(0, 127, 0), (0, 127, 0),
threshold=1, threshold=1,
msg='white test pixel incorrect') msg="white test pixel incorrect",
)
def test_exif_transpose(self): def test_exif_transpose(self):
exts = [".jpg"] exts = [".jpg"]
if HAVE_WEBP and _webp.HAVE_WEBPANIM: if HAVE_WEBP and _webp.HAVE_WEBPANIM:
exts.append(".webp") exts.append(".webp")
for ext in exts: for ext in exts:
base_im = Image.open("Tests/images/hopper"+ext) base_im = Image.open("Tests/images/hopper" + ext)
orientations = [base_im] orientations = [base_im]
for i in range(2, 9): for i in range(2, 9):
im = Image.open("Tests/images/hopper_orientation_"+str(i)+ext) im = Image.open("Tests/images/hopper_orientation_" + str(i) + ext)
orientations.append(im) orientations.append(im)
for i, orientation_im in enumerate(orientations): for i, orientation_im in enumerate(orientations):
for im in [ for im in [orientation_im, orientation_im.copy()]: # ImageFile # Image
orientation_im, # ImageFile
orientation_im.copy() # Image
]:
if i == 0: if i == 0:
self.assertNotIn("exif", im.info) self.assertNotIn("exif", im.info)
else: else:

View File

@ -8,7 +8,6 @@ snakes = Image.open("Tests/images/color_snakes.png")
class TestImageOpsUsm(PillowTestCase): class TestImageOpsUsm(PillowTestCase):
def test_filter_api(self): def test_filter_api(self):
test_filter = ImageFilter.GaussianBlur(2.0) test_filter = ImageFilter.GaussianBlur(2.0)
@ -47,24 +46,36 @@ class TestImageOpsUsm(PillowTestCase):
def test_usm_accuracy(self): def test_usm_accuracy(self):
src = snakes.convert('RGB') src = snakes.convert("RGB")
i = src.filter(ImageFilter.UnsharpMask(5, 1024, 0)) i = src.filter(ImageFilter.UnsharpMask(5, 1024, 0))
# Image should not be changed because it have only 0 and 255 levels. # Image should not be changed because it have only 0 and 255 levels.
self.assertEqual(i.tobytes(), src.tobytes()) self.assertEqual(i.tobytes(), src.tobytes())
def test_blur_accuracy(self): def test_blur_accuracy(self):
i = snakes.filter(ImageFilter.GaussianBlur(.4)) i = snakes.filter(ImageFilter.GaussianBlur(0.4))
# These pixels surrounded with pixels with 255 intensity. # These pixels surrounded with pixels with 255 intensity.
# They must be very close to 255. # They must be very close to 255.
for x, y, c in [(1, 0, 1), (2, 0, 1), (7, 8, 1), (8, 8, 1), (2, 9, 1), for x, y, c in [
(7, 3, 0), (8, 3, 0), (5, 8, 0), (5, 9, 0), (1, 3, 0), (1, 0, 1),
(4, 3, 2), (4, 2, 2)]: (2, 0, 1),
(7, 8, 1),
(8, 8, 1),
(2, 9, 1),
(7, 3, 0),
(8, 3, 0),
(5, 8, 0),
(5, 9, 0),
(1, 3, 0),
(4, 3, 2),
(4, 2, 2),
]:
self.assertGreaterEqual(i.im.getpixel((x, y))[c], 250) self.assertGreaterEqual(i.im.getpixel((x, y))[c], 250)
# Fuzzy match. # Fuzzy match.
def gp(x, y): def gp(x, y):
return i.im.getpixel((x, y)) return i.im.getpixel((x, y))
self.assertTrue(236 <= gp(7, 4)[0] <= 239) self.assertTrue(236 <= gp(7, 4)[0] <= 239)
self.assertTrue(236 <= gp(7, 5)[2] <= 239) self.assertTrue(236 <= gp(7, 5)[2] <= 239)
self.assertTrue(236 <= gp(7, 6)[2] <= 239) self.assertTrue(236 <= gp(7, 6)[2] <= 239)

View File

@ -4,12 +4,12 @@ from PIL import ImagePalette, Image
class TestImagePalette(PillowTestCase): class TestImagePalette(PillowTestCase):
def test_sanity(self): def test_sanity(self):
ImagePalette.ImagePalette("RGB", list(range(256))*3) ImagePalette.ImagePalette("RGB", list(range(256)) * 3)
self.assertRaises(ValueError, self.assertRaises(
ImagePalette.ImagePalette, "RGB", list(range(256))*2) ValueError, ImagePalette.ImagePalette, "RGB", list(range(256)) * 2
)
def test_getcolor(self): def test_getcolor(self):
@ -27,7 +27,7 @@ class TestImagePalette(PillowTestCase):
def test_file(self): def test_file(self):
palette = ImagePalette.ImagePalette("RGB", list(range(256))*3) palette = ImagePalette.ImagePalette("RGB", list(range(256)) * 3)
f = self.tempfile("temp.lut") f = self.tempfile("temp.lut")
@ -65,8 +65,9 @@ class TestImagePalette(PillowTestCase):
white = 255 white = 255
# Act # Act
self.assertRaises(NotImplementedError, self.assertRaises(
ImagePalette.make_linear_lut, black, white) NotImplementedError, ImagePalette.make_linear_lut, black, white
)
def test_make_gamma_lut(self): def test_make_gamma_lut(self):
# Arrange # Arrange
@ -87,7 +88,7 @@ class TestImagePalette(PillowTestCase):
def test_rawmode_valueerrors(self): def test_rawmode_valueerrors(self):
# Arrange # Arrange
palette = ImagePalette.raw("RGB", list(range(256))*3) palette = ImagePalette.raw("RGB", list(range(256)) * 3)
# Act / Assert # Act / Assert
self.assertRaises(ValueError, palette.tobytes) self.assertRaises(ValueError, palette.tobytes)
@ -97,7 +98,7 @@ class TestImagePalette(PillowTestCase):
def test_getdata(self): def test_getdata(self):
# Arrange # Arrange
data_in = list(range(256))*3 data_in = list(range(256)) * 3
palette = ImagePalette.ImagePalette("RGB", data_in) palette = ImagePalette.ImagePalette("RGB", data_in)
# Act # Act
@ -108,7 +109,7 @@ class TestImagePalette(PillowTestCase):
def test_rawmode_getdata(self): def test_rawmode_getdata(self):
# Arrange # Arrange
data_in = list(range(256))*3 data_in = list(range(256)) * 3
palette = ImagePalette.raw("RGB", data_in) palette = ImagePalette.raw("RGB", data_in)
# Act # Act
@ -120,17 +121,16 @@ class TestImagePalette(PillowTestCase):
def test_2bit_palette(self): def test_2bit_palette(self):
# issue #2258, 2 bit palettes are corrupted. # issue #2258, 2 bit palettes are corrupted.
outfile = self.tempfile('temp.png') outfile = self.tempfile("temp.png")
rgb = b'\x00' * 2 + b'\x01' * 2 + b'\x02' * 2 rgb = b"\x00" * 2 + b"\x01" * 2 + b"\x02" * 2
img = Image.frombytes('P', (6, 1), rgb) img = Image.frombytes("P", (6, 1), rgb)
img.putpalette(b'\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF') # RGB img.putpalette(b"\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF") # RGB
img.save(outfile, format='PNG') img.save(outfile, format="PNG")
reloaded = Image.open(outfile) reloaded = Image.open(outfile)
self.assert_image_equal(img, reloaded) self.assert_image_equal(img, reloaded)
def test_invalid_palette(self): def test_invalid_palette(self):
self.assertRaises(IOError, self.assertRaises(IOError, ImagePalette.load, "Tests/images/hopper.jpg")
ImagePalette.load, "Tests/images/hopper.jpg")

View File

@ -8,7 +8,6 @@ import struct
class TestImagePath(PillowTestCase): class TestImagePath(PillowTestCase):
def test_path(self): def test_path(self):
p = ImagePath.Path(list(range(10))) p = ImagePath.Path(list(range(10)))
@ -19,21 +18,19 @@ class TestImagePath(PillowTestCase):
self.assertEqual(p[-1], (8.0, 9.0)) self.assertEqual(p[-1], (8.0, 9.0))
self.assertEqual(list(p[:1]), [(0.0, 1.0)]) self.assertEqual(list(p[:1]), [(0.0, 1.0)])
with self.assertRaises(TypeError) as cm: with self.assertRaises(TypeError) as cm:
p['foo'] p["foo"]
self.assertEqual(str(cm.exception), "Path indices must be integers, not str")
self.assertEqual( self.assertEqual(
str(cm.exception), list(p), [(0.0, 1.0), (2.0, 3.0), (4.0, 5.0), (6.0, 7.0), (8.0, 9.0)]
"Path indices must be integers, not str") )
self.assertEqual(
list(p),
[(0.0, 1.0), (2.0, 3.0), (4.0, 5.0), (6.0, 7.0), (8.0, 9.0)])
# method sanity check # method sanity check
self.assertEqual( self.assertEqual(
p.tolist(), p.tolist(), [(0.0, 1.0), (2.0, 3.0), (4.0, 5.0), (6.0, 7.0), (8.0, 9.0)]
[(0.0, 1.0), (2.0, 3.0), (4.0, 5.0), (6.0, 7.0), (8.0, 9.0)]) )
self.assertEqual( self.assertEqual(
p.tolist(1), p.tolist(1), [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) )
self.assertEqual(p.getbbox(), (0.0, 1.0, 8.0, 9.0)) self.assertEqual(p.getbbox(), (0.0, 1.0, 8.0, 9.0))
@ -62,7 +59,7 @@ class TestImagePath(PillowTestCase):
self.assertEqual(list(p), [(0.0, 1.0)]) self.assertEqual(list(p), [(0.0, 1.0)])
arr = array.array("f", [0, 1]) arr = array.array("f", [0, 1])
if hasattr(arr, 'tobytes'): if hasattr(arr, "tobytes"):
p = ImagePath.Path(arr.tobytes()) p = ImagePath.Path(arr.tobytes())
else: else:
p = ImagePath.Path(arr.tostring()) p = ImagePath.Path(arr.tostring())
@ -79,9 +76,9 @@ class TestImagePath(PillowTestCase):
# and segfaults # and segfaults
for i in range(200000): for i in range(200000):
if py3: if py3:
x[i] = b'0'*16 x[i] = b"0" * 16
else: else:
x[i] = "0"*16 x[i] = "0" * 16
class evil: class evil:

View File

@ -17,13 +17,15 @@ if ImageQt.qt_is_installed:
def skip_if_qt_is_not_installed(_): def skip_if_qt_is_not_installed(_):
pass pass
else: else:
def skip_if_qt_is_not_installed(test_case): def skip_if_qt_is_not_installed(test_case):
test_case.skipTest('Qt bindings are not installed') test_case.skipTest("Qt bindings are not installed")
class PillowQtTestCase(object): class PillowQtTestCase(object):
def setUp(self): def setUp(self):
skip_if_qt_is_not_installed(self) skip_if_qt_is_not_installed(self)
@ -32,20 +34,19 @@ class PillowQtTestCase(object):
class PillowQPixmapTestCase(PillowQtTestCase): class PillowQPixmapTestCase(PillowQtTestCase):
def setUp(self): def setUp(self):
PillowQtTestCase.setUp(self) PillowQtTestCase.setUp(self)
try: try:
if ImageQt.qt_version == '5': if ImageQt.qt_version == "5":
from PyQt5.QtGui import QGuiApplication from PyQt5.QtGui import QGuiApplication
elif ImageQt.qt_version == '4': elif ImageQt.qt_version == "4":
from PyQt4.QtGui import QGuiApplication from PyQt4.QtGui import QGuiApplication
elif ImageQt.qt_version == 'side': elif ImageQt.qt_version == "side":
from PySide.QtGui import QGuiApplication from PySide.QtGui import QGuiApplication
elif ImageQt.qt_version == 'side2': elif ImageQt.qt_version == "side2":
from PySide2.QtGui import QGuiApplication from PySide2.QtGui import QGuiApplication
except ImportError: except ImportError:
self.skipTest('QGuiApplication not installed') self.skipTest("QGuiApplication not installed")
self.app = QGuiApplication([]) self.app = QGuiApplication([])
@ -55,29 +56,28 @@ class PillowQPixmapTestCase(PillowQtTestCase):
class TestImageQt(PillowQtTestCase, PillowTestCase): class TestImageQt(PillowQtTestCase, PillowTestCase):
def test_rgb(self): def test_rgb(self):
# from https://doc.qt.io/archives/qt-4.8/qcolor.html # from https://doc.qt.io/archives/qt-4.8/qcolor.html
# typedef QRgb # typedef QRgb
# An ARGB quadruplet on the format #AARRGGBB, # An ARGB quadruplet on the format #AARRGGBB,
# equivalent to an unsigned int. # equivalent to an unsigned int.
if ImageQt.qt_version == '5': if ImageQt.qt_version == "5":
from PyQt5.QtGui import qRgb from PyQt5.QtGui import qRgb
elif ImageQt.qt_version == '4': elif ImageQt.qt_version == "4":
from PyQt4.QtGui import qRgb from PyQt4.QtGui import qRgb
elif ImageQt.qt_version == 'side': elif ImageQt.qt_version == "side":
from PySide.QtGui import qRgb from PySide.QtGui import qRgb
elif ImageQt.qt_version == 'side2': elif ImageQt.qt_version == "side2":
from PySide2.QtGui import qRgb from PySide2.QtGui import qRgb
self.assertEqual(qRgb(0, 0, 0), qRgba(0, 0, 0, 255)) self.assertEqual(qRgb(0, 0, 0), qRgba(0, 0, 0, 255))
def checkrgb(r, g, b): def checkrgb(r, g, b):
val = ImageQt.rgb(r, g, b) val = ImageQt.rgb(r, g, b)
val = val % 2**24 # drop the alpha val = val % 2 ** 24 # drop the alpha
self.assertEqual(val >> 16, r) self.assertEqual(val >> 16, r)
self.assertEqual(((val >> 8) % 2**8), g) self.assertEqual(((val >> 8) % 2 ** 8), g)
self.assertEqual(val % 2**8, b) self.assertEqual(val % 2 ** 8, b)
checkrgb(0, 0, 0) checkrgb(0, 0, 0)
checkrgb(255, 0, 0) checkrgb(255, 0, 0)
@ -85,7 +85,7 @@ class TestImageQt(PillowQtTestCase, PillowTestCase):
checkrgb(0, 0, 255) checkrgb(0, 0, 255)
def test_image(self): def test_image(self):
for mode in ('1', 'RGB', 'RGBA', 'L', 'P'): for mode in ("1", "RGB", "RGBA", "L", "P"):
ImageQt.ImageQt(hopper(mode)) ImageQt.ImageQt(hopper(mode))
def test_deprecated(self): def test_deprecated(self):

View File

@ -4,7 +4,6 @@ from PIL import Image, ImageSequence, TiffImagePlugin
class TestImageSequence(PillowTestCase): class TestImageSequence(PillowTestCase):
def test_sanity(self): def test_sanity(self):
test_file = self.tempfile("temp.im") test_file = self.tempfile("temp.im")
@ -25,19 +24,19 @@ class TestImageSequence(PillowTestCase):
self.assertRaises(AttributeError, ImageSequence.Iterator, 0) self.assertRaises(AttributeError, ImageSequence.Iterator, 0)
def test_iterator(self): def test_iterator(self):
im = Image.open('Tests/images/multipage.tiff') im = Image.open("Tests/images/multipage.tiff")
i = ImageSequence.Iterator(im) i = ImageSequence.Iterator(im)
for index in range(0, im.n_frames): for index in range(0, im.n_frames):
self.assertEqual(i[index], next(i)) self.assertEqual(i[index], next(i))
self.assertRaises(IndexError, lambda: i[index+1]) self.assertRaises(IndexError, lambda: i[index + 1])
self.assertRaises(StopIteration, next, i) self.assertRaises(StopIteration, next, i)
def _test_multipage_tiff(self): def _test_multipage_tiff(self):
im = Image.open('Tests/images/multipage.tiff') im = Image.open("Tests/images/multipage.tiff")
for index, frame in enumerate(ImageSequence.Iterator(im)): for index, frame in enumerate(ImageSequence.Iterator(im)):
frame.load() frame.load()
self.assertEqual(index, im.tell()) self.assertEqual(index, im.tell())
frame.convert('RGB') frame.convert("RGB")
def test_tiff(self): def test_tiff(self):
self._test_multipage_tiff() self._test_multipage_tiff()
@ -53,7 +52,7 @@ class TestImageSequence(PillowTestCase):
TiffImagePlugin.READ_LIBTIFF = False TiffImagePlugin.READ_LIBTIFF = False
def test_consecutive(self): def test_consecutive(self):
im = Image.open('Tests/images/multipage.tiff') im = Image.open("Tests/images/multipage.tiff")
firstFrame = None firstFrame = None
for frame in ImageSequence.Iterator(im): for frame in ImageSequence.Iterator(im):
if firstFrame is None: if firstFrame is None:
@ -64,7 +63,7 @@ class TestImageSequence(PillowTestCase):
def test_palette_mmap(self): def test_palette_mmap(self):
# Using mmap in ImageFile can require to reload the palette. # Using mmap in ImageFile can require to reload the palette.
im = Image.open('Tests/images/multipage-mmap.tiff') im = Image.open("Tests/images/multipage-mmap.tiff")
color1 = im.getpalette()[0:3] color1 = im.getpalette()[0:3]
im.seek(0) im.seek(0)
color2 = im.getpalette()[0:3] color2 = im.getpalette()[0:3]

View File

@ -5,7 +5,6 @@ from PIL import ImageShow
class TestImageShow(PillowTestCase): class TestImageShow(PillowTestCase):
def test_sanity(self): def test_sanity(self):
dir(Image) dir(Image)
dir(ImageShow) dir(ImageShow)
@ -24,6 +23,7 @@ class TestImageShow(PillowTestCase):
def show(self, image, title=None, **options): def show(self, image, title=None, **options):
self.methodCalled = True self.methodCalled = True
return True return True
viewer = TestViewer() viewer = TestViewer()
ImageShow.register(viewer, -1) ImageShow.register(viewer, -1)
@ -43,4 +43,4 @@ class TestImageShow(PillowTestCase):
def test_viewers(self): def test_viewers(self):
for viewer in ImageShow._viewers: for viewer in ImageShow._viewers:
viewer.get_command('test.jpg') viewer.get_command("test.jpg")

View File

@ -5,7 +5,6 @@ from PIL import ImageStat
class TestImageStat(PillowTestCase): class TestImageStat(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im = hopper() im = hopper()
@ -48,8 +47,8 @@ class TestImageStat(PillowTestCase):
st = ImageStat.Stat(im) st = ImageStat.Stat(im)
self.assertEqual(st.extrema[0], (128, 128)) self.assertEqual(st.extrema[0], (128, 128))
self.assertEqual(st.sum[0], 128**3) self.assertEqual(st.sum[0], 128 ** 3)
self.assertEqual(st.sum2[0], 128**4) self.assertEqual(st.sum2[0], 128 ** 4)
self.assertEqual(st.mean[0], 128) self.assertEqual(st.mean[0], 128)
self.assertEqual(st.median[0], 128) self.assertEqual(st.median[0], 128)
self.assertEqual(st.rms[0], 128) self.assertEqual(st.rms[0], 128)

View File

@ -5,6 +5,7 @@ from PIL._util import py3
try: try:
from PIL import ImageTk from PIL import ImageTk
if py3: if py3:
import tkinter as tk import tkinter as tk
else: else:
@ -15,12 +16,11 @@ except (OSError, ImportError):
# Skipped via setUp() # Skipped via setUp()
HAS_TK = False HAS_TK = False
TK_MODES = ('1', 'L', 'P', 'RGB', 'RGBA') TK_MODES = ("1", "L", "P", "RGB", "RGBA")
@unittest.skipIf(not HAS_TK, "Tk not installed") @unittest.skipIf(not HAS_TK, "Tk not installed")
class TestImageTk(PillowTestCase): class TestImageTk(PillowTestCase):
def setUp(self): def setUp(self):
try: try:
# setup tk # setup tk
@ -34,7 +34,7 @@ class TestImageTk(PillowTestCase):
TEST_PNG = "Tests/images/hopper.png" TEST_PNG = "Tests/images/hopper.png"
im1 = Image.open(TEST_JPG) im1 = Image.open(TEST_JPG)
im2 = Image.open(TEST_PNG) im2 = Image.open(TEST_PNG)
with open(TEST_PNG, 'rb') as fp: with open(TEST_PNG, "rb") as fp:
data = fp.read() data = fp.read()
kw = {"file": TEST_JPG, "data": data} kw = {"file": TEST_JPG, "data": data}
@ -76,7 +76,7 @@ class TestImageTk(PillowTestCase):
# self.assert_image_equal(reloaded, im) # self.assert_image_equal(reloaded, im)
def test_bitmapimage(self): def test_bitmapimage(self):
im = hopper('1') im = hopper("1")
# this should not crash # this should not crash
im_tk = ImageTk.BitmapImage(im) im_tk = ImageTk.BitmapImage(im)

View File

@ -5,7 +5,6 @@ import sys
class TestImageWin(PillowTestCase): class TestImageWin(PillowTestCase):
def test_sanity(self): def test_sanity(self):
dir(ImageWin) dir(ImageWin)
@ -32,9 +31,8 @@ class TestImageWin(PillowTestCase):
self.assertEqual(wnd2, 50) self.assertEqual(wnd2, 50)
@unittest.skipUnless(sys.platform.startswith('win32'), "Windows only") @unittest.skipUnless(sys.platform.startswith("win32"), "Windows only")
class TestImageWinDib(PillowTestCase): class TestImageWinDib(PillowTestCase):
def test_dib_image(self): def test_dib_image(self):
# Arrange # Arrange
im = hopper() im = hopper()

View File

@ -7,33 +7,33 @@ from io import BytesIO
# see https://github.com/python-pillow/Pillow/pull/1431#issuecomment-144692652 # see https://github.com/python-pillow/Pillow/pull/1431#issuecomment-144692652
if sys.platform.startswith('win32'): if sys.platform.startswith("win32"):
import ctypes.wintypes import ctypes.wintypes
class BITMAPFILEHEADER(ctypes.Structure): class BITMAPFILEHEADER(ctypes.Structure):
_pack_ = 2 _pack_ = 2
_fields_ = [ _fields_ = [
('bfType', ctypes.wintypes.WORD), ("bfType", ctypes.wintypes.WORD),
('bfSize', ctypes.wintypes.DWORD), ("bfSize", ctypes.wintypes.DWORD),
('bfReserved1', ctypes.wintypes.WORD), ("bfReserved1", ctypes.wintypes.WORD),
('bfReserved2', ctypes.wintypes.WORD), ("bfReserved2", ctypes.wintypes.WORD),
('bfOffBits', ctypes.wintypes.DWORD), ("bfOffBits", ctypes.wintypes.DWORD),
] ]
class BITMAPINFOHEADER(ctypes.Structure): class BITMAPINFOHEADER(ctypes.Structure):
_pack_ = 2 _pack_ = 2
_fields_ = [ _fields_ = [
('biSize', ctypes.wintypes.DWORD), ("biSize", ctypes.wintypes.DWORD),
('biWidth', ctypes.wintypes.LONG), ("biWidth", ctypes.wintypes.LONG),
('biHeight', ctypes.wintypes.LONG), ("biHeight", ctypes.wintypes.LONG),
('biPlanes', ctypes.wintypes.WORD), ("biPlanes", ctypes.wintypes.WORD),
('biBitCount', ctypes.wintypes.WORD), ("biBitCount", ctypes.wintypes.WORD),
('biCompression', ctypes.wintypes.DWORD), ("biCompression", ctypes.wintypes.DWORD),
('biSizeImage', ctypes.wintypes.DWORD), ("biSizeImage", ctypes.wintypes.DWORD),
('biXPelsPerMeter', ctypes.wintypes.LONG), ("biXPelsPerMeter", ctypes.wintypes.LONG),
('biYPelsPerMeter', ctypes.wintypes.LONG), ("biYPelsPerMeter", ctypes.wintypes.LONG),
('biClrUsed', ctypes.wintypes.DWORD), ("biClrUsed", ctypes.wintypes.DWORD),
('biClrImportant', ctypes.wintypes.DWORD), ("biClrImportant", ctypes.wintypes.DWORD),
] ]
BI_RGB = 0 BI_RGB = 0
@ -57,15 +57,19 @@ if sys.platform.startswith('win32'):
DeleteObject.argtypes = [ctypes.wintypes.HGDIOBJ] DeleteObject.argtypes = [ctypes.wintypes.HGDIOBJ]
CreateDIBSection = ctypes.windll.gdi32.CreateDIBSection CreateDIBSection = ctypes.windll.gdi32.CreateDIBSection
CreateDIBSection.argtypes = [ctypes.wintypes.HDC, ctypes.c_void_p, CreateDIBSection.argtypes = [
ctypes.wintypes.HDC,
ctypes.c_void_p,
ctypes.c_uint, ctypes.c_uint,
ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_void_p),
ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD] ctypes.wintypes.HANDLE,
ctypes.wintypes.DWORD,
]
CreateDIBSection.restype = ctypes.wintypes.HBITMAP CreateDIBSection.restype = ctypes.wintypes.HBITMAP
def serialize_dib(bi, pixels): def serialize_dib(bi, pixels):
bf = BITMAPFILEHEADER() bf = BITMAPFILEHEADER()
bf.bfType = 0x4d42 bf.bfType = 0x4D42
bf.bfOffBits = ctypes.sizeof(bf) + bi.biSize bf.bfOffBits = ctypes.sizeof(bf) + bi.biSize
bf.bfSize = bf.bfOffBits + bi.biSizeImage bf.bfSize = bf.bfOffBits + bi.biSizeImage
bf.bfReserved1 = bf.bfReserved2 = 0 bf.bfReserved1 = bf.bfReserved2 = 0
@ -81,7 +85,7 @@ if sys.platform.startswith('win32'):
def test_pointer(self): def test_pointer(self):
im = hopper() im = hopper()
(width, height) = im.size (width, height) = im.size
opath = self.tempfile('temp.png') opath = self.tempfile("temp.png")
imdib = ImageWin.Dib(im) imdib = ImageWin.Dib(im)
hdr = BITMAPINFOHEADER() hdr = BITMAPINFOHEADER()
@ -97,8 +101,9 @@ if sys.platform.startswith('win32'):
hdc = CreateCompatibleDC(None) hdc = CreateCompatibleDC(None)
pixels = ctypes.c_void_p() pixels = ctypes.c_void_p()
dib = CreateDIBSection(hdc, ctypes.byref(hdr), DIB_RGB_COLORS, dib = CreateDIBSection(
ctypes.byref(pixels), None, 0) hdc, ctypes.byref(hdr), DIB_RGB_COLORS, ctypes.byref(pixels), None, 0
)
SelectObject(hdc, dib) SelectObject(hdc, dib)
imdib.expose(hdc) imdib.expose(hdc)

View File

@ -4,7 +4,6 @@ from PIL import Image
class TestLibImage(PillowTestCase): class TestLibImage(PillowTestCase):
def test_setmode(self): def test_setmode(self):
im = Image.new("L", (1, 1), 255) im = Image.new("L", (1, 1), 255)
@ -33,5 +32,5 @@ class TestLibImage(PillowTestCase):
self.assertRaises(ValueError, im.im.setmode, "RGBABCDE") self.assertRaises(ValueError, im.im.setmode, "RGBABCDE")
if __name__ == '__main__': if __name__ == "__main__":
unittest.main() unittest.main()

View File

@ -24,32 +24,31 @@ class TestLibPack(PillowTestCase):
self.assertEqual(data, im.tobytes("raw", rawmode)) self.assertEqual(data, im.tobytes("raw", rawmode))
def test_1(self): def test_1(self):
self.assert_pack("1", "1", b'\x01', 0, 0, 0, 0, 0, 0, 0, X) self.assert_pack("1", "1", b"\x01", 0, 0, 0, 0, 0, 0, 0, X)
self.assert_pack("1", "1;I", b'\x01', X, X, X, X, X, X, X, 0) self.assert_pack("1", "1;I", b"\x01", X, X, X, X, X, X, X, 0)
self.assert_pack("1", "1;R", b'\x01', X, 0, 0, 0, 0, 0, 0, 0) self.assert_pack("1", "1;R", b"\x01", X, 0, 0, 0, 0, 0, 0, 0)
self.assert_pack("1", "1;IR", b'\x01', 0, X, X, X, X, X, X, X) self.assert_pack("1", "1;IR", b"\x01", 0, X, X, X, X, X, X, X)
self.assert_pack("1", "1", b'\xaa', X, 0, X, 0, X, 0, X, 0) self.assert_pack("1", "1", b"\xaa", X, 0, X, 0, X, 0, X, 0)
self.assert_pack("1", "1;I", b'\xaa', 0, X, 0, X, 0, X, 0, X) self.assert_pack("1", "1;I", b"\xaa", 0, X, 0, X, 0, X, 0, X)
self.assert_pack("1", "1;R", b'\xaa', 0, X, 0, X, 0, X, 0, X) self.assert_pack("1", "1;R", b"\xaa", 0, X, 0, X, 0, X, 0, X)
self.assert_pack("1", "1;IR", b'\xaa', X, 0, X, 0, X, 0, X, 0) self.assert_pack("1", "1;IR", b"\xaa", X, 0, X, 0, X, 0, X, 0)
self.assert_pack( self.assert_pack("1", "L", b"\xff\x00\x00\xff\x00\x00", X, 0, 0, X, 0, 0)
"1", "L", b'\xff\x00\x00\xff\x00\x00', X, 0, 0, X, 0, 0)
def test_L(self): def test_L(self):
self.assert_pack("L", "L", 1, 1, 2, 3, 4) self.assert_pack("L", "L", 1, 1, 2, 3, 4)
self.assert_pack("L", "L;16", b'\x00\xc6\x00\xaf', 198, 175) self.assert_pack("L", "L;16", b"\x00\xc6\x00\xaf", 198, 175)
self.assert_pack("L", "L;16B", b'\xc6\x00\xaf\x00', 198, 175) self.assert_pack("L", "L;16B", b"\xc6\x00\xaf\x00", 198, 175)
def test_LA(self): def test_LA(self):
self.assert_pack("LA", "LA", 2, (1, 2), (3, 4), (5, 6)) self.assert_pack("LA", "LA", 2, (1, 2), (3, 4), (5, 6))
self.assert_pack("LA", "LA;L", 2, (1, 4), (2, 5), (3, 6)) self.assert_pack("LA", "LA;L", 2, (1, 4), (2, 5), (3, 6))
def test_P(self): def test_P(self):
self.assert_pack("P", "P;1", b'\xe4', 1, 1, 1, 0, 0, 255, 0, 0) self.assert_pack("P", "P;1", b"\xe4", 1, 1, 1, 0, 0, 255, 0, 0)
self.assert_pack("P", "P;2", b'\xe4', 3, 2, 1, 0) self.assert_pack("P", "P;2", b"\xe4", 3, 2, 1, 0)
self.assert_pack("P", "P;4", b'\x02\xef', 0, 2, 14, 15) self.assert_pack("P", "P;4", b"\x02\xef", 0, 2, 14, 15)
self.assert_pack("P", "P", 1, 1, 2, 3, 4) self.assert_pack("P", "P", 1, 1, 2, 3, 4)
def test_PA(self): def test_PA(self):
@ -59,116 +58,118 @@ class TestLibPack(PillowTestCase):
def test_RGB(self): def test_RGB(self):
self.assert_pack("RGB", "RGB", 3, (1, 2, 3), (4, 5, 6), (7, 8, 9)) self.assert_pack("RGB", "RGB", 3, (1, 2, 3), (4, 5, 6), (7, 8, 9))
self.assert_pack( self.assert_pack(
"RGB", "RGBX", "RGB", "RGBX", b"\x01\x02\x03\xff\x05\x06\x07\xff", (1, 2, 3), (5, 6, 7)
b'\x01\x02\x03\xff\x05\x06\x07\xff', (1, 2, 3), (5, 6, 7)) )
self.assert_pack( self.assert_pack(
"RGB", "XRGB", "RGB", "XRGB", b"\x00\x02\x03\x04\x00\x06\x07\x08", (2, 3, 4), (6, 7, 8)
b'\x00\x02\x03\x04\x00\x06\x07\x08', (2, 3, 4), (6, 7, 8)) )
self.assert_pack("RGB", "BGR", 3, (3, 2, 1), (6, 5, 4), (9, 8, 7)) self.assert_pack("RGB", "BGR", 3, (3, 2, 1), (6, 5, 4), (9, 8, 7))
self.assert_pack( self.assert_pack(
"RGB", "BGRX", "RGB", "BGRX", b"\x01\x02\x03\x00\x05\x06\x07\x00", (3, 2, 1), (7, 6, 5)
b'\x01\x02\x03\x00\x05\x06\x07\x00', (3, 2, 1), (7, 6, 5)) )
self.assert_pack( self.assert_pack(
"RGB", "XBGR", "RGB", "XBGR", b"\x00\x02\x03\x04\x00\x06\x07\x08", (4, 3, 2), (8, 7, 6)
b'\x00\x02\x03\x04\x00\x06\x07\x08', (4, 3, 2), (8, 7, 6)) )
self.assert_pack("RGB", "RGB;L", 3, (1, 4, 7), (2, 5, 8), (3, 6, 9)) self.assert_pack("RGB", "RGB;L", 3, (1, 4, 7), (2, 5, 8), (3, 6, 9))
self.assert_pack("RGB", "R", 1, (1, 9, 9), (2, 9, 9), (3, 9, 9)) self.assert_pack("RGB", "R", 1, (1, 9, 9), (2, 9, 9), (3, 9, 9))
self.assert_pack("RGB", "G", 1, (9, 1, 9), (9, 2, 9), (9, 3, 9)) self.assert_pack("RGB", "G", 1, (9, 1, 9), (9, 2, 9), (9, 3, 9))
self.assert_pack("RGB", "B", 1, (9, 9, 1), (9, 9, 2), (9, 9, 3)) self.assert_pack("RGB", "B", 1, (9, 9, 1), (9, 9, 2), (9, 9, 3))
def test_RGBA(self): def test_RGBA(self):
self.assert_pack("RGBA", "RGBA", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12))
self.assert_pack( self.assert_pack(
"RGBA", "RGBA", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)) "RGBA", "RGBA;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)
)
self.assert_pack("RGBA", "RGB", 3, (1, 2, 3, 14), (4, 5, 6, 15), (7, 8, 9, 16))
self.assert_pack("RGBA", "BGR", 3, (3, 2, 1, 14), (6, 5, 4, 15), (9, 8, 7, 16))
self.assert_pack("RGBA", "BGRA", 4, (3, 2, 1, 4), (7, 6, 5, 8), (11, 10, 9, 12))
self.assert_pack("RGBA", "ABGR", 4, (4, 3, 2, 1), (8, 7, 6, 5), (12, 11, 10, 9))
self.assert_pack( self.assert_pack(
"RGBA", "RGBA;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)) "RGBA",
self.assert_pack( "BGRa",
"RGBA", "RGB", 3, (1, 2, 3, 14), (4, 5, 6, 15), (7, 8, 9, 16)) 4,
self.assert_pack( (191, 127, 63, 4),
"RGBA", "BGR", 3, (3, 2, 1, 14), (6, 5, 4, 15), (9, 8, 7, 16)) (223, 191, 159, 8),
self.assert_pack( (233, 212, 191, 12),
"RGBA", "BGRA", 4, )
(3, 2, 1, 4), (7, 6, 5, 8), (11, 10, 9, 12)) self.assert_pack("RGBA", "R", 1, (1, 0, 8, 9), (2, 0, 8, 9), (3, 0, 8, 0))
self.assert_pack( self.assert_pack("RGBA", "G", 1, (6, 1, 8, 9), (6, 2, 8, 9), (6, 3, 8, 9))
"RGBA", "ABGR", 4, (4, 3, 2, 1), (8, 7, 6, 5), (12, 11, 10, 9)) self.assert_pack("RGBA", "B", 1, (6, 7, 1, 9), (6, 7, 2, 0), (6, 7, 3, 9))
self.assert_pack( self.assert_pack("RGBA", "A", 1, (6, 7, 0, 1), (6, 7, 0, 2), (0, 7, 0, 3))
"RGBA", "BGRa", 4,
(191, 127, 63, 4), (223, 191, 159, 8), (233, 212, 191, 12))
self.assert_pack(
"RGBA", "R", 1, (1, 0, 8, 9), (2, 0, 8, 9), (3, 0, 8, 0))
self.assert_pack(
"RGBA", "G", 1, (6, 1, 8, 9), (6, 2, 8, 9), (6, 3, 8, 9))
self.assert_pack(
"RGBA", "B", 1, (6, 7, 1, 9), (6, 7, 2, 0), (6, 7, 3, 9))
self.assert_pack(
"RGBA", "A", 1, (6, 7, 0, 1), (6, 7, 0, 2), (0, 7, 0, 3))
def test_RGBa(self): def test_RGBa(self):
self.assert_pack( self.assert_pack("RGBa", "RGBa", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12))
"RGBa", "RGBa", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)) self.assert_pack("RGBa", "BGRa", 4, (3, 2, 1, 4), (7, 6, 5, 8), (11, 10, 9, 12))
self.assert_pack( self.assert_pack("RGBa", "aBGR", 4, (4, 3, 2, 1), (8, 7, 6, 5), (12, 11, 10, 9))
"RGBa", "BGRa", 4, (3, 2, 1, 4), (7, 6, 5, 8), (11, 10, 9, 12))
self.assert_pack(
"RGBa", "aBGR", 4, (4, 3, 2, 1), (8, 7, 6, 5), (12, 11, 10, 9))
def test_RGBX(self): def test_RGBX(self):
self.assert_pack("RGBX", "RGBX", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12))
self.assert_pack( self.assert_pack(
"RGBX", "RGBX", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)) "RGBX", "RGBX;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)
)
self.assert_pack("RGBX", "RGB", 3, (1, 2, 3, X), (4, 5, 6, X), (7, 8, 9, X))
self.assert_pack("RGBX", "BGR", 3, (3, 2, 1, X), (6, 5, 4, X), (9, 8, 7, X))
self.assert_pack( self.assert_pack(
"RGBX", "RGBX;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)) "RGBX",
"BGRX",
b"\x01\x02\x03\x00\x05\x06\x07\x00\t\n\x0b\x00",
(3, 2, 1, X),
(7, 6, 5, X),
(11, 10, 9, X),
)
self.assert_pack( self.assert_pack(
"RGBX", "RGB", 3, (1, 2, 3, X), (4, 5, 6, X), (7, 8, 9, X)) "RGBX",
self.assert_pack( "XBGR",
"RGBX", "BGR", 3, (3, 2, 1, X), (6, 5, 4, X), (9, 8, 7, X)) b"\x00\x02\x03\x04\x00\x06\x07\x08\x00\n\x0b\x0c",
self.assert_pack( (4, 3, 2, X),
"RGBX", "BGRX", (8, 7, 6, X),
b'\x01\x02\x03\x00\x05\x06\x07\x00\t\n\x0b\x00', (12, 11, 10, X),
(3, 2, 1, X), (7, 6, 5, X), (11, 10, 9, X)) )
self.assert_pack( self.assert_pack("RGBX", "R", 1, (1, 0, 8, 9), (2, 0, 8, 9), (3, 0, 8, 0))
"RGBX", "XBGR", self.assert_pack("RGBX", "G", 1, (6, 1, 8, 9), (6, 2, 8, 9), (6, 3, 8, 9))
b'\x00\x02\x03\x04\x00\x06\x07\x08\x00\n\x0b\x0c', self.assert_pack("RGBX", "B", 1, (6, 7, 1, 9), (6, 7, 2, 0), (6, 7, 3, 9))
(4, 3, 2, X), (8, 7, 6, X), (12, 11, 10, X)) self.assert_pack("RGBX", "X", 1, (6, 7, 0, 1), (6, 7, 0, 2), (0, 7, 0, 3))
self.assert_pack("RGBX", "R", 1,
(1, 0, 8, 9), (2, 0, 8, 9), (3, 0, 8, 0))
self.assert_pack("RGBX", "G", 1,
(6, 1, 8, 9), (6, 2, 8, 9), (6, 3, 8, 9))
self.assert_pack("RGBX", "B", 1,
(6, 7, 1, 9), (6, 7, 2, 0), (6, 7, 3, 9))
self.assert_pack("RGBX", "X", 1,
(6, 7, 0, 1), (6, 7, 0, 2), (0, 7, 0, 3))
def test_CMYK(self): def test_CMYK(self):
self.assert_pack("CMYK", "CMYK", 4, self.assert_pack("CMYK", "CMYK", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12))
(1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12))
self.assert_pack( self.assert_pack(
"CMYK", "CMYK;I", 4, "CMYK",
(254, 253, 252, 251), (250, 249, 248, 247), (246, 245, 244, 243)) "CMYK;I",
4,
(254, 253, 252, 251),
(250, 249, 248, 247),
(246, 245, 244, 243),
)
self.assert_pack( self.assert_pack(
"CMYK", "CMYK;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)) "CMYK", "CMYK;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)
self.assert_pack("CMYK", "K", 1, )
(6, 7, 0, 1), (6, 7, 0, 2), (0, 7, 0, 3)) self.assert_pack("CMYK", "K", 1, (6, 7, 0, 1), (6, 7, 0, 2), (0, 7, 0, 3))
def test_YCbCr(self): def test_YCbCr(self):
self.assert_pack("YCbCr", "YCbCr", 3, (1, 2, 3), (4, 5, 6), (7, 8, 9)) self.assert_pack("YCbCr", "YCbCr", 3, (1, 2, 3), (4, 5, 6), (7, 8, 9))
self.assert_pack("YCbCr", "YCbCr;L", 3, self.assert_pack("YCbCr", "YCbCr;L", 3, (1, 4, 7), (2, 5, 8), (3, 6, 9))
(1, 4, 7), (2, 5, 8), (3, 6, 9))
self.assert_pack( self.assert_pack(
"YCbCr", "YCbCrX", "YCbCr",
b'\x01\x02\x03\xff\x05\x06\x07\xff\t\n\x0b\xff', "YCbCrX",
(1, 2, 3), (5, 6, 7), (9, 10, 11)) b"\x01\x02\x03\xff\x05\x06\x07\xff\t\n\x0b\xff",
(1, 2, 3),
(5, 6, 7),
(9, 10, 11),
)
self.assert_pack( self.assert_pack(
"YCbCr", "YCbCrK", "YCbCr",
b'\x01\x02\x03\xff\x05\x06\x07\xff\t\n\x0b\xff', "YCbCrK",
(1, 2, 3), (5, 6, 7), (9, 10, 11)) b"\x01\x02\x03\xff\x05\x06\x07\xff\t\n\x0b\xff",
self.assert_pack("YCbCr", "Y", 1, (1, 2, 3),
(1, 0, 8, 9), (2, 0, 8, 9), (3, 0, 8, 0)) (5, 6, 7),
self.assert_pack("YCbCr", "Cb", 1, (9, 10, 11),
(6, 1, 8, 9), (6, 2, 8, 9), (6, 3, 8, 9)) )
self.assert_pack("YCbCr", "Cr", 1, self.assert_pack("YCbCr", "Y", 1, (1, 0, 8, 9), (2, 0, 8, 9), (3, 0, 8, 0))
(6, 7, 1, 9), (6, 7, 2, 0), (6, 7, 3, 9)) self.assert_pack("YCbCr", "Cb", 1, (6, 1, 8, 9), (6, 2, 8, 9), (6, 3, 8, 9))
self.assert_pack("YCbCr", "Cr", 1, (6, 7, 1, 9), (6, 7, 2, 0), (6, 7, 3, 9))
def test_LAB(self): def test_LAB(self):
self.assert_pack( self.assert_pack("LAB", "LAB", 3, (1, 130, 131), (4, 133, 134), (7, 136, 137))
"LAB", "LAB", 3, (1, 130, 131), (4, 133, 134), (7, 136, 137))
self.assert_pack("LAB", "L", 1, (1, 9, 9), (2, 9, 9), (3, 9, 9)) self.assert_pack("LAB", "L", 1, (1, 9, 9), (2, 9, 9), (3, 9, 9))
self.assert_pack("LAB", "A", 1, (9, 1, 9), (9, 2, 9), (9, 3, 9)) self.assert_pack("LAB", "A", 1, (9, 1, 9), (9, 2, 9), (9, 3, 9))
self.assert_pack("LAB", "B", 1, (9, 9, 1), (9, 9, 2), (9, 9, 3)) self.assert_pack("LAB", "B", 1, (9, 9, 1), (9, 9, 2), (9, 9, 3))
@ -182,34 +183,41 @@ class TestLibPack(PillowTestCase):
def test_I(self): def test_I(self):
self.assert_pack("I", "I;16B", 2, 0x0102, 0x0304) self.assert_pack("I", "I;16B", 2, 0x0102, 0x0304)
self.assert_pack( self.assert_pack(
"I", "I;32S", "I", "I;32S", b"\x83\x00\x00\x01\x01\x00\x00\x83", 0x01000083, -2097151999
b'\x83\x00\x00\x01\x01\x00\x00\x83', 0x01000083, -2097151999) )
if sys.byteorder == 'little': if sys.byteorder == "little":
self.assert_pack("I", "I", 4, 0x04030201, 0x08070605) self.assert_pack("I", "I", 4, 0x04030201, 0x08070605)
self.assert_pack( self.assert_pack(
"I", "I;32NS", "I",
b'\x83\x00\x00\x01\x01\x00\x00\x83', 0x01000083, -2097151999) "I;32NS",
b"\x83\x00\x00\x01\x01\x00\x00\x83",
0x01000083,
-2097151999,
)
else: else:
self.assert_pack("I", "I", 4, 0x01020304, 0x05060708) self.assert_pack("I", "I", 4, 0x01020304, 0x05060708)
self.assert_pack( self.assert_pack(
"I", "I;32NS", "I",
b'\x83\x00\x00\x01\x01\x00\x00\x83', -2097151999, 0x01000083) "I;32NS",
b"\x83\x00\x00\x01\x01\x00\x00\x83",
-2097151999,
0x01000083,
)
def test_F_float(self): def test_F_float(self):
self.assert_pack( self.assert_pack("F", "F;32F", 4, 1.539989614439558e-36, 4.063216068939723e-34)
"F", "F;32F", 4, 1.539989614439558e-36, 4.063216068939723e-34)
if sys.byteorder == 'little': if sys.byteorder == "little":
self.assert_pack("F", "F", 4, 1.539989614439558e-36, 4.063216068939723e-34)
self.assert_pack( self.assert_pack(
"F", "F", 4, 1.539989614439558e-36, 4.063216068939723e-34) "F", "F;32NF", 4, 1.539989614439558e-36, 4.063216068939723e-34
self.assert_pack( )
"F", "F;32NF", 4, 1.539989614439558e-36, 4.063216068939723e-34)
else: else:
self.assert_pack("F", "F", 4, 2.387939260590663e-38, 6.301941157072183e-36)
self.assert_pack( self.assert_pack(
"F", "F", 4, 2.387939260590663e-38, 6.301941157072183e-36) "F", "F;32NF", 4, 2.387939260590663e-38, 6.301941157072183e-36
self.assert_pack( )
"F", "F;32NF", 4, 2.387939260590663e-38, 6.301941157072183e-36)
class TestLibUnpack(PillowTestCase): class TestLibUnpack(PillowTestCase):
@ -221,54 +229,53 @@ class TestLibUnpack(PillowTestCase):
data_len = data * len(pixels) data_len = data * len(pixels)
data = bytes(bytearray(range(1, data_len + 1))) data = bytes(bytearray(range(1, data_len + 1)))
im = Image.frombytes(mode, (len(pixels), 1), data, im = Image.frombytes(mode, (len(pixels), 1), data, "raw", rawmode, 0, 1)
"raw", rawmode, 0, 1)
for x, pixel in enumerate(pixels): for x, pixel in enumerate(pixels):
self.assertEqual(pixel, im.getpixel((x, 0))) self.assertEqual(pixel, im.getpixel((x, 0)))
def test_1(self): def test_1(self):
self.assert_unpack("1", "1", b'\x01', 0, 0, 0, 0, 0, 0, 0, X) self.assert_unpack("1", "1", b"\x01", 0, 0, 0, 0, 0, 0, 0, X)
self.assert_unpack("1", "1;I", b'\x01', X, X, X, X, X, X, X, 0) self.assert_unpack("1", "1;I", b"\x01", X, X, X, X, X, X, X, 0)
self.assert_unpack("1", "1;R", b'\x01', X, 0, 0, 0, 0, 0, 0, 0) self.assert_unpack("1", "1;R", b"\x01", X, 0, 0, 0, 0, 0, 0, 0)
self.assert_unpack("1", "1;IR", b'\x01', 0, X, X, X, X, X, X, X) self.assert_unpack("1", "1;IR", b"\x01", 0, X, X, X, X, X, X, X)
self.assert_unpack("1", "1", b'\xaa', X, 0, X, 0, X, 0, X, 0) self.assert_unpack("1", "1", b"\xaa", X, 0, X, 0, X, 0, X, 0)
self.assert_unpack("1", "1;I", b'\xaa', 0, X, 0, X, 0, X, 0, X) self.assert_unpack("1", "1;I", b"\xaa", 0, X, 0, X, 0, X, 0, X)
self.assert_unpack("1", "1;R", b'\xaa', 0, X, 0, X, 0, X, 0, X) self.assert_unpack("1", "1;R", b"\xaa", 0, X, 0, X, 0, X, 0, X)
self.assert_unpack("1", "1;IR", b'\xaa', X, 0, X, 0, X, 0, X, 0) self.assert_unpack("1", "1;IR", b"\xaa", X, 0, X, 0, X, 0, X, 0)
self.assert_unpack("1", "1;8", b'\x00\x01\x02\xff', 0, X, X, X) self.assert_unpack("1", "1;8", b"\x00\x01\x02\xff", 0, X, X, X)
def test_L(self): def test_L(self):
self.assert_unpack("L", "L;2", b'\xe4', 255, 170, 85, 0) self.assert_unpack("L", "L;2", b"\xe4", 255, 170, 85, 0)
self.assert_unpack("L", "L;2I", b'\xe4', 0, 85, 170, 255) self.assert_unpack("L", "L;2I", b"\xe4", 0, 85, 170, 255)
self.assert_unpack("L", "L;2R", b'\xe4', 0, 170, 85, 255) self.assert_unpack("L", "L;2R", b"\xe4", 0, 170, 85, 255)
self.assert_unpack("L", "L;2IR", b'\xe4', 255, 85, 170, 0) self.assert_unpack("L", "L;2IR", b"\xe4", 255, 85, 170, 0)
self.assert_unpack("L", "L;4", b'\x02\xef', 0, 34, 238, 255) self.assert_unpack("L", "L;4", b"\x02\xef", 0, 34, 238, 255)
self.assert_unpack("L", "L;4I", b'\x02\xef', 255, 221, 17, 0) self.assert_unpack("L", "L;4I", b"\x02\xef", 255, 221, 17, 0)
self.assert_unpack("L", "L;4R", b'\x02\xef', 68, 0, 255, 119) self.assert_unpack("L", "L;4R", b"\x02\xef", 68, 0, 255, 119)
self.assert_unpack("L", "L;4IR", b'\x02\xef', 187, 255, 0, 136) self.assert_unpack("L", "L;4IR", b"\x02\xef", 187, 255, 0, 136)
self.assert_unpack("L", "L", 1, 1, 2, 3, 4) self.assert_unpack("L", "L", 1, 1, 2, 3, 4)
self.assert_unpack("L", "L;I", 1, 254, 253, 252, 251) self.assert_unpack("L", "L;I", 1, 254, 253, 252, 251)
self.assert_unpack("L", "L;R", 1, 128, 64, 192, 32) self.assert_unpack("L", "L;R", 1, 128, 64, 192, 32)
self.assert_unpack("L", "L;16", 2, 2, 4, 6, 8) self.assert_unpack("L", "L;16", 2, 2, 4, 6, 8)
self.assert_unpack("L", "L;16B", 2, 1, 3, 5, 7) self.assert_unpack("L", "L;16B", 2, 1, 3, 5, 7)
self.assert_unpack("L", "L;16", b'\x00\xc6\x00\xaf', 198, 175) self.assert_unpack("L", "L;16", b"\x00\xc6\x00\xaf", 198, 175)
self.assert_unpack("L", "L;16B", b'\xc6\x00\xaf\x00', 198, 175) self.assert_unpack("L", "L;16B", b"\xc6\x00\xaf\x00", 198, 175)
def test_LA(self): def test_LA(self):
self.assert_unpack("LA", "LA", 2, (1, 2), (3, 4), (5, 6)) self.assert_unpack("LA", "LA", 2, (1, 2), (3, 4), (5, 6))
self.assert_unpack("LA", "LA;L", 2, (1, 4), (2, 5), (3, 6)) self.assert_unpack("LA", "LA;L", 2, (1, 4), (2, 5), (3, 6))
def test_P(self): def test_P(self):
self.assert_unpack("P", "P;1", b'\xe4', 1, 1, 1, 0, 0, 1, 0, 0) self.assert_unpack("P", "P;1", b"\xe4", 1, 1, 1, 0, 0, 1, 0, 0)
self.assert_unpack("P", "P;2", b'\xe4', 3, 2, 1, 0) self.assert_unpack("P", "P;2", b"\xe4", 3, 2, 1, 0)
# erroneous? # erroneous?
# self.assert_unpack("P", "P;2L", b'\xe4', 1, 1, 1, 0) # self.assert_unpack("P", "P;2L", b'\xe4', 1, 1, 1, 0)
self.assert_unpack("P", "P;4", b'\x02\xef', 0, 2, 14, 15) self.assert_unpack("P", "P;4", b"\x02\xef", 0, 2, 14, 15)
# erroneous? # erroneous?
# self.assert_unpack("P", "P;4L", b'\x02\xef', 2, 10, 10, 0) # self.assert_unpack("P", "P;4L", b'\x02\xef', 2, 10, 10, 0)
self.assert_unpack("P", "P", 1, 1, 2, 3, 4) self.assert_unpack("P", "P", 1, 1, 2, 3, 4)
@ -293,195 +300,256 @@ class TestLibUnpack(PillowTestCase):
self.assert_unpack("RGB", "RGBX", 4, (1, 2, 3), (5, 6, 7), (9, 10, 11)) self.assert_unpack("RGB", "RGBX", 4, (1, 2, 3), (5, 6, 7), (9, 10, 11))
self.assert_unpack("RGB", "RGBX;L", 4, (1, 4, 7), (2, 5, 8), (3, 6, 9)) self.assert_unpack("RGB", "RGBX;L", 4, (1, 4, 7), (2, 5, 8), (3, 6, 9))
self.assert_unpack("RGB", "BGRX", 4, (3, 2, 1), (7, 6, 5), (11, 10, 9)) self.assert_unpack("RGB", "BGRX", 4, (3, 2, 1), (7, 6, 5), (11, 10, 9))
self.assert_unpack("RGB", "XRGB", 4, (2, 3, 4), (6, 7, 8), (10, 11, 12))
self.assert_unpack("RGB", "XBGR", 4, (4, 3, 2), (8, 7, 6), (12, 11, 10))
self.assert_unpack( self.assert_unpack(
"RGB", "XRGB", 4, (2, 3, 4), (6, 7, 8), (10, 11, 12)) "RGB",
self.assert_unpack( "YCC;P",
"RGB", "XBGR", 4, (4, 3, 2), (8, 7, 6), (12, 11, 10)) b"D]\x9c\x82\x1a\x91\xfaOC\xe7J\x12", # random data
self.assert_unpack( (127, 102, 0),
"RGB", "YCC;P", (192, 227, 0),
b'D]\x9c\x82\x1a\x91\xfaOC\xe7J\x12', # random data (213, 255, 170),
(127, 102, 0), (192, 227, 0), (213, 255, 170), (98, 255, 133)) (98, 255, 133),
)
self.assert_unpack("RGB", "R", 1, (1, 0, 0), (2, 0, 0), (3, 0, 0)) self.assert_unpack("RGB", "R", 1, (1, 0, 0), (2, 0, 0), (3, 0, 0))
self.assert_unpack("RGB", "G", 1, (0, 1, 0), (0, 2, 0), (0, 3, 0)) self.assert_unpack("RGB", "G", 1, (0, 1, 0), (0, 2, 0), (0, 3, 0))
self.assert_unpack("RGB", "B", 1, (0, 0, 1), (0, 0, 2), (0, 0, 3)) self.assert_unpack("RGB", "B", 1, (0, 0, 1), (0, 0, 2), (0, 0, 3))
def test_RGBA(self): def test_RGBA(self):
self.assert_unpack("RGBA", "LA", 2, (1, 1, 1, 2), (3, 3, 3, 4), (5, 5, 5, 6))
self.assert_unpack( self.assert_unpack(
"RGBA", "LA", 2, (1, 1, 1, 2), (3, 3, 3, 4), (5, 5, 5, 6)) "RGBA", "LA;16B", 4, (1, 1, 1, 3), (5, 5, 5, 7), (9, 9, 9, 11)
)
self.assert_unpack( self.assert_unpack(
"RGBA", "LA;16B", 4, (1, 1, 1, 3), (5, 5, 5, 7), (9, 9, 9, 11)) "RGBA", "RGBA", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBA", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)) "RGBA", "RGBAX", 5, (1, 2, 3, 4), (6, 7, 8, 9), (11, 12, 13, 14)
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBAX", 5, (1, 2, 3, 4), (6, 7, 8, 9), (11, 12, 13, 14)) "RGBA", "RGBAXX", 6, (1, 2, 3, 4), (7, 8, 9, 10), (13, 14, 15, 16)
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBAXX", 6, (1, 2, 3, 4), (7, 8, 9, 10), (13, 14, 15, 16)) "RGBA",
"RGBa",
4,
(63, 127, 191, 4),
(159, 191, 223, 8),
(191, 212, 233, 12),
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBa", 4, "RGBA",
(63, 127, 191, 4), (159, 191, 223, 8), (191, 212, 233, 12)) "RGBa",
b"\x01\x02\x03\x00\x10\x20\x30\x7f\x10\x20\x30\xff",
(0, 0, 0, 0),
(32, 64, 96, 127),
(16, 32, 48, 255),
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBa", "RGBA",
b'\x01\x02\x03\x00\x10\x20\x30\x7f\x10\x20\x30\xff', "RGBaX",
(0, 0, 0, 0), (32, 64, 96, 127), (16, 32, 48, 255)) b"\x01\x02\x03\x00-\x10\x20\x30\x7f-\x10\x20\x30\xff-",
(0, 0, 0, 0),
(32, 64, 96, 127),
(16, 32, 48, 255),
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBaX", "RGBA",
b'\x01\x02\x03\x00-\x10\x20\x30\x7f-\x10\x20\x30\xff-', "RGBaXX",
(0, 0, 0, 0), (32, 64, 96, 127), (16, 32, 48, 255)) b"\x01\x02\x03\x00==\x10\x20\x30\x7f!!\x10\x20\x30\xff??",
(0, 0, 0, 0),
(32, 64, 96, 127),
(16, 32, 48, 255),
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBaXX", "RGBA",
b'\x01\x02\x03\x00==\x10\x20\x30\x7f!!\x10\x20\x30\xff??', "RGBa;16L",
(0, 0, 0, 0), (32, 64, 96, 127), (16, 32, 48, 255)) 8,
(63, 127, 191, 8),
(159, 191, 223, 16),
(191, 212, 233, 24),
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBa;16L", 8, "RGBA",
(63, 127, 191, 8), (159, 191, 223, 16), (191, 212, 233, 24)) "RGBa;16L",
b"\x88\x01\x88\x02\x88\x03\x88\x00" b"\x88\x10\x88\x20\x88\x30\x88\xff",
(0, 0, 0, 0),
(16, 32, 48, 255),
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBa;16L", "RGBA",
b'\x88\x01\x88\x02\x88\x03\x88\x00' "RGBa;16B",
b'\x88\x10\x88\x20\x88\x30\x88\xff', 8,
(0, 0, 0, 0), (16, 32, 48, 255)) (36, 109, 182, 7),
(153, 187, 221, 15),
(188, 210, 232, 23),
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBa;16B", 8, "RGBA",
(36, 109, 182, 7), (153, 187, 221, 15), (188, 210, 232, 23)) "RGBa;16B",
b"\x01\x88\x02\x88\x03\x88\x00\x88" b"\x10\x88\x20\x88\x30\x88\xff\x88",
(0, 0, 0, 0),
(16, 32, 48, 255),
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBa;16B", "RGBA",
b'\x01\x88\x02\x88\x03\x88\x00\x88' "BGRa",
b'\x10\x88\x20\x88\x30\x88\xff\x88', 4,
(0, 0, 0, 0), (16, 32, 48, 255)) (191, 127, 63, 4),
(223, 191, 159, 8),
(233, 212, 191, 12),
)
self.assert_unpack( self.assert_unpack(
"RGBA", "BGRa", 4, "RGBA",
(191, 127, 63, 4), (223, 191, 159, 8), (233, 212, 191, 12)) "BGRa",
b"\x01\x02\x03\x00\x10\x20\x30\xff",
(0, 0, 0, 0),
(48, 32, 16, 255),
)
self.assert_unpack( self.assert_unpack(
"RGBA", "BGRa", "RGBA",
b'\x01\x02\x03\x00\x10\x20\x30\xff', "RGBA;I",
(0, 0, 0, 0), (48, 32, 16, 255)) 4,
(254, 253, 252, 4),
(250, 249, 248, 8),
(246, 245, 244, 12),
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBA;I", 4, "RGBA", "RGBA;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)
(254, 253, 252, 4), (250, 249, 248, 8), (246, 245, 244, 12)) )
self.assert_unpack(
"RGBA", "RGBA;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12))
self.assert_unpack("RGBA", "RGBA;15", 2, (8, 131, 0, 0), (24, 0, 8, 0)) self.assert_unpack("RGBA", "RGBA;15", 2, (8, 131, 0, 0), (24, 0, 8, 0))
self.assert_unpack("RGBA", "BGRA;15", 2, (0, 131, 8, 0), (8, 0, 24, 0)) self.assert_unpack("RGBA", "BGRA;15", 2, (0, 131, 8, 0), (8, 0, 24, 0))
self.assert_unpack("RGBA", "RGBA;4B", 2, (17, 0, 34, 0), (51, 0, 68, 0))
self.assert_unpack("RGBA", "RGBA;16L", 8, (2, 4, 6, 8), (10, 12, 14, 16))
self.assert_unpack("RGBA", "RGBA;16B", 8, (1, 3, 5, 7), (9, 11, 13, 15))
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBA;4B", 2, (17, 0, 34, 0), (51, 0, 68, 0)) "RGBA", "BGRA", 4, (3, 2, 1, 4), (7, 6, 5, 8), (11, 10, 9, 12)
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBA;16L", 8, (2, 4, 6, 8), (10, 12, 14, 16)) "RGBA", "ARGB", 4, (2, 3, 4, 1), (6, 7, 8, 5), (10, 11, 12, 9)
)
self.assert_unpack( self.assert_unpack(
"RGBA", "RGBA;16B", 8, (1, 3, 5, 7), (9, 11, 13, 15)) "RGBA", "ABGR", 4, (4, 3, 2, 1), (8, 7, 6, 5), (12, 11, 10, 9)
)
self.assert_unpack( self.assert_unpack(
"RGBA", "BGRA", 4, (3, 2, 1, 4), (7, 6, 5, 8), (11, 10, 9, 12)) "RGBA",
self.assert_unpack( "YCCA;P",
"RGBA", "ARGB", 4, (2, 3, 4, 1), (6, 7, 8, 5), (10, 11, 12, 9)) b"]bE\x04\xdd\xbej\xed57T\xce\xac\xce:\x11", # random data
self.assert_unpack( (0, 161, 0, 4),
"RGBA", "ABGR", 4, (4, 3, 2, 1), (8, 7, 6, 5), (12, 11, 10, 9)) (255, 255, 255, 237),
self.assert_unpack( (27, 158, 0, 206),
"RGBA", "YCCA;P", (0, 118, 0, 17),
b']bE\x04\xdd\xbej\xed57T\xce\xac\xce:\x11', # random data )
(0, 161, 0, 4), (255, 255, 255, 237), self.assert_unpack("RGBA", "R", 1, (1, 0, 0, 0), (2, 0, 0, 0), (3, 0, 0, 0))
(27, 158, 0, 206), (0, 118, 0, 17)) self.assert_unpack("RGBA", "G", 1, (0, 1, 0, 0), (0, 2, 0, 0), (0, 3, 0, 0))
self.assert_unpack( self.assert_unpack("RGBA", "B", 1, (0, 0, 1, 0), (0, 0, 2, 0), (0, 0, 3, 0))
"RGBA", "R", 1, (1, 0, 0, 0), (2, 0, 0, 0), (3, 0, 0, 0)) self.assert_unpack("RGBA", "A", 1, (0, 0, 0, 1), (0, 0, 0, 2), (0, 0, 0, 3))
self.assert_unpack(
"RGBA", "G", 1, (0, 1, 0, 0), (0, 2, 0, 0), (0, 3, 0, 0))
self.assert_unpack(
"RGBA", "B", 1, (0, 0, 1, 0), (0, 0, 2, 0), (0, 0, 3, 0))
self.assert_unpack(
"RGBA", "A", 1, (0, 0, 0, 1), (0, 0, 0, 2), (0, 0, 0, 3))
def test_RGBa(self): def test_RGBa(self):
self.assert_unpack( self.assert_unpack(
"RGBa", "RGBa", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)) "RGBa", "RGBa", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)
)
self.assert_unpack( self.assert_unpack(
"RGBa", "BGRa", 4, (3, 2, 1, 4), (7, 6, 5, 8), (11, 10, 9, 12)) "RGBa", "BGRa", 4, (3, 2, 1, 4), (7, 6, 5, 8), (11, 10, 9, 12)
)
self.assert_unpack( self.assert_unpack(
"RGBa", "aRGB", 4, (2, 3, 4, 1), (6, 7, 8, 5), (10, 11, 12, 9)) "RGBa", "aRGB", 4, (2, 3, 4, 1), (6, 7, 8, 5), (10, 11, 12, 9)
)
self.assert_unpack( self.assert_unpack(
"RGBa", "aBGR", 4, (4, 3, 2, 1), (8, 7, 6, 5), (12, 11, 10, 9)) "RGBa", "aBGR", 4, (4, 3, 2, 1), (8, 7, 6, 5), (12, 11, 10, 9)
)
def test_RGBX(self): def test_RGBX(self):
self.assert_unpack("RGBX", "RGB", 3, self.assert_unpack("RGBX", "RGB", 3, (1, 2, 3, X), (4, 5, 6, X), (7, 8, 9, X))
(1, 2, 3, X), (4, 5, 6, X), (7, 8, 9, X)) self.assert_unpack("RGBX", "RGB;L", 3, (1, 4, 7, X), (2, 5, 8, X), (3, 6, 9, X))
self.assert_unpack("RGBX", "RGB;L", 3,
(1, 4, 7, X), (2, 5, 8, X), (3, 6, 9, X))
self.assert_unpack("RGBX", "RGB;16B", 6, (1, 3, 5, X), (7, 9, 11, X)) self.assert_unpack("RGBX", "RGB;16B", 6, (1, 3, 5, X), (7, 9, 11, X))
self.assert_unpack("RGBX", "BGR", 3, self.assert_unpack("RGBX", "BGR", 3, (3, 2, 1, X), (6, 5, 4, X), (9, 8, 7, X))
(3, 2, 1, X), (6, 5, 4, X), (9, 8, 7, X))
self.assert_unpack("RGBX", "RGB;15", 2, (8, 131, 0, X), (24, 0, 8, X)) self.assert_unpack("RGBX", "RGB;15", 2, (8, 131, 0, X), (24, 0, 8, X))
self.assert_unpack("RGBX", "BGR;15", 2, (0, 131, 8, X), (8, 0, 24, X)) self.assert_unpack("RGBX", "BGR;15", 2, (0, 131, 8, X), (8, 0, 24, X))
self.assert_unpack("RGBX", "RGB;4B", 2, (17, 0, 34, X), (51, 0, 68, X)) self.assert_unpack("RGBX", "RGB;4B", 2, (17, 0, 34, X), (51, 0, 68, X))
self.assert_unpack( self.assert_unpack(
"RGBX", "RGBX", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)) "RGBX", "RGBX", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)
)
self.assert_unpack( self.assert_unpack(
"RGBX", "RGBXX", 5, (1, 2, 3, 4), (6, 7, 8, 9), (11, 12, 13, 14)) "RGBX", "RGBXX", 5, (1, 2, 3, 4), (6, 7, 8, 9), (11, 12, 13, 14)
)
self.assert_unpack( self.assert_unpack(
"RGBX", "RGBXXX", 6, (1, 2, 3, 4), (7, 8, 9, 10), (13, 14, 15, 16)) "RGBX", "RGBXXX", 6, (1, 2, 3, 4), (7, 8, 9, 10), (13, 14, 15, 16)
)
self.assert_unpack( self.assert_unpack(
"RGBX", "RGBX;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)) "RGBX", "RGBX;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)
self.assert_unpack("RGBX", "RGBX;16L", 8, )
(2, 4, 6, 8), (10, 12, 14, 16)) self.assert_unpack("RGBX", "RGBX;16L", 8, (2, 4, 6, 8), (10, 12, 14, 16))
self.assert_unpack("RGBX", "RGBX;16B", 8, self.assert_unpack("RGBX", "RGBX;16B", 8, (1, 3, 5, 7), (9, 11, 13, 15))
(1, 3, 5, 7), (9, 11, 13, 15))
self.assert_unpack("RGBX", "BGRX", 4,
(3, 2, 1, X), (7, 6, 5, X), (11, 10, 9, X))
self.assert_unpack("RGBX", "XRGB", 4,
(2, 3, 4, X), (6, 7, 8, X), (10, 11, 12, X))
self.assert_unpack("RGBX", "XBGR", 4,
(4, 3, 2, X), (8, 7, 6, X), (12, 11, 10, X))
self.assert_unpack( self.assert_unpack(
"RGBX", "YCC;P", "RGBX", "BGRX", 4, (3, 2, 1, X), (7, 6, 5, X), (11, 10, 9, X)
b'D]\x9c\x82\x1a\x91\xfaOC\xe7J\x12', # random data )
(127, 102, 0, X), (192, 227, 0, X), self.assert_unpack(
(213, 255, 170, X), (98, 255, 133, X)) "RGBX", "XRGB", 4, (2, 3, 4, X), (6, 7, 8, X), (10, 11, 12, X)
self.assert_unpack("RGBX", "R", 1, )
(1, 0, 0, 0), (2, 0, 0, 0), (3, 0, 0, 0)) self.assert_unpack(
self.assert_unpack("RGBX", "G", 1, "RGBX", "XBGR", 4, (4, 3, 2, X), (8, 7, 6, X), (12, 11, 10, X)
(0, 1, 0, 0), (0, 2, 0, 0), (0, 3, 0, 0)) )
self.assert_unpack("RGBX", "B", 1, self.assert_unpack(
(0, 0, 1, 0), (0, 0, 2, 0), (0, 0, 3, 0)) "RGBX",
self.assert_unpack("RGBX", "X", 1, "YCC;P",
(0, 0, 0, 1), (0, 0, 0, 2), (0, 0, 0, 3)) b"D]\x9c\x82\x1a\x91\xfaOC\xe7J\x12", # random data
(127, 102, 0, X),
(192, 227, 0, X),
(213, 255, 170, X),
(98, 255, 133, X),
)
self.assert_unpack("RGBX", "R", 1, (1, 0, 0, 0), (2, 0, 0, 0), (3, 0, 0, 0))
self.assert_unpack("RGBX", "G", 1, (0, 1, 0, 0), (0, 2, 0, 0), (0, 3, 0, 0))
self.assert_unpack("RGBX", "B", 1, (0, 0, 1, 0), (0, 0, 2, 0), (0, 0, 3, 0))
self.assert_unpack("RGBX", "X", 1, (0, 0, 0, 1), (0, 0, 0, 2), (0, 0, 0, 3))
def test_CMYK(self): def test_CMYK(self):
self.assert_unpack( self.assert_unpack(
"CMYK", "CMYK", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)) "CMYK", "CMYK", 4, (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)
)
self.assert_unpack( self.assert_unpack(
"CMYK", "CMYKX", 5, (1, 2, 3, 4), (6, 7, 8, 9), (11, 12, 13, 14)) "CMYK", "CMYKX", 5, (1, 2, 3, 4), (6, 7, 8, 9), (11, 12, 13, 14)
)
self.assert_unpack( self.assert_unpack(
"CMYK", "CMYKXX", 6, (1, 2, 3, 4), (7, 8, 9, 10), (13, 14, 15, 16)) "CMYK", "CMYKXX", 6, (1, 2, 3, 4), (7, 8, 9, 10), (13, 14, 15, 16)
)
self.assert_unpack( self.assert_unpack(
"CMYK", "CMYK;I", 4, "CMYK",
(254, 253, 252, 251), (250, 249, 248, 247), (246, 245, 244, 243)) "CMYK;I",
4,
(254, 253, 252, 251),
(250, 249, 248, 247),
(246, 245, 244, 243),
)
self.assert_unpack( self.assert_unpack(
"CMYK", "CMYK;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)) "CMYK", "CMYK;L", 4, (1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)
self.assert_unpack("CMYK", "C", 1, )
(1, 0, 0, 0), (2, 0, 0, 0), (3, 0, 0, 0)) self.assert_unpack("CMYK", "C", 1, (1, 0, 0, 0), (2, 0, 0, 0), (3, 0, 0, 0))
self.assert_unpack("CMYK", "M", 1, self.assert_unpack("CMYK", "M", 1, (0, 1, 0, 0), (0, 2, 0, 0), (0, 3, 0, 0))
(0, 1, 0, 0), (0, 2, 0, 0), (0, 3, 0, 0)) self.assert_unpack("CMYK", "Y", 1, (0, 0, 1, 0), (0, 0, 2, 0), (0, 0, 3, 0))
self.assert_unpack("CMYK", "Y", 1, self.assert_unpack("CMYK", "K", 1, (0, 0, 0, 1), (0, 0, 0, 2), (0, 0, 0, 3))
(0, 0, 1, 0), (0, 0, 2, 0), (0, 0, 3, 0))
self.assert_unpack("CMYK", "K", 1,
(0, 0, 0, 1), (0, 0, 0, 2), (0, 0, 0, 3))
self.assert_unpack( self.assert_unpack(
"CMYK", "C;I", 1, (254, 0, 0, 0), (253, 0, 0, 0), (252, 0, 0, 0)) "CMYK", "C;I", 1, (254, 0, 0, 0), (253, 0, 0, 0), (252, 0, 0, 0)
)
self.assert_unpack( self.assert_unpack(
"CMYK", "M;I", 1, (0, 254, 0, 0), (0, 253, 0, 0), (0, 252, 0, 0)) "CMYK", "M;I", 1, (0, 254, 0, 0), (0, 253, 0, 0), (0, 252, 0, 0)
)
self.assert_unpack( self.assert_unpack(
"CMYK", "Y;I", 1, (0, 0, 254, 0), (0, 0, 253, 0), (0, 0, 252, 0)) "CMYK", "Y;I", 1, (0, 0, 254, 0), (0, 0, 253, 0), (0, 0, 252, 0)
)
self.assert_unpack( self.assert_unpack(
"CMYK", "K;I", 1, (0, 0, 0, 254), (0, 0, 0, 253), (0, 0, 0, 252)) "CMYK", "K;I", 1, (0, 0, 0, 254), (0, 0, 0, 253), (0, 0, 0, 252)
)
def test_YCbCr(self): def test_YCbCr(self):
self.assert_unpack( self.assert_unpack("YCbCr", "YCbCr", 3, (1, 2, 3), (4, 5, 6), (7, 8, 9))
"YCbCr", "YCbCr", 3, (1, 2, 3), (4, 5, 6), (7, 8, 9)) self.assert_unpack("YCbCr", "YCbCr;L", 3, (1, 4, 7), (2, 5, 8), (3, 6, 9))
self.assert_unpack( self.assert_unpack("YCbCr", "YCbCrK", 4, (1, 2, 3), (5, 6, 7), (9, 10, 11))
"YCbCr", "YCbCr;L", 3, (1, 4, 7), (2, 5, 8), (3, 6, 9)) self.assert_unpack("YCbCr", "YCbCrX", 4, (1, 2, 3), (5, 6, 7), (9, 10, 11))
self.assert_unpack(
"YCbCr", "YCbCrK", 4, (1, 2, 3), (5, 6, 7), (9, 10, 11))
self.assert_unpack(
"YCbCr", "YCbCrX", 4, (1, 2, 3), (5, 6, 7), (9, 10, 11))
def test_LAB(self): def test_LAB(self):
self.assert_unpack( self.assert_unpack("LAB", "LAB", 3, (1, 130, 131), (4, 133, 134), (7, 136, 137))
"LAB", "LAB", 3, (1, 130, 131), (4, 133, 134), (7, 136, 137))
self.assert_unpack("LAB", "L", 1, (1, 0, 0), (2, 0, 0), (3, 0, 0)) self.assert_unpack("LAB", "L", 1, (1, 0, 0), (2, 0, 0), (3, 0, 0))
self.assert_unpack("LAB", "A", 1, (0, 1, 0), (0, 2, 0), (0, 3, 0)) self.assert_unpack("LAB", "A", 1, (0, 1, 0), (0, 2, 0), (0, 3, 0))
self.assert_unpack("LAB", "B", 1, (0, 0, 1), (0, 0, 2), (0, 0, 3)) self.assert_unpack("LAB", "B", 1, (0, 0, 1), (0, 0, 2), (0, 0, 3))
@ -494,120 +562,141 @@ class TestLibUnpack(PillowTestCase):
def test_I(self): def test_I(self):
self.assert_unpack("I", "I;8", 1, 0x01, 0x02, 0x03, 0x04) self.assert_unpack("I", "I;8", 1, 0x01, 0x02, 0x03, 0x04)
self.assert_unpack("I", "I;8S", b'\x01\x83', 1, -125) self.assert_unpack("I", "I;8S", b"\x01\x83", 1, -125)
self.assert_unpack("I", "I;16", 2, 0x0201, 0x0403) self.assert_unpack("I", "I;16", 2, 0x0201, 0x0403)
self.assert_unpack("I", "I;16S", b'\x83\x01\x01\x83', 0x0183, -31999) self.assert_unpack("I", "I;16S", b"\x83\x01\x01\x83", 0x0183, -31999)
self.assert_unpack("I", "I;16B", 2, 0x0102, 0x0304) self.assert_unpack("I", "I;16B", 2, 0x0102, 0x0304)
self.assert_unpack("I", "I;16BS", b'\x83\x01\x01\x83', -31999, 0x0183) self.assert_unpack("I", "I;16BS", b"\x83\x01\x01\x83", -31999, 0x0183)
self.assert_unpack("I", "I;32", 4, 0x04030201, 0x08070605) self.assert_unpack("I", "I;32", 4, 0x04030201, 0x08070605)
self.assert_unpack( self.assert_unpack(
"I", "I;32S", "I", "I;32S", b"\x83\x00\x00\x01\x01\x00\x00\x83", 0x01000083, -2097151999
b'\x83\x00\x00\x01\x01\x00\x00\x83', 0x01000083, -2097151999) )
self.assert_unpack("I", "I;32B", 4, 0x01020304, 0x05060708) self.assert_unpack("I", "I;32B", 4, 0x01020304, 0x05060708)
self.assert_unpack( self.assert_unpack(
"I", "I;32BS", "I", "I;32BS", b"\x83\x00\x00\x01\x01\x00\x00\x83", -2097151999, 0x01000083
b'\x83\x00\x00\x01\x01\x00\x00\x83', -2097151999, 0x01000083) )
if sys.byteorder == 'little': if sys.byteorder == "little":
self.assert_unpack("I", "I", 4, 0x04030201, 0x08070605) self.assert_unpack("I", "I", 4, 0x04030201, 0x08070605)
self.assert_unpack("I", "I;16N", 2, 0x0201, 0x0403) self.assert_unpack("I", "I;16N", 2, 0x0201, 0x0403)
self.assert_unpack("I", "I;16NS", self.assert_unpack("I", "I;16NS", b"\x83\x01\x01\x83", 0x0183, -31999)
b'\x83\x01\x01\x83', 0x0183, -31999)
self.assert_unpack("I", "I;32N", 4, 0x04030201, 0x08070605) self.assert_unpack("I", "I;32N", 4, 0x04030201, 0x08070605)
self.assert_unpack( self.assert_unpack(
"I", "I;32NS", "I",
b'\x83\x00\x00\x01\x01\x00\x00\x83', 0x01000083, -2097151999) "I;32NS",
b"\x83\x00\x00\x01\x01\x00\x00\x83",
0x01000083,
-2097151999,
)
else: else:
self.assert_unpack("I", "I", 4, 0x01020304, 0x05060708) self.assert_unpack("I", "I", 4, 0x01020304, 0x05060708)
self.assert_unpack("I", "I;16N", 2, 0x0102, 0x0304) self.assert_unpack("I", "I;16N", 2, 0x0102, 0x0304)
self.assert_unpack("I", "I;16NS", self.assert_unpack("I", "I;16NS", b"\x83\x01\x01\x83", -31999, 0x0183)
b'\x83\x01\x01\x83', -31999, 0x0183)
self.assert_unpack("I", "I;32N", 4, 0x01020304, 0x05060708) self.assert_unpack("I", "I;32N", 4, 0x01020304, 0x05060708)
self.assert_unpack( self.assert_unpack(
"I", "I;32NS", "I",
b'\x83\x00\x00\x01\x01\x00\x00\x83', -2097151999, 0x01000083) "I;32NS",
b"\x83\x00\x00\x01\x01\x00\x00\x83",
-2097151999,
0x01000083,
)
def test_F_int(self): def test_F_int(self):
self.assert_unpack("F", "F;8", 1, 0x01, 0x02, 0x03, 0x04) self.assert_unpack("F", "F;8", 1, 0x01, 0x02, 0x03, 0x04)
self.assert_unpack("F", "F;8S", b'\x01\x83', 1, -125) self.assert_unpack("F", "F;8S", b"\x01\x83", 1, -125)
self.assert_unpack("F", "F;16", 2, 0x0201, 0x0403) self.assert_unpack("F", "F;16", 2, 0x0201, 0x0403)
self.assert_unpack("F", "F;16S", b'\x83\x01\x01\x83', 0x0183, -31999) self.assert_unpack("F", "F;16S", b"\x83\x01\x01\x83", 0x0183, -31999)
self.assert_unpack("F", "F;16B", 2, 0x0102, 0x0304) self.assert_unpack("F", "F;16B", 2, 0x0102, 0x0304)
self.assert_unpack("F", "F;16BS", b'\x83\x01\x01\x83', -31999, 0x0183) self.assert_unpack("F", "F;16BS", b"\x83\x01\x01\x83", -31999, 0x0183)
self.assert_unpack("F", "F;32", 4, 67305984, 134678016) self.assert_unpack("F", "F;32", 4, 67305984, 134678016)
self.assert_unpack( self.assert_unpack(
"F", "F;32S", "F", "F;32S", b"\x83\x00\x00\x01\x01\x00\x00\x83", 16777348, -2097152000
b'\x83\x00\x00\x01\x01\x00\x00\x83', 16777348, -2097152000) )
self.assert_unpack("F", "F;32B", 4, 0x01020304, 0x05060708) self.assert_unpack("F", "F;32B", 4, 0x01020304, 0x05060708)
self.assert_unpack( self.assert_unpack(
"F", "F;32BS", "F", "F;32BS", b"\x83\x00\x00\x01\x01\x00\x00\x83", -2097152000, 16777348
b'\x83\x00\x00\x01\x01\x00\x00\x83', -2097152000, 16777348) )
if sys.byteorder == 'little': if sys.byteorder == "little":
self.assert_unpack("F", "F;16N", 2, 0x0201, 0x0403) self.assert_unpack("F", "F;16N", 2, 0x0201, 0x0403)
self.assert_unpack( self.assert_unpack("F", "F;16NS", b"\x83\x01\x01\x83", 0x0183, -31999)
"F", "F;16NS",
b'\x83\x01\x01\x83', 0x0183, -31999)
self.assert_unpack("F", "F;32N", 4, 67305984, 134678016) self.assert_unpack("F", "F;32N", 4, 67305984, 134678016)
self.assert_unpack( self.assert_unpack(
"F", "F;32NS", "F",
b'\x83\x00\x00\x01\x01\x00\x00\x83', 16777348, -2097152000) "F;32NS",
b"\x83\x00\x00\x01\x01\x00\x00\x83",
16777348,
-2097152000,
)
else: else:
self.assert_unpack("F", "F;16N", 2, 0x0102, 0x0304) self.assert_unpack("F", "F;16N", 2, 0x0102, 0x0304)
self.assert_unpack( self.assert_unpack("F", "F;16NS", b"\x83\x01\x01\x83", -31999, 0x0183)
"F", "F;16NS",
b'\x83\x01\x01\x83', -31999, 0x0183)
self.assert_unpack("F", "F;32N", 4, 0x01020304, 0x05060708) self.assert_unpack("F", "F;32N", 4, 0x01020304, 0x05060708)
self.assert_unpack( self.assert_unpack(
"F", "F;32NS", "F",
b'\x83\x00\x00\x01\x01\x00\x00\x83', "F;32NS",
-2097152000, 16777348) b"\x83\x00\x00\x01\x01\x00\x00\x83",
-2097152000,
16777348,
)
def test_F_float(self): def test_F_float(self):
self.assert_unpack( self.assert_unpack(
"F", "F;32F", 4, "F", "F;32F", 4, 1.539989614439558e-36, 4.063216068939723e-34
1.539989614439558e-36, 4.063216068939723e-34) )
self.assert_unpack( self.assert_unpack(
"F", "F;32BF", 4, "F", "F;32BF", 4, 2.387939260590663e-38, 6.301941157072183e-36
2.387939260590663e-38, 6.301941157072183e-36) )
self.assert_unpack( self.assert_unpack(
"F", "F;64F", "F",
b'333333\xc3?\x00\x00\x00\x00\x00J\x93\xc0', # by struct.pack "F;64F",
0.15000000596046448, -1234.5) b"333333\xc3?\x00\x00\x00\x00\x00J\x93\xc0", # by struct.pack
0.15000000596046448,
-1234.5,
)
self.assert_unpack( self.assert_unpack(
"F", "F;64BF", "F",
b'?\xc3333333\xc0\x93J\x00\x00\x00\x00\x00', # by struct.pack "F;64BF",
0.15000000596046448, -1234.5) b"?\xc3333333\xc0\x93J\x00\x00\x00\x00\x00", # by struct.pack
0.15000000596046448,
-1234.5,
)
if sys.byteorder == 'little': if sys.byteorder == "little":
self.assert_unpack( self.assert_unpack(
"F", "F", 4, "F", "F", 4, 1.539989614439558e-36, 4.063216068939723e-34
1.539989614439558e-36, 4.063216068939723e-34) )
self.assert_unpack( self.assert_unpack(
"F", "F;32NF", 4, "F", "F;32NF", 4, 1.539989614439558e-36, 4.063216068939723e-34
1.539989614439558e-36, 4.063216068939723e-34) )
self.assert_unpack( self.assert_unpack(
"F", "F;64NF", "F",
b'333333\xc3?\x00\x00\x00\x00\x00J\x93\xc0', "F;64NF",
0.15000000596046448, -1234.5) b"333333\xc3?\x00\x00\x00\x00\x00J\x93\xc0",
0.15000000596046448,
-1234.5,
)
else: else:
self.assert_unpack( self.assert_unpack(
"F", "F", 4, "F", "F", 4, 2.387939260590663e-38, 6.301941157072183e-36
2.387939260590663e-38, 6.301941157072183e-36) )
self.assert_unpack( self.assert_unpack(
"F", "F;32NF", 4, "F", "F;32NF", 4, 2.387939260590663e-38, 6.301941157072183e-36
2.387939260590663e-38, 6.301941157072183e-36) )
self.assert_unpack( self.assert_unpack(
"F", "F;64NF", "F",
b'?\xc3333333\xc0\x93J\x00\x00\x00\x00\x00', "F;64NF",
0.15000000596046448, -1234.5) b"?\xc3333333\xc0\x93J\x00\x00\x00\x00\x00",
0.15000000596046448,
-1234.5,
)
def test_I16(self): def test_I16(self):
self.assert_unpack("I;16", "I;16", 2, 0x0201, 0x0403, 0x0605) self.assert_unpack("I;16", "I;16", 2, 0x0201, 0x0403, 0x0605)
self.assert_unpack("I;16B", "I;16B", 2, 0x0102, 0x0304, 0x0506) self.assert_unpack("I;16B", "I;16B", 2, 0x0102, 0x0304, 0x0506)
self.assert_unpack("I;16L", "I;16L", 2, 0x0201, 0x0403, 0x0605) self.assert_unpack("I;16L", "I;16L", 2, 0x0201, 0x0403, 0x0605)
self.assert_unpack("I;16", "I;12", 2, 0x0010, 0x0203, 0x0040) self.assert_unpack("I;16", "I;12", 2, 0x0010, 0x0203, 0x0040)
if sys.byteorder == 'little': if sys.byteorder == "little":
self.assert_unpack("I;16", "I;16N", 2, 0x0201, 0x0403, 0x0605) self.assert_unpack("I;16", "I;16N", 2, 0x0201, 0x0403, 0x0605)
self.assert_unpack("I;16B", "I;16N", 2, 0x0201, 0x0403, 0x0605) self.assert_unpack("I;16B", "I;16N", 2, 0x0201, 0x0403, 0x0605)
self.assert_unpack("I;16L", "I;16N", 2, 0x0201, 0x0403, 0x0605) self.assert_unpack("I;16L", "I;16N", 2, 0x0201, 0x0403, 0x0605)

View File

@ -24,11 +24,10 @@ path = "Tests/images/hopper.jpg"
class TestLocale(PillowTestCase): class TestLocale(PillowTestCase):
def test_sanity(self): def test_sanity(self):
Image.open(path) Image.open(path)
try: try:
locale.setlocale(locale.LC_ALL, "polish") locale.setlocale(locale.LC_ALL, "polish")
except locale.Error: except locale.Error:
unittest.skip('Polish locale not available') unittest.skip("Polish locale not available")
Image.open(path) Image.open(path)

View File

@ -4,8 +4,7 @@ import sys
from PIL import Image from PIL import Image
@unittest.skipIf(sys.platform.startswith('win32'), @unittest.skipIf(sys.platform.startswith("win32"), "Win32 does not call map_buffer")
"Win32 does not call map_buffer")
class TestMap(PillowTestCase): class TestMap(PillowTestCase):
def test_overflow(self): def test_overflow(self):
# There is the potential to overflow comparisons in map.c # There is the potential to overflow comparisons in map.c
@ -18,7 +17,7 @@ class TestMap(PillowTestCase):
Image.MAX_IMAGE_PIXELS = None Image.MAX_IMAGE_PIXELS = None
# This image hits the offset test. # This image hits the offset test.
im = Image.open('Tests/images/l2rgb_read.bmp') im = Image.open("Tests/images/l2rgb_read.bmp")
with self.assertRaises((ValueError, MemoryError, IOError)): with self.assertRaises((ValueError, MemoryError, IOError)):
im.load() im.load()

View File

@ -5,7 +5,7 @@ from PIL import Image
class TestModeI16(PillowTestCase): class TestModeI16(PillowTestCase):
original = hopper().resize((32, 32)).convert('I') original = hopper().resize((32, 32)).convert("I")
def verify(self, im1): def verify(self, im1):
im2 = self.original.copy() im2 = self.original.copy()
@ -18,9 +18,10 @@ class TestModeI16(PillowTestCase):
p1 = pix1[xy] p1 = pix1[xy]
p2 = pix2[xy] p2 = pix2[xy]
self.assertEqual( self.assertEqual(
p1, p2, p1,
("got %r from mode %s at %s, expected %r" % p2,
(p1, im1.mode, xy, p2))) ("got %r from mode %s at %s, expected %r" % (p1, im1.mode, xy, p2)),
)
def test_basic(self): def test_basic(self):
# PIL 1.1 has limited support for 16-bit image data. Check that # PIL 1.1 has limited support for 16-bit image data. Check that
@ -51,8 +52,8 @@ class TestModeI16(PillowTestCase):
self.verify(imOut) self.verify(imOut)
imOut = Image.new(mode, (w, h), None) imOut = Image.new(mode, (w, h), None)
imOut.paste(imIn.crop((0, 0, w//2, h)), (0, 0)) imOut.paste(imIn.crop((0, 0, w // 2, h)), (0, 0))
imOut.paste(imIn.crop((w//2, 0, w, h)), (w//2, 0)) imOut.paste(imIn.crop((w // 2, 0, w, h)), (w // 2, 0))
self.verify(imIn) self.verify(imIn)
self.verify(imOut) self.verify(imOut)
@ -83,11 +84,10 @@ class TestModeI16(PillowTestCase):
basic("I") basic("I")
def test_tobytes(self): def test_tobytes(self):
def tobytes(mode): def tobytes(mode):
return Image.new(mode, (1, 1), 1).tobytes() return Image.new(mode, (1, 1), 1).tobytes()
order = 1 if Image._ENDIAN == '<' else -1 order = 1 if Image._ENDIAN == "<" else -1
self.assertEqual(tobytes("L"), b"\x01") self.assertEqual(tobytes("L"), b"\x01")
self.assertEqual(tobytes("I;16"), b"\x01\x00") self.assertEqual(tobytes("I;16"), b"\x01\x00")

View File

@ -15,7 +15,6 @@ TEST_IMAGE_SIZE = (10, 10)
@unittest.skipIf(numpy is None, "Numpy is not installed") @unittest.skipIf(numpy is None, "Numpy is not installed")
class TestNumpy(PillowTestCase): class TestNumpy(PillowTestCase):
def test_numpy_to_image(self): def test_numpy_to_image(self):
def to_image(dtype, bands=1, boolean=0): def to_image(dtype, bands=1, boolean=0):
if bands == 1: if bands == 1:
if boolean: if boolean:
@ -29,7 +28,7 @@ class TestNumpy(PillowTestCase):
print("data mismatch for", dtype) print("data mismatch for", dtype)
else: else:
data = list(range(100)) data = list(range(100))
a = numpy.array([[x]*bands for x in data], dtype=dtype) a = numpy.array([[x] * bands for x in data], dtype=dtype)
a.shape = TEST_IMAGE_SIZE[0], TEST_IMAGE_SIZE[1], bands a.shape = TEST_IMAGE_SIZE[0], TEST_IMAGE_SIZE[1], bands
i = Image.fromarray(a) i = Image.fromarray(a)
if list(i.getchannel(0).getdata()) != list(range(100)): if list(i.getchannel(0).getdata()) != list(range(100)):
@ -37,8 +36,8 @@ class TestNumpy(PillowTestCase):
return i return i
# Check supported 1-bit integer formats # Check supported 1-bit integer formats
self.assert_image(to_image(numpy.bool, 1, 1), '1', TEST_IMAGE_SIZE) self.assert_image(to_image(numpy.bool, 1, 1), "1", TEST_IMAGE_SIZE)
self.assert_image(to_image(numpy.bool8, 1, 1), '1', TEST_IMAGE_SIZE) self.assert_image(to_image(numpy.bool8, 1, 1), "1", TEST_IMAGE_SIZE)
# Check supported 8-bit integer formats # Check supported 8-bit integer formats
self.assert_image(to_image(numpy.uint8), "L", TEST_IMAGE_SIZE) self.assert_image(to_image(numpy.uint8), "L", TEST_IMAGE_SIZE)
@ -53,7 +52,7 @@ class TestNumpy(PillowTestCase):
# self.assert_image(to_image(numpy.int), "I", TEST_IMAGE_SIZE) # self.assert_image(to_image(numpy.int), "I", TEST_IMAGE_SIZE)
# Check 16-bit integer formats # Check 16-bit integer formats
if Image._ENDIAN == '<': if Image._ENDIAN == "<":
self.assert_image(to_image(numpy.uint16), "I;16", TEST_IMAGE_SIZE) self.assert_image(to_image(numpy.uint16), "I;16", TEST_IMAGE_SIZE)
else: else:
self.assert_image(to_image(numpy.uint16), "I;16B", TEST_IMAGE_SIZE) self.assert_image(to_image(numpy.uint16), "I;16B", TEST_IMAGE_SIZE)
@ -96,22 +95,22 @@ class TestNumpy(PillowTestCase):
np_size = np.shape[1], np.shape[0] np_size = np.shape[1], np.shape[0]
self.assertEqual(img.size, np_size) self.assertEqual(img.size, np_size)
px = img.load() px = img.load()
for x in range(0, img.size[0], int(img.size[0]/10)): for x in range(0, img.size[0], int(img.size[0] / 10)):
for y in range(0, img.size[1], int(img.size[1]/10)): for y in range(0, img.size[1], int(img.size[1] / 10)):
self.assert_deep_equal(px[x, y], np[y, x]) self.assert_deep_equal(px[x, y], np[y, x])
def test_16bit(self): def test_16bit(self):
img = Image.open('Tests/images/16bit.cropped.tif') img = Image.open("Tests/images/16bit.cropped.tif")
np_img = numpy.array(img) np_img = numpy.array(img)
self._test_img_equals_nparray(img, np_img) self._test_img_equals_nparray(img, np_img)
self.assertEqual(np_img.dtype, numpy.dtype('<u2')) self.assertEqual(np_img.dtype, numpy.dtype("<u2"))
def test_1bit(self): def test_1bit(self):
# Test that 1-bit arrays convert to numpy and back # Test that 1-bit arrays convert to numpy and back
# See: https://github.com/python-pillow/Pillow/issues/350 # See: https://github.com/python-pillow/Pillow/issues/350
arr = numpy.array([[1, 0, 0, 1, 0], [0, 1, 0, 0, 0]], 'u1') arr = numpy.array([[1, 0, 0, 1, 0], [0, 1, 0, 0, 0]], "u1")
img = Image.fromarray(arr * 255).convert('1') img = Image.fromarray(arr * 255).convert("1")
self.assertEqual(img.mode, '1') self.assertEqual(img.mode, "1")
arr_back = numpy.array(img) arr_back = numpy.array(img)
numpy.testing.assert_array_equal(arr, arr_back) numpy.testing.assert_array_equal(arr, arr_back)
@ -119,8 +118,8 @@ class TestNumpy(PillowTestCase):
# Tests that we're getting the pixel value in the right byte order. # Tests that we're getting the pixel value in the right byte order.
pixel_value = 0x1234 pixel_value = 0x1234
a = numpy.array( a = numpy.array(
[pixel_value] * TEST_IMAGE_SIZE[0] * TEST_IMAGE_SIZE[1], [pixel_value] * TEST_IMAGE_SIZE[0] * TEST_IMAGE_SIZE[1], dtype=numpy.uint16
dtype=numpy.uint16) )
a.shape = TEST_IMAGE_SIZE a.shape = TEST_IMAGE_SIZE
img = Image.fromarray(a) img = Image.fromarray(a)
@ -128,7 +127,6 @@ class TestNumpy(PillowTestCase):
self.assertEqual(img_px[0, 0], pixel_value) self.assertEqual(img_px[0, 0], pixel_value)
def test_to_array(self): def test_to_array(self):
def _to_array(mode, dtype): def _to_array(mode, dtype):
img = hopper(mode) img = hopper(mode)
@ -140,7 +138,8 @@ class TestNumpy(PillowTestCase):
self._test_img_equals_nparray(img, np_img) self._test_img_equals_nparray(img, np_img)
self.assertEqual(np_img.dtype, dtype) self.assertEqual(np_img.dtype, dtype)
modes = [("L", numpy.uint8), modes = [
("L", numpy.uint8),
("I", numpy.int32), ("I", numpy.int32),
("F", numpy.float32), ("F", numpy.float32),
("LA", numpy.uint8), ("LA", numpy.uint8),
@ -149,9 +148,9 @@ class TestNumpy(PillowTestCase):
("RGBX", numpy.uint8), ("RGBX", numpy.uint8),
("CMYK", numpy.uint8), ("CMYK", numpy.uint8),
("YCbCr", numpy.uint8), ("YCbCr", numpy.uint8),
("I;16", '<u2'), ("I;16", "<u2"),
("I;16B", '>u2'), ("I;16B", ">u2"),
("I;16L", '<u2'), ("I;16L", "<u2"),
("HSV", numpy.uint8), ("HSV", numpy.uint8),
] ]
@ -161,7 +160,7 @@ class TestNumpy(PillowTestCase):
def test_point_lut(self): def test_point_lut(self):
# see https://github.com/python-pillow/Pillow/issues/439 # see https://github.com/python-pillow/Pillow/issues/439
data = list(range(256))*3 data = list(range(256)) * 3
lut = numpy.array(data, dtype=numpy.uint8) lut = numpy.array(data, dtype=numpy.uint8)
im = hopper() im = hopper()
@ -172,17 +171,26 @@ class TestNumpy(PillowTestCase):
# shouldn't segfault # shouldn't segfault
# see https://github.com/python-pillow/Pillow/issues/1008 # see https://github.com/python-pillow/Pillow/issues/1008
im = Image.new('F', (150, 100)) im = Image.new("F", (150, 100))
arr = numpy.zeros((15000,), numpy.float32) arr = numpy.zeros((15000,), numpy.float32)
im.putdata(arr) im.putdata(arr)
self.assertEqual(len(im.getdata()), len(arr)) self.assertEqual(len(im.getdata()), len(arr))
def test_roundtrip_eye(self): def test_roundtrip_eye(self):
for dtype in (numpy.bool, numpy.bool8, for dtype in (
numpy.int8, numpy.int16, numpy.int32, numpy.bool,
numpy.uint8, numpy.uint16, numpy.uint32, numpy.bool8,
numpy.float, numpy.float32, numpy.float64): numpy.int8,
numpy.int16,
numpy.int32,
numpy.uint8,
numpy.uint16,
numpy.uint32,
numpy.float,
numpy.float32,
numpy.float64,
):
arr = numpy.eye(10, dtype=dtype) arr = numpy.eye(10, dtype=dtype)
numpy.testing.assert_array_equal(arr, numpy.array(Image.fromarray(arr))) numpy.testing.assert_array_equal(arr, numpy.array(Image.fromarray(arr)))
@ -206,7 +214,8 @@ class TestNumpy(PillowTestCase):
# https://github.com/python-pillow/Pillow/issues/835 # https://github.com/python-pillow/Pillow/issues/835
# Arrange # Arrange
from numpy import array from numpy import array
test_file = 'Tests/images/hopper.png'
test_file = "Tests/images/hopper.png"
im = Image.open(test_file) im = Image.open(test_file)
# Act/Assert # Act/Assert

View File

@ -1,13 +1,22 @@
from .helper import PillowTestCase from .helper import PillowTestCase
from PIL.PdfParser import IndirectObjectDef, IndirectReference, PdfBinary, \ from PIL.PdfParser import (
PdfDict, PdfFormatError, PdfName, PdfParser, \ IndirectObjectDef,
PdfStream, decode_text, encode_text, pdf_repr IndirectReference,
PdfBinary,
PdfDict,
PdfFormatError,
PdfName,
PdfParser,
PdfStream,
decode_text,
encode_text,
pdf_repr,
)
import time import time
class TestPdfParser(PillowTestCase): class TestPdfParser(PillowTestCase):
def test_text_encode_decode(self): def test_text_encode_decode(self):
self.assertEqual(encode_text("abc"), b"\xFE\xFF\x00a\x00b\x00c") self.assertEqual(encode_text("abc"), b"\xFE\xFF\x00a\x00b\x00c")
self.assertEqual(decode_text(b"\xFE\xFF\x00a\x00b\x00c"), "abc") self.assertEqual(decode_text(b"\xFE\xFF\x00a\x00b\x00c"), "abc")
@ -25,37 +34,37 @@ class TestPdfParser(PillowTestCase):
self.assertNotEqual(IndirectObjectDef(1, 2), (1, 2)) self.assertNotEqual(IndirectObjectDef(1, 2), (1, 2))
def test_parsing(self): def test_parsing(self):
self.assertEqual(PdfParser.interpret_name(b"Name#23Hash"), self.assertEqual(PdfParser.interpret_name(b"Name#23Hash"), b"Name#Hash")
b"Name#Hash") self.assertEqual(
self.assertEqual(PdfParser.interpret_name( PdfParser.interpret_name(b"Name#23Hash", as_text=True), "Name#Hash"
b"Name#23Hash", as_text=True )
), "Name#Hash") self.assertEqual(
self.assertEqual(PdfParser.get_value(b"1 2 R ", 0), PdfParser.get_value(b"1 2 R ", 0), (IndirectReference(1, 2), 5)
(IndirectReference(1, 2), 5)) )
self.assertEqual(PdfParser.get_value(b"true[", 0), (True, 4)) self.assertEqual(PdfParser.get_value(b"true[", 0), (True, 4))
self.assertEqual(PdfParser.get_value(b"false%", 0), (False, 5)) self.assertEqual(PdfParser.get_value(b"false%", 0), (False, 5))
self.assertEqual(PdfParser.get_value(b"null<", 0), (None, 4)) self.assertEqual(PdfParser.get_value(b"null<", 0), (None, 4))
self.assertEqual(PdfParser.get_value(b"%cmt\n %cmt\n 123\n", 0), self.assertEqual(PdfParser.get_value(b"%cmt\n %cmt\n 123\n", 0), (123, 15))
(123, 15)) self.assertEqual(PdfParser.get_value(b"<901FA3>", 0), (b"\x90\x1F\xA3", 8))
self.assertEqual(PdfParser.get_value(b"<901FA3>", 0), self.assertEqual(
(b"\x90\x1F\xA3", 8)) PdfParser.get_value(b"asd < 9 0 1 f A > qwe", 3), (b"\x90\x1F\xA0", 17)
self.assertEqual(PdfParser.get_value(b"asd < 9 0 1 f A > qwe", 3), )
(b"\x90\x1F\xA0", 17))
self.assertEqual(PdfParser.get_value(b"(asd)", 0), (b"asd", 5)) self.assertEqual(PdfParser.get_value(b"(asd)", 0), (b"asd", 5))
self.assertEqual(PdfParser.get_value(b"(asd(qwe)zxc)zzz(aaa)", 0), self.assertEqual(
(b"asd(qwe)zxc", 13)) PdfParser.get_value(b"(asd(qwe)zxc)zzz(aaa)", 0), (b"asd(qwe)zxc", 13)
self.assertEqual(PdfParser.get_value(b"(Two \\\nwords.)", 0), )
(b"Two words.", 14)) self.assertEqual(
self.assertEqual(PdfParser.get_value(b"(Two\nlines.)", 0), PdfParser.get_value(b"(Two \\\nwords.)", 0), (b"Two words.", 14)
(b"Two\nlines.", 12)) )
self.assertEqual(PdfParser.get_value(b"(Two\r\nlines.)", 0), self.assertEqual(PdfParser.get_value(b"(Two\nlines.)", 0), (b"Two\nlines.", 12))
(b"Two\nlines.", 13)) self.assertEqual(
self.assertEqual(PdfParser.get_value(b"(Two\\nlines.)", 0), PdfParser.get_value(b"(Two\r\nlines.)", 0), (b"Two\nlines.", 13)
(b"Two\nlines.", 13)) )
self.assertEqual(PdfParser.get_value(b"(One\\(paren).", 0), self.assertEqual(
(b"One(paren", 12)) PdfParser.get_value(b"(Two\\nlines.)", 0), (b"Two\nlines.", 13)
self.assertEqual(PdfParser.get_value(b"(One\\)paren).", 0), )
(b"One)paren", 12)) self.assertEqual(PdfParser.get_value(b"(One\\(paren).", 0), (b"One(paren", 12))
self.assertEqual(PdfParser.get_value(b"(One\\)paren).", 0), (b"One)paren", 12))
self.assertEqual(PdfParser.get_value(b"(\\0053)", 0), (b"\x053", 7)) self.assertEqual(PdfParser.get_value(b"(\\0053)", 0), (b"\x053", 7))
self.assertEqual(PdfParser.get_value(b"(\\053)", 0), (b"\x2B", 6)) self.assertEqual(PdfParser.get_value(b"(\\053)", 0), (b"\x2B", 6))
self.assertEqual(PdfParser.get_value(b"(\\53)", 0), (b"\x2B", 5)) self.assertEqual(PdfParser.get_value(b"(\\53)", 0), (b"\x2B", 5))
@ -88,37 +97,43 @@ class TestPdfParser(PillowTestCase):
b"D:2018072921": "20180729210000", b"D:2018072921": "20180729210000",
b"D:20180729214124Z": "20180729214124", b"D:20180729214124Z": "20180729214124",
b"D:20180729214124+08'00'": "20180729134124", b"D:20180729214124+08'00'": "20180729134124",
b"D:20180729214124-05'00'": "20180730024124" b"D:20180729214124-05'00'": "20180730024124",
}.items(): }.items():
d = PdfParser.get_value( d = PdfParser.get_value(
b"<</"+name.encode()+b" ("+date+b")>>", 0)[0] b"<</" + name.encode() + b" (" + date + b")>>", 0
self.assertEqual( )[0]
time.strftime("%Y%m%d%H%M%S", getattr(d, name)), value) self.assertEqual(time.strftime("%Y%m%d%H%M%S", getattr(d, name)), value)
def test_pdf_repr(self): def test_pdf_repr(self):
self.assertEqual(bytes(IndirectReference(1, 2)), b"1 2 R") self.assertEqual(bytes(IndirectReference(1, 2)), b"1 2 R")
self.assertEqual(bytes(IndirectObjectDef(*IndirectReference(1, 2))), self.assertEqual(bytes(IndirectObjectDef(*IndirectReference(1, 2))), b"1 2 obj")
b"1 2 obj")
self.assertEqual(bytes(PdfName(b"Name#Hash")), b"/Name#23Hash") self.assertEqual(bytes(PdfName(b"Name#Hash")), b"/Name#23Hash")
self.assertEqual(bytes(PdfName("Name#Hash")), b"/Name#23Hash") self.assertEqual(bytes(PdfName("Name#Hash")), b"/Name#23Hash")
self.assertEqual(bytes(PdfDict({b"Name": IndirectReference(1, 2)})), self.assertEqual(
b"<<\n/Name 1 2 R\n>>") bytes(PdfDict({b"Name": IndirectReference(1, 2)})), b"<<\n/Name 1 2 R\n>>"
self.assertEqual(bytes(PdfDict({"Name": IndirectReference(1, 2)})), )
b"<<\n/Name 1 2 R\n>>") self.assertEqual(
bytes(PdfDict({"Name": IndirectReference(1, 2)})), b"<<\n/Name 1 2 R\n>>"
)
self.assertEqual(pdf_repr(IndirectReference(1, 2)), b"1 2 R") self.assertEqual(pdf_repr(IndirectReference(1, 2)), b"1 2 R")
self.assertEqual(pdf_repr(IndirectObjectDef(*IndirectReference(1, 2))), self.assertEqual(
b"1 2 obj") pdf_repr(IndirectObjectDef(*IndirectReference(1, 2))), b"1 2 obj"
)
self.assertEqual(pdf_repr(PdfName(b"Name#Hash")), b"/Name#23Hash") self.assertEqual(pdf_repr(PdfName(b"Name#Hash")), b"/Name#23Hash")
self.assertEqual(pdf_repr(PdfName("Name#Hash")), b"/Name#23Hash") self.assertEqual(pdf_repr(PdfName("Name#Hash")), b"/Name#23Hash")
self.assertEqual(pdf_repr(PdfDict({b"Name": IndirectReference(1, 2)})), self.assertEqual(
b"<<\n/Name 1 2 R\n>>") pdf_repr(PdfDict({b"Name": IndirectReference(1, 2)})),
self.assertEqual(pdf_repr(PdfDict({"Name": IndirectReference(1, 2)})), b"<<\n/Name 1 2 R\n>>",
b"<<\n/Name 1 2 R\n>>") )
self.assertEqual(
pdf_repr(PdfDict({"Name": IndirectReference(1, 2)})), b"<<\n/Name 1 2 R\n>>"
)
self.assertEqual(pdf_repr(123), b"123") self.assertEqual(pdf_repr(123), b"123")
self.assertEqual(pdf_repr(True), b"true") self.assertEqual(pdf_repr(True), b"true")
self.assertEqual(pdf_repr(False), b"false") self.assertEqual(pdf_repr(False), b"false")
self.assertEqual(pdf_repr(None), b"null") self.assertEqual(pdf_repr(None), b"null")
self.assertEqual(pdf_repr(b"a)/b\\(c"), br"(a\)/b\\\(c)") self.assertEqual(pdf_repr(b"a)/b\\(c"), br"(a\)/b\\\(c)")
self.assertEqual(pdf_repr([123, True, {"a": PdfName(b"b")}]), self.assertEqual(
b"[ 123 true <<\n/a /b\n>> ]") pdf_repr([123, True, {"a": PdfName(b"b")}]), b"[ 123 true <<\n/a /b\n>> ]"
)
self.assertEqual(pdf_repr(PdfBinary(b"\x90\x1F\xA0")), b"<901FA0>") self.assertEqual(pdf_repr(PdfBinary(b"\x90\x1F\xA0")), b"<901FA0>")

View File

@ -4,25 +4,25 @@ from PIL import Image
class TestPickle(PillowTestCase): class TestPickle(PillowTestCase):
def helper_pickle_file(self, pickle, protocol=0, mode=None): def helper_pickle_file(self, pickle, protocol=0, mode=None):
# Arrange # Arrange
im = Image.open('Tests/images/hopper.jpg') im = Image.open("Tests/images/hopper.jpg")
filename = self.tempfile('temp.pkl') filename = self.tempfile("temp.pkl")
if mode: if mode:
im = im.convert(mode) im = im.convert(mode)
# Act # Act
with open(filename, 'wb') as f: with open(filename, "wb") as f:
pickle.dump(im, f, protocol) pickle.dump(im, f, protocol)
with open(filename, 'rb') as f: with open(filename, "rb") as f:
loaded_im = pickle.load(f) loaded_im = pickle.load(f)
# Assert # Assert
self.assertEqual(im, loaded_im) self.assertEqual(im, loaded_im)
def helper_pickle_string(self, pickle, protocol=0, def helper_pickle_string(
test_file='Tests/images/hopper.jpg', mode=None): self, pickle, protocol=0, test_file="Tests/images/hopper.jpg", mode=None
):
im = Image.open(test_file) im = Image.open(test_file)
if mode: if mode:
im = im.convert(mode) im = im.convert(mode)
@ -68,12 +68,12 @@ class TestPickle(PillowTestCase):
"Tests/images/non_zero_bb_scale2.png", "Tests/images/non_zero_bb_scale2.png",
"Tests/images/p_trns_single.png", "Tests/images/p_trns_single.png",
"Tests/images/pil123p.png", "Tests/images/pil123p.png",
"Tests/images/itxt_chunks.png" "Tests/images/itxt_chunks.png",
]: ]:
for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1): for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1):
self.helper_pickle_string(pickle, self.helper_pickle_string(
protocol=protocol, pickle, protocol=protocol, test_file=test_file
test_file=test_file) )
def test_pickle_pa_mode(self): def test_pickle_pa_mode(self):
# Arrange # Arrange
@ -96,16 +96,17 @@ class TestPickle(PillowTestCase):
def test_pickle_la_mode_with_palette(self): def test_pickle_la_mode_with_palette(self):
# Arrange # Arrange
import pickle import pickle
im = Image.open('Tests/images/hopper.jpg')
filename = self.tempfile('temp.pkl') im = Image.open("Tests/images/hopper.jpg")
filename = self.tempfile("temp.pkl")
im = im.convert("PA") im = im.convert("PA")
# Act / Assert # Act / Assert
for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1): for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1):
im.mode = "LA" im.mode = "LA"
with open(filename, 'wb') as f: with open(filename, "wb") as f:
pickle.dump(im, f, protocol) pickle.dump(im, f, protocol)
with open(filename, 'rb') as f: with open(filename, "rb") as f:
loaded_im = pickle.load(f) loaded_im = pickle.load(f)
im.mode = "PA" im.mode = "PA"

View File

@ -6,17 +6,16 @@ import sys
class TestPsDraw(PillowTestCase): class TestPsDraw(PillowTestCase):
def _create_document(self, ps): def _create_document(self, ps):
im = Image.open("Tests/images/hopper.ppm") im = Image.open("Tests/images/hopper.ppm")
title = "hopper" title = "hopper"
box = (1*72, 2*72, 7*72, 10*72) # in points box = (1 * 72, 2 * 72, 7 * 72, 10 * 72) # in points
ps.begin_document(title) ps.begin_document(title)
# draw diagonal lines in a cross # draw diagonal lines in a cross
ps.line((1*72, 2*72), (7*72, 10*72)) ps.line((1 * 72, 2 * 72), (7 * 72, 10 * 72))
ps.line((7*72, 2*72), (1*72, 10*72)) ps.line((7 * 72, 2 * 72), (1 * 72, 10 * 72))
# draw the image (75 dpi) # draw the image (75 dpi)
ps.image(box, im, 75) ps.image(box, im, 75)
@ -24,7 +23,7 @@ class TestPsDraw(PillowTestCase):
# draw title # draw title
ps.setfont("Courier", 36) ps.setfont("Courier", 36)
ps.text((3*72, 4*72), title) ps.text((3 * 72, 4 * 72), title)
ps.end_document() ps.end_document()
@ -34,7 +33,7 @@ class TestPsDraw(PillowTestCase):
# https://pillow.readthedocs.io/en/latest/handbook/tutorial.html#drawing-postscript # https://pillow.readthedocs.io/en/latest/handbook/tutorial.html#drawing-postscript
# Arrange # Arrange
tempfile = self.tempfile('temp.ps') tempfile = self.tempfile("temp.ps")
with open(tempfile, "wb") as fp: with open(tempfile, "wb") as fp:
# Act # Act
ps = PSDraw.PSDraw(fp) ps = PSDraw.PSDraw(fp)

View File

@ -5,12 +5,11 @@ from PIL import ImageQt
class TestFromQPixmap(PillowQPixmapTestCase, PillowTestCase): class TestFromQPixmap(PillowQPixmapTestCase, PillowTestCase):
def roundtrip(self, expected): def roundtrip(self, expected):
result = ImageQt.fromqpixmap(ImageQt.toqpixmap(expected)) result = ImageQt.fromqpixmap(ImageQt.toqpixmap(expected))
# Qt saves all pixmaps as rgb # Qt saves all pixmaps as rgb
self.assert_image_equal(result, expected.convert('RGB')) self.assert_image_equal(result, expected.convert("RGB"))
def test_sanity(self): def test_sanity(self):
for mode in ('1', 'RGB', 'RGBA', 'L', 'P'): for mode in ("1", "RGB", "RGBA", "L", "P"):
self.roundtrip(hopper(mode)) self.roundtrip(hopper(mode))

View File

@ -10,30 +10,30 @@ if ImageQt.qt_is_installed:
try: try:
from PyQt5 import QtGui from PyQt5 import QtGui
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QLabel, QApplication from PyQt5.QtWidgets import QWidget, QHBoxLayout, QLabel, QApplication
QT_VERSION = 5 QT_VERSION = 5
except (ImportError, RuntimeError): except (ImportError, RuntimeError):
try: try:
from PySide2 import QtGui from PySide2 import QtGui
from PySide2.QtWidgets import QWidget, QHBoxLayout, QLabel, \ from PySide2.QtWidgets import QWidget, QHBoxLayout, QLabel, QApplication
QApplication
QT_VERSION = 5 QT_VERSION = 5
except (ImportError, RuntimeError): except (ImportError, RuntimeError):
try: try:
from PyQt4 import QtGui from PyQt4 import QtGui
from PyQt4.QtGui import QWidget, QHBoxLayout, QLabel, \ from PyQt4.QtGui import QWidget, QHBoxLayout, QLabel, QApplication
QApplication
QT_VERSION = 4 QT_VERSION = 4
except (ImportError, RuntimeError): except (ImportError, RuntimeError):
from PySide import QtGui from PySide import QtGui
from PySide.QtGui import QWidget, QHBoxLayout, QLabel, \ from PySide.QtGui import QWidget, QHBoxLayout, QLabel, QApplication
QApplication
QT_VERSION = 4 QT_VERSION = 4
class TestToQImage(PillowQtTestCase, PillowTestCase): class TestToQImage(PillowQtTestCase, PillowTestCase):
def test_sanity(self): def test_sanity(self):
for mode in ('RGB', 'RGBA', 'L', 'P', '1'): for mode in ("RGB", "RGBA", "L", "P", "1"):
src = hopper(mode) src = hopper(mode)
data = ImageQt.toqimage(src) data = ImageQt.toqimage(src)
@ -42,12 +42,12 @@ class TestToQImage(PillowQtTestCase, PillowTestCase):
# reload directly from the qimage # reload directly from the qimage
rt = ImageQt.fromqimage(data) rt = ImageQt.fromqimage(data)
if mode in ('L', 'P', '1'): if mode in ("L", "P", "1"):
self.assert_image_equal(rt, src.convert('RGB')) self.assert_image_equal(rt, src.convert("RGB"))
else: else:
self.assert_image_equal(rt, src) self.assert_image_equal(rt, src)
if mode == '1': if mode == "1":
# BW appears to not save correctly on QT4 and QT5 # BW appears to not save correctly on QT4 and QT5
# kicks out errors on console: # kicks out errors on console:
# libpng warning: Invalid color type/bit depth combination # libpng warning: Invalid color type/bit depth combination
@ -56,15 +56,15 @@ class TestToQImage(PillowQtTestCase, PillowTestCase):
continue continue
# Test saving the file # Test saving the file
tempfile = self.tempfile('temp_{}.png'.format(mode)) tempfile = self.tempfile("temp_{}.png".format(mode))
data.save(tempfile) data.save(tempfile)
# Check that it actually worked. # Check that it actually worked.
reloaded = Image.open(tempfile) reloaded = Image.open(tempfile)
# Gray images appear to come back in palette mode. # Gray images appear to come back in palette mode.
# They're roughly equivalent # They're roughly equivalent
if QT_VERSION == 4 and mode == 'L': if QT_VERSION == 4 and mode == "L":
src = src.convert('P') src = src.convert("P")
self.assert_image_equal(reloaded, src) self.assert_image_equal(reloaded, src)
def test_segfault(self): def test_segfault(self):
@ -75,8 +75,8 @@ class TestToQImage(PillowQtTestCase, PillowTestCase):
if ImageQt.qt_is_installed: if ImageQt.qt_is_installed:
class Example(QWidget):
class Example(QWidget):
def __init__(self): def __init__(self):
super(Example, self).__init__() super(Example, self).__init__()

View File

@ -8,14 +8,13 @@ if ImageQt.qt_is_installed:
class TestToQPixmap(PillowQPixmapTestCase, PillowTestCase): class TestToQPixmap(PillowQPixmapTestCase, PillowTestCase):
def test_sanity(self): def test_sanity(self):
for mode in ('1', 'RGB', 'RGBA', 'L', 'P'): for mode in ("1", "RGB", "RGBA", "L", "P"):
data = ImageQt.toqpixmap(hopper(mode)) data = ImageQt.toqpixmap(hopper(mode))
self.assertIsInstance(data, QPixmap) self.assertIsInstance(data, QPixmap)
self.assertFalse(data.isNull()) self.assertFalse(data.isNull())
# Test saving the file # Test saving the file
tempfile = self.tempfile('temp_{}.png'.format(mode)) tempfile = self.tempfile("temp_{}.png".format(mode))
data.save(tempfile) data.save(tempfile)

View File

@ -9,18 +9,11 @@ from PIL import Image, JpegImagePlugin, GifImagePlugin
TEST_JPG = "Tests/images/hopper.jpg" TEST_JPG = "Tests/images/hopper.jpg"
TEST_GIF = "Tests/images/hopper.gif" TEST_GIF = "Tests/images/hopper.gif"
test_filenames = ( test_filenames = ("temp_';", 'temp_";', "temp_'\"|", "temp_'\"||", "temp_'\"&&")
"temp_';",
"temp_\";",
"temp_'\"|",
"temp_'\"||",
"temp_'\"&&",
)
@unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or macOS") @unittest.skipIf(sys.platform.startswith("win32"), "requires Unix or macOS")
class TestShellInjection(PillowTestCase): class TestShellInjection(PillowTestCase):
def assert_save_filename_check(self, src_img, save_func): def assert_save_filename_check(self, src_img, save_func):
for filename in test_filenames: for filename in test_filenames:
dest_file = self.tempfile(filename) dest_file = self.tempfile(filename)

View File

@ -7,7 +7,6 @@ from fractions import Fraction
class Test_IFDRational(PillowTestCase): class Test_IFDRational(PillowTestCase):
def _test_equal(self, num, denom, target): def _test_equal(self, num, denom, target):
t = IFDRational(num, denom) t = IFDRational(num, denom)
@ -44,17 +43,16 @@ class Test_IFDRational(PillowTestCase):
def test_ifd_rational_save(self): def test_ifd_rational_save(self):
methods = (True, False) methods = (True, False)
if 'libtiff_encoder' not in dir(Image.core): if "libtiff_encoder" not in dir(Image.core):
methods = (False,) methods = (False,)
for libtiff in methods: for libtiff in methods:
TiffImagePlugin.WRITE_LIBTIFF = libtiff TiffImagePlugin.WRITE_LIBTIFF = libtiff
im = hopper() im = hopper()
out = self.tempfile('temp.tiff') out = self.tempfile("temp.tiff")
res = IFDRational(301, 1) res = IFDRational(301, 1)
im.save(out, dpi=(res, res), compression='raw') im.save(out, dpi=(res, res), compression="raw")
reloaded = Image.open(out) reloaded = Image.open(out)
self.assertEqual(float(IFDRational(301, 1)), self.assertEqual(float(IFDRational(301, 1)), float(reloaded.tag_v2[282]))
float(reloaded.tag_v2[282]))

View File

@ -3,11 +3,11 @@ from .helper import PillowTestCase, hopper
class TestUploader(PillowTestCase): class TestUploader(PillowTestCase):
def check_upload_equal(self): def check_upload_equal(self):
result = hopper('P').convert('RGB') result = hopper("P").convert("RGB")
target = hopper('RGB') target = hopper("RGB")
self.assert_image_equal(result, target) self.assert_image_equal(result, target)
def check_upload_similar(self): def check_upload_similar(self):
result = hopper('P').convert('RGB') result = hopper("P").convert("RGB")
target = hopper('RGB') target = hopper("RGB")
self.assert_image_similar(result, target, 0) self.assert_image_similar(result, target, 0)

View File

@ -4,7 +4,6 @@ from PIL import _util
class TestUtil(PillowTestCase): class TestUtil(PillowTestCase):
def test_is_string_type(self): def test_is_string_type(self):
# Arrange # Arrange
color = "red" color = "red"
@ -35,11 +34,12 @@ class TestUtil(PillowTestCase):
# Assert # Assert
self.assertTrue(it_is) self.assertTrue(it_is)
@unittest.skipIf(not _util.py36, 'os.path support for Paths added in 3.6') @unittest.skipIf(not _util.py36, "os.path support for Paths added in 3.6")
def test_path_obj_is_path(self): def test_path_obj_is_path(self):
# Arrange # Arrange
from pathlib import Path from pathlib import Path
test_path = Path('filename.ext')
test_path = Path("filename.ext")
# Act # Act
it_is = _util.isPath(test_path) it_is = _util.isPath(test_path)
@ -50,7 +50,7 @@ class TestUtil(PillowTestCase):
def test_is_not_path(self): def test_is_not_path(self):
# Arrange # Arrange
filename = self.tempfile("temp.ext") filename = self.tempfile("temp.ext")
fp = open(filename, 'w').close() fp = open(filename, "w").close()
# Act # Act
it_is_not = _util.isPath(fp) it_is_not = _util.isPath(fp)

View File

@ -5,14 +5,14 @@ from io import BytesIO
test_file = "Tests/images/hopper.webp" test_file = "Tests/images/hopper.webp"
@unittest.skipUnless(features.check('webp'), "WebP is not installed") @unittest.skipUnless(features.check("webp"), "WebP is not installed")
class TestWebPLeaks(PillowLeakTestCase): class TestWebPLeaks(PillowLeakTestCase):
mem_limit = 3 * 1024 # kb mem_limit = 3 * 1024 # kb
iterations = 100 iterations = 100
def test_leak_load(self): def test_leak_load(self):
with open(test_file, 'rb') as f: with open(test_file, "rb") as f:
im_data = f.read() im_data = f.read()
def core(): def core():