Extending PIL
Q. I am writing an C-extension which takes Imaging as input from Python interpreter as well as return Imaging back to Python environment. I am having problem with the latter.
An Imaging object is just an ordinary C struct, it’s not a valid Python type (it doesn’t have the PyObject_HEAD stuff required by Python). The Python bindings are defined in _imaging.c, and are currently not exported to external users.
To work around this, you can:
1) Link your code with the _imaging module, and call PyImagingNew to wrap an Imaging pointer in a Python-compatible ImagingObject (see the _imaging.c sources for details).
or:
2) Create the new image in Python code, and pass its “id” attribute to your extension. This is the approach I usually use. An example:
def myoperation(imIn, arg): imIn.load() # make sure it's loaded imOut = Image.new(imIn.mode, imIn.size, None) mymodule.myoperation(imIn.im.id, imOut.im.id, arg) return imOut
Inside the C extension, you can then do something like:
static PyObject * myoperation(PyObject* self, PyObject* args) { Imaging imIn, imOut; int x, y; long idIn, idOut; int arg; if (!PyArg_ParseTuple(args, "lli", &idIn, &idOut, &arg)) return NULL; /* get image */ imIn = (Imaging) idIn; imOut = (Imaging) idOut; /* check modes, sizes, etc */ /* do some processing */ for (y = 0; y < imIn->ysize; y++) { UINT8* in = imIn->image[y]; UINT8* out = imOut->image[y]; for (x = 0; x < imIn->xsize; x++) out[x] = in[x] + arg; } Py_INCREF(Py_None); return Py_None; }
Future versions of PIL will probably include some way to wrap the Imaging pointer in a Python CObject.