Use PyCapsule in _imagingtk

This commit is contained in:
Aleksandr Karpinskii 2024-09-02 04:29:34 +04:00
parent c69ad03af0
commit 920c4ac447
2 changed files with 31 additions and 15 deletions

View File

@ -48,18 +48,18 @@ def _get_image_from_kw(kw: dict[str, Any]) -> ImageFile.ImageFile | None:
def _pyimagingtkcall(
command: str, photo: PhotoImage | tkinter.PhotoImage, id: int
command: str, photo: PhotoImage | tkinter.PhotoImage, ptr: object
) -> None:
tk = photo.tk
try:
tk.call(command, photo, id)
tk.call(command, photo, repr(ptr))
except tkinter.TclError:
# activate Tkinter hook
# may raise an error if it cannot attach to Tkinter
from . import _imagingtk
_imagingtk.tkinit(tk.interpaddr())
tk.call(command, photo, id)
tk.call(command, photo, repr(ptr))
# --------------------------------------------------------------------
@ -181,7 +181,7 @@ class PhotoImage:
block = image.new_block(self.__mode, im.size)
image.convert2(block, image) # convert directly between buffers
_pyimagingtkcall("PyImagingPhoto", self.__photo, block.id)
_pyimagingtkcall("PyImagingPhoto", self.__photo, block.ptr)
# --------------------------------------------------------------------
@ -255,9 +255,8 @@ class BitmapImage:
def getimage(photo: PhotoImage) -> Image.Image:
"""Copies the contents of a PhotoImage to a PIL image memory."""
im = Image.new("RGBA", (photo.width(), photo.height()))
block = im.im
_pyimagingtkcall("PyImagingPhotoGet", photo, block.id)
_pyimagingtkcall("PyImagingPhotoGet", photo, im.im.ptr)
return im

View File

@ -56,19 +56,36 @@ static Tk_PhotoPutBlock_t TK_PHOTO_PUT_BLOCK;
static Imaging
ImagingFind(const char *name) {
Py_ssize_t id;
PyObject *capsule;
int direct_pointer = 0;
const char *expected = "capsule object \"" IMAGING_MAGIC "\" at 0x";
/* FIXME: use CObject instead? */
#if defined(_WIN64)
id = _atoi64(name);
#else
id = atol(name);
#endif
if (!id) {
if (name[0] == '<') {
name++;
} else {
// Special case for PyPy, where the string representation of a Capsule
// refers directly to the pointer itself, not to the PyCapsule object.
direct_pointer = 1;
}
if (strncmp(name, expected, strlen(expected))) {
return NULL;
}
return (Imaging)id;
capsule = (PyObject *)strtoull(name + strlen(expected), NULL, 16);
if (direct_pointer) {
return (Imaging)capsule;
}
if (!PyCapsule_IsValid(capsule, IMAGING_MAGIC)) {
PyErr_Format(
PyExc_TypeError, "Expected PyCapsule with '%s' name.", IMAGING_MAGIC
);
return NULL;
}
return (Imaging)PyCapsule_GetPointer(capsule, IMAGING_MAGIC);
}
static int