53 PyExc_ReferenceError,
"ImBuf data of type %.200s has been freed", Py_TYPE(
self)->tp_name);
57#define PY_IMBUF_CHECK_OBJ(obj) \
58 if (UNLIKELY(py_imbuf_valid_check(obj) == -1)) { \
62#define PY_IMBUF_CHECK_INT(obj) \
63 if (UNLIKELY(py_imbuf_valid_check(obj) == -1)) { \
77 ".. method:: resize(size, method='FAST')\n"
79 " Resize the image.\n"
81 " :arg size: New size.\n"
82 " :type size: tuple[int, int]\n"
83 " :arg method: Method of resizing ('FAST', 'BILINEAR')\n"
84 " :type method: str\n");
91 enum { FAST, BILINEAR };
94 {BILINEAR,
"BILINEAR"},
99 static const char *_keywords[] = {
"size",
"method",
nullptr};
100 static _PyArg_Parser _parser = {
109 if (!_PyArg_ParseTupleAndKeywordsFast(
114 if (size[0] <= 0 || size[1] <= 0) {
115 PyErr_Format(PyExc_ValueError,
"resize: Image size cannot be below 1 (%d, %d)",
UNPACK2(size));
119 if (method.value_found == FAST) {
122 else if (method.value_found == BILINEAR) {
134 ".. method:: crop(min, max)\n"
138 " :arg min: X, Y minimum.\n"
139 " :type min: tuple[int, int]\n"
140 " :arg max: X, Y maximum.\n"
141 " :type max: tuple[int, int]\n");
148 static const char *_keywords[] = {
"min",
"max",
nullptr};
149 static _PyArg_Parser _parser = {
157 if (!_PyArg_ParseTupleAndKeywordsFast(
172 PyErr_SetString(PyExc_ValueError,
"ImBuf crop min/max not in range");
182 ".. method:: copy()\n"
184 " :return: A copy of the image.\n"
185 " :rtype: :class:`ImBuf`\n");
191 if (
UNLIKELY(ibuf_copy ==
nullptr)) {
192 PyErr_SetString(PyExc_MemoryError,
194 "failed to allocate memory");
211 ".. method:: free()\n"
213 " Clear image data immediately (causing an error on re-use).\n");
218 self->ibuf =
nullptr;
223#if (defined(__GNUC__) && !defined(__clang__))
224# pragma GCC diagnostic push
225# pragma GCC diagnostic ignored "-Wcast-function-type"
229 {
"resize", (PyCFunction)
py_imbuf_resize, METH_VARARGS | METH_KEYWORDS, py_imbuf_resize_doc},
230 {
"crop", (PyCFunction)
py_imbuf_crop, METH_VARARGS | METH_KEYWORDS, (
char *)py_imbuf_crop_doc},
231 {
"free", (PyCFunction)
py_imbuf_free, METH_NOARGS, py_imbuf_free_doc},
232 {
"copy", (PyCFunction)
py_imbuf_copy, METH_NOARGS, py_imbuf_copy_doc},
233 {
"__copy__", (PyCFunction)
py_imbuf_copy, METH_NOARGS, py_imbuf_copy_doc},
234 {
"__deepcopy__", (PyCFunction)
py_imbuf_deepcopy, METH_VARARGS, py_imbuf_copy_doc},
235 {
nullptr,
nullptr, 0,
nullptr},
238#if (defined(__GNUC__) && !defined(__clang__))
239# pragma GCC diagnostic pop
251 "size of the image in pixels.\n"
253 ":type: pair of ints");
264 "pixels per meter.\n"
266 ":type: pair of floats");
279 if (
PyC_AsArray(ppm,
sizeof(*ppm), value, 2, &PyFloat_Type,
"ppm") == -1) {
283 if (ppm[0] <= 0.0 || ppm[1] <= 0.0) {
284 PyErr_SetString(PyExc_ValueError,
"invalid ppm value");
289 ibuf->
ppm[0] = ppm[0];
290 ibuf->
ppm[1] = ppm[1];
296 py_imbuf_filepath_doc,
297 "filepath associated with this image.\n"
311 if (!PyUnicode_Check(value)) {
312 PyErr_SetString(PyExc_TypeError,
"expected a string!");
317 const Py_ssize_t value_str_len_max =
sizeof(ibuf->
filepath);
318 Py_ssize_t value_str_len;
319 const char *value_str = PyUnicode_AsUTF8AndSize(value, &value_str_len);
320 if (value_str_len >= value_str_len_max) {
321 PyErr_Format(PyExc_TypeError,
"filepath length over %zd", value_str_len_max - 1);
324 memcpy(ibuf->
filepath, value_str, value_str_len + 1);
331 "Number of bits associated with this image.\n"
338 return PyLong_FromLong(imbuf->
planes);
343 py_imbuf_channels_doc,
344 "Number of bit-planes.\n"
351 return PyLong_FromLong(imbuf->
channels);
355 {
"size", (getter)
py_imbuf_size_get, (setter)
nullptr, py_imbuf_size_doc,
nullptr},
360 py_imbuf_filepath_doc,
364 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
376 if (ibuf !=
nullptr) {
378 self->ibuf =
nullptr;
386 if (ibuf !=
nullptr) {
387 return PyUnicode_FromFormat(
"<imbuf: address=%p, filepath='%s', size=(%d, %d)>",
394 return PyUnicode_FromString(
"<imbuf: address=0x0>");
399 return _Py_HashPointer(
self->ibuf);
403 PyVarObject_HEAD_INIT(
nullptr, 0)
458 return (PyObject *)
self;
470 ".. function:: new(size)\n"
472 " Load a new image.\n"
474 " :arg size: The size of the image in pixels.\n"
475 " :type size: tuple[int, int]\n"
476 " :return: the newly loaded image.\n"
477 " :rtype: :class:`ImBuf`\n");
478static PyObject *
M_imbuf_new(PyObject * , PyObject *args, PyObject *kw)
481 static const char *_keywords[] = {
"size",
nullptr};
482 static _PyArg_Parser _parser = {
489 if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &size[0], &size[1])) {
492 if (size[0] <= 0 || size[1] <= 0) {
493 PyErr_Format(PyExc_ValueError,
"new: Image size cannot be below 1 (%d, %d)",
UNPACK2(size));
498 const uchar planes = 4;
502 if (ibuf ==
nullptr) {
503 PyErr_Format(PyExc_ValueError,
"new: Unable to create image (%d, %d)",
UNPACK2(size));
513 PyErr_Format(PyExc_IOError,
"load: %s, failed to open file '%s'", strerror(errno), filepath);
521 if (ibuf ==
nullptr) {
523 PyExc_ValueError,
"load: Unable to recognize image format for file '%s'", filepath);
535 ".. function:: load(filepath)\n"
537 " Load an image from a file.\n"
539 " :arg filepath: the filepath of the image.\n"
540 " :type filepath: str | bytes\n"
541 " :return: the newly loaded image.\n"
542 " :rtype: :class:`ImBuf`\n");
543static PyObject *
M_imbuf_load(PyObject * , PyObject *args, PyObject *kw)
547 static const char *_keywords[] = {
"filepath",
nullptr};
548 static _PyArg_Parser _parser = {
555 if (!_PyArg_ParseTupleAndKeywordsFast(
571 PyExc_IOError,
"write: Unable to write image file (%s) '%s'", strerror(errno), filepath);
580 ".. function:: write(image, filepath=image.filepath)\n"
584 " :arg image: the image to write.\n"
585 " :type image: :class:`ImBuf`\n"
586 " :arg filepath: Optional filepath of the image (fallback to the images file path).\n"
587 " :type filepath: str | bytes | None\n");
593 static const char *_keywords[] = {
"image",
"filepath",
nullptr};
594 static _PyArg_Parser _parser = {
603 if (!_PyArg_ParseTupleAndKeywordsFast(args,
614 const char *filepath = filepath_data.
value;
615 if (filepath ==
nullptr) {
630#if (defined(__GNUC__) && !defined(__clang__))
631# pragma GCC diagnostic push
632# pragma GCC diagnostic ignored "-Wcast-function-type"
636 {
"new", (PyCFunction)
M_imbuf_new, METH_VARARGS | METH_KEYWORDS, M_imbuf_new_doc},
637 {
"load", (PyCFunction)
M_imbuf_load, METH_VARARGS | METH_KEYWORDS, M_imbuf_load_doc},
638 {
"write", (PyCFunction)
M_imbuf_write, METH_VARARGS | METH_KEYWORDS, M_imbuf_write_doc},
639 {
nullptr,
nullptr, 0,
nullptr},
642#if (defined(__GNUC__) && !defined(__clang__))
643# pragma GCC diagnostic pop
649 "This module provides access to Blender's image manipulation API.\n"
651 "It provides access to image buffers outside of Blender's\n"
652 ":class:`bpy.types.Image` data-block context.\n");
654 PyModuleDef_HEAD_INIT,
669 PyObject *sys_modules = PyImport_GetModuleDict();
675 PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
692 "This module provides access to image buffer types.\n"
696 " Image buffer is also the structure used by :class:`bpy.types.Image`\n"
697 " ID type to store and manipulate image data at runtime.\n");
700 PyModuleDef_HEAD_INIT,
#define BLI_assert_unreachable()
File and directory operations.
int BLI_open(const char *filepath, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define STRNCPY(dst, src)
ImBuf * IMB_loadifffile(int file, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
ImBuf * IMB_dupImBuf(const ImBuf *ibuf1)
void IMB_rect_crop(ImBuf *ibuf, const rcti *crop)
bool IMB_scale(ImBuf *ibuf, unsigned int newx, unsigned int newy, IMBScaleFilter filter, bool threaded=true)
Contains defines and structs used throughout the imbuf module.
struct ImBuf * IMB_allocImBuf(unsigned int, unsigned int, unsigned char, unsigned int)
bool IMB_saveiff(struct ImBuf *, const char *, int)
void IMB_freeImBuf(ImBuf *)
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 * 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)
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[]
static PyObject * BPyInit_imbuf_types(void)
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)
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")
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
ccl_device_inline int mod(int x, int m)