1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-28 23:03:03 +04:00

Merge remote-tracking branch 'upstream/3.4' into merge-3.4

This commit is contained in:
Alexander Alekhin
2021-04-01 01:40:14 +00:00
22 changed files with 1153 additions and 221 deletions
+30 -6
View File
@@ -47,6 +47,7 @@
#define CV_HAS_CONVERSION_ERROR(x) (((x) == -1) && PyErr_Occurred())
static PyObject* opencv_error = NULL;
class ArgInfo
{
@@ -69,14 +70,32 @@ struct PyOpenCV_Converter
//static inline PyObject* from(const T& src);
};
// exception-safe pyopencv_to
template<typename _Tp> static
bool pyopencv_to_safe(PyObject* obj, _Tp& value, const ArgInfo& info)
{
try
{
return pyopencv_to(obj, value, info);
}
catch (const std::exception &e)
{
PyErr_SetString(opencv_error, cv::format("Conversion error: %s, what: %s", info.name, e.what()).c_str());
return false;
}
catch (...)
{
PyErr_SetString(opencv_error, cv::format("Conversion error: %s", info.name).c_str());
return false;
}
}
template<typename T> static
bool pyopencv_to(PyObject* obj, T& p, const ArgInfo& info) { return PyOpenCV_Converter<T>::to(obj, p, info); }
template<typename T> static
PyObject* pyopencv_from(const T& src) { return PyOpenCV_Converter<T>::from(src); }
static PyObject* opencv_error = NULL;
static bool isPythonBindingsDebugEnabled()
{
static bool param_debug = cv::utils::getConfigurationParameterBool("OPENCV_PYTHON_DEBUG", false);
@@ -214,6 +233,11 @@ catch (const std::exception &e) \
{ \
PyErr_SetString(opencv_error, e.what()); \
return 0; \
} \
catch (...) \
{ \
PyErr_SetString(opencv_error, "Unknown C++ exception from OpenCV code"); \
return 0; \
}
using namespace cv;
@@ -2174,9 +2198,9 @@ static int convert_to_char(PyObject *o, char *dst, const ArgInfo& info)
#include "pyopencv_generated_enums.h"
#ifdef CVPY_DYNAMIC_INIT
#define CVPY_TYPE(NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE_DYNAMIC(NAME, STORAGE, SNAME)
#define CVPY_TYPE(WNAME, NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE_DYNAMIC(WNAME, NAME, STORAGE, SNAME)
#else
#define CVPY_TYPE(NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE(NAME, STORAGE, SNAME)
#define CVPY_TYPE(WNAME, NAME, STORAGE, SNAME, _1, _2) CVPY_TYPE_DECLARE(WNAME, NAME, STORAGE, SNAME)
#endif
#include "pyopencv_generated_types.h"
#undef CVPY_TYPE
@@ -2267,10 +2291,10 @@ static bool init_body(PyObject * m)
#undef CVPY_MODULE
#ifdef CVPY_DYNAMIC_INIT
#define CVPY_TYPE(NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_DYNAMIC(NAME, return false, BASE, CONSTRUCTOR)
#define CVPY_TYPE(WNAME, NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_DYNAMIC(WNAME, NAME, return false, BASE, CONSTRUCTOR)
PyObject * pyopencv_NoBase_TypePtr = NULL;
#else
#define CVPY_TYPE(NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_STATIC(NAME, return false, BASE, CONSTRUCTOR)
#define CVPY_TYPE(WNAME, NAME, _1, _2, BASE, CONSTRUCTOR) CVPY_TYPE_INIT_STATIC(WNAME, NAME, return false, BASE, CONSTRUCTOR)
PyTypeObject * pyopencv_NoBase_TypePtr = NULL;
#endif
#include "pyopencv_generated_types.h"
+33 -14
View File
@@ -47,7 +47,7 @@ gen_template_func_body = Template("""$code_decl
gen_template_mappable = Template("""
{
${mappable} _src;
if (pyopencv_to(src, _src, info))
if (pyopencv_to_safe(src, _src, info))
{
return cv_mappable_to(_src, dst);
}
@@ -91,7 +91,7 @@ gen_template_set_prop_from_map = Template("""
if( PyMapping_HasKeyString(src, (char*)"$propname") )
{
tmp = PyMapping_GetItemString(src, (char*)"$propname");
ok = tmp && pyopencv_to(tmp, dst.$propname, ArgInfo("$propname", false));
ok = tmp && pyopencv_to_safe(tmp, dst.$propname, ArgInfo("$propname", false));
Py_DECREF(tmp);
if(!ok) return false;
}""")
@@ -145,7 +145,7 @@ static int pyopencv_${name}_set_${member}(pyopencv_${name}_t* p, PyObject *value
PyErr_SetString(PyExc_TypeError, "Cannot delete the ${member} attribute");
return -1;
}
return pyopencv_to(value, p->v${access}${member}, ArgInfo("value", false)) ? 0 : -1;
return pyopencv_to_safe(value, p->v${access}${member}, ArgInfo("value", false)) ? 0 : -1;
}
""")
@@ -163,7 +163,7 @@ static int pyopencv_${name}_set_${member}(pyopencv_${name}_t* p, PyObject *value
failmsgp("Incorrect type of object (must be '${name}' or its derivative)");
return -1;
}
return pyopencv_to(value, _self_${access}${member}, ArgInfo("value", false)) ? 0 : -1;
return pyopencv_to_safe(value, _self_${access}${member}, ArgInfo("value", false)) ? 0 : -1;
}
""")
@@ -266,7 +266,12 @@ class ClassInfo(object):
for m in decl[2]:
if m.startswith("="):
self.wname = m[1:]
wname = m[1:]
npos = name.rfind('.')
if npos >= 0:
self.wname = normalize_class_name(name[:npos] + '.' + wname)
else:
self.wname = wname
customname = True
elif m == "/Map":
self.ismap = True
@@ -282,7 +287,7 @@ class ClassInfo(object):
code = "static bool pyopencv_to(PyObject* src, %s& dst, const ArgInfo& info)\n{\n PyObject* tmp;\n bool ok;\n" % (self.cname)
code += "".join([gen_template_set_prop_from_map.substitute(propname=p.name,proptype=p.tp) for p in self.props])
if self.base:
code += "\n return pyopencv_to(src, (%s&)dst, info);\n}\n" % all_classes[self.base].cname
code += "\n return pyopencv_to_safe(src, (%s&)dst, info);\n}\n" % all_classes[self.base].cname
else:
code += "\n return true;\n}\n"
return code
@@ -345,7 +350,8 @@ class ClassInfo(object):
if self.constructor is not None:
constructor_name = self.constructor.get_wrapper_name()
return "CVPY_TYPE({}, {}, {}, {}, {});\n".format(
return "CVPY_TYPE({}, {}, {}, {}, {}, {});\n".format(
self.wname,
self.name,
self.cname if self.issimple else "Ptr<{}>".format(self.cname),
self.sname if self.issimple else "Ptr",
@@ -668,7 +674,7 @@ class FuncInfo(object):
if a.tp == 'char':
code_cvt_list.append("convert_to_char(pyobj_%s, &%s, %s)" % (a.name, a.name, a.crepr()))
else:
code_cvt_list.append("pyopencv_to(pyobj_%s, %s, %s)" % (a.name, a.name, a.crepr()))
code_cvt_list.append("pyopencv_to_safe(pyobj_%s, %s, %s)" % (a.name, a.name, a.crepr()))
all_cargs.append([arg_type_info, parse_name])
@@ -919,7 +925,7 @@ class PythonWrapperGenerator(object):
if classes:
classname = normalize_class_name('.'.join(namespace+classes))
bareclassname = classes[-1]
namespace = '.'.join(namespace)
namespace_str = '.'.join(namespace)
isconstructor = name == bareclassname
is_static = False
@@ -944,23 +950,36 @@ class PythonWrapperGenerator(object):
if is_static:
# Add it as a method to the class
func_map = self.classes[classname].methods
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace, is_static))
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace_str, is_static))
func.add_variant(decl, isphantom)
# Add it as global function
g_name = "_".join(classes+[name])
func_map = self.namespaces.setdefault(namespace, Namespace()).funcs
func = func_map.setdefault(g_name, FuncInfo("", g_name, cname, isconstructor, namespace, False))
w_classes = []
for i in range(0, len(classes)):
classes_i = classes[:i+1]
classname_i = normalize_class_name('.'.join(namespace+classes_i))
w_classname = self.classes[classname_i].wname
namespace_prefix = normalize_class_name('.'.join(namespace)) + '_'
if w_classname.startswith(namespace_prefix):
w_classname = w_classname[len(namespace_prefix):]
w_classes.append(w_classname)
g_wname = "_".join(w_classes+[name])
func_map = self.namespaces.setdefault(namespace_str, Namespace()).funcs
func = func_map.setdefault(g_name, FuncInfo("", g_name, cname, isconstructor, namespace_str, False))
func.add_variant(decl, isphantom)
if g_wname != g_name: # TODO OpenCV 5.0
wfunc = func_map.setdefault(g_wname, FuncInfo("", g_wname, cname, isconstructor, namespace_str, False))
wfunc.add_variant(decl, isphantom)
else:
if classname and not isconstructor:
if not isphantom:
cname = barename
func_map = self.classes[classname].methods
else:
func_map = self.namespaces.setdefault(namespace, Namespace()).funcs
func_map = self.namespaces.setdefault(namespace_str, Namespace()).funcs
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace, is_static))
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace_str, is_static))
func.add_variant(decl, isphantom)
if classname and isconstructor:
+7 -1
View File
@@ -260,6 +260,8 @@ class CppHeaderParser(object):
l = l.replace("CV_EXPORTS_W_SIMPLE", "")
modlist.append("/Simple")
npos = l.find("CV_EXPORTS_AS")
if npos < 0:
npos = l.find('CV_WRAP_AS')
if npos >= 0:
macro_arg, npos3 = self.get_macro_arg(l, npos)
modlist.append("=" + macro_arg)
@@ -842,7 +844,11 @@ class CppHeaderParser(object):
continue
state = SCAN
l = re.sub(r'//(.+)?', '', l).strip() # drop // comment
if l == '#if 0' or l == '#if defined(__OPENCV_BUILD)' or l == '#ifdef __OPENCV_BUILD':
if l in [
'#if 0',
'#if defined(__OPENCV_BUILD)', '#ifdef __OPENCV_BUILD',
'#if !defined(OPENCV_BINDING_PARSER)', '#ifndef OPENCV_BINDING_PARSER',
]:
state = DIRECTIVE_IF_0
depth_if_0 = 1
continue
+10 -10
View File
@@ -172,7 +172,7 @@ PyObject* pyopencv_from(const TYPE& src)
#endif
#define CVPY_TYPE_DECLARE(NAME, STORAGE, SNAME) \
#define CVPY_TYPE_DECLARE(WNAME, NAME, STORAGE, SNAME) \
struct pyopencv_##NAME##_t \
{ \
PyObject_HEAD \
@@ -181,7 +181,7 @@ PyObject* pyopencv_from(const TYPE& src)
static PyTypeObject pyopencv_##NAME##_TypeXXX = \
{ \
CVPY_TYPE_HEAD \
MODULESTR"."#NAME, \
MODULESTR"."#WNAME, \
sizeof(pyopencv_##NAME##_t), \
}; \
static PyTypeObject * pyopencv_##NAME##_TypePtr = &pyopencv_##NAME##_TypeXXX; \
@@ -208,12 +208,12 @@ PyObject* pyopencv_from(const TYPE& src)
static PyObject* pyopencv_##NAME##_repr(PyObject* self) \
{ \
char str[1000]; \
sprintf(str, "<"#NAME" %p>", self); \
sprintf(str, "<"#WNAME" %p>", self); \
return PyString_FromString(str); \
}
#define CVPY_TYPE_INIT_STATIC(NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \
#define CVPY_TYPE_INIT_STATIC(WNAME, NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \
{ \
pyopencv_##NAME##_TypePtr->tp_base = pyopencv_##BASE##_TypePtr; \
pyopencv_##NAME##_TypePtr->tp_dealloc = pyopencv_##NAME##_dealloc; \
@@ -229,12 +229,12 @@ PyObject* pyopencv_from(const TYPE& src)
ERROR_HANDLER; \
} \
CVPY_TYPE_INCREF(pyopencv_##NAME##_TypePtr); \
PyModule_AddObject(m, #NAME, (PyObject *)pyopencv_##NAME##_TypePtr); \
PyModule_AddObject(m, #WNAME, (PyObject *)pyopencv_##NAME##_TypePtr); \
}
//==================================================================================================
#define CVPY_TYPE_DECLARE_DYNAMIC(NAME, STORAGE, SNAME) \
#define CVPY_TYPE_DECLARE_DYNAMIC(WNAME, NAME, STORAGE, SNAME) \
struct pyopencv_##NAME##_t \
{ \
PyObject_HEAD \
@@ -264,7 +264,7 @@ PyObject* pyopencv_from(const TYPE& src)
static PyObject* pyopencv_##NAME##_repr(PyObject* self) \
{ \
char str[1000]; \
sprintf(str, "<"#NAME" %p>", self); \
sprintf(str, "<"#WNAME" %p>", self); \
return PyString_FromString(str); \
} \
static PyType_Slot pyopencv_##NAME##_Slots[] = \
@@ -280,14 +280,14 @@ PyObject* pyopencv_from(const TYPE& src)
}; \
static PyType_Spec pyopencv_##NAME##_Spec = \
{ \
MODULESTR"."#NAME, \
MODULESTR"."#WNAME, \
sizeof(pyopencv_##NAME##_t), \
0, \
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \
pyopencv_##NAME##_Slots \
};
#define CVPY_TYPE_INIT_DYNAMIC(NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \
#define CVPY_TYPE_INIT_DYNAMIC(WNAME, NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \
{ \
pyopencv_##NAME##_Slots[0].pfunc /*tp_dealloc*/ = (void*)pyopencv_##NAME##_dealloc; \
pyopencv_##NAME##_Slots[1].pfunc /*tp_repr*/ = (void*)pyopencv_##NAME##_repr; \
@@ -302,7 +302,7 @@ PyObject* pyopencv_from(const TYPE& src)
pyopencv_##NAME##_TypePtr = PyType_FromSpecWithBases(&pyopencv_##NAME##_Spec, bases); \
if (!pyopencv_##NAME##_TypePtr) \
{ \
printf("Failed to init: " #NAME ", base (" #BASE ")" "\n"); \
printf("Failed to init: " #WNAME ", base (" #BASE ")" "\n"); \
ERROR_HANDLER; \
} \
PyModule_AddObject(m, #NAME, (PyObject *)pyopencv_##NAME##_TypePtr); \