mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
Support old Python 2 buffer protocol in PTA and Texture ram_image
This enables passing eg. str and array.array objects in Python 2
This commit is contained in:
parent
096d54de00
commit
f0b21ee969
@ -203,34 +203,37 @@ set_data(PyObject *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PyBuffer_Release(&view);
|
PyBuffer_Release(&view);
|
||||||
} else {
|
return;
|
||||||
Dtool_Raise_TypeError("PointerToArray.set_data() requires a buffer object");
|
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
// In Python 2.5 we didn't have the new buffer protocol, only str.
|
|
||||||
if (PyString_CheckExact(data)) {
|
// In Python 2, there was also an older buffer protocol, supported by eg.
|
||||||
int size = PyString_Size(data);
|
// str and array objects.
|
||||||
if (size % sizeof(Element) != 0) {
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
// The old, deprecated buffer interface, as used by eg. the array module.
|
||||||
|
const void *buffer;
|
||||||
|
Py_ssize_t buffer_len;
|
||||||
|
if (!PyUnicode_CheckExact(data) &&
|
||||||
|
PyObject_AsReadBuffer(data, &buffer, &buffer_len) == 0) {
|
||||||
|
if (buffer_len % sizeof(Element) != 0) {
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
"str object is not a multiple of %zu bytes",
|
"byte buffer is not a multiple of %zu bytes",
|
||||||
sizeof(Element));
|
sizeof(Element));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int num_elements = size / sizeof(Element);
|
if (buffer_len > 0) {
|
||||||
this->_this->insert(this->_this->begin(), num_elements, Element());
|
this->_this->resize(buffer_len / sizeof(Element));
|
||||||
|
memcpy(this->_this->p(), buffer, buffer_len);
|
||||||
// Hope there aren't any constructors or destructors involved here.
|
|
||||||
if (size != 0) {
|
|
||||||
const char *ptr = PyString_AsString(data);
|
|
||||||
memcpy(this->_this->p(), ptr, size);
|
|
||||||
} else {
|
} else {
|
||||||
this->_this->clear();
|
this->_this->clear();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Dtool_Raise_TypeError("PointerToArray.set_data() requires a str");
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Dtool_Raise_TypeError("PointerToArray.set_data() requires a buffer object");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,6 +84,29 @@ set_ram_image(PyObject *image, Texture::CompressionMode compression,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
// The old, deprecated buffer interface, as used by eg. the array module.
|
||||||
|
const void *buffer;
|
||||||
|
Py_ssize_t buffer_len;
|
||||||
|
if (!PyUnicode_CheckExact(image) &&
|
||||||
|
PyObject_AsReadBuffer(image, &buffer, &buffer_len) == 0) {
|
||||||
|
if (compression == Texture::CM_off) {
|
||||||
|
int component_width = _this->get_component_width();
|
||||||
|
if (buffer_len % component_width != 0) {
|
||||||
|
PyErr_Format(PyExc_ValueError,
|
||||||
|
"byte buffer is not a multiple of %d bytes",
|
||||||
|
component_width);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PTA_uchar data = PTA_uchar::empty_array(buffer_len, Texture::get_class_type());
|
||||||
|
memcpy(data.p(), buffer, buffer_len);
|
||||||
|
_this->set_ram_image(MOVE(data), compression, page_size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Dtool_Raise_ArgTypeError(image, 0, "Texture.set_ram_image", "CPTA_uchar or buffer");
|
Dtool_Raise_ArgTypeError(image, 0, "Texture.set_ram_image", "CPTA_uchar or buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user