Use PyCapsule in _imagingmorph

This commit is contained in:
Aleksandr Karpinskii 2024-09-02 01:43:38 +04:00
parent 56bc6a1a71
commit f916b5dc87
3 changed files with 43 additions and 19 deletions

View File

@ -328,13 +328,13 @@ def test_wrong_mode() -> None:
iml = Image.new("L", (10, 10)) iml = Image.new("L", (10, 10))
with pytest.raises(RuntimeError): 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): 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): with pytest.raises(RuntimeError):
_imagingmorph.match(bytes(lut), imrgb.im.id) _imagingmorph.match(bytes(lut), imrgb.im.ptr)
# Should not raise # Should not raise
_imagingmorph.match(bytes(lut), iml.im.id) _imagingmorph.match(bytes(lut), iml.im.ptr)

View File

@ -213,7 +213,7 @@ class MorphOp:
msg = "Image mode must be L" msg = "Image mode must be L"
raise ValueError(msg) raise ValueError(msg)
outimage = Image.new(image.mode, image.size, None) 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 return count, outimage
def match(self, image: Image.Image) -> list[tuple[int, int]]: def match(self, image: Image.Image) -> list[tuple[int, int]]:
@ -229,7 +229,7 @@ class MorphOp:
if image.mode != "L": if image.mode != "L":
msg = "Image mode must be L" msg = "Image mode must be L"
raise ValueError(msg) 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]]: def get_on_pixels(self, image: Image.Image) -> list[tuple[int, int]]:
"""Get a list of all turned on pixels in a binary image """Get a list of all turned on pixels in a binary image
@ -240,7 +240,7 @@ class MorphOp:
if image.mode != "L": if image.mode != "L":
msg = "Image mode must be L" msg = "Image mode must be L"
raise ValueError(msg) 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: def load_lut(self, filename: str) -> None:
"""Load an operator from an mrl file""" """Load an operator from an mrl file"""

View File

@ -30,15 +30,15 @@
static PyObject * static PyObject *
apply(PyObject *self, PyObject *args) { apply(PyObject *self, PyObject *args) {
const char *lut; const char *lut;
PyObject *py_lut; PyObject *py_lut, *i0, *i1;
Py_ssize_t lut_len, i0, i1; Py_ssize_t lut_len;
Imaging imgin, imgout; Imaging imgin, imgout;
int width, height; int width, height;
int row_idx, col_idx; int row_idx, col_idx;
UINT8 **inrows, **outrows; UINT8 **inrows, **outrows;
int num_changed_pixels = 0; 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"); PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem");
return NULL; return NULL;
} }
@ -57,8 +57,16 @@ apply(PyObject *self, PyObject *args) {
lut = PyBytes_AsString(py_lut); lut = PyBytes_AsString(py_lut);
imgin = (Imaging)i0; if (!PyCapsule_IsValid(i0, IMAGING_MAGIC) ||
imgout = (Imaging)i1; !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; width = imgin->xsize;
height = imgin->ysize; height = imgin->ysize;
@ -129,8 +137,8 @@ apply(PyObject *self, PyObject *args) {
static PyObject * static PyObject *
match(PyObject *self, PyObject *args) { match(PyObject *self, PyObject *args) {
const char *lut; const char *lut;
PyObject *py_lut; PyObject *py_lut, *i0;
Py_ssize_t lut_len, i0; Py_ssize_t lut_len;
Imaging imgin; Imaging imgin;
int width, height; int width, height;
int row_idx, col_idx; int row_idx, col_idx;
@ -140,7 +148,7 @@ match(PyObject *self, PyObject *args) {
return NULL; return NULL;
} }
if (!PyArg_ParseTuple(args, "On", &py_lut, &i0)) { if (!PyArg_ParseTuple(args, "OO", &py_lut, &i0)) {
Py_DECREF(ret); Py_DECREF(ret);
PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem");
return NULL; return NULL;
@ -161,7 +169,15 @@ match(PyObject *self, PyObject *args) {
} }
lut = PyBytes_AsString(py_lut); 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) { if (imgin->type != IMAGING_TYPE_UINT8 || imgin->bands != 1) {
Py_DECREF(ret); Py_DECREF(ret);
@ -215,7 +231,7 @@ match(PyObject *self, PyObject *args) {
*/ */
static PyObject * static PyObject *
get_on_pixels(PyObject *self, PyObject *args) { get_on_pixels(PyObject *self, PyObject *args) {
Py_ssize_t i0; PyObject *i0;
Imaging img; Imaging img;
UINT8 **rows; UINT8 **rows;
int row_idx, col_idx; int row_idx, col_idx;
@ -225,12 +241,20 @@ get_on_pixels(PyObject *self, PyObject *args) {
return NULL; return NULL;
} }
if (!PyArg_ParseTuple(args, "n", &i0)) { if (!PyArg_ParseTuple(args, "O", &i0)) {
Py_DECREF(ret); Py_DECREF(ret);
PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem");
return NULL; 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; rows = img->image8;
width = img->xsize; width = img->xsize;
height = img->ysize; height = img->ysize;