diff --git a/src/_imagingmath.c b/src/_imagingmath.c index 3181bca222b..3d0fc394dc9 100644 --- a/src/_imagingmath.c +++ b/src/_imagingmath.c @@ -17,45 +17,45 @@ #include "libImaging/Imaging.h" +#include #include #include -#define MAX_INT32 2147483647.0 -#define MIN_INT32 -2147483648.0 - #define MATH_FUNC_UNOP_MAGIC "Pillow Math unary func" #define MATH_FUNC_BINOP_MAGIC "Pillow Math binary func" -#define UNOP(name, op, type) \ - void name(Imaging out, Imaging im1) { \ - int x, y; \ - for (y = 0; y < out->ysize; y++) { \ - type *p0 = (type *)out->image[y]; \ - type *p1 = (type *)im1->image[y]; \ - for (x = 0; x < out->xsize; x++) { \ - *p0 = op(type, *p1); \ - p0++; \ - p1++; \ - } \ - } \ - } - -#define BINOP(name, op, type) \ - void name(Imaging out, Imaging im1, Imaging im2) { \ - int x, y; \ - for (y = 0; y < out->ysize; y++) { \ - type *p0 = (type *)out->image[y]; \ - type *p1 = (type *)im1->image[y]; \ - type *p2 = (type *)im2->image[y]; \ - for (x = 0; x < out->xsize; x++) { \ - *p0 = op(type, *p1, *p2); \ +// Contract: `out` is the same size and type as `im1`, +// and a different image. +#define UNOP(name, op, type) \ + static void name(Imaging out, Imaging im1) { \ + int xsize = out->xsize; \ + for (int y = 0; y < out->ysize; y++) { \ + type *restrict p0 = (type *)out->image[y]; \ + type *restrict p1 = (type *)im1->image[y]; \ + for (int x = 0; x < xsize; x++) { \ + *p0 = op(type, *p1); \ p0++; \ p1++; \ - p2++; \ } \ } \ } +#define BINOP(name, op, type) \ + static void name(Imaging out, Imaging im1, Imaging im2) { \ + int xsize = out->xsize; \ + for (int y = 0; y < out->ysize; y++) { \ + type *restrict p0 = (type *)out->image[y]; \ + type *restrict p1 = (type *)im1->image[y]; \ + type *restrict p2 = (type *)im2->image[y]; \ + for (int x = 0; x < xsize; x++) { \ + *p0 = op(type, *p1, *p2); \ + p0++; \ + p1++; \ + p2++; \ + } \ + } \ + } + #define NEG(type, v1) -(v1) #define INVERT(type, v1) ~(v1) @@ -95,12 +95,7 @@ powi(int x, int y) { if (errno == EDOM) { return 0; } - if (v < MIN_INT32) { - v = MIN_INT32; - } else if (v > MAX_INT32) { - v = MAX_INT32; - } - return (int)v; + return v < INT32_MIN ? INT32_MIN : (v > INT32_MAX ? INT32_MAX : (int)v); } #define POW_I(type, v1, v2) powi(v1, v2) @@ -165,6 +160,16 @@ BINOP(le_F, LE, FLOAT32) BINOP(gt_F, GT, FLOAT32) BINOP(ge_F, GE, FLOAT32) +/** + * Apply an unary operation to the input image and store the result in the output image. + * The output image MUST be disparate from the input image, + * otherwise the result will be undefined. + * + * Python arguments: + * * op: A Capsule containing a pointer to the unary operation function. + * * i0: A Capsule containing a pointer to the output Imaging object. + * * i1: A Capsule containing a pointer to the input Imaging object. + */ static PyObject * _unop(PyObject *self, PyObject *args) { Imaging out; @@ -204,6 +209,18 @@ _unop(PyObject *self, PyObject *args) { Py_RETURN_NONE; } +/** + * Apply the given binary operation to the two input images and store the result in the + * output image. + * The output image MUST be disparate from the input images, + * otherwise the result will be undefined. + * + * Python arguments: + * * op: A Capsule containing a pointer to the binary operation function. + * * i0: A Capsule containing a pointer to the output Imaging object. + * * i1: A Capsule containing a pointer to the first input Imaging object. + * * i2: A Capsule containing a pointer to the second input Imaging object. + */ static PyObject * _binop(PyObject *self, PyObject *args) { Imaging out;