4 def __init__(self, fields):
11 if fields[2][0] == '/':
12 self.flags = fields[2][1:].split(",")
17 for l in open("%s/api" % sys.argv[1]):
28 api.append((f[0], [], ty))
30 api[-1][1].append(argument(f))
33 if n.startswith("CV"):
40 # RHS is how the aggregate gets expanded in the C call
42 'pts_npts_contours' : '!.pts,!.npts,!.contours',
43 'cvarr_count' : '!.cvarr,!.count',
44 'cvarr_plane_count' : '!.cvarr,!.count',
47 'CvPoints' : '!.p,!.count',
48 'CvPoint2D32fs' : '!.p,!.count',
49 'CvPoint3D32fs' : '!.p,!.count',
52 'IplImages' : '!.ims',
53 'intpair' : '!.pairs,!.count',
54 'cvpoint2d32f_count' : '!.points,&!.count'
60 'CvBox2D', # '((ff)(ff)f)',
67 'CvHaarClassifierCascade*',
77 'CvPoint2D32f', # '(ff)',
86 'CvSeqOfCvConvexityDefect',
89 'CvStarDetectorParams',
99 return s.replace('*', 'PTR').replace('[', '_').replace(']', '_')
101 def has_optional(al):
102 """ return true if any argument is optional """
103 return any([a.init for a in al])
105 def gen(name, args, ty):
107 if has_optional(args):
108 yield "static PyObject *pycv%s(PyObject *self, PyObject *args, PyObject *kw)" % cname(name)
110 yield "static PyObject *pycv%s(PyObject *self, PyObject *args)" % cname(name)
118 'CvMatND' : 'CvMatND*',
119 'IplImage' : 'IplImage*',
120 'CvMemStorage' : 'CvMemStorage*',
121 'CvHistogram':'CvHistogram*',
123 'CvHaarClassifierCascade' : 'CvHaarClassifierCascade*'
125 ctype = remap.get(a.ty, a.ty)
127 init = " = %s" % a.init
130 yield " %s %s%s;" % (ctype, a.nm, init)
133 if a.ty in (conversion_types + aggregate.keys()):
134 yield ' PyObject *pyobj_%s = NULL;' % (a.nm)
135 destinations.append('&pyobj_%s' % (a.nm))
136 elif a.ty in [ 'CvPoint2D32f' ]:
137 destinations.append('&%s.x, &%s.y' % (a.nm, a.nm))
138 elif a.ty in [ 'CvTermCriteria' ]:
139 destinations.append('&%s.type, &%s.max_iter, &%s.epsilon' % ((a.nm,)*3))
140 elif a.ty in [ 'CvSURFParams' ]:
141 destinations.append('&%s.extended, &%s.hessianThreshold, &%s.nOctaves, &%s.nOctaveLayers' % ((a.nm,)*4))
142 elif a.nm in [ 'CvBox2D' ]:
143 s = ", ".join([('&' + a.nm +'.' + fld) for fld in [ 'center.x', 'center.y', 'size.width', 'size.height', 'angle' ] ])
144 destinations.append(s)
146 destinations.append('&%s' % a.nm)
148 'CvSURFParams' : '(idii)',
155 for k in (conversion_types + aggregate.keys()):
157 in_args = [ a for a in args if not 'O' in a.flags ]
158 fmt0 = "".join([ fmap[a.ty] for a in in_args if not a.init])
159 fmt1 = "".join([ fmap[a.ty] for a in in_args if a.init])
162 if len(fmt0 + fmt1) > 0:
164 yield ' const char *keywords[] = { %s };' % (", ".join([ '"%s"' % arg.nm for arg in args if not 'O' in arg.flags ] + ['NULL']))
165 yield ' if (!PyArg_ParseTupleAndKeywords(args, kw, "%s|%s", %s))' % (fmt0, fmt1, ", ".join(['(char**)keywords'] + destinations))
166 if '(' in (fmt0 + fmt1):
167 print "Tuple with kwargs is not allowed, function", name
170 yield ' if (!PyArg_ParseTuple(args, "%s", %s))' % (fmt0, ", ".join(destinations))
171 yield ' return NULL;'
173 # Do the conversions:
175 joinwith = [f[2:] for f in a.flags if f.startswith("J:")]
176 if len(joinwith) > 0:
177 yield 'preShareData(%s, &%s);' % (joinwith[0], a.nm)
180 if a.ty in (conversion_types + aggregate.keys()):
182 pred = '(pyobj_%s != NULL) && ' % a.nm
185 yield ' if (%s!convert_to_%s(pyobj_%s, &%s, "%s")) return NULL;' % (pred, safename(a.ty), a.nm, a.nm, a.nm)
189 prefix = "(const CvArr **)"
190 elif 'O' in a.flags and not 'A' in a.flags:
194 if a.ty in aggregate:
195 return prefix + aggregate[a.ty].replace('!', a.nm)
200 # The name by which the function is called, in C
201 if s.startswith("CV"):
205 tocall = '%s(%s)' % (funcname(name), ", ".join(invokename(a) for a in args))
207 yield ' ERRWRAP(%s);' % tocall
208 yield ' Py_RETURN_NONE;'
222 'CvSeqOfCvConvexityDefect*',
223 'CvSeqOfCvStarKeypoint*',
224 'CvSeqOfCvSURFPoint*',
225 'CvSeqOfCvSURFDescriptor*',
242 yield ' %s r;' % (ty)
243 yield ' ERRWRAP(r = %s);' % (tocall)
244 yield ' return FROM_%s(r);' % safename(ty)
246 all_returns = ty.split(",")
247 return_value_from_call = len(set(Rtypes) & set(all_returns)) != 0
248 if return_value_from_call:
249 yield ' %s r;' % list(set(Rtypes) & set(all_returns))[0]
250 yield ' ERRWRAP(r = %s);' % (tocall)
252 yield ' ERRWRAP(%s);' % (tocall)
253 typed = dict([ (a.nm,a.ty) for a in args])
254 for i in range(len(all_returns)):
255 if all_returns[i] in Rtypes:
256 typed['r'] = all_returns[i]
258 if len(all_returns) == 1:
259 af = dict([ (a.nm,a.flags) for a in args])
260 joinwith = [f[2:] for f in af.get(all_returns[0], []) if f.startswith("J:")]
261 if len(joinwith) > 0:
262 yield ' return shareData(pyobj_%s, %s, %s);' % (joinwith[0], joinwith[0], all_returns[0])
264 yield ' return FROM_%s(%s);' % (safename(typed[all_returns[0]]), all_returns[0])
266 yield ' return Py_BuildValue("%s", %s);' % ("N" * len(all_returns), ", ".join(["FROM_%s(%s)" % (safename(typed[n]), n) for n in all_returns]))
270 gen_c = [ open("generated%d.i" % i, "w") for i in range(3) ]
272 print "Generated %d functions" % len(api)
273 for nm,args,ty in sorted(api):
275 # Figure out docstring into ds_*
277 mandatory = [a.nm for a in args if not ('O' in a.flags) and not a.init]
278 optional = [a.nm for a in args if not ('O' in a.flags) and a.init]
279 ds_args = ", ".join(mandatory)
284 return ' [, %s%s]' % (o[0], o2s(o[1:]))
285 ds_args += o2s(optional)
287 ds = "%s(%s) -> %s" % (nm, ds_args, str(ty))
290 if has_optional(args):
291 entry = '{"%%s", (PyCFunction)pycv%s, METH_KEYWORDS, "%s"},' % (cname(nm), ds)
293 entry = '{"%%s", pycv%s, METH_VARARGS, "%s"},' % (cname(nm), ds)
294 print >>gen_c[1], entry % (nm)
295 if nm.startswith('CV_'):
296 print >>gen_c[1], entry % (nm[3:])
297 for l in gen(nm,args,ty):
300 for l in open("%s/defs" % sys.argv[1]):
301 print >>gen_c[2], "PUBLISH(%s);" % l.split()[1]