2013-07-01 02:42:19 +04:00
|
|
|
/*
|
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
|
|
|
}
|