51 PyExc_ReferenceError,
"ImBuf data of type %.200s has been freed", Py_TYPE(
self)->tp_name);
55#define PY_IMBUF_CHECK_OBJ(obj) \
56 if (UNLIKELY(py_imbuf_valid_check(obj) == -1)) { \
60#define PY_IMBUF_CHECK_INT(obj) \
61 if (UNLIKELY(py_imbuf_valid_check(obj) == -1)) { \
75 ".. method:: resize(size, *, method='FAST')\n"
77 " Resize the image.\n"
79 " :arg size: New size.\n"
80 " :type size: tuple[int, int]\n"
81 " :arg method: Method of resizing ('FAST', 'BILINEAR')\n"
82 " :type method: str\n");
89 enum { FAST, BILINEAR };
92 {BILINEAR,
"BILINEAR"},
97 static const char *_keywords[] = {
"size",
"method",
nullptr};
98 static _PyArg_Parser _parser = {
107 if (!_PyArg_ParseTupleAndKeywordsFast(
113 PyErr_Format(PyExc_ValueError,
"resize: Image size cannot be below 1 (%d, %d)",
UNPACK2(
size));
132 ".. method:: crop(min, max)\n"
136 " :arg min: X, Y minimum.\n"
137 " :type min: tuple[int, int]\n"
138 " :arg max: X, Y maximum.\n"
139 " :type max: tuple[int, int]\n");
146 static const char *_keywords[] = {
"min",
"max",
nullptr};
147 static _PyArg_Parser _parser = {
155 if (!_PyArg_ParseTupleAndKeywordsFast(
170 PyErr_SetString(PyExc_ValueError,
"ImBuf crop min/max not in range");
180 ".. method:: copy()\n"
182 " :return: A copy of the image.\n"
183 " :rtype: :class:`ImBuf`\n");
189 if (
UNLIKELY(ibuf_copy ==
nullptr)) {
190 PyErr_SetString(PyExc_MemoryError,
192 "failed to allocate memory");
209 ".. method:: free()\n"
211 " Clear image data immediately (causing an error on re-use).\n");
216 self->ibuf =
nullptr;
223# pragma clang diagnostic push
224# pragma clang diagnostic ignored "-Wcast-function-type"
226# pragma GCC diagnostic push
227# pragma GCC diagnostic ignored "-Wcast-function-type"
232 {
"resize", (PyCFunction)
py_imbuf_resize, METH_VARARGS | METH_KEYWORDS, py_imbuf_resize_doc},
233 {
"crop", (PyCFunction)
py_imbuf_crop, METH_VARARGS | METH_KEYWORDS, (
char *)py_imbuf_crop_doc},
234 {
"free", (PyCFunction)
py_imbuf_free, METH_NOARGS, py_imbuf_free_doc},
235 {
"copy", (PyCFunction)
py_imbuf_copy, METH_NOARGS, py_imbuf_copy_doc},
236 {
"__copy__", (PyCFunction)
py_imbuf_copy, METH_NOARGS, py_imbuf_copy_doc},
237 {
"__deepcopy__", (PyCFunction)
py_imbuf_deepcopy, METH_VARARGS, py_imbuf_copy_doc},
238 {
nullptr,
nullptr, 0,
nullptr},
243# pragma clang diagnostic pop
245# pragma GCC diagnostic pop
258 "size of the image in pixels.\n"
260 ":type: tuple[int, int]\n");
271 "pixels per meter.\n"
273 ":type: tuple[float, float]\n");
286 if (
PyC_AsArray(ppm,
sizeof(*ppm), value, 2, &PyFloat_Type,
"ppm") == -1) {
290 if (ppm[0] <= 0.0 || ppm[1] <= 0.0) {
291 PyErr_SetString(PyExc_ValueError,
"invalid ppm value");
296 ibuf->
ppm[0] = ppm[0];
297 ibuf->
ppm[1] = ppm[1];
303 py_imbuf_filepath_doc,
304 "filepath associated with this image.\n"
318 if (!PyUnicode_Check(value)) {
319 PyErr_SetString(PyExc_TypeError,
"expected a string!");
324 const Py_ssize_t value_str_len_max =
sizeof(ibuf->
filepath);
325 PyObject *value_coerce =
nullptr;
326 Py_ssize_t value_str_len;
328 if (value_str_len >= value_str_len_max) {
329 PyErr_Format(PyExc_TypeError,
"filepath length over %zd", value_str_len_max - 1);
330 Py_XDECREF(value_coerce);
333 memcpy(ibuf->
filepath, value_str, value_str_len + 1);
334 Py_XDECREF(value_coerce);
341 "Number of bits associated with this image.\n"
348 return PyLong_FromLong(imbuf->
planes);
353 py_imbuf_channels_doc,
354 "Number of bit-planes.\n"
361 return PyLong_FromLong(imbuf->
channels);
365 {
"size", (getter)
py_imbuf_size_get, (setter)
nullptr, py_imbuf_size_doc,
nullptr},
370 py_imbuf_filepath_doc,
374 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
386 if (ibuf !=
nullptr) {
388 self->ibuf =
nullptr;
396 if (ibuf !=
nullptr) {
397 return PyUnicode_FromFormat(
"<imbuf: address=%p, filepath='%s', size=(%d, %d)>",
404 return PyUnicode_FromString(
"<imbuf: address=0x0>");
413 PyVarObject_HEAD_INIT(
nullptr, 0)
468 return (PyObject *)
self;
480 ".. function:: new(size)\n"
482 " Load a new image.\n"
484 " :arg size: The size of the image in pixels.\n"
485 " :type size: tuple[int, int]\n"
486 " :return: the newly loaded image.\n"
487 " :rtype: :class:`ImBuf`\n");
488static PyObject *
M_imbuf_new(PyObject * , PyObject *args, PyObject *kw)
491 static const char *_keywords[] = {
"size",
nullptr};
492 static _PyArg_Parser _parser = {
499 if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &
size[0], &
size[1])) {
503 PyErr_Format(PyExc_ValueError,
"new: Image size cannot be below 1 (%d, %d)",
UNPACK2(
size));
508 const uchar planes = 32;
512 if (ibuf ==
nullptr) {
513 PyErr_Format(PyExc_ValueError,
"new: Unable to create image (%d, %d)",
UNPACK2(
size));
523 PyErr_Format(PyExc_IOError,
"load: %s, failed to open file '%s'", strerror(errno), filepath);
531 if (ibuf ==
nullptr) {
533 PyExc_ValueError,
"load: Unable to recognize image format for file '%s'", filepath);
545 ".. function:: load(filepath)\n"
547 " Load an image from a file.\n"
549 " :arg filepath: the filepath of the image.\n"
550 " :type filepath: str | bytes\n"
551 " :return: the newly loaded image.\n"
552 " :rtype: :class:`ImBuf`\n");
553static PyObject *
M_imbuf_load(PyObject * , PyObject *args, PyObject *kw)
557 static const char *_keywords[] = {
"filepath",
nullptr};
558 static _PyArg_Parser _parser = {
565 if (!_PyArg_ParseTupleAndKeywordsFast(
577 const size_t buffer_size,
581 reinterpret_cast<const uchar *
>(buffer), buffer_size, flags,
"<imbuf.load_from_buffer>");
583 if (ibuf ==
nullptr) {
584 PyErr_SetString(PyExc_ValueError,
"load_from_buffer: Unable to load image from memory");
593 M_imbuf_load_from_buffer_doc,
594 ".. function:: load_from_buffer(buffer)\n"
596 " Load an image from a buffer.\n"
598 " :arg buffer: A buffer containing the image data.\n"
599 " :type buffer: collections.abc.Buffer\n"
600 " :return: the newly loaded image.\n"
601 " :rtype: :class:`ImBuf`\n");
604 PyObject *buffer_py_ob;
606 static const char *_keywords[] = {
"buffer",
nullptr};
607 static _PyArg_Parser _parser = {
614 if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &buffer_py_ob)) {
618 PyObject *
result =
nullptr;
623 if (PyObject_CheckBuffer(buffer_py_ob)) {
625 if (PyObject_GetBuffer(buffer_py_ob, &pybuffer, PyBUF_SIMPLE) == -1) {
629 reinterpret_cast<const char *
>(pybuffer.buf), pybuffer.len, flags);
631 PyBuffer_Release(&pybuffer);
634 PyErr_Format(PyExc_TypeError,
635 "load_from_buffer: expected a buffer, unsupported type %.200s",
636 Py_TYPE(buffer_py_ob)->tp_name);
647 PyExc_IOError,
"write: Unable to write image file (%s) '%s'", strerror(errno), filepath);
656 ".. function:: write(image, *, filepath=image.filepath)\n"
660 " :arg image: the image to write.\n"
661 " :type image: :class:`ImBuf`\n"
662 " :arg filepath: Optional filepath of the image (fallback to the images file path).\n"
663 " :type filepath: str | bytes | None\n");
669 static const char *_keywords[] = {
"image",
"filepath",
nullptr};
670 static _PyArg_Parser _parser = {
679 if (!_PyArg_ParseTupleAndKeywordsFast(args,
690 const char *filepath = filepath_data.
value;
691 if (filepath ==
nullptr) {
708# pragma clang diagnostic push
709# pragma clang diagnostic ignored "-Wcast-function-type"
711# pragma GCC diagnostic push
712# pragma GCC diagnostic ignored "-Wcast-function-type"
717 {
"new", (PyCFunction)
M_imbuf_new, METH_VARARGS | METH_KEYWORDS, M_imbuf_new_doc},
718 {
"load", (PyCFunction)
M_imbuf_load, METH_VARARGS | METH_KEYWORDS, M_imbuf_load_doc},
721 METH_VARARGS | METH_KEYWORDS,
722 M_imbuf_load_from_buffer_doc},
723 {
"write", (PyCFunction)
M_imbuf_write, METH_VARARGS | METH_KEYWORDS, M_imbuf_write_doc},
724 {
nullptr,
nullptr, 0,
nullptr},
729# pragma clang diagnostic pop
731# pragma GCC diagnostic pop
738 "This module provides access to Blender's image manipulation API.\n"
740 "It provides access to image buffers outside of Blender's\n"
741 ":class:`bpy.types.Image` data-block context.\n");
758 PyObject *sys_modules = PyImport_GetModuleDict();
764 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
781 "This module provides access to image buffer types.\n"
785 " Image buffer is also the structure used by :class:`bpy.types.Image`\n"
786 " ID type to store and manipulate image data at runtime.\n");
827 return ((
Py_ImBuf *)py_imbuf)->ibuf;
#define BLI_assert_unreachable()
File and directory operations.
int BLI_open(const char *filepath, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
char * STRNCPY(char(&dst)[N], const char *src)
ImBuf * IMB_dupImBuf(const ImBuf *ibuf1)
ImBuf * IMB_load_image_from_memory(const unsigned char *mem, const size_t size, const int flags, const char *descr, const char *filepath=nullptr, char r_colorspace[IM_MAX_SPACE]=nullptr)
void IMB_rect_crop(ImBuf *ibuf, const rcti *crop)
void IMB_freeImBuf(ImBuf *ibuf)
ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
ImBuf * IMB_load_image_from_file_descriptor(const int file, const int flags, const char *filepath=nullptr, char r_colorspace[IM_MAX_SPACE]=nullptr)
bool IMB_save_image(ImBuf *ibuf, const char *filepath, const int flags)
bool IMB_scale(ImBuf *ibuf, unsigned int newx, unsigned int newy, IMBScaleFilter filter, bool threaded=true)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
static PyObject * Py_ImBuf_CreatePyObject(ImBuf *ibuf)
static PyObject * py_imbuf_filepath_get(Py_ImBuf *self, void *)
static PyObject * M_imbuf_load(PyObject *, PyObject *args, PyObject *kw)
static PyObject * py_imbuf_planes_get(Py_ImBuf *self, void *)
static PyObject * py_imbuf_channels_get(Py_ImBuf *self, void *)
static int py_imbuf_filepath_set(Py_ImBuf *self, PyObject *value, void *)
static PyObject * M_imbuf_write(PyObject *, PyObject *args, PyObject *kw)
static PyObject * py_imbuf_size_get(Py_ImBuf *self, void *)
static PyObject * imbuf_load_impl(const char *filepath)
static PyObject * BPyInit_imbuf_types()
static PyObject * py_imbuf_copy(Py_ImBuf *self)
static PyObject * py_imbuf_resize(Py_ImBuf *self, PyObject *args, PyObject *kw)
static Py_hash_t py_imbuf_hash(Py_ImBuf *self)
#define PY_IMBUF_CHECK_OBJ(obj)
static PyMethodDef IMB_methods[]
static PyObject * M_imbuf_new(PyObject *, PyObject *args, PyObject *kw)
#define PY_IMBUF_CHECK_INT(obj)
static PyObject * py_imbuf_ppm_get(Py_ImBuf *self, void *)
static PyModuleDef IMB_module_def
static PyObject * py_imbuf_crop(Py_ImBuf *self, PyObject *args, PyObject *kw)
static int py_imbuf_ppm_set(Py_ImBuf *self, PyObject *value, void *)
static PyObject * py_imbuf_repr(Py_ImBuf *self)
PyDoc_STRVAR(py_imbuf_resize_doc, ".. method:: resize(size, *, method='FAST')\n" "\n" " Resize the image.\n" "\n" " :arg size: New size.\n" " :type size: tuple[int, int]\n" " :arg method: Method of resizing ('FAST', 'BILINEAR')\n" " :type method: str\n")
static PyObject * imbuf_write_impl(ImBuf *ibuf, const char *filepath)
PyObject * BPyInit_imbuf()
static PyObject * py_imbuf_free(Py_ImBuf *self)
static PyGetSetDef Py_ImBuf_getseters[]
PyTypeObject Py_ImBuf_Type
static PyMethodDef Py_ImBuf_methods[]
ImBuf * BPy_ImBuf_FromPyObject(PyObject *py_imbuf)
static int py_imbuf_valid_check(Py_ImBuf *self)
static PyModuleDef IMB_types_module_def
static void py_imbuf_dealloc(Py_ImBuf *self)
static PyObject * py_imbuf_deepcopy(Py_ImBuf *self, PyObject *args)
static PyObject * M_imbuf_load_from_buffer(PyObject *, PyObject *args, PyObject *kw)
static PyObject * imbuf_load_from_memory_impl(const char *buffer, const size_t buffer_size, int flags)
const char * PyC_UnicodeAsBytesAndSize(PyObject *py_str, Py_ssize_t *r_size, PyObject **r_coerce)
int PyC_CheckArgs_DeepCopy(PyObject *args)
int PyC_ParseUnicodeAsBytesAndSize(PyObject *o, void *p)
int PyC_ParseStringEnum(PyObject *o, void *p)
PyObject * PyC_UnicodeFromBytes(const char *str)
int PyC_AsArray(void *array, const size_t array_item_size, PyObject *value, const Py_ssize_t length, const PyTypeObject *type, const char *error_prefix)
int PyC_ParseUnicodeAsBytesAndSize_OrNone(PyObject *o, void *p)
PyObject * PyC_Tuple_Pack_I32(const blender::Span< int > values)
PyObject * PyC_Tuple_Pack_F64(const blender::Span< double > values)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
char filepath[IMB_FILEPATH_SIZE]
PyObject_VAR_HEAD ImBuf * ibuf