Pillow/src/libImaging/Blend.c

80 lines
2.3 KiB
C
Raw Normal View History

/*
2010-07-31 06:52:47 +04:00
* The Python Imaging Library
* $Id$
*
* interpolate between two existing images
*
* history:
2020-05-01 15:08:57 +03:00
* 96-03-20 fl Created
* 96-05-18 fl Simplified blend expression
* 96-10-05 fl Fixed expression bug, special case for interpolation
2010-07-31 06:52:47 +04:00
*
* Copyright (c) Fredrik Lundh 1996.
* Copyright (c) Secret Labs AB 1997.
*
* See the README file for details on usage and redistribution.
*/
#include "Imaging.h"
Imaging
2021-01-03 06:17:51 +03:00
ImagingBlend(Imaging imIn1, Imaging imIn2, float alpha) {
2010-07-31 06:52:47 +04:00
Imaging imOut;
int x, y;
/* Check arguments */
2021-01-03 06:17:51 +03:00
if (!imIn1 || !imIn2 || imIn1->type != IMAGING_TYPE_UINT8 || imIn1->palette ||
strcmp(imIn1->mode, "1") == 0 || imIn2->palette ||
strcmp(imIn2->mode, "1") == 0) {
2017-09-15 00:22:26 +03:00
return ImagingError_ModeError();
2020-05-10 12:56:36 +03:00
}
2017-09-15 00:22:26 +03:00
2021-01-03 06:17:51 +03:00
if (imIn1->type != imIn2->type || imIn1->bands != imIn2->bands ||
imIn1->xsize != imIn2->xsize || imIn1->ysize != imIn2->ysize) {
2020-05-01 15:08:57 +03:00
return ImagingError_Mismatch();
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
/* Shortcuts */
2020-05-10 12:56:36 +03:00
if (alpha == 0.0) {
2020-05-01 15:08:57 +03:00
return ImagingCopy(imIn1);
2020-05-10 12:56:36 +03:00
} else if (alpha == 1.0) {
2020-05-01 15:08:57 +03:00
return ImagingCopy(imIn2);
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
imOut = ImagingNewDirty(imIn1->mode, imIn1->xsize, imIn1->ysize);
2020-05-10 12:56:36 +03:00
if (!imOut) {
2020-05-01 15:08:57 +03:00
return NULL;
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
if (alpha >= 0 && alpha <= 1.0) {
2020-05-01 15:08:57 +03:00
/* Interpolate between bands */
for (y = 0; y < imIn1->ysize; y++) {
2021-01-03 06:17:51 +03:00
UINT8 *in1 = (UINT8 *)imIn1->image[y];
UINT8 *in2 = (UINT8 *)imIn2->image[y];
UINT8 *out = (UINT8 *)imOut->image[y];
2020-05-10 12:56:36 +03:00
for (x = 0; x < imIn1->linesize; x++) {
2021-01-03 06:17:51 +03:00
out[x] = (UINT8)((int)in1[x] + alpha * ((int)in2[x] - (int)in1[x]));
2020-05-10 12:56:36 +03:00
}
2020-05-01 15:08:57 +03:00
}
2010-07-31 06:52:47 +04:00
} else {
2020-05-01 15:08:57 +03:00
/* Extrapolation; must make sure to clip resulting values */
for (y = 0; y < imIn1->ysize; y++) {
2021-01-03 06:17:51 +03:00
UINT8 *in1 = (UINT8 *)imIn1->image[y];
UINT8 *in2 = (UINT8 *)imIn2->image[y];
UINT8 *out = (UINT8 *)imOut->image[y];
2020-05-01 15:08:57 +03:00
for (x = 0; x < imIn1->linesize; x++) {
2021-01-03 06:17:51 +03:00
float temp = (float)((int)in1[x] + alpha * ((int)in2[x] - (int)in1[x]));
2020-05-10 12:56:36 +03:00
if (temp <= 0.0) {
2020-05-01 15:08:57 +03:00
out[x] = 0;
2020-05-10 12:56:36 +03:00
} else if (temp >= 255.0) {
2020-05-01 15:08:57 +03:00
out[x] = 255;
2020-05-10 12:56:36 +03:00
} else {
2021-01-03 06:17:51 +03:00
out[x] = (UINT8)temp;
2020-05-10 12:56:36 +03:00
}
2020-05-01 15:08:57 +03:00
}
}
2010-07-31 06:52:47 +04:00
}
return imOut;
}