Java API: added class pointer ret type support, CV_EXPORTS_AS(x) support for classes...
authorAndrey Pavlenko <no@email>
Mon, 1 Aug 2011 16:11:24 +0000 (16:11 +0000)
committerAndrey Pavlenko <no@email>
Mon, 1 Aug 2011 16:11:24 +0000 (16:11 +0000)
modules/java/gen_java.py
modules/java/src/cpp/features2d_manual.hpp

index 23645a6..4bb1fea 100644 (file)
@@ -454,8 +454,8 @@ JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Core_n_1getTextSize
 # { class : { func : {arg_name : ctype} } }\r
 func_arg_fix = {\r
     '' : {\r
-        'randu'    : { 'low'     : 'Scalar', 'high'   : 'Scalar', },\r
-        'randn'    : { 'mean'    : 'Scalar', 'stddev' : 'Scalar', },\r
+        'randu'    : { 'low'     : 'double', 'high'   : 'double', },\r
+        'randn'    : { 'mean'    : 'double', 'stddev' : 'double', },\r
         'inRange'  : { 'lowerb'  : 'Scalar', 'upperb' : 'Scalar', },\r
         'goodFeaturesToTrack' : { 'corners' : 'vector_Point' },\r
     }, # '', i.e. empty class\r
@@ -486,6 +486,7 @@ class ClassInfo(object):
         self.private_consts = []\r
         self.imports = set()\r
         self.props= []\r
+        self.jname = self.name\r
         for m in decl[2]:\r
             if m.startswith("="):\r
                 self.jname = m[1:]\r
@@ -569,6 +570,7 @@ class JavaWrapperGenerator(object):
         self.skipped_func_list = []\r
 \r
     def add_class_code_stream(self, class_name):\r
+        jname = self.classes[class_name].jname\r
         self.java_code[class_name] = { "j_code" : StringIO(), "jn_code" : StringIO(), }\r
         if class_name != self.Module:\r
             self.java_code[class_name]["j_code"].write("""\r
@@ -581,12 +583,12 @@ $imports
 \r
 // C++: class %(c)s\r
 //javadoc: %(c)s\r
-public class %(c)s {\r
+public class %(jc)s {\r
 \r
     protected final long nativeObj;\r
-    protected %(c)s(long addr) { nativeObj = addr; }\r
+    protected %(jc)s(long addr) { nativeObj = addr; }\r
 \r
-""" % { 'm' : self.module, 'c' : class_name } )\r
+""" % { 'm' : self.module, 'c' : class_name, 'jc' : jname } )\r
 \r
         else: # class_name == self.Module\r
             self.java_code[class_name]["j_code"].write("""\r
@@ -597,8 +599,8 @@ package org.opencv.%(m)s;
 \r
 $imports\r
 \r
-public class %(c)s {\r
-""" % { 'm' : self.module, 'c' : class_name } )\r
+public class %(jc)s {\r
+""" % { 'm' : self.module, 'jc' : jname } )\r
 \r
         self.java_code[class_name]["jn_code"].write("""\r
     //\r
@@ -613,37 +615,43 @@ public class %(c)s {
         classinfo = ClassInfo(decl)\r
         if classinfo.name in class_ignore_list:\r
             return\r
-        if classinfo.name in self.classes:\r
+        name = classinfo.name\r
+        if name in self.classes:\r
             print "Generator error: class %s (%s) is duplicated" % \\r
-                    (classinfo.name, classinfo.cname)\r
+                    (name, classinfo.cname)\r
             return\r
-        self.classes[classinfo.name] = classinfo\r
-        if classinfo.name in type_dict:\r
-            print "Duplicated class: " + classinfo.name\r
+        self.classes[name] = classinfo\r
+        if name in type_dict:\r
+            print "Duplicated class: " + name\r
             return\r
-        type_dict[classinfo.name] = \\r
-            { "j_type" : classinfo.name,\r
+        type_dict[name] = \\r
+            { "j_type" : classinfo.jname,\r
               "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),),\r
-              "jni_name" : "(*("+classinfo.name+"*)%(n)s_nativeObj)", "jni_type" : "jlong",\r
+              "jni_name" : "(*("+name+"*)%(n)s_nativeObj)", "jni_type" : "jlong",\r
+              "suffix" : "J" }\r
+        type_dict[name+'*'] = \\r
+            { "j_type" : classinfo.jname,\r
+              "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),),\r
+              "jni_name" : "("+name+"*)%(n)s_nativeObj", "jni_type" : "jlong",\r
               "suffix" : "J" }\r
 \r
         # missing_consts { Module : { public : [[name, val],...], private : [[]...] } }\r
-        if classinfo.name in missing_consts:\r
-            if 'private' in missing_consts[classinfo.name]:\r
-                for (name, val) in missing_consts[classinfo.name]['private']:\r
-                    classinfo.private_consts.append( ConstInfo(name, name, val, True) )\r
-            if 'public' in missing_consts[classinfo.name]:\r
-                for (name, val) in missing_consts[classinfo.name]['public']:\r
-                    classinfo.consts.append( ConstInfo(name, name, val, True) )\r
+        if name in missing_consts:\r
+            if 'private' in missing_consts[name]:\r
+                for (n, val) in missing_consts[name]['private']:\r
+                    classinfo.private_consts.append( ConstInfo(n, n, val, True) )\r
+            if 'public' in missing_consts[name]:\r
+                for (n, val) in missing_consts[name]['public']:\r
+                    classinfo.consts.append( ConstInfo(n, n, val, True) )\r
 \r
         # class props\r
         for p in decl[3]:\r
             if "vector" not in p[0]:\r
                 classinfo.props.append( ClassPropInfo(p) )\r
             else:\r
-                print "Skipped property: [%s]" % classinfo.name, p\r
+                print "Skipped property: [%s]" % name, p\r
 \r
-        self.add_class_code_stream(classinfo.name)\r
+        self.add_class_code_stream(name)\r
 \r
 \r
     def add_const(self, decl): # [ "const cname", val, [], [] ]\r
@@ -754,17 +762,16 @@ extern "C" {
 \r
         # generate code for the classes\r
         for name in self.classes.keys():\r
+            if name == "Mat":\r
+                continue\r
             self.gen_class(name)\r
-\r
-        # saving code streams\r
-        for cls in self.java_code.keys():\r
+            # saving code streams\r
             imports = "\n".join([ "import %s;" % c for c in \\r
-                sorted(self.classes[cls].imports) if not c.startswith('org.opencv.'+self.module) ])\r
-            ##imports = "import org.opencv.core.*;\nimport org.opencv.Converters;\n"\r
-            self.java_code[cls]["j_code"].write("\n\n%s\n}\n" % self.java_code[cls]["jn_code"].getvalue())\r
-            java_code = self.java_code[cls]["j_code"].getvalue()\r
+                sorted(self.classes[name].imports) if not c.startswith('org.opencv.'+self.module) ])\r
+            self.java_code[name]["j_code"].write("\n\n%s\n}\n" % self.java_code[name]["jn_code"].getvalue())\r
+            java_code = self.java_code[name]["j_code"].getvalue()\r
             java_code = Template(java_code).substitute(imports = imports)\r
-            self.save("%s/%s+%s.java" % (output_path, module, cls), java_code)\r
+            self.save("%s/%s+%s.java" % (output_path, module, self.classes[name].jname), java_code)\r
 \r
         self.cpp_code.write( '\n} // extern "C"\n' )\r
         self.save(output_path+"/"+module+".cpp",  self.cpp_code.getvalue())\r
@@ -944,20 +951,30 @@ extern "C" {
             # e.g.\r
             # public static void add( Mat src1, Mat src2, Mat dst, Mat mask, int dtype )\r
             # { n_add( src1.nativeObj, src2.nativeObj, dst.nativeObj, mask.nativeObj, dtype );  }\r
-            ret_val = type_dict[fi.ctype]["j_type"] + " retVal = "\r
+            ret_type = fi.ctype\r
+            if fi.ctype.endswith('*'):\r
+                ret_type = ret_type[:-1]\r
+            ret_val = type_dict[ret_type]["j_type"] + " retVal = "\r
             tail = ""\r
             ret = "return retVal;"\r
-            if fi.ctype == "void":\r
+            if ret_type.startswith('vector'):\r
+                ret_val = "Mat retValMat = new Mat("\r
+                tail = ")"\r
+                j_type = type_dict[ret_type]["j_type"]\r
+                j_prologue.append( j_type + ' retVal = new Array' + j_type+'();')\r
+                self.classes[fi.classname or self.Module].imports.add('java.util.ArrayList')\r
+                j_epilogue.append('Converters.Mat_to_' + ret_type + '(retValMat, retVal);')\r
+            elif ret_type == "void":\r
                 ret_val = ""\r
                 ret = "return;"\r
-            elif fi.ctype == "": # c-tor\r
+            elif ret_type == "": # c-tor\r
                 ret_val = "nativeObj = "\r
                 ret = "return;"\r
-            elif fi.ctype in self.classes: # wrapped class\r
-                ret_val = type_dict[fi.ctype]["j_type"] + " retVal = new " + self.classes[fi.ctype].jname + "("\r
+            elif ret_type in self.classes: # wrapped class\r
+                ret_val = type_dict[ret_type]["j_type"] + " retVal = new " + self.classes[ret_type].jname + "("\r
                 tail = ")"\r
-            elif "jn_type" not in type_dict[fi.ctype]:\r
-                ret_val = type_dict[fi.ctype]["j_type"] + " retVal = new " + type_dict[fi.ctype]["j_type"] + "("\r
+            elif "jn_type" not in type_dict[ret_type]:\r
+                ret_val = type_dict[fi.ctype]["j_type"] + " retVal = new " + type_dict[ret_type]["j_type"] + "("\r
                 tail = ")"\r
 \r
             static = "static"\r
@@ -998,11 +1015,15 @@ extern "C" {
                 default = "return;"\r
             elif not fi.ctype: # c-tor\r
                 ret = "return (jlong) _retval_;"\r
+            elif fi.ctype.startswith('vector'): # c-tor\r
+                ret = "return (jlong) _retval_;"\r
             elif fi.ctype == "string":\r
                 ret = "return env->NewStringUTF(_retval_.c_str());"\r
                 default = 'return env->NewStringUTF("");'\r
             elif fi.ctype in self.classes: # wrapped class:\r
                 ret = "return (jlong) new %s(_retval_);" % fi.ctype\r
+            elif ret_type in self.classes: # pointer to wrapped class:\r
+                ret = "return (jlong) _retval_;"\r
             elif type_dict[fi.ctype]["jni_type"] == "jdoubleArray":\r
                 ret = "return _da_retval_;"\r
 \r
@@ -1018,6 +1039,10 @@ extern "C" {
             retval = fi.ctype + " _retval_ = "\r
             if fi.ctype == "void":\r
                 retval = ""\r
+            elif fi.ctype.startswith('vector'):\r
+                retval = type_dict[fi.ctype]['jni_var'] % {"n" : '_ret_val_vector_'} + " = "\r
+                c_epilogue.append("Mat* _retval_ = new Mat();")\r
+                c_epilogue.append(fi.ctype+"_to_Mat(_ret_val_vector_, *_retval_);")\r
             if fi.classname:\r
                 if not fi.ctype: # c-tor\r
                     retval = fi.classname + "* _retval_ = "\r
@@ -1096,8 +1121,6 @@ JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname
 \r
     def gen_class(self, name):\r
         # generate code for the class\r
-        if name == "Mat":\r
-            return\r
         ci = self.classes[name]\r
         # constants\r
         if ci.private_consts:\r
@@ -1116,6 +1139,9 @@ JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname
         for n, ffi in fflist:\r
             if ffi.isconstructor:\r
                 for fi in ffi.funcs:\r
+                    fi.jname = ci.jname\r
+                    fi.jn_name = "n_" + fi.jname\r
+                    fi.jni_name= re.sub("_", "_1", fi.jn_name)\r
                     self.gen_func(fi, len(ffi.funcs)>1)\r
         # other methods\r
         for n, ffi in fflist:\r
index 0ed747b..47b7c4d 100644 (file)
@@ -33,7 +33,7 @@ public:
 #if 0\r
     CV_WRAP virtual bool isMaskSupported() const;\r
        CV_WRAP virtual void add( const vector<Mat>& descriptors );\r
-       //CV_WRAP const vector<Mat>& getTrainDescriptors() const;\r
+       CV_WRAP const vector<Mat>& getTrainDescriptors() const;\r
        CV_WRAP virtual void clear();\r
        CV_WRAP virtual bool empty() const;\r
        CV_WRAP virtual void train();\r