diff --git a/src/libImaging/Blend.c b/src/libImaging/Blend.c index df94920f62e..19662abf044 100644 --- a/src/libImaging/Blend.c +++ b/src/libImaging/Blend.c @@ -35,7 +35,7 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) { } /* Shortcuts */ - if (alpha == 0.0) { + if (imIn1 == imIn2 || alpha == 0.0) { return ImagingCopy(imIn1); } else if (alpha == 1.0) { return ImagingCopy(imIn2); @@ -46,23 +46,30 @@ ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) { return NULL; } + // We know these won't change in the loops below, + // so the compiler can optimize better if we pull them out. + int ysize = imIn1->ysize; + int linesize = imIn1->linesize; + if (alpha >= 0 && alpha <= 1.0) { /* Interpolate between bands */ - for (y = 0; y < imIn1->ysize; y++) { - UINT8 *in1 = (UINT8 *)imIn1->image[y]; - UINT8 *in2 = (UINT8 *)imIn2->image[y]; - UINT8 *out = (UINT8 *)imOut->image[y]; - for (x = 0; x < imIn1->linesize; x++) { + for (y = 0; y < ysize; y++) { + // restrict safe: imIn1 and imIn2 are read-only; imOut is a new allocation + UINT8 *restrict in1 = (UINT8 *)imIn1->image[y]; + UINT8 *restrict in2 = (UINT8 *)imIn2->image[y]; + UINT8 *restrict out = (UINT8 *)imOut->image[y]; + for (x = 0; x < linesize; x++) { out[x] = (UINT8)((int)in1[x] + alpha * ((int)in2[x] - (int)in1[x])); } } } else { /* Extrapolation; must make sure to clip resulting values */ - for (y = 0; y < imIn1->ysize; y++) { - UINT8 *in1 = (UINT8 *)imIn1->image[y]; - UINT8 *in2 = (UINT8 *)imIn2->image[y]; - UINT8 *out = (UINT8 *)imOut->image[y]; - for (x = 0; x < imIn1->linesize; x++) { + for (y = 0; y < ysize; y++) { + // restrict safe: imIn1 and imIn2 are read-only; imOut is a new allocation + UINT8 *restrict in1 = (UINT8 *)imIn1->image[y]; + UINT8 *restrict in2 = (UINT8 *)imIn2->image[y]; + UINT8 *restrict out = (UINT8 *)imOut->image[y]; + for (x = 0; x < linesize; x++) { float temp = (float)((int)in1[x] + alpha * ((int)in2[x] - (int)in1[x])); if (temp <= 0.0) { out[x] = 0;