Open GoogleCodeExporter opened 9 years ago
The docstrings are wrong here.
Looking at the code, the data must pass trough
pyglet.image.ImageData._ensure_string_data, which is
def _ensure_string_data(self):
if type(self._current_data) is not bytes_type:
buf = create_string_buffer(len(self._current_data))
memmove(buf, self._current_data, len(self._current_data))
self._current_data = buf.raw
So 'data' must be suitable for the call
ctypes.memmove(buf, data, len(data))
ctypes.memmove assumes a contiguous C byte buffer, so python lists are not
suitable
Minimal patch
=============
A minimal patch to close the issue would only correct the docstrings, something
like the attached as issue_#752_minimal_patch.diff
More exploration
================
A bit of experimentation shows that two common python wrappers for C buffers,
'bytearray' and "array.array('B',...)" are not accepted, while type
T=ctypes.c_char * size is accepted.
Additionally, with the last type the code performs one unnecessary copy: first
it explicitly copies with the memmove, later an implicit copy is made by python
when referencing buf.raw ( see ctypes docs, or make a buffer an compare id(a)
id(b) after doing a = buf.raw; b = buf.raw )
This suggest to change to:
def _ensure_string_data(self):
if type(self._current_data) is not bytes_type:
T = c_char * len(self._current_data)
# binds buf to the buffer into self._current_data (no copy)
buf = T.from_buffer(self._current_data)
# buf raw generates a new str, filled with the contents of buf
# (implicit copy)
self._current_data = buf.raw
This allows to pass bytearray and array.array('B', ...) types, and type
T=ctypes.c_char * size continues working. Also, no innecesary copy is performed.
In fact, the body's if will accept anything supporting the writable buffer
protocol (ref: ctypes docs)
I don't know if they are relevant types accepted by the original code but not
by the later but:
- trying a number of pyglet samples and tests, (including video.py), they all work; also the cocos's autotest suite (200+ tests) runs normal with this change
- If need arises, a proper conditional branch for other types can be added later, and then the tests should show which extra types are needed
This lends to a
Medium patch
============
Includes the suggested modification plus tests and docstrings, attached as
issue_#752_medium_patch.diff
Tested in py2.6 and py 3.3
Original comment by ccanepacc@gmail.com
on 15 Jul 2014 at 5:12
Attachments:
Original comment by useboxnet
on 16 Jul 2014 at 4:50
Original comment by useboxnet
on 16 Jul 2014 at 4:50
Original issue reported on code.google.com by
icefo...@gmail.com
on 23 Jun 2014 at 10:51Attachments: