Pillow/src/libImaging/Chops.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

163 lines
4.8 KiB
C
Raw Normal View History

/*
2010-07-31 06:52:47 +04:00
* The Python Imaging Library
* $Id$
*
* basic channel operations
*
* history:
* 1996-03-28 fl Created
* 1996-08-13 fl Added and/or/xor for "1" images
* 1996-12-14 fl Added add_modulo, sub_modulo
* 2005-09-10 fl Fixed output values from and/or/xor
*
* Copyright (c) 1996 by Fredrik Lundh.
* Copyright (c) 1997 by Secret Labs AB.
*
* See the README file for details on usage and redistribution.
*/
#include "Imaging.h"
2020-05-14 11:16:54 +03:00
#define CHOP(operation) \
2010-07-31 06:52:47 +04:00
int x, y; \
Imaging imOut; \
2020-05-14 11:16:54 +03:00
imOut = create(imIn1, imIn2, NULL); \
2020-05-10 12:56:36 +03:00
if (!imOut) { \
2017-08-17 03:23:13 +03:00
return NULL; \
2020-05-10 12:56:36 +03:00
} \
2010-07-31 06:52:47 +04:00
for (y = 0; y < imOut->ysize; y++) { \
2017-08-17 03:23:13 +03:00
UINT8 *out = (UINT8 *)imOut->image[y]; \
UINT8 *in1 = (UINT8 *)imIn1->image[y]; \
UINT8 *in2 = (UINT8 *)imIn2->image[y]; \
for (x = 0; x < imOut->linesize; x++) { \
int temp = operation; \
2020-05-10 12:56:36 +03:00
if (temp <= 0) { \
2017-08-17 03:23:13 +03:00
out[x] = 0; \
2020-05-10 12:56:36 +03:00
} else if (temp >= 255) { \
2017-08-17 03:23:13 +03:00
out[x] = 255; \
2020-05-10 12:56:36 +03:00
} else { \
2017-08-17 03:23:13 +03:00
out[x] = temp; \
2020-05-10 12:56:36 +03:00
} \
2017-08-17 03:23:13 +03:00
} \
2010-07-31 06:52:47 +04:00
} \
return imOut;
2017-08-17 03:23:13 +03:00
#define CHOP2(operation, mode) \
2010-07-31 06:52:47 +04:00
int x, y; \
Imaging imOut; \
imOut = create(imIn1, imIn2, mode); \
2020-05-10 12:56:36 +03:00
if (!imOut) { \
2017-08-17 03:23:13 +03:00
return NULL; \
2020-05-10 12:56:36 +03:00
} \
2010-07-31 06:52:47 +04:00
for (y = 0; y < imOut->ysize; y++) { \
2017-08-17 03:23:13 +03:00
UINT8 *out = (UINT8 *)imOut->image[y]; \
UINT8 *in1 = (UINT8 *)imIn1->image[y]; \
UINT8 *in2 = (UINT8 *)imIn2->image[y]; \
for (x = 0; x < imOut->linesize; x++) { \
out[x] = operation; \
} \
2010-07-31 06:52:47 +04:00
} \
return imOut;
static Imaging
create(Imaging im1, Imaging im2, char *mode) {
int xsize, ysize;
if (!im1 || !im2 || im1->type != IMAGING_TYPE_UINT8 ||
2020-05-10 12:56:36 +03:00
(mode != NULL && (strcmp(im1->mode, "1") || strcmp(im2->mode, "1")))) {
2017-08-17 03:23:13 +03:00
return (Imaging)ImagingError_ModeError();
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
if (im1->type != im2->type || im1->bands != im2->bands) {
2017-08-17 03:23:13 +03:00
return (Imaging)ImagingError_Mismatch();
2020-05-10 12:56:36 +03:00
}
2010-07-31 06:52:47 +04:00
xsize = (im1->xsize < im2->xsize) ? im1->xsize : im2->xsize;
ysize = (im1->ysize < im2->ysize) ? im1->ysize : im2->ysize;
2017-08-17 03:23:13 +03:00
return ImagingNewDirty(im1->mode, xsize, ysize);
2010-07-31 06:52:47 +04:00
}
Imaging
ImagingChopLighter(Imaging imIn1, Imaging imIn2) {
2020-05-14 11:16:54 +03:00
CHOP((in1[x] > in2[x]) ? in1[x] : in2[x]);
2010-07-31 06:52:47 +04:00
}
Imaging
ImagingChopDarker(Imaging imIn1, Imaging imIn2) {
2020-05-14 11:16:54 +03:00
CHOP((in1[x] < in2[x]) ? in1[x] : in2[x]);
2010-07-31 06:52:47 +04:00
}
Imaging
ImagingChopDifference(Imaging imIn1, Imaging imIn2) {
2020-05-14 11:16:54 +03:00
CHOP(abs((int)in1[x] - (int)in2[x]));
2010-07-31 06:52:47 +04:00
}
Imaging
ImagingChopMultiply(Imaging imIn1, Imaging imIn2) {
2020-05-14 11:16:54 +03:00
CHOP((int)in1[x] * (int)in2[x] / 255);
2010-07-31 06:52:47 +04:00
}
Imaging
ImagingChopScreen(Imaging imIn1, Imaging imIn2) {
2020-05-14 11:16:54 +03:00
CHOP(255 - ((int)(255 - in1[x]) * (int)(255 - in2[x])) / 255);
2010-07-31 06:52:47 +04:00
}
Imaging
ImagingChopAdd(Imaging imIn1, Imaging imIn2, float scale, int offset) {
2020-05-14 11:16:54 +03:00
CHOP(((int)in1[x] + (int)in2[x]) / scale + offset);
2010-07-31 06:52:47 +04:00
}
Imaging
ImagingChopSubtract(Imaging imIn1, Imaging imIn2, float scale, int offset) {
2020-05-14 11:16:54 +03:00
CHOP(((int)in1[x] - (int)in2[x]) / scale + offset);
2010-07-31 06:52:47 +04:00
}
Imaging
ImagingChopAnd(Imaging imIn1, Imaging imIn2) {
CHOP2((in1[x] && in2[x]) ? 255 : 0, "1");
}
Imaging
ImagingChopOr(Imaging imIn1, Imaging imIn2) {
CHOP2((in1[x] || in2[x]) ? 255 : 0, "1");
}
Imaging
ImagingChopXor(Imaging imIn1, Imaging imIn2) {
CHOP2(((in1[x] != 0) ^ (in2[x] != 0)) ? 255 : 0, "1");
}
Imaging
ImagingChopAddModulo(Imaging imIn1, Imaging imIn2) {
CHOP2(in1[x] + in2[x], NULL);
}
Imaging
ImagingChopSubtractModulo(Imaging imIn1, Imaging imIn2) {
CHOP2(in1[x] - in2[x], NULL);
}
2019-11-22 16:03:59 +03:00
Imaging
2019-11-22 16:03:59 +03:00
ImagingChopSoftLight(Imaging imIn1, Imaging imIn2) {
CHOP2(
(((255 - in1[x]) * (in1[x] * in2[x])) / 65536) +
2019-11-22 16:03:59 +03:00
(in1[x] * (255 - ((255 - in1[x]) * (255 - in2[x]) / 255))) / 255,
NULL);
}
Imaging
2019-11-22 16:03:59 +03:00
ImagingChopHardLight(Imaging imIn1, Imaging imIn2) {
CHOP2(
(in2[x] < 128) ? ((in1[x] * in2[x]) / 127)
: 255 - (((255 - in2[x]) * (255 - in1[x])) / 127),
2019-11-22 16:03:59 +03:00
NULL);
2019-11-22 16:30:43 +03:00
}
Imaging
2019-11-22 16:03:59 +03:00
ImagingOverlay(Imaging imIn1, Imaging imIn2) {
CHOP2(
(in1[x] < 128) ? ((in1[x] * in2[x]) / 127)
: 255 - (((255 - in1[x]) * (255 - in2[x])) / 127),
2019-11-22 16:30:43 +03:00
NULL);
2019-11-22 16:03:59 +03:00
}