Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
turn on ImagingReduce5x5 special case
  • Loading branch information
homm committed Dec 5, 2019
commit e54b9b3720d20adc88537ec6e334ce127c7d4f1a
66 changes: 44 additions & 22 deletions 66 Tests/test_image_reduce.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,29 @@
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
Expand All @@ -20,7 +38,7 @@ def setUpClass(cls):

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)
Expand Down Expand Up @@ -70,15 +88,15 @@ def test_unsupported_modes(self):

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
band = bands[-1].transpose(Image.ROTATE_90)
bands.append(band)
# Correct alpha channel to exclude completely transparent pixels.
homm marked this conversation as resolved.
Outdated
Show resolved Hide resolved
# 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:
Expand Down Expand Up @@ -136,10 +154,8 @@ def compare_reduce_with_reference(self, im, factor, average_diff=0.4, max_diff=1
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)

Expand All @@ -148,19 +164,25 @@ def assert_compare_images(self, a, b, max_average_diff, max_diff=255):
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):
Expand All @@ -173,9 +195,9 @@ def test_mode_LA(self):
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
homm marked this conversation as resolved.
Outdated
Show resolved Hide resolved
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)
Expand All @@ -198,7 +220,7 @@ def test_mode_RGBA(self):
self.compare_reduce_with_reference(im, factor, 0.8, 5)

# With opaque alpha, error should be way smaller
homm marked this conversation as resolved.
Outdated
Show resolved Hide resolved
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)
Expand Down
42 changes: 26 additions & 16 deletions 42 src/libImaging/Reduce.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.