java: force using of 'Ptr<>' for OpenCV classes
authorAlexander Alekhin <alexander.alekhin@intel.com>
Fri, 2 Jul 2021 10:41:41 +0000 (10:41 +0000)
committerAlexander Alekhin <alexander.alekhin@intel.com>
Fri, 2 Jul 2021 21:13:49 +0000 (21:13 +0000)
modules/dnn/misc/java/gen_dict.json
modules/java/generator/gen_java.py
modules/video/misc/java/test/TrackerCreateTest.java

index 5a397eac51c00d6e2faed16970b33f0bfee64ee3..65ecfdc25ea758cf02ad1346bfcad08b3e1d4d8c 100644 (file)
@@ -54,7 +54,7 @@
                 ]
 
             ],
-            "jni_name": "(*(cv::dnn::DictValue*)%(n)s_nativeObj)",
+            "jni_name": "(*(*(Ptr<cv::dnn::DictValue>*)%(n)s_nativeObj))",
             "jni_type": "jlong",
             "suffix": "J",
             "j_import": "org.opencv.dnn.DictValue"
index 6019ca340d2530e8c768b0fcf73ac7452115204c..c5b4f34a8f2b45c40a43f19d3621d8e73dc52fcc 100755 (executable)
@@ -258,6 +258,8 @@ class ClassInfo(GeneralInfo):
         for m in decl[2]:
             if m.startswith("="):
                 self.jname = m[1:]
+            if m == '/Simple':
+                self.smart = False
 
         if self.classpath:
             prefix = self.classpath.replace('.', '_')
@@ -445,7 +447,7 @@ class JavaWrapperGenerator(object):
 
     def clear(self):
         self.namespaces = ["cv"]
-        classinfo_Mat = ClassInfo([ 'class cv.Mat', '', [], [] ], self.namespaces)
+        classinfo_Mat = ClassInfo([ 'class cv.Mat', '', ['/Simple'], [] ], self.namespaces)
         self.classes = { "Mat" : classinfo_Mat }
         self.module = ""
         self.Module = ""
@@ -466,10 +468,15 @@ class JavaWrapperGenerator(object):
         if name in type_dict and not classinfo.base:
             logging.warning('duplicated: %s', classinfo)
             return
+        if self.isSmartClass(classinfo):
+            jni_name = "*((*(Ptr<"+classinfo.fullNameCPP()+">*)%(n)s_nativeObj).get())"
+        else:
+            jni_name = "(*("+classinfo.fullNameCPP()+"*)%(n)s_nativeObj)"
         type_dict.setdefault(name, {}).update(
             { "j_type" : classinfo.jname,
               "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),),
-              "jni_name" : "(*("+classinfo.fullNameCPP()+"*)%(n)s_nativeObj)", "jni_type" : "jlong",
+              "jni_name" : jni_name,
+              "jni_type" : "jlong",
               "suffix" : "J",
               "j_import" : "org.opencv.%s.%s" % (self.module, classinfo.jname)
             }
@@ -477,7 +484,8 @@ class JavaWrapperGenerator(object):
         type_dict.setdefault(name+'*', {}).update(
             { "j_type" : classinfo.jname,
               "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),),
-              "jni_name" : "("+classinfo.fullNameCPP()+"*)%(n)s_nativeObj", "jni_type" : "jlong",
+              "jni_name" : "&("+jni_name+")",
+              "jni_type" : "jlong",
               "suffix" : "J",
               "j_import" : "org.opencv.%s.%s" % (self.module, classinfo.jname)
             }
@@ -966,7 +974,13 @@ class JavaWrapperGenerator(object):
                 ret = "return env->NewStringUTF(_retval_.c_str());"
                 default = 'return env->NewStringUTF("");'
             elif self.isWrapped(fi.ctype): # wrapped class:
-                ret = "return (jlong) new %s(_retval_);" % self.fullTypeNameCPP(fi.ctype)
+                ret = None
+                if fi.ctype in self.classes:
+                    ret_ci = self.classes[fi.ctype]
+                    if self.isSmartClass(ret_ci):
+                        ret = "return (jlong)(new Ptr<%(ctype)s>(new %(ctype)s(_retval_)));" % { 'ctype': ret_ci.fullNameCPP() }
+                if ret is None:
+                    ret = "return (jlong) new %s(_retval_);" % self.fullTypeNameCPP(fi.ctype)
             elif fi.ctype.startswith('Ptr_'):
                 c_prologue.append("typedef Ptr<%s> %s;" % (self.fullTypeNameCPP(fi.ctype[4:]), fi.ctype))
                 ret = "return (jlong)(new %(ctype)s(_retval_));" % { 'ctype':fi.ctype }
@@ -1207,17 +1221,7 @@ JNIEXPORT void JNICALL Java_org_opencv_%(module)s_%(j_cls)s_delete
         if ci.smart != None:
             return ci.smart
 
-        # if parents are smart (we hope) then children are!
-        # if not we believe the class is smart if it has "create" method
-        ci.smart = False
-        if ci.base or ci.name == 'Algorithm':
-            ci.smart = True
-        else:
-            for fi in ci.methods:
-                if fi.name == "create":
-                    ci.smart = True
-                    break
-
+        ci.smart = True  # smart class is not properly handled in case of base/derived classes
         return ci.smart
 
     def smartWrap(self, ci, fullname):
index dad696bebfa246dfe4a3c5755beef857e1605d11..83bbd0b5d5ce3799ca95ec201c4ca70a48960e7b 100644 (file)
@@ -1,7 +1,10 @@
 package org.opencv.test.video;
 
 import org.opencv.core.Core;
+import org.opencv.core.CvType;
 import org.opencv.core.CvException;
+import org.opencv.core.Mat;
+import org.opencv.core.Rect;
 import org.opencv.test.OpenCVTestCase;
 
 import org.opencv.video.Tracker;
@@ -27,6 +30,10 @@ public class TrackerCreateTest extends OpenCVTestCase {
 
     public void testCreateTrackerMIL() {
         Tracker tracker = TrackerMIL.create();
+        assert(tracker != null);
+        Mat mat = new Mat(100, 100, CvType.CV_8UC1);
+        Rect rect = new Rect(10, 10, 30, 30);
+        tracker.init(mat, rect);  // should not crash (https://github.com/opencv/opencv/issues/19915)
     }
 
 }