Pillow/_imagingmath.c
Brian Crowell af5228896a py3k: Add module initialization and unicode/bytes int/long thunks
This commit:

* Adds Python 3 module initialization functions. I split out the main init
  of each module into a static setup_module function.
* Adds a py3.h which unifies int/long in Python 3 and unicode/bytes in
  Python 2. _imagingft.c unfortunately looks a little kludgy after this
  because it was already using PyUnicode functions, and I had to mix and
  match there manually.

With this commit, the modules all build successfully under Python 3.

What this commit does NOT do is patch all of the uses of PyArg_ParseTuple
and Py_BuildValue, which all need to be checked for proper use of bytes
and unicode codes. It also does not let selftest.py run yet, because there
are probably hundreds of issues to fix in the Python code itself.
2013-01-10 08:46:37 -06:00

312 lines
7.1 KiB
C

/*
* The Python Imaging Library
*
* a simple math add-on for the Python Imaging Library
*
* history:
* 1999-02-15 fl Created
* 2005-05-05 fl Simplified and cleaned up for PIL 1.1.6
*
* Copyright (c) 1999-2005 by Secret Labs AB
* Copyright (c) 2005 by Fredrik Lundh
*
* See the README file for information on usage and redistribution.
*/
#include "Python.h"
#include "Imaging.h"
#include "py3.h"
#include "math.h"
#include "float.h"
#define MAX_INT32 2147483647.0
#define MIN_INT32 -2147483648.0
#if defined(_MSC_VER) && _MSC_VER < 1500
/* python 2.1/2.2/2.3 = VC98 = VER 1200 */
/* python 2.4/2.5 = VS.NET 2003 = VER 1310 */
/* python 2.6 = VS 9.0 = VER 1500 */
#define powf(a, b) ((float) pow((double) (a), (double) (b)))
#endif
#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);\
p0++; p1++; p2++;\
}\
}\
}
#define NEG(type, v1) -(v1)
#define INVERT(type, v1) ~(v1)
#define ADD(type, v1, v2) (v1)+(v2)
#define SUB(type, v1, v2) (v1)-(v2)
#define MUL(type, v1, v2) (v1)*(v2)
#define MIN(type, v1, v2) ((v1)<(v2))?(v1):(v2)
#define MAX(type, v1, v2) ((v1)>(v2))?(v1):(v2)
#define AND(type, v1, v2) (v1)&(v2)
#define OR(type, v1, v2) (v1)|(v2)
#define XOR(type, v1, v2) (v1)^(v2)
#define LSHIFT(type, v1, v2) (v1)<<(v2)
#define RSHIFT(type, v1, v2) (v1)>>(v2)
#define ABS_I(type, v1) abs((v1))
#define ABS_F(type, v1) fabs((v1))
/* --------------------------------------------------------------------
* some day, we should add FPE protection mechanisms. see pyfpe.h for
* details.
*
* PyFPE_START_PROTECT("Error in foobar", return 0)
* PyFPE_END_PROTECT(result)
*/
#define DIV_I(type, v1, v2) ((v2)!=0)?(v1)/(v2):0
#define DIV_F(type, v1, v2) ((v2)!=0.0F)?(v1)/(v2):0.0F
#define MOD_I(type, v1, v2) ((v2)!=0)?(v1)%(v2):0
#define MOD_F(type, v1, v2) ((v2)!=0.0F)?fmod((v1),(v2)):0.0F
static int powi(int x, int y)
{
double v = pow(x, y) + 0.5;
if (errno == EDOM)
return 0;
if (v < MIN_INT32)
v = MIN_INT32;
else if (v > MAX_INT32)
v = MAX_INT32;
return (int) v;
}
#define POW_I(type, v1, v2) powi(v1, v2)
#define POW_F(type, v1, v2) powf(v1, v2) /* FIXME: EDOM handling */
#define DIFF_I(type, v1, v2) abs((v1)-(v2))
#define DIFF_F(type, v1, v2) fabs((v1)-(v2))
#define EQ(type, v1, v2) (v1)==(v2)
#define NE(type, v1, v2) (v1)!=(v2)
#define LT(type, v1, v2) (v1)<(v2)
#define LE(type, v1, v2) (v1)<=(v2)
#define GT(type, v1, v2) (v1)>(v2)
#define GE(type, v1, v2) (v1)>=(v2)
UNOP(abs_I, ABS_I, INT32)
UNOP(neg_I, NEG, INT32)
BINOP(add_I, ADD, INT32)
BINOP(sub_I, SUB, INT32)
BINOP(mul_I, MUL, INT32)
BINOP(div_I, DIV_I, INT32)
BINOP(mod_I, MOD_I, INT32)
BINOP(pow_I, POW_I, INT32)
BINOP(diff_I, DIFF_I, INT32)
UNOP(invert_I, INVERT, INT32)
BINOP(and_I, AND, INT32)
BINOP(or_I, OR, INT32)
BINOP(xor_I, XOR, INT32)
BINOP(lshift_I, LSHIFT, INT32)
BINOP(rshift_I, RSHIFT, INT32)
BINOP(min_I, MIN, INT32)
BINOP(max_I, MAX, INT32)
BINOP(eq_I, EQ, INT32)
BINOP(ne_I, NE, INT32)
BINOP(lt_I, LT, INT32)
BINOP(le_I, LE, INT32)
BINOP(gt_I, GT, INT32)
BINOP(ge_I, GE, INT32)
UNOP(abs_F, ABS_F, FLOAT32)
UNOP(neg_F, NEG, FLOAT32)
BINOP(add_F, ADD, FLOAT32)
BINOP(sub_F, SUB, FLOAT32)
BINOP(mul_F, MUL, FLOAT32)
BINOP(div_F, DIV_F, FLOAT32)
BINOP(mod_F, MOD_F, FLOAT32)
BINOP(pow_F, POW_F, FLOAT32)
BINOP(diff_F, DIFF_F, FLOAT32)
BINOP(min_F, MIN, FLOAT32)
BINOP(max_F, MAX, FLOAT32)
BINOP(eq_F, EQ, FLOAT32)
BINOP(ne_F, NE, FLOAT32)
BINOP(lt_F, LT, FLOAT32)
BINOP(le_F, LE, FLOAT32)
BINOP(gt_F, GT, FLOAT32)
BINOP(ge_F, GE, FLOAT32)
static PyObject *
_unop(PyObject* self, PyObject* args)
{
Imaging out;
Imaging im1;
void (*unop)(Imaging, Imaging);
long op, i0, i1;
if (!PyArg_ParseTuple(args, "lll", &op, &i0, &i1))
return NULL;
out = (Imaging) i0;
im1 = (Imaging) i1;
unop = (void*) op;
unop(out, im1);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject *
_binop(PyObject* self, PyObject* args)
{
Imaging out;
Imaging im1;
Imaging im2;
void (*binop)(Imaging, Imaging, Imaging);
long op, i0, i1, i2;
if (!PyArg_ParseTuple(args, "llll", &op, &i0, &i1, &i2))
return NULL;
out = (Imaging) i0;
im1 = (Imaging) i1;
im2 = (Imaging) i2;
binop = (void*) op;
binop(out, im1, im2);
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef _functions[] = {
{"unop", _unop, 1},
{"binop", _binop, 1},
{NULL, NULL}
};
static void
install(PyObject *d, char* name, void* value)
{
PyObject *v = PyInt_FromLong((long) value);
if (!v || PyDict_SetItemString(d, name, v))
PyErr_Clear();
Py_XDECREF(v);
}
static int
setup_module(PyObject* m) {
PyObject* d = PyModule_GetDict(m);
install(d, "abs_I", abs_I);
install(d, "neg_I", neg_I);
install(d, "add_I", add_I);
install(d, "sub_I", sub_I);
install(d, "diff_I", diff_I);
install(d, "mul_I", mul_I);
install(d, "div_I", div_I);
install(d, "mod_I", mod_I);
install(d, "min_I", min_I);
install(d, "max_I", max_I);
install(d, "pow_I", pow_I);
install(d, "invert_I", invert_I);
install(d, "and_I", and_I);
install(d, "or_I", or_I);
install(d, "xor_I", xor_I);
install(d, "lshift_I", lshift_I);
install(d, "rshift_I", rshift_I);
install(d, "eq_I", eq_I);
install(d, "ne_I", ne_I);
install(d, "lt_I", lt_I);
install(d, "le_I", le_I);
install(d, "gt_I", gt_I);
install(d, "ge_I", ge_I);
install(d, "abs_F", abs_F);
install(d, "neg_F", neg_F);
install(d, "add_F", add_F);
install(d, "sub_F", sub_F);
install(d, "diff_F", diff_F);
install(d, "mul_F", mul_F);
install(d, "div_F", div_F);
install(d, "mod_F", mod_F);
install(d, "min_F", min_F);
install(d, "max_F", max_F);
install(d, "pow_F", pow_F);
install(d, "eq_F", eq_F);
install(d, "ne_F", ne_F);
install(d, "lt_F", lt_F);
install(d, "le_F", le_F);
install(d, "gt_F", gt_F);
install(d, "ge_F", ge_F);
return 0;
}
#if PY_VERSION_HEX >= 0x03000000
PyMODINIT_FUNC
PyInit__imagingmath(void) {
PyObject* m;
static PyModuleDef module_def = {
PyModuleDef_HEAD_INIT,
"_imagingmath", /* m_name */
NULL, /* m_doc */
-1, /* m_size */
_functions, /* m_methods */
};
m = PyModule_Create(&module_def);
if (setup_module(m) < 0)
return NULL;
return m;
}
#else
PyMODINIT_FUNC
init_imagingmath(void)
{
PyObject* m = Py_InitModule("_imagingmath", _functions);
setup_module(m);
}
#endif