Skip to content

Commit bed3a7c

Browse files
utibenkeiD00E
authored andcommitted
Merge pull request opencv#27567 from utibenkei:fix-java-wrapper-missing-vec4i
Enable Java wrapper generation for Vec4i opencv#27567 Fixes an issue where Java wrapper generation skips methods using Vec4i. Related PR in opencv_contrib: opencv/opencv_contrib#3988 The root cause was the absence of Vec4i in gen_java.json, which led to important methods such as aruco.drawCharucoDiamond() and ximgproc.HoughPoint2Line() being omitted from the Java bindings. This PR includes the following changes: - Added Vec4i definition to gen_java.json - Updated gen_java.py to handle jintArray-based types properly - ~~Also adjusted jn_args and jni_var for Vec2d and Vec3d to ensure correct JNI behavior~~ The modified Java wrapper generator successfully builds and includes the expected methods using Vec4i. ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake
1 parent a888dd7 commit bed3a7c

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

modules/core/misc/java/gen_dict.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,31 @@
648648
"jni_var": "Vec3d %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2)",
649649
"suffix": "DDD"
650650
},
651+
"Vec4i": {
652+
"j_type": "int[]",
653+
"jn_args": [
654+
[
655+
"int",
656+
".val[0]"
657+
],
658+
[
659+
"int",
660+
".val[1]"
661+
],
662+
[
663+
"int",
664+
".val[2]"
665+
],
666+
[
667+
"int",
668+
".val[3]"
669+
]
670+
],
671+
"jn_type": "int[]",
672+
"jni_type": "jintArray",
673+
"jni_var": "Vec4i %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2, %(n)s_val3)",
674+
"suffix": "IIII"
675+
},
651676
"c_string": {
652677
"j_type": "String",
653678
"jn_type": "String",

modules/java/generator/gen_java.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,13 @@ def gen_func(self, ci, fi, prop_name=''):
743743
"jdouble _tmp_retval_[%(cnt)i] = {%(args)s}; " +
744744
"env->SetDoubleArrayRegion(_da_retval_, 0, %(cnt)i, _tmp_retval_);") %
745745
{ "cnt" : len(fields), "args" : ", ".join(["(jdouble)_retval_" + f[1] for f in fields]) } )
746+
elif type_dict[fi.ctype]["jni_type"] == "jintArray":
747+
fields = type_dict[fi.ctype]["jn_args"]
748+
c_epilogue.append(
749+
("jintArray _ia_retval_ = env->NewIntArray(%(cnt)i); " +
750+
"jint _tmp_retval_[%(cnt)i] = {%(args)s}; " +
751+
"env->SetIntArrayRegion(_ia_retval_, 0, %(cnt)i, _tmp_retval_);") %
752+
{ "cnt" : len(fields), "args" : ", ".join(["(jint)_retval_" + f[1] for f in fields]) } )
746753
if fi.classname and fi.ctype and not fi.static: # non-static class method except c-tor
747754
# adding 'self'
748755
jn_args.append ( ArgInfo([ "__int64", "nativeObj", "", [], "" ]) )
@@ -790,7 +797,14 @@ def gen_func(self, ci, fi, prop_name=''):
790797
fields = type_dict[a.ctype].get("jn_args", ((a.ctype, ""),))
791798
if "I" in a.out or not a.out or self.isWrapped(a.ctype): # input arg, pass by primitive fields
792799
for f in fields:
793-
jn_args.append ( ArgInfo([ f[0], a.name + f[1], "", [], "" ]) )
800+
# Use array access format for Java code when jn_type is array type
801+
if type_dict[a.ctype].get("jn_type", "").endswith("[]"):
802+
# For Java code: convert .val[0] format to [0] format
803+
jn_args.append ( ArgInfo([ f[0], a.name + f[1].replace(".val[", "["), "", [], "" ]) )
804+
else:
805+
# For non-array types, use conventional format
806+
jn_args.append ( ArgInfo([ f[0], a.name + f[1], "", [], "" ]) )
807+
# For C++ code: use conventional format as is
794808
jni_args.append( ArgInfo([ f[0], a.name + normalize_field_name(f[1]), "", [], "" ]) )
795809
if "O" in a.out and not self.isWrapped(a.ctype): # out arg, pass as double[]
796810
jn_args.append ( ArgInfo([ "double[]", "%s_out" % a.name, "", [], "" ]) )
@@ -805,9 +819,16 @@ def gen_func(self, ci, fi, prop_name=''):
805819
set_vals = []
806820
i = 0
807821
for f in fields:
808-
set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" %
809-
{"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1], "i" : i}
810-
)
822+
# Use array access format for Java code when jn_type is array type
823+
if type_dict[a.ctype].get("jn_type", "").endswith("[]"):
824+
# For Java code: convert .val[0] format to [0] format
825+
set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" %
826+
{"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1].replace(".val[", "["), "i" : i}
827+
)
828+
else:
829+
set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" %
830+
{"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1], "i" : i}
831+
)
811832
i += 1
812833
j_epilogue.append( "if("+a.name+"!=null){ " + "; ".join(set_vals) + "; } ")
813834

@@ -1002,6 +1023,8 @@ def gen_func(self, ci, fi, prop_name=''):
10021023
ret = "return (jlong) _retval_;"
10031024
elif type_dict[fi.ctype]["jni_type"] == "jdoubleArray":
10041025
ret = "return _da_retval_;"
1026+
elif type_dict[fi.ctype]["jni_type"] == "jintArray":
1027+
ret = "return _ia_retval_;"
10051028
elif "jni_var" in type_dict[ret_type]:
10061029
c_epilogue.append(type_dict[ret_type]["jni_var"] % {"n" : '_retval_'})
10071030
ret = f"return {type_dict[ret_type]['jni_name'] % {'n' : '_retval_'}};"

0 commit comments

Comments
 (0)