diff --git a/Tests/test_imagemorph.py b/Tests/test_imagemorph.py index 80d8c3815..04860fd61 100644 --- a/Tests/test_imagemorph.py +++ b/Tests/test_imagemorph.py @@ -328,13 +328,13 @@ def test_wrong_mode() -> None: iml = Image.new("L", (10, 10)) with pytest.raises(RuntimeError): - _imagingmorph.apply(bytes(lut), imrgb.im.id, iml.im.id) + _imagingmorph.apply(bytes(lut), imrgb.im.ptr, iml.im.ptr) with pytest.raises(RuntimeError): - _imagingmorph.apply(bytes(lut), iml.im.id, imrgb.im.id) + _imagingmorph.apply(bytes(lut), iml.im.ptr, imrgb.im.ptr) with pytest.raises(RuntimeError): - _imagingmorph.match(bytes(lut), imrgb.im.id) + _imagingmorph.match(bytes(lut), imrgb.im.ptr) # Should not raise - _imagingmorph.match(bytes(lut), iml.im.id) + _imagingmorph.match(bytes(lut), iml.im.ptr) diff --git a/src/PIL/ImageMorph.py b/src/PIL/ImageMorph.py index 6a43983d3..bc7ed66d3 100644 --- a/src/PIL/ImageMorph.py +++ b/src/PIL/ImageMorph.py @@ -213,7 +213,7 @@ class MorphOp: msg = "Image mode must be L" raise ValueError(msg) outimage = Image.new(image.mode, image.size, None) - count = _imagingmorph.apply(bytes(self.lut), image.im.id, outimage.im.id) + count = _imagingmorph.apply(bytes(self.lut), image.im.ptr, outimage.im.ptr) return count, outimage def match(self, image: Image.Image) -> list[tuple[int, int]]: @@ -229,7 +229,7 @@ class MorphOp: if image.mode != "L": msg = "Image mode must be L" raise ValueError(msg) - return _imagingmorph.match(bytes(self.lut), image.im.id) + return _imagingmorph.match(bytes(self.lut), image.im.ptr) def get_on_pixels(self, image: Image.Image) -> list[tuple[int, int]]: """Get a list of all turned on pixels in a binary image @@ -240,7 +240,7 @@ class MorphOp: if image.mode != "L": msg = "Image mode must be L" raise ValueError(msg) - return _imagingmorph.get_on_pixels(image.im.id) + return _imagingmorph.get_on_pixels(image.im.ptr) def load_lut(self, filename: str) -> None: """Load an operator from an mrl file""" diff --git a/src/_imagingmorph.c b/src/_imagingmorph.c index 614dfbe7f..c7933cc7d 100644 --- a/src/_imagingmorph.c +++ b/src/_imagingmorph.c @@ -30,15 +30,15 @@ static PyObject * apply(PyObject *self, PyObject *args) { const char *lut; - PyObject *py_lut; - Py_ssize_t lut_len, i0, i1; + PyObject *py_lut, *i0, *i1; + Py_ssize_t lut_len; Imaging imgin, imgout; int width, height; int row_idx, col_idx; UINT8 **inrows, **outrows; int num_changed_pixels = 0; - if (!PyArg_ParseTuple(args, "Onn", &py_lut, &i0, &i1)) { + if (!PyArg_ParseTuple(args, "OOO", &py_lut, &i0, &i1)) { PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); return NULL; } @@ -57,8 +57,16 @@ apply(PyObject *self, PyObject *args) { lut = PyBytes_AsString(py_lut); - imgin = (Imaging)i0; - imgout = (Imaging)i1; + if (!PyCapsule_IsValid(i0, IMAGING_MAGIC) || + !PyCapsule_IsValid(i1, IMAGING_MAGIC)) { + PyErr_Format( + PyExc_TypeError, "Expected PyCapsule with '%s' name.", IMAGING_MAGIC + ); + return NULL; + } + + imgin = (Imaging)PyCapsule_GetPointer(i0, IMAGING_MAGIC); + imgout = (Imaging)PyCapsule_GetPointer(i1, IMAGING_MAGIC); width = imgin->xsize; height = imgin->ysize; @@ -129,8 +137,8 @@ apply(PyObject *self, PyObject *args) { static PyObject * match(PyObject *self, PyObject *args) { const char *lut; - PyObject *py_lut; - Py_ssize_t lut_len, i0; + PyObject *py_lut, *i0; + Py_ssize_t lut_len; Imaging imgin; int width, height; int row_idx, col_idx; @@ -140,7 +148,7 @@ match(PyObject *self, PyObject *args) { return NULL; } - if (!PyArg_ParseTuple(args, "On", &py_lut, &i0)) { + if (!PyArg_ParseTuple(args, "OO", &py_lut, &i0)) { Py_DECREF(ret); PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); return NULL; @@ -161,7 +169,15 @@ match(PyObject *self, PyObject *args) { } lut = PyBytes_AsString(py_lut); - imgin = (Imaging)i0; + + if (!PyCapsule_IsValid(i0, IMAGING_MAGIC)) { + PyErr_Format( + PyExc_TypeError, "Expected PyCapsule with '%s' name.", IMAGING_MAGIC + ); + return NULL; + } + + imgin = (Imaging)PyCapsule_GetPointer(i0, IMAGING_MAGIC); if (imgin->type != IMAGING_TYPE_UINT8 || imgin->bands != 1) { Py_DECREF(ret); @@ -215,7 +231,7 @@ match(PyObject *self, PyObject *args) { */ static PyObject * get_on_pixels(PyObject *self, PyObject *args) { - Py_ssize_t i0; + PyObject *i0; Imaging img; UINT8 **rows; int row_idx, col_idx; @@ -225,12 +241,20 @@ get_on_pixels(PyObject *self, PyObject *args) { return NULL; } - if (!PyArg_ParseTuple(args, "n", &i0)) { + if (!PyArg_ParseTuple(args, "O", &i0)) { Py_DECREF(ret); PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); return NULL; } - img = (Imaging)i0; + + if (!PyCapsule_IsValid(i0, IMAGING_MAGIC)) { + PyErr_Format( + PyExc_TypeError, "Expected PyCapsule with '%s' name.", IMAGING_MAGIC + ); + return NULL; + } + + img = (Imaging)PyCapsule_GetPointer(i0, IMAGING_MAGIC); rows = img->image8; width = img->xsize; height = img->ysize;