mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-06-30 18:03:07 +03:00
If pasting image to self at lower position with mask, copy from bottom
This commit is contained in:
parent
79f834ef65
commit
81fa4e18c7
|
@ -125,14 +125,17 @@ class TestImagingPaste:
|
||||||
assert_image_equal(im, im2)
|
assert_image_equal(im, im2)
|
||||||
|
|
||||||
@pytest.mark.parametrize("y", [10, -10])
|
@pytest.mark.parametrize("y", [10, -10])
|
||||||
def test_image_self(self, y: int) -> None:
|
@pytest.mark.parametrize("mode", ["L", "RGB"])
|
||||||
im = self.gradient_RGB
|
@pytest.mark.parametrize("mask_mode", ["", "1", "L", "LA", "RGBa"])
|
||||||
|
def test_image_self(self, y: int, mode: str, mask_mode: str) -> None:
|
||||||
|
im = getattr(self, "gradient_" + mode)
|
||||||
|
mask = Image.new(mask_mode, im.size, 0xFFFFFFFF) if mask_mode else None
|
||||||
|
|
||||||
im_self = im.copy()
|
im_self = im.copy()
|
||||||
im_self.paste(im_self, (0, y))
|
im_self.paste(im_self, (0, y), mask)
|
||||||
|
|
||||||
im_copy = im.copy()
|
im_copy = im.copy()
|
||||||
im_copy.paste(im_copy.copy(), (0, y))
|
im_copy.paste(im_copy.copy(), (0, y), mask)
|
||||||
|
|
||||||
assert_image_equal(im_self, im_copy)
|
assert_image_equal(im_self, im_copy)
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,18 @@
|
||||||
|
|
||||||
#include "Imaging.h"
|
#include "Imaging.h"
|
||||||
|
|
||||||
|
#define PREPARE_PASTE_LOOP() \
|
||||||
|
int y, y_end, offset; \
|
||||||
|
if (imOut == imIn && dy > sy) { \
|
||||||
|
y = ysize - 1; \
|
||||||
|
y_end = -1; \
|
||||||
|
offset = -1; \
|
||||||
|
} else { \
|
||||||
|
y = 0; \
|
||||||
|
y_end = ysize; \
|
||||||
|
offset = 1; \
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
paste(
|
paste(
|
||||||
Imaging imOut,
|
Imaging imOut,
|
||||||
|
@ -37,21 +49,14 @@ paste(
|
||||||
) {
|
) {
|
||||||
/* paste opaque region */
|
/* paste opaque region */
|
||||||
|
|
||||||
int y;
|
|
||||||
|
|
||||||
dx *= pixelsize;
|
dx *= pixelsize;
|
||||||
sx *= pixelsize;
|
sx *= pixelsize;
|
||||||
|
|
||||||
xsize *= pixelsize;
|
xsize *= pixelsize;
|
||||||
|
|
||||||
if (imOut == imIn && dy > sy) {
|
PREPARE_PASTE_LOOP();
|
||||||
for (y = ysize - 1; y >= 0; y--) {
|
for (; y != y_end; y += offset) {
|
||||||
memcpy(imOut->image[y + dy] + dx, imIn->image[y + sy] + sx, xsize);
|
memcpy(imOut->image[y + dy] + dx, imIn->image[y + sy] + sx, xsize);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (y = 0; y < ysize; y++) {
|
|
||||||
memcpy(imOut->image[y + dy] + dx, imIn->image[y + sy] + sx, xsize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,12 +75,13 @@ paste_mask_1(
|
||||||
) {
|
) {
|
||||||
/* paste with mode "1" mask */
|
/* paste with mode "1" mask */
|
||||||
|
|
||||||
int x, y;
|
int x;
|
||||||
|
|
||||||
|
PREPARE_PASTE_LOOP();
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
int in_i16 = strncmp(imIn->mode, "I;16", 4) == 0;
|
int in_i16 = strncmp(imIn->mode, "I;16", 4) == 0;
|
||||||
int out_i16 = strncmp(imOut->mode, "I;16", 4) == 0;
|
int out_i16 = strncmp(imOut->mode, "I;16", 4) == 0;
|
||||||
for (y = 0; y < ysize; y++) {
|
for (; y != y_end; y += offset) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
if (out_i16) {
|
if (out_i16) {
|
||||||
out += dx;
|
out += dx;
|
||||||
|
@ -103,7 +109,7 @@ paste_mask_1(
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (y = 0; y < ysize; y++) {
|
for (; y != y_end; y += offset) {
|
||||||
INT32 *out = imOut->image32[y + dy] + dx;
|
INT32 *out = imOut->image32[y + dy] + dx;
|
||||||
INT32 *in = imIn->image32[y + sy] + sx;
|
INT32 *in = imIn->image32[y + sy] + sx;
|
||||||
UINT8 *mask = imMask->image8[y + sy] + sx;
|
UINT8 *mask = imMask->image8[y + sy] + sx;
|
||||||
|
@ -132,11 +138,12 @@ paste_mask_L(
|
||||||
) {
|
) {
|
||||||
/* paste with mode "L" matte */
|
/* paste with mode "L" matte */
|
||||||
|
|
||||||
int x, y;
|
int x;
|
||||||
unsigned int tmp1;
|
unsigned int tmp1;
|
||||||
|
|
||||||
|
PREPARE_PASTE_LOOP();
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
for (y = 0; y < ysize; y++) {
|
for (; y != y_end; y += offset) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
UINT8 *in = imIn->image8[y + sy] + sx;
|
UINT8 *in = imIn->image8[y + sy] + sx;
|
||||||
UINT8 *mask = imMask->image8[y + sy] + sx;
|
UINT8 *mask = imMask->image8[y + sy] + sx;
|
||||||
|
@ -147,7 +154,7 @@ paste_mask_L(
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (y = 0; y < ysize; y++) {
|
for (; y != y_end; y += offset) {
|
||||||
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
||||||
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
||||||
UINT8 *mask = (UINT8 *)(imMask->image8[y + sy] + sx);
|
UINT8 *mask = (UINT8 *)(imMask->image8[y + sy] + sx);
|
||||||
|
@ -180,11 +187,12 @@ paste_mask_RGBA(
|
||||||
) {
|
) {
|
||||||
/* paste with mode "RGBA" matte */
|
/* paste with mode "RGBA" matte */
|
||||||
|
|
||||||
int x, y;
|
int x;
|
||||||
unsigned int tmp1;
|
unsigned int tmp1;
|
||||||
|
|
||||||
|
PREPARE_PASTE_LOOP();
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
for (y = 0; y < ysize; y++) {
|
for (; y != y_end; y += offset) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
UINT8 *in = imIn->image8[y + sy] + sx;
|
UINT8 *in = imIn->image8[y + sy] + sx;
|
||||||
UINT8 *mask = (UINT8 *)imMask->image[y + sy] + sx * 4 + 3;
|
UINT8 *mask = (UINT8 *)imMask->image[y + sy] + sx * 4 + 3;
|
||||||
|
@ -195,7 +203,7 @@ paste_mask_RGBA(
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (y = 0; y < ysize; y++) {
|
for (; y != y_end; y += offset) {
|
||||||
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
||||||
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
||||||
UINT8 *mask = (UINT8 *)(imMask->image32[y + sy] + sx);
|
UINT8 *mask = (UINT8 *)(imMask->image32[y + sy] + sx);
|
||||||
|
@ -228,11 +236,12 @@ paste_mask_RGBa(
|
||||||
) {
|
) {
|
||||||
/* paste with mode "RGBa" matte */
|
/* paste with mode "RGBa" matte */
|
||||||
|
|
||||||
int x, y;
|
int x;
|
||||||
unsigned int tmp1;
|
unsigned int tmp1;
|
||||||
|
|
||||||
|
PREPARE_PASTE_LOOP();
|
||||||
if (imOut->image8) {
|
if (imOut->image8) {
|
||||||
for (y = 0; y < ysize; y++) {
|
for (; y != y_end; y += offset) {
|
||||||
UINT8 *out = imOut->image8[y + dy] + dx;
|
UINT8 *out = imOut->image8[y + dy] + dx;
|
||||||
UINT8 *in = imIn->image8[y + sy] + sx;
|
UINT8 *in = imIn->image8[y + sy] + sx;
|
||||||
UINT8 *mask = (UINT8 *)imMask->image[y + sy] + sx * 4 + 3;
|
UINT8 *mask = (UINT8 *)imMask->image[y + sy] + sx * 4 + 3;
|
||||||
|
@ -243,7 +252,7 @@ paste_mask_RGBa(
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (y = 0; y < ysize; y++) {
|
for (; y != y_end; y += offset) {
|
||||||
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
UINT8 *out = (UINT8 *)(imOut->image32[y + dy] + dx);
|
||||||
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
UINT8 *in = (UINT8 *)(imIn->image32[y + sy] + sx);
|
||||||
UINT8 *mask = (UINT8 *)(imMask->image32[y + sy] + sx);
|
UINT8 *mask = (UINT8 *)(imMask->image32[y + sy] + sx);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user