1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
|
#!/usr/bin/env python
# This file is part of OpenCV project.
# It is subject to the license terms in the LICENSE file found in the top-level directory
# of this distribution and at http://opencv.org/license.html
# Copyright (C) 2020 by Archit Rungta
from __future__ import unicode_literals # Needed for python2
import hdr_parser, sys, re, os
from string import Template
from pprint import pprint
from collections import namedtuple
if sys.version_info[0] >= 3:
from io import StringIO
else:
from cStringIO import StringIO
import os, shutil
from parse_tree import *
jl_cpp_argmap = {}
jl_cpp_defmap = {}
julia_types = ["Int32", "Float32", "Float64", "Bool", "String", "Array", "Any"]
cv_types = ["UMat","Size" ]
submodule_template = Template('')
root_template = Template('')
with open("binding_templates_jl/template_cv2_submodule_cxx.jl", "r") as f:
submodule_template = Template(f.read())
with open("binding_templates_jl/template_cv2_root.jl", "r") as f:
root_template = Template(f.read())
with open("typemap.txt", 'r') as f:
tmp = f.readlines()
for ln in tmp:
ln = ln.strip('\n').split(':')
jl_cpp_argmap[ln[0]] = ln[1]
with open("defval.txt", 'r') as f:
tmp = f.readlines()
for ln in tmp:
ln = ln.strip('\n').split('|')
if ln[0] not in jl_cpp_defmap:
jl_cpp_defmap[ln[0]] = {}
jl_cpp_defmap[ln[0]][ln[1]] = ln[2]
def handle_def_arg(inp, tp = '', ns=''):
tp = tp.strip()
inp = inp.strip()
out = ''
if inp in jl_cpp_defmap[tp]:
out = jl_cpp_defmap[tp][inp]
elif inp != '':
print(inp+" not found")
# print(inp, tp, out)
return out
def handle_jl_arg(inp):
if not inp:
return ''
inp = inp.replace('std::', '')
if inp in jl_cpp_argmap:
return jl_cpp_argmap[inp]
inp = inp.replace('cv::', '')
return inp
# return outs
class ClassInfo(ClassInfo):
def get_jl_code(self):
if self.ismap:
return ''
return self.overload_get()+self.overload_set()
def overload_get(self):
stra = "function Base.getproperty(m::%s, s::Symbol)\n" %(self.mapped_name)
if self.isalgorithm:
stra = "function Base.getproperty(m::cv_Ptr{%s}, s::Symbol)\n" %(self.mapped_name)
for prop in self.props:
stra = stra + " if s==:" + prop.name+"\n"
stra = stra + " return cpp_to_julia(%s(m))\n"%self.get_prop_func_cpp("get", prop.name)
stra = stra + " end\n"
stra = stra + " return Base.getfield(m, s)\nend\n"
return stra
def overload_set(self):
stra = "function Base.setproperty!(m::%s, s::Symbol, v)\n" %(self.mapped_name)
if self.isalgorithm:
stra = "function Base.setproperty!(m::cv_Ptr{%s}, s::Symbol, v)\n" %(self.mapped_name)
for prop in self.props:
if not prop.readonly:
continue
stra = stra + " if s==:" + prop.name+"\n"
stra = stra + " %s(m, julia_to_cpp(v))\n"%(self.get_prop_func_cpp("set", prop.name))
stra = stra + " end\n"
stra = stra + " return Base.setfield!(m, s, v)\nend\n"
return stra
class FuncVariant(FuncVariant):
def promote_type(self, tp):
if tp=='int':
return 'long long'
elif tp =='float':
return 'double'
return tp
def get_argument_full(self, classname='', isalgo = False):
arglist = self.inlist + self.optlist
argnamelist = [arg.name+"::"+(handle_jl_arg(self.promote_type(arg.tp)) if handle_jl_arg(arg.tp) not in pass_by_val_types else handle_jl_arg(self.promote_type(arg.tp[:-1]))) for arg in arglist]
argstr = ", ".join(argnamelist)
return argstr
def get_argument_opt(self, ns=''):
# [print(arg.default_value,":",handle_def_arg(arg.default_value, handle_jl_arg(arg.tp))) for arg in self.optlist]
try:
str2 = ", ".join(["%s::%s = %s(%s)" % (arg.name, handle_jl_arg(self.promote_type(arg.tp)), handle_jl_arg(self.promote_type(arg.tp)) if (arg.tp == 'int' or arg.tp=='float' or arg.tp=='double') else '', handle_def_arg(arg.default_value, handle_jl_arg(self.promote_type(arg.tp)), ns)) for arg in self.optlist])
return str2
except KeyError:
return ''
def get_argument_def(self, classname, isalgo):
arglist = self.inlist
argnamelist = [arg.name+"::"+(handle_jl_arg(self.promote_type(arg.tp)) if handle_jl_arg(self.promote_type(arg.tp)) not in pass_by_val_types else handle_jl_arg(self.promote_type(arg.tp[:-1]))) for arg in arglist]
argstr = ", ".join(argnamelist)
return argstr
def get_return(self, classname=''):
argstr = ''
arglist = self.inlist + self.optlist
return "return cpp_to_julia(%s(%s))" %(self.get_wrapper_name(), ",".join(["julia_to_cpp(%s)" % (x.name) for x in arglist]))
def get_algo_tp(self, classname, isalgo):
if not isalgo or not classname:
return ''
return ' where {T <: %s}' % classname
def get_complete_code(self, classname='', isalgo = False, iscons = False, gen_default = True, ns = ''):
if classname and not iscons:
if isalgo:
self.inlist = [ArgInfo("cobj", "cv_Ptr{T}")] + self.inlist
else:
self.inlist = [ArgInfo("cobj", classname)] + self.inlist
map_name = self.mapped_name
if ns!='cv':
map_name = '%s_%s' %(ns.split('::')[-1], map_name)
outstr = 'function %s(%s)%s\n\t%s\nend\n' % (map_name, self.get_argument_full(classname, isalgo), self.get_algo_tp(classname, isalgo),self.get_return())
str2 = ", ".join([x.name for x in self.inlist + self.optlist])
# outstr = outstr +
if self.get_argument_opt() != '' and gen_default:
outstr = outstr + ('%s(%s; %s)%s = %s(%s)\n' % (map_name, self.get_argument_def(classname, isalgo), self.get_argument_opt(ns), self.get_algo_tp(classname, isalgo), map_name, str2))
if iscons and len(self.inlist+self.optlist)==0 and ns=='cv':
return ''
return outstr
def gen(srcfiles):
namespaces, _ = gen_tree(srcfiles)
jl_code = StringIO()
for name, ns in namespaces.items():
cv_types.extend(ns.registered)
jl_code = StringIO()
nsname = name
for e1,e2 in ns.enums.items():
# jl_code.write('\n const {0} = Int32'.format(e2[0]))
jl_code.write('\n const {0} = Int64 \n'.format(e2[0].replace("cv::", "").replace("::", "_")))
# Do not duplicate functions. This should prevent overwriting of Mat function by UMat functions
function_signatures = []
for cname, cl in ns.classes.items():
cl.__class__ = ClassInfo
jl_code.write(cl.get_jl_code())
for mname, fs in cl.methods.items():
for f in fs:
f.__class__ = FuncVariant
sign = (f.name, f.mapped_name, f.classname, [x.tp for x in f.inlist+f.optlist])
if sign in function_signatures:
print("Skipping entirely: ", f.name)
continue
sign2 = (f.name, f.mapped_name, f.classname, [x.tp for x in f.inlist])
gend = True
if sign2 in function_signatures:
print("Skipping default declaration: ", f.name)
gend = False
jl_code.write('\n%s' % f.get_complete_code(classname = cl.mapped_name, isalgo = cl.isalgorithm, gen_default = gend, ns=nsname))
function_signatures.append(sign)
function_signatures.append(sign2)
for f in cl.constructors:
f.__class__ = FuncVariant
jl_code.write('\n%s' % f.get_complete_code(classname = cl.mapped_name, isalgo = cl.isalgorithm, iscons = True, ns=nsname))
for mname, fs in ns.funcs.items():
for f in fs:
f.__class__ = FuncVariant
sign = (f.name, f.mapped_name, f.classname, [x.tp for x in f.inlist+f.optlist])
if sign in function_signatures:
print("Skipping entirely: ", f.name)
continue
gend = True
sign2 = (f.name, f.mapped_name, f.classname, [x.tp for x in f.inlist])
if sign2 in function_signatures:
print("Skipping default declaration: ", f.name)
gend = False
jl_code.write('\n%s' % f.get_complete_code(gen_default = gend, ns=nsname))
function_signatures.append(sign)
function_signatures.append(sign2)
imports = ''
for namex in namespaces:
if namex.startswith(name) and len(namex.split('::')) == 1 + len(name.split('::')):
imports = imports + '\ninclude("%s_cxx_wrap.jl")'%namex.replace('::', '_')
code = ''
if name == 'cv':
code = root_template.substitute(modname = name, code = jl_code.getvalue(), submodule_imports = imports)
else:
code = submodule_template.substitute(code = jl_code.getvalue(), submodule_imports = imports)
with open ('autogen_jl/%s_cxx_wrap.jl' % ns.name.replace('::', '_'), 'w') as fd:
fd.write(code)
srcfiles = hdr_parser.opencv_hdr_list
if len(sys.argv) > 1:
srcfiles = [l.strip() for l in sys.argv[1].split(';')]
gen(srcfiles)
|