From e54b9b3720d20adc88537ec6e334ce127c7d4f1a Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 5 Dec 2019 22:10:44 +0300 Subject: [PATCH] turn on ImagingReduce5x5 special case --- Tests/test_image_reduce.py | 66 +++++++++++++++++++++++++------------- src/libImaging/Reduce.c | 42 +++++++++++++++--------- 2 files changed, 70 insertions(+), 38 deletions(-) diff --git a/Tests/test_image_reduce.py b/Tests/test_image_reduce.py index 04234b746..e77f37426 100644 --- a/Tests/test_image_reduce.py +++ b/Tests/test_image_reduce.py @@ -6,11 +6,29 @@ from .helper import PillowTestCase, hopper, convert_to_comparable class TestImageReduce(PillowTestCase): # There are several internal implementations remarkable_factors = [ - 1, 2, 3, 4, 5, 6, # special implementations - (1, 2), (1, 3), (1, 4), (1, 7), # 1xN implementation - (2, 1), (3, 1), (4, 1), (7, 1), # Nx1 implementation + # special implementations + 1, + 2, + 3, + 4, + 5, + 6, + # 1xN implementation + (1, 2), + (1, 3), + (1, 4), + (1, 7), + # Nx1 implementation + (2, 1), + (3, 1), + (4, 1), + (7, 1), # general implementation with different paths - (4, 6), (5, 6), (4, 7), (5, 7), (19, 17), + (4, 6), + (5, 6), + (4, 7), + (5, 7), + (19, 17), ] @classmethod @@ -20,7 +38,7 @@ class TestImageReduce(PillowTestCase): def test_args_factor(self): im = Image.new("L", (10, 10)) - + self.assertEqual((4, 4), im.reduce(3).size) self.assertEqual((4, 10), im.reduce((3, 1)).size) self.assertEqual((10, 4), im.reduce((1, 3)).size) @@ -70,7 +88,7 @@ class TestImageReduce(PillowTestCase): def get_image(self, mode): mode_info = ImageMode.getmode(mode) - if mode_info.basetype == 'L': + if mode_info.basetype == "L": bands = [self.gradients_image] for _ in mode_info.bands[1:]: # rotate previous image @@ -78,7 +96,7 @@ class TestImageReduce(PillowTestCase): bands.append(band) # Correct alpha channel to exclude completely transparent pixels. # Low alpha values also emphasize error after alpha multiplication. - if mode.endswith('A'): + if mode.endswith("A"): bands[-1] = bands[-1].point(lambda x: int(85 + x / 1.5)) im = Image.merge(mode, bands) else: @@ -136,10 +154,8 @@ class TestImageReduce(PillowTestCase): self.assert_compare_images(reduced, reference, average_diff, max_diff) def assert_compare_images(self, a, b, max_average_diff, max_diff=255): - self.assertEqual( - a.mode, b.mode, "got mode %r, expected %r" % (a.mode, b.mode)) - self.assertEqual( - a.size, b.size, "got size %r, expected %r" % (a.size, b.size)) + self.assertEqual(a.mode, b.mode, "got mode %r, expected %r" % (a.mode, b.mode)) + self.assertEqual(a.size, b.size, "got size %r, expected %r" % (a.size, b.size)) a, b = convert_to_comparable(a, b) @@ -148,19 +164,25 @@ class TestImageReduce(PillowTestCase): ch_diff = ImageMath.eval("convert(abs(a - b), 'L')", a=ach, b=bch) ch_hist = ch_diff.histogram() - average_diff = (sum(i * num for i, num in enumerate(ch_hist)) - / float(a.size[0] * a.size[1])) + average_diff = sum(i * num for i, num in enumerate(ch_hist)) / float( + a.size[0] * a.size[1] + ) self.assertGreaterEqual( - max_average_diff, average_diff, - ("average pixel value difference {:.4f} > expected {:.4f} " - "for '{}' band").format(average_diff, max_average_diff, band), + max_average_diff, + average_diff, + ( + "average pixel value difference {:.4f} > expected {:.4f} " + "for '{}' band" + ).format(average_diff, max_average_diff, band), ) last_diff = [i for i, num in enumerate(ch_hist) if num > 0][-1] self.assertGreaterEqual( - max_diff, last_diff, - "max pixel value difference {} > expected {} for '{}' band" - .format(last_diff, max_diff, band), + max_diff, + last_diff, + "max pixel value difference {} > expected {} for '{}' band".format( + last_diff, max_diff, band + ), ) def test_mode_L(self): @@ -173,9 +195,9 @@ class TestImageReduce(PillowTestCase): im = self.get_image("LA") for factor in self.remarkable_factors: self.compare_reduce_with_reference(im, factor, 0.8, 5) - + # With opaque alpha, error should be way smaller - im.putalpha(Image.new('L', im.size, 255)) + im.putalpha(Image.new("L", im.size, 255)) for factor in self.remarkable_factors: self.compare_reduce_with_reference(im, factor) self.compare_reduce_with_box(im, factor) @@ -198,7 +220,7 @@ class TestImageReduce(PillowTestCase): self.compare_reduce_with_reference(im, factor, 0.8, 5) # With opaque alpha, error should be way smaller - im.putalpha(Image.new('L', im.size, 255)) + im.putalpha(Image.new("L", im.size, 255)) for factor in self.remarkable_factors: self.compare_reduce_with_reference(im, factor) self.compare_reduce_with_box(im, factor) diff --git a/src/libImaging/Reduce.c b/src/libImaging/Reduce.c index 3841c4f83..d6ef92f5b 100644 --- a/src/libImaging/Reduce.c +++ b/src/libImaging/Reduce.c @@ -983,12 +983,16 @@ ImagingReduce5x5(Imaging imOut, Imaging imIn, int box[4]) for (x = 0; x < box[2] / xscale; x++) { int xx = box[0] + x*xscale; UINT32 v; - ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] + line0[xx*4 + 8] + - line1[xx*4 + 0] + line1[xx*4 + 4] + line1[xx*4 + 8] + - line2[xx*4 + 0] + line2[xx*4 + 4] + line2[xx*4 + 8]; - ss3 = line0[xx*4 + 3] + line0[xx*4 + 7] + line0[xx*4 + 11] + - line1[xx*4 + 3] + line1[xx*4 + 7] + line1[xx*4 + 11] + - line2[xx*4 + 3] + line2[xx*4 + 7] + line2[xx*4 + 11]; + ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] + line0[xx*4 + 8] + line0[xx*4 + 12] + line0[xx*4 + 16] + + line1[xx*4 + 0] + line1[xx*4 + 4] + line1[xx*4 + 8] + line1[xx*4 + 12] + line1[xx*4 + 16] + + line2[xx*4 + 0] + line2[xx*4 + 4] + line2[xx*4 + 8] + line2[xx*4 + 12] + line2[xx*4 + 16] + + line3[xx*4 + 0] + line3[xx*4 + 4] + line3[xx*4 + 8] + line3[xx*4 + 12] + line3[xx*4 + 16] + + line4[xx*4 + 0] + line4[xx*4 + 4] + line4[xx*4 + 8] + line4[xx*4 + 12] + line4[xx*4 + 16]; + ss3 = line0[xx*4 + 3] + line0[xx*4 + 7] + line0[xx*4 + 11] + line0[xx*4 + 15] + line0[xx*4 + 19] + + line1[xx*4 + 3] + line1[xx*4 + 7] + line1[xx*4 + 11] + line1[xx*4 + 15] + line1[xx*4 + 19] + + line2[xx*4 + 3] + line2[xx*4 + 7] + line2[xx*4 + 11] + line2[xx*4 + 15] + line2[xx*4 + 19] + + line3[xx*4 + 3] + line3[xx*4 + 7] + line3[xx*4 + 11] + line3[xx*4 + 15] + line3[xx*4 + 19] + + line4[xx*4 + 3] + line4[xx*4 + 7] + line4[xx*4 + 11] + line4[xx*4 + 15] + line4[xx*4 + 19]; v = MAKE_UINT32( ((ss0 + amend) * multiplier) >> 24, 0, 0, ((ss3 + amend) * multiplier) >> 24); @@ -998,15 +1002,21 @@ ImagingReduce5x5(Imaging imOut, Imaging imIn, int box[4]) for (x = 0; x < box[2] / xscale; x++) { int xx = box[0] + x*xscale; UINT32 v; - ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] + line0[xx*4 + 8] + - line1[xx*4 + 0] + line1[xx*4 + 4] + line1[xx*4 + 8] + - line2[xx*4 + 0] + line2[xx*4 + 4] + line2[xx*4 + 8]; - ss1 = line0[xx*4 + 1] + line0[xx*4 + 5] + line0[xx*4 + 9] + - line1[xx*4 + 1] + line1[xx*4 + 5] + line1[xx*4 + 9] + - line2[xx*4 + 1] + line2[xx*4 + 5] + line2[xx*4 + 9]; - ss2 = line0[xx*4 + 2] + line0[xx*4 + 6] + line0[xx*4 + 10] + - line1[xx*4 + 2] + line1[xx*4 + 6] + line1[xx*4 + 10] + - line2[xx*4 + 2] + line2[xx*4 + 6] + line2[xx*4 + 10]; + ss0 = line0[xx*4 + 0] + line0[xx*4 + 4] + line0[xx*4 + 8] + line0[xx*4 + 12] + line0[xx*4 + 16] + + line1[xx*4 + 0] + line1[xx*4 + 4] + line1[xx*4 + 8] + line1[xx*4 + 12] + line1[xx*4 + 16] + + line2[xx*4 + 0] + line2[xx*4 + 4] + line2[xx*4 + 8] + line2[xx*4 + 12] + line2[xx*4 + 16] + + line3[xx*4 + 0] + line3[xx*4 + 4] + line3[xx*4 + 8] + line3[xx*4 + 12] + line3[xx*4 + 16] + + line4[xx*4 + 0] + line4[xx*4 + 4] + line4[xx*4 + 8] + line4[xx*4 + 12] + line4[xx*4 + 16]; + ss1 = line0[xx*4 + 1] + line0[xx*4 + 5] + line0[xx*4 + 9] + line0[xx*4 + 13] + line0[xx*4 + 17] + + line1[xx*4 + 1] + line1[xx*4 + 5] + line1[xx*4 + 9] + line1[xx*4 + 13] + line1[xx*4 + 17] + + line2[xx*4 + 1] + line2[xx*4 + 5] + line2[xx*4 + 9] + line2[xx*4 + 13] + line2[xx*4 + 17] + + line3[xx*4 + 1] + line3[xx*4 + 5] + line3[xx*4 + 9] + line3[xx*4 + 13] + line3[xx*4 + 17] + + line4[xx*4 + 1] + line4[xx*4 + 5] + line4[xx*4 + 9] + line4[xx*4 + 13] + line4[xx*4 + 17]; + ss2 = line0[xx*4 + 2] + line0[xx*4 + 6] + line0[xx*4 + 10] + line0[xx*4 + 14] + line0[xx*4 + 18] + + line1[xx*4 + 2] + line1[xx*4 + 6] + line1[xx*4 + 10] + line1[xx*4 + 14] + line1[xx*4 + 18] + + line2[xx*4 + 2] + line2[xx*4 + 6] + line2[xx*4 + 10] + line2[xx*4 + 14] + line2[xx*4 + 18] + + line3[xx*4 + 2] + line3[xx*4 + 6] + line3[xx*4 + 10] + line3[xx*4 + 14] + line3[xx*4 + 18] + + line4[xx*4 + 2] + line4[xx*4 + 6] + line4[xx*4 + 10] + line4[xx*4 + 14] + line4[xx*4 + 18]; v = MAKE_UINT32( ((ss0 + amend) * multiplier) >> 24, ((ss1 + amend) * multiplier) >> 24, ((ss2 + amend) * multiplier) >> 24, 0); @@ -1397,7 +1407,7 @@ ImagingReduce(Imaging imIn, int xscale, int yscale, int box[4]) } else { ImagingReduceNx1(imOut, imIn, box, xscale); } - } else if (xscale == yscale && xscale <= 4) { + } else if (xscale == yscale && xscale <= 5) { if (xscale == 2) { ImagingReduce2x2(imOut, imIn, box); } else if (xscale == 3) {