From 387a4a03c823ff8bb90a0d1aafde92a366993b39 Mon Sep 17 00:00:00 2001 From: Andre Anjos <andre.dos.anjos@gmail.com> Date: Wed, 29 Jan 2014 16:46:58 +0100 Subject: [PATCH] Cleaning-up... --- xbob/io/externals.cpp | 268 +++++++++++----------------------- xbob/io/file.cpp | 28 ++-- xbob/io/hdf5.cpp | 109 +++++++------- xbob/io/include/xbob.io/api.h | 12 -- xbob/io/videoreader.cpp | 31 ++-- xbob/io/videowriter.cpp | 6 +- 6 files changed, 170 insertions(+), 284 deletions(-) diff --git a/xbob/io/externals.cpp b/xbob/io/externals.cpp index f7abc1d..273b360 100644 --- a/xbob/io/externals.cpp +++ b/xbob/io/externals.cpp @@ -7,6 +7,9 @@ #include <Python.h> +#ifdef NO_IMPORT_ARRAY +#undef NO_IMPORT_ARRAY +#endif #define XBOB_IO_MODULE #include <xbob.io/config.h> @@ -19,6 +22,9 @@ #include <bob/io/CodecRegistry.h> #include <bob/io/VideoUtilities.h> +#include <xbob.blitz/capi.h> +#include <xbob.blitz/cleanup.h> + extern "C" { #ifdef NO_IMPORT_ARRAY @@ -61,16 +67,16 @@ extern "C" { static int dict_set(PyObject* d, const char* key, const char* value) { PyObject* v = Py_BuildValue("s", value); if (!v) return 0; + auto v_ = make_safe(v); int retval = PyDict_SetItemString(d, key, v); - Py_DECREF(v); if (retval == 0) return 1; //all good return 0; //a problem occurred } static int dict_steal(PyObject* d, const char* key, PyObject* value) { if (!value) return 0; + auto value_ = make_safe(value); int retval = PyDict_SetItemString(d, key, value); - Py_DECREF(value); if (retval == 0) return 1; //all good return 0; //a problem occurred } @@ -169,38 +175,32 @@ static PyObject* hdf5_version() { static PyObject* ffmpeg_version() { PyObject* retval = PyDict_New(); if (!retval) return 0; + auto retval_ = make_safe(retval); #if WITH_FFMPEG # if defined(FFMPEG_VERSION) if (std::strlen(FFMPEG_VERSION)) { - if (!dict_set(retval, "ffmpeg", FFMPEG_VERSION)) { - Py_DECREF(retval); - return 0; - } + if (!dict_set(retval, "ffmpeg", FFMPEG_VERSION)) return 0; } # endif if (!dict_set(retval, "avformat", BOOST_PP_STRINGIZE(LIBAVFORMAT_VERSION))) { - Py_DECREF(retval); return 0; } if (!dict_set(retval, "avcodec", BOOST_PP_STRINGIZE(LIBAVCODEC_VERSION))) { - Py_DECREF(retval); return 0; } if (!dict_set(retval, "avutil", BOOST_PP_STRINGIZE(LIBAVUTIL_VERSION))) { - Py_DECREF(retval); return 0; } if (!dict_set(retval, "swscale", BOOST_PP_STRINGIZE(LIBSWSCALE_VERSION))) { - Py_DECREF(retval); return 0; } #else if (!dict_set(retval, "ffmpeg", "unavailable")) { - Py_DECREF(retval); return 0; } #endif + Py_INCREF(retval); return retval; } @@ -278,47 +278,25 @@ static PyObject* build_version_dictionary() { PyObject* retval = PyDict_New(); if (!retval) return 0; + auto retval_ = make_safe(retval); - if (!dict_steal(retval, "HDF5", hdf5_version())) { - Py_DECREF(retval); - return 0; - } + if (!dict_steal(retval, "HDF5", hdf5_version())) return 0; - if (!dict_steal(retval, "FFmpeg", ffmpeg_version())) { - Py_DECREF(retval); - return 0; - } + if (!dict_steal(retval, "FFmpeg", ffmpeg_version())) return 0; - if (!dict_steal(retval, "libjpeg", libjpeg_version())) { - Py_DECREF(retval); - return 0; - } + if (!dict_steal(retval, "libjpeg", libjpeg_version())) return 0; - if (!dict_set(retval, "libnetpbm", "Unknown version")) { - Py_DECREF(retval); - return 0; - } + if (!dict_set(retval, "libnetpbm", "Unknown version")) return 0; - if (!dict_steal(retval, "libpng", libpng_version())) { - Py_DECREF(retval); - return 0; - } + if (!dict_steal(retval, "libpng", libpng_version())) return 0; - if (!dict_steal(retval, "libtiff", libtiff_version())) { - Py_DECREF(retval); - return 0; - } + if (!dict_steal(retval, "libtiff", libtiff_version())) return 0; - if (!dict_steal(retval, "giflib", giflib_version())) { - Py_DECREF(retval); - return 0; - } + if (!dict_steal(retval, "giflib", giflib_version())) return 0; - if (!dict_steal(retval, "MatIO", matio_version())) { - Py_DECREF(retval); - return 0; - } + if (!dict_steal(retval, "MatIO", matio_version())) return 0; + Py_INCREF(retval); return retval; } @@ -537,21 +515,16 @@ static PyObject* get_video_codecs(void (*f)(std::map<std::string, const AVCodec* PyObject* retval = PyDict_New(); if (!retval) return 0; + auto retval_ = make_safe(retval); for (auto k=m.begin(); k!=m.end(); ++k) { PyObject* pyvalue = describe_codec(k->second); - if (!pyvalue) { - Py_DECREF(retval); - return 0; - } - if (PyDict_SetItemString(retval, k->first.c_str(), pyvalue) != 0) { - Py_DECREF(pyvalue); - Py_DECREF(retval); - return 0; - } - Py_DECREF(pyvalue); + if (!pyvalue) return 0; + auto pyvalue_ = make_safe(pyvalue); + if (PyDict_SetItemString(retval, k->first.c_str(), pyvalue) != 0) return 0; } + Py_INCREF(retval); return retval; } @@ -592,60 +565,39 @@ static PyObject* get_video_iformats(void (*f)(std::map<std::string, AVInputForma PyObject* retval = PyDict_New(); if (!retval) return 0; + auto retval_ = make_safe(retval); for (auto k=m.begin(); k!=m.end(); ++k) { PyObject* property = PyDict_New(); - if (!property) { - Py_DECREF(retval); - return 0; - } + if (!property) return 0; + auto property_ = make_safe(property); - if (!dict_set(property, "name", k->second->name)) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!dict_set(property, "name", k->second->name)) return 0; - if (!dict_set(property, "long_name", k->second->long_name)) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!dict_set(property, "long_name", k->second->long_name)) return 0; // get extensions std::vector<std::string> exts; bob::io::detail::ffmpeg::tokenize_csv(k->second->extensions, exts); PyObject* ext_list = PyList_New(0); - if (!ext_list) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!ext_list) return 0; + auto ext_list_ = make_safe(ext_list); for (auto ext=exts.begin(); ext!=exts.end(); ++ext) { - if (!list_append(ext_list, ext->c_str())) { - Py_DECREF(ext_list); - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!list_append(ext_list, ext->c_str())) return 0; } - if (!dict_steal(property, "extensions", ext_list)) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + Py_INCREF(ext_list); + if (!dict_steal(property, "extensions", ext_list)) return 0; - if (!dict_steal(retval, k->first.c_str(), property)) { - Py_DECREF(retval); - return 0; - } + Py_INCREF(property); + if (!dict_steal(retval, k->first.c_str(), property)) return 0; } + Py_INCREF(retval); return retval; } @@ -687,59 +639,34 @@ static PyObject* get_video_oformats(bool supported) { PyObject* retval = PyDict_New(); if (!retval) return 0; + auto retval_ = make_safe(retval); for (auto k=m.begin(); k!=m.end(); ++k) { PyObject* property = PyDict_New(); - if (!property) { - Py_DECREF(retval); - return 0; - } + if (!property) return 0; + auto property_ = make_safe(property); - if (!dict_set(property, "name", k->second->name)) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!dict_set(property, "name", k->second->name)) return 0; - if (!dict_set(property, "long_name", k->second->long_name)) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!dict_set(property, "long_name", k->second->long_name)) return 0; - if (!dict_set(property, "mime_type", k->second->mime_type)) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!dict_set(property, "mime_type", k->second->mime_type)) return 0; // get extensions std::vector<std::string> exts; bob::io::detail::ffmpeg::tokenize_csv(k->second->extensions, exts); PyObject* ext_list = PyList_New(0); - if (!ext_list) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!ext_list) return 0; + auto ext_list_ = make_safe(ext_list); for (auto ext=exts.begin(); ext!=exts.end(); ++ext) { - - if (!list_append(ext_list, ext->c_str())) { - Py_DECREF(ext_list); - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!list_append(ext_list, ext->c_str())) return 0; } - if (!dict_steal(property, "extensions", ext_list)) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + Py_INCREF(ext_list); + if (!dict_steal(property, "extensions", ext_list)) return 0; /** get recommended codec **/ PyObject* default_codec = 0; @@ -747,11 +674,7 @@ static PyObject* get_video_oformats(bool supported) { AVCodec* codec = avcodec_find_encoder(k->second->video_codec); if (codec) { default_codec = describe_codec(codec); - if (!default_codec) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!default_codec) return 0; } } @@ -760,11 +683,7 @@ static PyObject* get_video_oformats(bool supported) { default_codec = Py_None; } - if (!dict_steal(property, "default_codec", default_codec)) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!dict_steal(property, "default_codec", default_codec)) return 0; /** get supported codec list **/ if (supported) { @@ -772,41 +691,27 @@ static PyObject* get_video_oformats(bool supported) { bob::io::detail::ffmpeg::oformat_supported_codecs(k->second->name, codecs); PyObject* supported_codecs = PyDict_New(); - if (!supported_codecs) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + if (!supported_codecs) return 0; + auto supported_codecs_ = make_safe(supported_codecs); for (auto c=codecs.begin(); c!=codecs.end(); ++c) { PyObject* codec_descr = describe_codec(*c); - if (!codec_descr) { - Py_DECREF(supported_codecs); - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } - if (!dict_steal(supported_codecs, (*c)->name, codec_descr)) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + auto codec_descr_ = make_safe(codec_descr); + if (!codec_descr) return 0; + Py_INCREF(codec_descr); + if (!dict_steal(supported_codecs, (*c)->name, codec_descr)) return 0; } - if (!dict_steal(property, "supported_codecs", supported_codecs)) { - Py_DECREF(property); - Py_DECREF(retval); - return 0; - } + Py_INCREF(supported_codecs); + if (!dict_steal(property, "supported_codecs", supported_codecs)) return 0; } - if (!dict_steal(retval, k->first.c_str(), property)) { - Py_DECREF(retval); - return 0; - } + Py_INCREF(property); + if (!dict_steal(retval, k->first.c_str(), property)) return 0; } + Py_INCREF(retval); return retval; } @@ -849,19 +754,13 @@ static PyObject* PyBobIo_Extensions(PyObject*) { PyObject* retval = PyDict_New(); if (!retval) return 0; + auto retval_ = make_safe(retval); for (auto it=table.begin(); it!=table.end(); ++it) { PyObject* pyvalue = make_object(it->second.c_str()); - if (!pyvalue) { - Py_DECREF(retval); - return 0; - } - if (PyDict_SetItemString(retval, it->first.c_str(), pyvalue) != 0) { - Py_DECREF(pyvalue); - Py_DECREF(retval); - return 0; - } - Py_DECREF(pyvalue); + if (!pyvalue) return 0; + auto pyvalue_ = make_safe(retval); + if (PyDict_SetItemString(retval, it->first.c_str(), pyvalue) != 0) return 0; } return retval; @@ -952,27 +851,34 @@ static PyModuleDef module_definition = { }; #endif -PyMODINIT_FUNC XBOB_EXT_ENTRY_NAME (void) { +static PyObject* create_module (void) { # if PY_VERSION_HEX >= 0x03000000 PyObject* m = PyModule_Create(&module_definition); - if (!m) return 0; # else - PyObject* m = Py_InitModule3(XBOB_EXT_MODULE_NAME, - module_methods, module_docstr); - if (!m) return; + PyObject* m = Py_InitModule3(XBOB_EXT_MODULE_NAME, module_methods, module_docstr); # endif + if (!m) return 0; + auto m_ = make_safe(m); ///< protects against early returns - /* register some constants */ - PyModule_AddIntConstant(m, "__api_version__", XBOB_IO_API_VERSION); - PyModule_AddStringConstant(m, "__version__", XBOB_EXT_MODULE_VERSION); - PyModule_AddObject(m, "versions", build_version_dictionary()); + /* register version numbers and constants */ + if (PyModule_AddIntConstant(m, "__api_version__", XBOB_IO_API_VERSION) < 0) + return 0; + if (PyModule_AddStringConstant(m, "__version__", XBOB_EXT_MODULE_VERSION) < 0) + return 0; + if (PyModule_AddObject(m, "versions", build_version_dictionary()) < 0) return 0; - /* imports the NumPy C-API */ - import_array(); + /* imports xbob.blitz C-API + dependencies */ + if (import_xbob_blitz() < 0) return 0; -# if PY_VERSION_HEX >= 0x03000000 + Py_INCREF(m); return m; -# endif } + +PyMODINIT_FUNC XBOB_EXT_ENTRY_NAME (void) { +# if PY_VERSION_HEX >= 0x03000000 + return +# endif + create_module(); +} diff --git a/xbob/io/file.cpp b/xbob/io/file.cpp index d7d13c6..e143e45 100644 --- a/xbob/io/file.cpp +++ b/xbob/io/file.cpp @@ -256,6 +256,7 @@ static PyObject* PyBobIoFile_GetIndex (PyBobIoFileObject* self, Py_ssize_t i) { PyObject* retval = PyArray_SimpleNew(info.nd, shape, type_num); if (!retval) return 0; + auto retval_ = make_safe(retval); try { bobskin skin((PyArrayObject*)retval, info.dtype); @@ -263,15 +264,14 @@ static PyObject* PyBobIoFile_GetIndex (PyBobIoFileObject* self, Py_ssize_t i) { } catch (std::exception& e) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_DECREF(retval); return 0; } catch (...) { if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught unknown exception while reading object #%" PY_FORMAT_SIZE_T "d from file `%s'", i, self->f->filename().c_str()); - Py_DECREF(retval); return 0; } + Py_INCREF(retval); return retval; } @@ -300,23 +300,19 @@ static PyObject* PyBobIoFile_GetSlice (PyBobIoFileObject* self, PySliceObject* s PyObject* retval = PyArray_SimpleNew(info.nd+1, shape, type_num); if (!retval) return 0; + auto retval_ = make_safe(retval); Py_ssize_t counter = 0; for (auto i = start; (start<=stop)?i<stop:i>stop; i+=step) { //get slice to fill PyObject* islice = Py_BuildValue("n", counter++); - if (!islice) { - Py_DECREF(retval); - return 0; - } + if (!islice) return 0; + auto islice_ = make_safe(islice); PyObject* item = PyObject_GetItem(retval, islice); - Py_DECREF(islice); - if (!item) { - Py_DECREF(retval); - return 0; - } + if (!item) return 0; + auto item_ = make_safe(item); try { bobskin skin((PyArrayObject*)item, info.dtype); @@ -324,19 +320,16 @@ static PyObject* PyBobIoFile_GetSlice (PyBobIoFileObject* self, PySliceObject* s } catch (std::exception& e) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_DECREF(retval); - Py_DECREF(item); return 0; } catch (...) { if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught unknown exception while reading object #%" PY_FORMAT_SIZE_T "d from file `%s'", i, self->f->filename().c_str()); - Py_DECREF(retval); - Py_DECREF(item); return 0; } } + Py_INCREF(retval); return retval; } @@ -399,6 +392,7 @@ static PyObject* PyBobIoFile_Read(PyBobIoFileObject* self, PyObject *args, PyObj PyObject* retval = PyArray_SimpleNew(info.nd, shape, type_num); if (!retval) return 0; + auto retval_ = make_safe(retval); try { bobskin skin((PyArrayObject*)retval, info.dtype); @@ -406,20 +400,18 @@ static PyObject* PyBobIoFile_Read(PyBobIoFileObject* self, PyObject *args, PyObj } catch (std::runtime_error& e) { if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught std::runtime_error while reading all contents of file `%s': %s", self->f->filename().c_str(), e.what()); - Py_DECREF(retval); return 0; } catch (std::exception& e) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_DECREF(retval); return 0; } catch (...) { if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught unknown while reading all contents of file `%s'", self->f->filename().c_str()); - Py_DECREF(retval); return 0; } + Py_INCREF(retval); return retval; } diff --git a/xbob/io/hdf5.cpp b/xbob/io/hdf5.cpp index 2bdb2e0..a3ce2b2 100644 --- a/xbob/io/hdf5.cpp +++ b/xbob/io/hdf5.cpp @@ -384,6 +384,7 @@ static int PyBobIo_H5AsTypenum (bob::io::hdf5type type) { } static PyObject* PyBobIo_HDF5TypeAsTuple (const bob::io::HDF5Type& t) { + const bob::io::HDF5Shape& sh = t.shape(); size_t ndim = sh.n(); const hsize_t* shptr = sh.get(); @@ -397,18 +398,22 @@ static PyObject* PyBobIo_HDF5TypeAsTuple (const bob::io::HDF5Type& t) { PyObject* dtype = reinterpret_cast<PyObject*>(PyArray_DescrFromType(type_num)); if (!dtype) return 0; - PyObject* retval = Py_BuildValue("NN", dtype, PyTuple_New(ndim)); - if (!retval) { - Py_DECREF(dtype); - return 0; - } + PyObject* shape = PyTuple_New(ndim); + if (!shape) return 0; + + PyObject* retval = Py_BuildValue("NN", dtype, shape); //steals references + if (!retval) return 0; + auto retval_ = make_safe(retval); - PyObject* shape = PyTuple_GET_ITEM(retval, 1); for (Py_ssize_t i=0; i<(Py_ssize_t)ndim; ++i) { - PyTuple_SET_ITEM(shape, i, Py_BuildValue("n", shptr[i])); + PyObject* value = Py_BuildValue("n", shptr[i]); + if (!value) return 0; + PyTuple_SET_ITEM(shape, i, value); } + Py_INCREF(retval); return retval; + } static PyObject* PyBobIo_HDF5DescriptorAsTuple (const bob::io::HDF5Descriptor& d) { @@ -416,11 +421,14 @@ static PyObject* PyBobIo_HDF5DescriptorAsTuple (const bob::io::HDF5Descriptor& d PyObject* type = PyBobIo_HDF5TypeAsTuple(d.type); if (!type) return 0; PyObject* size = Py_BuildValue("n", d.size); - if (!type) return 0; + if (!size) { + Py_DECREF(type); + return 0; + } PyObject* expand = d.expandable? Py_True : Py_False; Py_INCREF(expand); - return Py_BuildValue("NNN", type, size, expand); + return Py_BuildValue("NNN", type, size, expand); //steals references } @@ -434,26 +442,29 @@ static PyObject* PyBobIoHDF5File_Describe(PyBobIoHDF5FileObject* self, PyObject if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &key)) return 0; PyObject* retval = 0; + std::shared_ptr<PyObject> retval_; try { const std::vector<bob::io::HDF5Descriptor>& dv = self->f->describe(key); retval = PyTuple_New(dv.size()); + retval_ = make_safe(retval); + for (size_t k=0; k<dv.size(); ++k) { PyObject* entry = PyBobIo_HDF5DescriptorAsTuple(dv[k]); - if (!entry) { - Py_DECREF(retval); - return 0; - } + if (!entry) return 0; PyTuple_SET_ITEM(retval, k, entry); } } catch (std::exception& e) { PyErr_SetString(PyExc_RuntimeError, e.what()); + return 0; } catch (...) { PyErr_Format(PyExc_RuntimeError, "unknown exception caught while getting description for dataset `%s' in HDF5 file `%s'", key, self->f->filename().c_str()); + return 0; } + Py_INCREF(retval); return retval; } @@ -572,11 +583,14 @@ static PyObject* PyBobIoHDF5File_Paths(PyBobIoHDF5FileObject* self, PyObject *ar if (pyrel && PyObject_IsTrue(pyrel)) relative = true; PyObject* retval = 0; + std::shared_ptr<PyObject> retval_; try { std::vector<std::string> values; self->f->paths(values, relative); retval = PyTuple_New(values.size()); + if (!retval) return 0; + retval_ = make_safe(retval); for (size_t i=0; i<values.size(); ++i) { PyTuple_SET_ITEM(retval, i, Py_BuildValue("s", values[i].c_str())); } @@ -590,6 +604,7 @@ static PyObject* PyBobIoHDF5File_Paths(PyBobIoHDF5FileObject* self, PyObject *ar return 0; } + Py_INCREF(retval); return retval; } @@ -749,21 +764,21 @@ static PyObject* PyBobIoHDF5File_Xread(PyBobIoHDF5FileObject* self, PyObject* retval = PyArray_SimpleNew(shape.n(), pyshape, type_num); if (!retval) return 0; + auto retval_ = make_safe(retval); try { self->f->read_buffer(p, pos, type, PyArray_DATA((PyArrayObject*)retval)); } catch (std::exception& e) { PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_DECREF(retval); return 0; } catch (...) { PyErr_Format(PyExc_RuntimeError, "caught unknown exception while reading dataset `%s' at position %d with descriptor `%s' from HDF5 file `%s'", p, pos, type.str().c_str(), self->f->filename().c_str()); - Py_DECREF(retval); return 0; } + Py_INCREF(retval); return retval; } @@ -823,16 +838,15 @@ static PyObject* PyBobIoHDF5File_ListRead(PyBobIoHDF5FileObject* self, PyObject PyObject* retval = PyTuple_New((*D)[0].size); if (!retval) return 0; + auto retval_ = make_safe(retval); for (uint64_t k=0; k<(*D)[0].size; ++k) { PyObject* item = PyBobIoHDF5File_Xread(self, key, 0, k); - if (!item) { - Py_DECREF(retval); - return 0; - } + if (!item) return 0; PyTuple_SET_ITEM(retval, k, item); } + Py_INCREF(retval); return retval; } @@ -1116,6 +1130,8 @@ static PyObject* PyBobIoHDF5File_Replace(PyBobIoHDF5FileObject* self, PyObject* bob::io::HDF5Type type; PyObject* converted = 0; int is_array = PyBobIoHDF5File_GetObjectType(data, type, &converted); + auto converted_ = make_xsafe(converted); + if (is_array < 0) { ///< error condition, signal PyErr_Format(PyExc_TypeError, "error replacing position %" PY_FORMAT_SIZE_T "d of dataset `%s' at HDF5 file `%s': no support for storing objects of type `%s' on HDF5 files", pos, path, self->f->filename().c_str(), Py_TYPE(data)->tp_name); return 0; @@ -1182,7 +1198,6 @@ static PyObject* PyBobIoHDF5File_Replace(PyBobIoHDF5FileObject* self, PyObject* case 3: //converted numpy.ndarray self->f->write_buffer(path, pos, type, PyArray_DATA((PyArrayObject*)converted)); - Py_DECREF(converted); break; default: @@ -1195,12 +1210,10 @@ static PyObject* PyBobIoHDF5File_Replace(PyBobIoHDF5FileObject* self, PyObject* } catch (std::exception& e) { PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_XDECREF(converted); return 0; } catch (...) { PyErr_Format(PyExc_RuntimeError, "cannot replace object in position %" PY_FORMAT_SIZE_T "d at HDF5 file `%s': unknown exception caught", pos, self->f->filename().c_str()); - Py_XDECREF(converted); return 0; } @@ -1250,6 +1263,8 @@ static int PyBobIoHDF5File_InnerAppend(PyBobIoHDF5FileObject* self, const char* bob::io::HDF5Type type; PyObject* converted = 0; int is_array = PyBobIoHDF5File_GetObjectType(data, type, &converted); + auto converted_ = make_xsafe(converted); + if (is_array < 0) { ///< error condition, signal PyErr_Format(PyExc_TypeError, "error appending to object `%s' of HDF5 file `%s': no support for storing objects of type `%s' on HDF5 files", path, self->f->filename().c_str(), Py_TYPE(data)->tp_name); return 0; @@ -1319,7 +1334,6 @@ static int PyBobIoHDF5File_InnerAppend(PyBobIoHDF5FileObject* self, const char* case 3: //converted numpy.ndarray if (!self->f->contains(path)) self->f->create(path, type, true, compression); self->f->extend_buffer(path, type, PyArray_DATA((PyArrayObject*)converted)); - Py_DECREF(converted); break; default: @@ -1363,15 +1377,12 @@ static PyObject* PyBobIoHDF5File_Append(PyBobIoHDF5FileObject* self, PyObject *a if (PyTuple_Check(data) || PyList_Check(data)) { PyObject* iter = PyObject_GetIter(data); if (!iter) return 0; + auto iter_ = make_safe(iter); while (PyObject* item = PyIter_Next(iter)) { + auto item_ = make_safe(item); int ok = PyBobIoHDF5File_InnerAppend(self, path, item, compression); - Py_DECREF(item); - if (!ok) { - Py_DECREF(iter); - return 0; - } + if (!ok) return 0; } - Py_DECREF(iter); Py_RETURN_NONE; } @@ -1442,6 +1453,8 @@ static PyObject* PyBobIoHDF5File_Set(PyBobIoHDF5FileObject* self, PyObject* args bob::io::HDF5Type type; PyObject* converted = 0; int is_array = PyBobIoHDF5File_GetObjectType(data, type, &converted); + auto converted_ = make_xsafe(converted); + if (is_array < 0) { ///< error condition, signal PyErr_Format(PyExc_TypeError, "error setting object `%s' of HDF5 file `%s': no support for storing objects of type `%s' on HDF5 files", path, self->f->filename().c_str(), Py_TYPE(data)->tp_name); return 0; @@ -1512,7 +1525,6 @@ static PyObject* PyBobIoHDF5File_Set(PyBobIoHDF5FileObject* self, PyObject* args case 3: //converted numpy.ndarray if (!self->f->contains(path)) self->f->create(path, type, false, compression); self->f->write_buffer(path, 0, type, PyArray_DATA((PyArrayObject*)converted)); - Py_DECREF(converted); break; default: @@ -1700,21 +1712,21 @@ static PyObject* PyBobIoHDF5File_ReadAttribute(PyBobIoHDF5FileObject* self, PyObject* retval = PyArray_SimpleNew(shape.n(), pyshape, type_num); if (!retval) return 0; + auto retval_ = make_safe(retval); try { self->f->read_attribute(path, name, type, PyArray_DATA((PyArrayObject*)retval)); } catch (std::exception& e) { PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_DECREF(retval); return 0; } catch (...) { PyErr_Format(PyExc_RuntimeError, "caught unknown exception while reading array attribute `%s' at resource `%s' with descriptor `%s' from HDF5 file `%s'", name, path, type.str().c_str(), self->f->filename().c_str()); - Py_DECREF(retval); return 0; } + Py_INCREF(retval); return retval; } @@ -1788,6 +1800,9 @@ static PyObject* PyBobIoHDF5File_GetAttributes(PyBobIoHDF5FileObject* self, PyOb std::map<std::string, bob::io::HDF5Type> attributes; self->f->listAttributes(path, attributes); PyObject* retval = PyDict_New(); + if (!retval) return 0; + auto retval_ = make_safe(retval); + for (auto k=attributes.begin(); k!=attributes.end(); ++k) { PyObject* item = 0; if (k->second.type() == bob::io::unsupported) { @@ -1799,14 +1814,14 @@ static PyObject* PyBobIoHDF5File_GetAttributes(PyBobIoHDF5FileObject* self, PyOb Py_INCREF(Py_None); } else item = PyBobIoHDF5File_ReadAttribute(self, path, k->first.c_str(), k->second); - int status = PyDict_SetItemString(retval, k->first.c_str(), item); - Py_DECREF(item); - if (status != 0) { - Py_DECREF(retval); - return 0; - } + + if (!item) return 0; + auto item_ = make_safe(item); + + if (PyDict_SetItemString(retval, k->first.c_str(), item) != 0) return 0; } + Py_INCREF(retval); return retval; } @@ -1937,7 +1952,6 @@ static PyObject* PyBobIoHDF5File_WriteAttribute(PyBobIoHDF5FileObject* self, case 3: //converted numpy.ndarray self->f->write_attribute(path, name, type, PyArray_DATA((PyArrayObject*)converted)); - Py_DECREF(converted); break; default: @@ -1947,12 +1961,10 @@ static PyObject* PyBobIoHDF5File_WriteAttribute(PyBobIoHDF5FileObject* self, } catch (std::exception& e) { PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_XDECREF(converted); return 0; } catch (...) { PyErr_Format(PyExc_RuntimeError, "caught unknown exception while writing array attribute `%s' at resource `%s' with descriptor `%s' at HDF5 file `%s'", name, path, type.str().c_str(), self->f->filename().c_str()); - Py_XDECREF(converted); return 0; } @@ -1976,6 +1988,8 @@ static PyObject* PyBobIoHDF5File_SetAttribute(PyBobIoHDF5FileObject* self, PyObj bob::io::HDF5Type type; PyObject* converted = 0; int is_array = PyBobIoHDF5File_GetObjectType(value, type, &converted); + auto converted_ = make_xsafe(converted); + if (is_array < 0) { ///< error condition, signal PyErr_Format(PyExc_TypeError, "error setting attribute `%s' of resource `%s' at HDF5 file `%s': no support for storing objects of type `%s' on HDF5 files", name, path, self->f->filename().c_str(), Py_TYPE(value)->tp_name); return 0; @@ -2046,6 +2060,8 @@ static PyObject* PyBobIoHDF5File_SetAttributes(PyBobIoHDF5FileObject* self, PyOb if (!name) return 0; int is_array = PyBobIoHDF5File_GetObjectType(value, type, &converted); + auto converted_ = make_xsafe(converted); + if (is_array < 0) { ///< error condition, signal PyErr_Format(PyExc_TypeError, "error setting attribute `%s' of resource `%s' at HDF5 file `%s': no support for storing objects of type `%s' on HDF5 files", name.get(), path, self->f->filename().c_str(), Py_TYPE(value)->tp_name); return 0; @@ -2159,28 +2175,23 @@ static PyObject* PyBobIoHDF5File_DelAttributes(PyBobIoHDF5FileObject* self, PyOb if (attrs) { PyObject* iter = PyObject_GetIter(attrs); if (!iter) return 0; + auto iter_ = make_safe(iter); while (PyObject* item = PyIter_Next(iter)) { + auto item_ = make_safe(item); auto name = PyBobIo_GetString(item); - Py_DECREF(item); - if (!name) { - Py_DECREF(iter); - return 0; - } + if (!name) return 0; try { self->f->deleteAttribute(path, name.get()); } catch (std::exception& e) { PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_DECREF(iter); return 0; } catch (...) { PyErr_Format(PyExc_RuntimeError, "cannot delete attribute `%s' at resource `%s' of HDF5 file `%s': unknown exception caught", name.get(), path, self->f->filename().c_str()); - Py_DECREF(iter); return 0; } } - Py_DECREF(iter); Py_RETURN_NONE; } diff --git a/xbob/io/include/xbob.io/api.h b/xbob/io/include/xbob.io/api.h index b605378..ecf4ffc 100644 --- a/xbob/io/include/xbob.io/api.h +++ b/xbob/io/include/xbob.io/api.h @@ -207,18 +207,6 @@ typedef struct { /* This section is used in modules that use `xbob.io's' C-API */ -/************************************************************************ - * Macros to avoid symbol collision and allow for separate compilation. * - * We pig-back on symbols already defined for NumPy and apply the same * - * set of rules here, creating our own API symbol names. * - ************************************************************************/ - -# if defined(PY_ARRAY_UNIQUE_SYMBOL) -# define XBOB_IO_MAKE_API_NAME_INNER(a) XBOB_IO_ ## a -# define XBOB_IO_MAKE_API_NAME(a) XBOB_IO_MAKE_API_NAME_INNER(a) -# define PyXbobIo_API XBOB_IO_MAKE_API_NAME(PY_ARRAY_UNIQUE_SYMBOL) -# endif - # if defined(NO_IMPORT_ARRAY) extern void **PyXbobIo_API; # else diff --git a/xbob/io/videoreader.cpp b/xbob/io/videoreader.cpp index 8f4063b..b6a92c5 100644 --- a/xbob/io/videoreader.cpp +++ b/xbob/io/videoreader.cpp @@ -353,6 +353,7 @@ static PyObject* PyBobIoVideoReader_Load(PyBobIoVideoReaderObject* self, PyObjec PyObject* retval = PyArray_SimpleNew(info.nd, shape, type_num); if (!retval) return 0; + auto retval_ = make_safe(retval); Py_ssize_t frames_read = 0; @@ -362,12 +363,10 @@ static PyObject* PyBobIoVideoReader_Load(PyBobIoVideoReaderObject* self, PyObjec } catch (std::exception& e) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_DECREF(retval); return 0; } catch (...) { if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught unknown exception while reading video from file `%s'", self->v->filename().c_str()); - Py_DECREF(retval); return 0; } @@ -380,6 +379,7 @@ static PyObject* PyBobIoVideoReader_Load(PyBobIoVideoReaderObject* self, PyObjec PyArray_Resize((PyArrayObject*)retval, &newshape, 1, NPY_ANYORDER); } + Py_INCREF(retval); return retval; } @@ -432,6 +432,7 @@ static PyObject* PyBobIoVideoReader_GetIndex (PyBobIoVideoReaderObject* self, Py PyObject* retval = PyArray_SimpleNew(info.nd, shape, type_num); if (!retval) return 0; + auto retval_ = make_safe(retval); try { auto it = self->v->begin(); @@ -441,15 +442,14 @@ static PyObject* PyBobIoVideoReader_GetIndex (PyBobIoVideoReaderObject* self, Py } catch (std::exception& e) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_DECREF(retval); return 0; } catch (...) { if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught unknown exception while reading frame #%" PY_FORMAT_SIZE_T "d from file `%s'", i, self->v->filename().c_str()); - Py_DECREF(retval); return 0; } + Py_INCREF(retval); return retval; } @@ -478,6 +478,7 @@ static PyObject* PyBobIoVideoReader_GetSlice (PyBobIoVideoReaderObject* self, Py PyObject* retval = PyArray_SimpleNew(info.nd+1, shape, type_num); if (!retval) return 0; + auto retval_ = make_safe(retval); Py_ssize_t counter; Py_ssize_t lo, hi, st; @@ -496,17 +497,12 @@ static PyObject* PyBobIoVideoReader_GetSlice (PyBobIoVideoReaderObject* self, Py //get slice to fill PyObject* islice = Py_BuildValue("n", counter); counter = (st == -step)? counter-1 : counter+1; - if (!islice) { - Py_DECREF(retval); - return 0; - } + if (!islice) return 0; + auto islice_ = make_safe(islice); PyObject* item = PyObject_GetItem(retval, islice); - Py_DECREF(islice); - if (!item) { - Py_DECREF(retval); - return 0; - } + if (!item) return 0; + auto item_ = make_safe(item); try { bobskin skin((PyArrayObject*)item, info.dtype); @@ -515,19 +511,16 @@ static PyObject* PyBobIoVideoReader_GetSlice (PyBobIoVideoReaderObject* self, Py } catch (std::exception& e) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_DECREF(retval); - Py_DECREF(item); return 0; } catch (...) { if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught unknown exception while reading frame #%" PY_FORMAT_SIZE_T "d from file `%s'", i, self->v->filename().c_str()); - Py_DECREF(retval); - Py_DECREF(item); return 0; } } + Py_INCREF(retval); return retval; } @@ -596,6 +589,7 @@ static PyObject* PyBobIoVideoReaderIterator_Next (PyBobIoVideoReaderIteratorObje PyObject* retval = PyArray_SimpleNew(info.nd, shape, type_num); if (!retval) return 0; + auto retval_ = make_safe(retval); try { bobskin skin((PyArrayObject*)retval, info.dtype); @@ -603,15 +597,14 @@ static PyObject* PyBobIoVideoReaderIterator_Next (PyBobIoVideoReaderIteratorObje } catch (std::exception& e) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_DECREF(retval); return 0; } catch (...) { if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught unknown exception while reading frame #%" PY_FORMAT_SIZE_T "d from file `%s'", self->iter->cur(), self->pyreader->v->filename().c_str()); - Py_DECREF(retval); return 0; } + Py_INCREF(retval); return retval; } diff --git a/xbob/io/videowriter.cpp b/xbob/io/videowriter.cpp index c8ebce2..7a6d2ae 100644 --- a/xbob/io/videowriter.cpp +++ b/xbob/io/videowriter.cpp @@ -419,16 +419,15 @@ static PyObject* PyBobIoVideoWriter_Append(PyBobIoVideoWriterObject* self, PyObj PyBlitzArrayObject* frame = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&", kwlist, &PyBlitzArray_BehavedConverter, &frame)) return 0; + auto frame_ = make_safe(frame); if (frame->ndim != 3 && frame->ndim != 4) { PyErr_Format(PyExc_ValueError, "input array should have 3 or 4 dimensions, but you passed an array with %" PY_FORMAT_SIZE_T "d dimensions", frame->ndim); - Py_DECREF(frame); return 0; } if (frame->type_num != NPY_UINT8) { PyErr_Format(PyExc_TypeError, "input array should have dtype `uint8', but you passed an array with dtype == `%s'", PyBlitzArray_TypenumAsString(frame->type_num)); - Py_DECREF(frame); return 0; } @@ -442,16 +441,13 @@ static PyObject* PyBobIoVideoWriter_Append(PyBobIoVideoWriterObject* self, PyObj } catch (std::exception& e) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, e.what()); - Py_DECREF(frame); return 0; } catch (...) { if (!PyErr_Occurred()) PyErr_Format(PyExc_RuntimeError, "caught unknown exception while writing frame #%" PY_FORMAT_SIZE_T "d to file `%s'", self->v->numberOfFrames(), self->v->filename().c_str()); - Py_DECREF(frame); return 0; } - Py_DECREF(frame); Py_RETURN_NONE; } -- GitLab