Skip to content

Commit 086fa4a

Browse files
authored
Speed up Image.blend() (#9649)
2 parents da60ab6 + 7a0534a commit 086fa4a

1 file changed

Lines changed: 18 additions & 11 deletions

File tree

src/libImaging/Blend.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) {
3535
}
3636

3737
/* Shortcuts */
38-
if (alpha == 0.0) {
38+
if (imIn1 == imIn2 || alpha == 0.0) {
3939
return ImagingCopy(imIn1);
4040
} else if (alpha == 1.0) {
4141
return ImagingCopy(imIn2);
@@ -46,23 +46,30 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) {
4646
return NULL;
4747
}
4848

49+
// We know these won't change in the loops below,
50+
// so the compiler can optimize better if we pull them out.
51+
int ysize = imIn1->ysize;
52+
int linesize = imIn1->linesize;
53+
4954
if (alpha >= 0 && alpha <= 1.0) {
5055
/* Interpolate between bands */
51-
for (y = 0; y < imIn1->ysize; y++) {
52-
UINT8 *in1 = (UINT8 *)imIn1->image[y];
53-
UINT8 *in2 = (UINT8 *)imIn2->image[y];
54-
UINT8 *out = (UINT8 *)imOut->image[y];
55-
for (x = 0; x < imIn1->linesize; x++) {
56+
for (y = 0; y < ysize; y++) {
57+
// restrict safe: imIn1 and imIn2 are read-only; imOut is a new allocation
58+
UINT8 *restrict in1 = (UINT8 *)imIn1->image[y];
59+
UINT8 *restrict in2 = (UINT8 *)imIn2->image[y];
60+
UINT8 *restrict out = (UINT8 *)imOut->image[y];
61+
for (x = 0; x < linesize; x++) {
5662
out[x] = (UINT8)((int)in1[x] + alpha * ((int)in2[x] - (int)in1[x]));
5763
}
5864
}
5965
} else {
6066
/* Extrapolation; must make sure to clip resulting values */
61-
for (y = 0; y < imIn1->ysize; y++) {
62-
UINT8 *in1 = (UINT8 *)imIn1->image[y];
63-
UINT8 *in2 = (UINT8 *)imIn2->image[y];
64-
UINT8 *out = (UINT8 *)imOut->image[y];
65-
for (x = 0; x < imIn1->linesize; x++) {
67+
for (y = 0; y < ysize; y++) {
68+
// restrict safe: imIn1 and imIn2 are read-only; imOut is a new allocation
69+
UINT8 *restrict in1 = (UINT8 *)imIn1->image[y];
70+
UINT8 *restrict in2 = (UINT8 *)imIn2->image[y];
71+
UINT8 *restrict out = (UINT8 *)imOut->image[y];
72+
for (x = 0; x < linesize; x++) {
6673
float temp = (float)((int)in1[x] + alpha * ((int)in2[x] - (int)in1[x]));
6774
if (temp <= 0.0) {
6875
out[x] = 0;

0 commit comments

Comments
 (0)