Skip to content

Commit 79f834e

Browse files
committed
If pasting an image onto itself at a lower position, copy from bottom
1 parent c8d98d5 commit 79f834e

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

Tests/test_image_paste.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,18 @@ def test_image_solid(self, mode: str) -> None:
124124
im = im.crop((12, 23, im2.width + 12, im2.height + 23))
125125
assert_image_equal(im, im2)
126126

127+
@pytest.mark.parametrize("y", [10, -10])
128+
def test_image_self(self, y: int) -> None:
129+
im = self.gradient_RGB
130+
131+
im_self = im.copy()
132+
im_self.paste(im_self, (0, y))
133+
134+
im_copy = im.copy()
135+
im_copy.paste(im_copy.copy(), (0, y))
136+
137+
assert_image_equal(im_self, im_copy)
138+
127139
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
128140
def test_image_mask_1(self, mode: str) -> None:
129141
im = Image.new(mode, (200, 200), "white")

src/libImaging/Paste.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,14 @@ paste(
4444

4545
xsize *= pixelsize;
4646

47-
for (y = 0; y < ysize; y++) {
48-
memcpy(imOut->image[y + dy] + dx, imIn->image[y + sy] + sx, xsize);
47+
if (imOut == imIn && dy > sy) {
48+
for (y = ysize - 1; y >= 0; y--) {
49+
memcpy(imOut->image[y + dy] + dx, imIn->image[y + sy] + sx, xsize);
50+
}
51+
} else {
52+
for (y = 0; y < ysize; y++) {
53+
memcpy(imOut->image[y + dy] + dx, imIn->image[y + sy] + sx, xsize);
54+
}
4955
}
5056
}
5157

0 commit comments

Comments
 (0)