1#!/usr/bin/env python 2 3import sys, re, os.path 4import logging 5from pprint import pformat 6from string import Template 7 8if sys.version_info[0] >= 3: 9 from io import StringIO 10else: 11 from cStringIO import StringIO 12 13class_ignore_list = ( 14 #core 15 "FileNode", "FileStorage", "KDTree", "KeyPoint", "DMatch", 16 #videoio 17 "VideoWriter", 18) 19 20const_ignore_list = ( 21 "CV_CAP_OPENNI", 22 "CV_CAP_PROP_OPENNI_", 23 "CV_CAP_INTELPERC", 24 "CV_CAP_PROP_INTELPERC_" 25 "WINDOW_AUTOSIZE", 26 "CV_WND_PROP_", 27 "CV_WINDOW_", 28 "CV_EVENT_", 29 "CV_GUI_", 30 "CV_PUSH_BUTTON", 31 "CV_CHECKBOX", 32 "CV_RADIOBOX", 33 34 #attention! 35 #the following constants are added to this list using code automatic generation 36 #TODO: should be checked 37 "CV_CAP_ANY", 38 "CV_CAP_MIL", 39 "CV_CAP_VFW", 40 "CV_CAP_V4L", 41 "CV_CAP_V4L2", 42 "CV_CAP_FIREWARE", 43 "CV_CAP_FIREWIRE", 44 "CV_CAP_IEEE1394", 45 "CV_CAP_DC1394", 46 "CV_CAP_CMU1394", 47 "CV_CAP_STEREO", 48 "CV_CAP_TYZX", 49 "CV_TYZX_LEFT", 50 "CV_TYZX_RIGHT", 51 "CV_TYZX_COLOR", 52 "CV_TYZX_Z", 53 "CV_CAP_QT", 54 "CV_CAP_UNICAP", 55 "CV_CAP_DSHOW", 56 "CV_CAP_PVAPI", 57 "CV_CAP_PROP_DC1394_OFF", 58 "CV_CAP_PROP_DC1394_MODE_MANUAL", 59 "CV_CAP_PROP_DC1394_MODE_AUTO", 60 "CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO", 61 "CV_CAP_PROP_POS_MSEC", 62 "CV_CAP_PROP_POS_FRAMES", 63 "CV_CAP_PROP_POS_AVI_RATIO", 64 "CV_CAP_PROP_FPS", 65 "CV_CAP_PROP_FOURCC", 66 "CV_CAP_PROP_FRAME_COUNT", 67 "CV_CAP_PROP_FORMAT", 68 "CV_CAP_PROP_MODE", 69 "CV_CAP_PROP_BRIGHTNESS", 70 "CV_CAP_PROP_CONTRAST", 71 "CV_CAP_PROP_SATURATION", 72 "CV_CAP_PROP_HUE", 73 "CV_CAP_PROP_GAIN", 74 "CV_CAP_PROP_EXPOSURE", 75 "CV_CAP_PROP_CONVERT_RGB", 76 "CV_CAP_PROP_WHITE_BALANCE_BLUE_U", 77 "CV_CAP_PROP_RECTIFICATION", 78 "CV_CAP_PROP_MONOCHROME", 79 "CV_CAP_PROP_SHARPNESS", 80 "CV_CAP_PROP_AUTO_EXPOSURE", 81 "CV_CAP_PROP_GAMMA", 82 "CV_CAP_PROP_TEMPERATURE", 83 "CV_CAP_PROP_TRIGGER", 84 "CV_CAP_PROP_TRIGGER_DELAY", 85 "CV_CAP_PROP_WHITE_BALANCE_RED_V", 86 "CV_CAP_PROP_MAX_DC1394", 87 "CV_CAP_GSTREAMER_QUEUE_LENGTH", 88 "CV_CAP_PROP_PVAPI_MULTICASTIP", 89 "CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING", 90 "EVENT_.*", 91 "CV_L?(BGRA?|RGBA?|GRAY|XYZ|YCrCb|Luv|Lab|HLS|YUV|HSV)\d*2L?(BGRA?|RGBA?|GRAY|XYZ|YCrCb|Luv|Lab|HLS|YUV|HSV).*", 92 "CV_COLORCVT_MAX", 93 "CV_.*Bayer.*", 94 "CV_YUV420(i|sp|p)2.+", 95 "CV_TM_.+", 96 "CV_FLOODFILL_.+", 97 "CV_ADAPTIVE_THRESH_.+", 98 "WINDOW_.+", 99 "WND_PROP_.+", 100) 101 102const_private_list = ( 103 "CV_MOP_.+", 104 "CV_INTER_.+", 105 "CV_THRESH_.+", 106 "CV_INPAINT_.+", 107 "CV_RETR_.+", 108 "CV_CHAIN_APPROX_.+", 109 "OPPONENTEXTRACTOR", 110 "GRIDDETECTOR", 111 "PYRAMIDDETECTOR", 112 "DYNAMICDETECTOR", 113) 114 115# { Module : { public : [[name, val],...], private : [[]...] } } 116missing_consts = \ 117{ 118 'Core' : 119 { 120 'private' : 121 ( 122 ('CV_8U', 0 ), ('CV_8S', 1 ), 123 ('CV_16U', 2 ), ('CV_16S', 3 ), 124 ('CV_32S', 4 ), 125 ('CV_32F', 5 ), ('CV_64F', 6 ), 126 ('CV_USRTYPE1', 7 ), 127 ), # private 128 'public' : 129 ( 130 ('SVD_MODIFY_A', 1), ('SVD_NO_UV', 2), ('SVD_FULL_UV', 4), 131 ('FILLED', -1), 132 ('REDUCE_SUM', 0), ('REDUCE_AVG', 1), ('REDUCE_MAX', 2), ('REDUCE_MIN', 3), 133 ) #public 134 }, # Core 135 136 "Imgproc": 137 { 138 'private' : 139 ( 140 ('IPL_BORDER_CONSTANT', 0 ), 141 ('IPL_BORDER_REPLICATE', 1 ), 142 ('IPL_BORDER_REFLECT', 2 ), 143 ('IPL_BORDER_WRAP', 3 ), 144 ('IPL_BORDER_REFLECT_101', 4 ), 145 ('IPL_BORDER_TRANSPARENT', 5 ), 146 ), # private 147 'public' : 148 ( 149 ('LINE_AA', 16), ('LINE_8', 8), ('LINE_4', 4), 150 ) #public 151 }, # Imgproc 152 153 "Calib3d": 154 { 155 'public' : 156 ( 157 ('CALIB_USE_INTRINSIC_GUESS', '1'), 158 ('CALIB_RECOMPUTE_EXTRINSIC', '2'), 159 ('CALIB_CHECK_COND', '4'), 160 ('CALIB_FIX_SKEW', '8'), 161 ('CALIB_FIX_K1', '16'), 162 ('CALIB_FIX_K2', '32'), 163 ('CALIB_FIX_K3', '64'), 164 ('CALIB_FIX_K4', '128'), 165 ('CALIB_FIX_INTRINSIC', '256') 166 ) 167 }, # Calib3d 168 169 "Video": 170 { 171 'private' : 172 ( 173 ('CV_LKFLOW_INITIAL_GUESSES', 4 ), 174 ('CV_LKFLOW_GET_MIN_EIGENVALS', 8 ), 175 ) # private 176 }, # Video 177 178} 179 180 181# c_type : { java/jni correspondence } 182type_dict = { 183# "simple" : { j_type : "?", jn_type : "?", jni_type : "?", suffix : "?" }, 184 "" : { "j_type" : "", "jn_type" : "long", "jni_type" : "jlong" }, # c-tor ret_type 185 "void" : { "j_type" : "void", "jn_type" : "void", "jni_type" : "void" }, 186 "env" : { "j_type" : "", "jn_type" : "", "jni_type" : "JNIEnv*"}, 187 "cls" : { "j_type" : "", "jn_type" : "", "jni_type" : "jclass"}, 188 "bool" : { "j_type" : "boolean", "jn_type" : "boolean", "jni_type" : "jboolean", "suffix" : "Z" }, 189 "int" : { "j_type" : "int", "jn_type" : "int", "jni_type" : "jint", "suffix" : "I" }, 190 "long" : { "j_type" : "int", "jn_type" : "int", "jni_type" : "jint", "suffix" : "I" }, 191 "float" : { "j_type" : "float", "jn_type" : "float", "jni_type" : "jfloat", "suffix" : "F" }, 192 "double" : { "j_type" : "double", "jn_type" : "double", "jni_type" : "jdouble", "suffix" : "D" }, 193 "size_t" : { "j_type" : "long", "jn_type" : "long", "jni_type" : "jlong", "suffix" : "J" }, 194 "__int64" : { "j_type" : "long", "jn_type" : "long", "jni_type" : "jlong", "suffix" : "J" }, 195 "int64" : { "j_type" : "long", "jn_type" : "long", "jni_type" : "jlong", "suffix" : "J" }, 196 "double[]": { "j_type" : "double[]", "jn_type" : "double[]", "jni_type" : "jdoubleArray", "suffix" : "_3D" }, 197 198# "complex" : { j_type : "?", jn_args : (("", ""),), jn_name : "", jni_var : "", jni_name : "", "suffix" : "?" }, 199 200 "vector_Point" : { "j_type" : "MatOfPoint", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<Point> %(n)s", "suffix" : "J" }, 201 "vector_Point2f" : { "j_type" : "MatOfPoint2f", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<Point2f> %(n)s", "suffix" : "J" }, 202 #"vector_Point2d" : { "j_type" : "MatOfPoint2d", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<Point2d> %(n)s", "suffix" : "J" }, 203 "vector_Point3i" : { "j_type" : "MatOfPoint3", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<Point3i> %(n)s", "suffix" : "J" }, 204 "vector_Point3f" : { "j_type" : "MatOfPoint3f", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<Point3f> %(n)s", "suffix" : "J" }, 205 #"vector_Point3d" : { "j_type" : "MatOfPoint3d", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<Point3d> %(n)s", "suffix" : "J" }, 206 "vector_KeyPoint" : { "j_type" : "MatOfKeyPoint", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<KeyPoint> %(n)s", "suffix" : "J" }, 207 "vector_DMatch" : { "j_type" : "MatOfDMatch", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<DMatch> %(n)s", "suffix" : "J" }, 208 "vector_Rect" : { "j_type" : "MatOfRect", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<Rect> %(n)s", "suffix" : "J" }, 209 "vector_uchar" : { "j_type" : "MatOfByte", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<uchar> %(n)s", "suffix" : "J" }, 210 "vector_char" : { "j_type" : "MatOfByte", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<char> %(n)s", "suffix" : "J" }, 211 "vector_int" : { "j_type" : "MatOfInt", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<int> %(n)s", "suffix" : "J" }, 212 "vector_float" : { "j_type" : "MatOfFloat", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<float> %(n)s", "suffix" : "J" }, 213 "vector_double" : { "j_type" : "MatOfDouble", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<double> %(n)s", "suffix" : "J" }, 214 "vector_Vec4i" : { "j_type" : "MatOfInt4", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<Vec4i> %(n)s", "suffix" : "J" }, 215 "vector_Vec4f" : { "j_type" : "MatOfFloat4", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<Vec4f> %(n)s", "suffix" : "J" }, 216 "vector_Vec6f" : { "j_type" : "MatOfFloat6", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<Vec6f> %(n)s", "suffix" : "J" }, 217 218 "vector_Mat" : { "j_type" : "List<Mat>", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector<Mat> %(n)s", "suffix" : "J" }, 219 220 "vector_vector_KeyPoint": { "j_type" : "List<MatOfKeyPoint>", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector< std::vector<KeyPoint> > %(n)s" }, 221 "vector_vector_DMatch" : { "j_type" : "List<MatOfDMatch>", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector< std::vector<DMatch> > %(n)s" }, 222 "vector_vector_char" : { "j_type" : "List<MatOfByte>", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector< std::vector<char> > %(n)s" }, 223 "vector_vector_Point" : { "j_type" : "List<MatOfPoint>", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector< std::vector<Point> > %(n)s" }, 224 "vector_vector_Point2f" : { "j_type" : "List<MatOfPoint2f>", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector< std::vector<Point2f> > %(n)s" }, 225 "vector_vector_Point3f" : { "j_type" : "List<MatOfPoint3f>", "jn_type" : "long", "jni_type" : "jlong", "jni_var" : "std::vector< std::vector<Point3f> > %(n)s" }, 226 227 "Mat" : { "j_type" : "Mat", "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), 228 "jni_var" : "Mat& %(n)s = *((Mat*)%(n)s_nativeObj)", 229 "jni_type" : "jlong", #"jni_name" : "*%(n)s", 230 "suffix" : "J" }, 231 232 "Point" : { "j_type" : "Point", "jn_args" : (("double", ".x"), ("double", ".y")), 233 "jni_var" : "Point %(n)s((int)%(n)s_x, (int)%(n)s_y)", "jni_type" : "jdoubleArray", 234 "suffix" : "DD"}, 235 "Point2f" : { "j_type" : "Point", "jn_args" : (("double", ".x"), ("double", ".y")), 236 "jni_var" : "Point2f %(n)s((float)%(n)s_x, (float)%(n)s_y)", "jni_type" : "jdoubleArray", 237 "suffix" : "DD"}, 238 "Point2d" : { "j_type" : "Point", "jn_args" : (("double", ".x"), ("double", ".y")), 239 "jni_var" : "Point2d %(n)s(%(n)s_x, %(n)s_y)", "jni_type" : "jdoubleArray", 240 "suffix" : "DD"}, 241 "Point3i" : { "j_type" : "Point3", "jn_args" : (("double", ".x"), ("double", ".y"), ("double", ".z")), 242 "jni_var" : "Point3i %(n)s((int)%(n)s_x, (int)%(n)s_y, (int)%(n)s_z)", "jni_type" : "jdoubleArray", 243 "suffix" : "DDD"}, 244 "Point3f" : { "j_type" : "Point3", "jn_args" : (("double", ".x"), ("double", ".y"), ("double", ".z")), 245 "jni_var" : "Point3f %(n)s((float)%(n)s_x, (float)%(n)s_y, (float)%(n)s_z)", "jni_type" : "jdoubleArray", 246 "suffix" : "DDD"}, 247 "Point3d" : { "j_type" : "Point3", "jn_args" : (("double", ".x"), ("double", ".y"), ("double", ".z")), 248 "jni_var" : "Point3d %(n)s(%(n)s_x, %(n)s_y, %(n)s_z)", "jni_type" : "jdoubleArray", 249 "suffix" : "DDD"}, 250 "KeyPoint": { "j_type" : "KeyPoint", "jn_args" : (("float", ".x"), ("float", ".y"), ("float", ".size"), 251 ("float", ".angle"), ("float", ".response"), ("int", ".octave"), ("int", ".class_id")), 252 "jni_var" : "KeyPoint %(n)s(%(n)s_x, %(n)s_y, %(n)s_size, %(n)s_angle, %(n)s_response, %(n)s_octave, %(n)s_class_id)", 253 "jni_type" : "jdoubleArray", 254 "suffix" : "FFFFFII"}, 255 "DMatch" : { "j_type" : "DMatch", "jn_args" : ( ('int', 'queryIdx'), ('int', 'trainIdx'), 256 ('int', 'imgIdx'), ('float', 'distance'), ), 257 "jni_var" : "DMatch %(n)s(%(n)s_queryIdx, %(n)s_trainIdx, %(n)s_imgIdx, %(n)s_distance)", 258 "jni_type" : "jdoubleArray", 259 "suffix" : "IIIF"}, 260 "Rect" : { "j_type" : "Rect", "jn_args" : (("int", ".x"), ("int", ".y"), ("int", ".width"), ("int", ".height")), 261 "jni_var" : "Rect %(n)s(%(n)s_x, %(n)s_y, %(n)s_width, %(n)s_height)", "jni_type" : "jdoubleArray", 262 "suffix" : "IIII"}, 263 "Size" : { "j_type" : "Size", "jn_args" : (("double", ".width"), ("double", ".height")), 264 "jni_var" : "Size %(n)s((int)%(n)s_width, (int)%(n)s_height)", "jni_type" : "jdoubleArray", 265 "suffix" : "DD"}, 266 "Size2f" : { "j_type" : "Size", "jn_args" : (("double", ".width"), ("double", ".height")), 267 "jni_var" : "Size2f %(n)s((float)%(n)s_width, (float)%(n)s_height)", "jni_type" : "jdoubleArray", 268 "suffix" : "DD"}, 269 "RotatedRect": { "j_type" : "RotatedRect", "jn_args" : (("double", ".center.x"), ("double", ".center.y"), ("double", ".size.width"), ("double", ".size.height"), ("double", ".angle")), 270 "jni_var" : "RotatedRect %(n)s(cv::Point2f(%(n)s_center_x, %(n)s_center_y), cv::Size2f(%(n)s_size_width, %(n)s_size_height), %(n)s_angle)", 271 "jni_type" : "jdoubleArray", "suffix" : "DDDDD"}, 272 "Scalar" : { "j_type" : "Scalar", "jn_args" : (("double", ".val[0]"), ("double", ".val[1]"), ("double", ".val[2]"), ("double", ".val[3]")), 273 "jni_var" : "Scalar %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2, %(n)s_val3)", "jni_type" : "jdoubleArray", 274 "suffix" : "DDDD"}, 275 "Range" : { "j_type" : "Range", "jn_args" : (("int", ".start"), ("int", ".end")), 276 "jni_var" : "Range %(n)s(%(n)s_start, %(n)s_end)", "jni_type" : "jdoubleArray", 277 "suffix" : "II"}, 278 "CvSlice" : { "j_type" : "Range", "jn_args" : (("int", ".start"), ("int", ".end")), 279 "jni_var" : "Range %(n)s(%(n)s_start, %(n)s_end)", "jni_type" : "jdoubleArray", 280 "suffix" : "II"}, 281 "String" : { "j_type" : "String", "jn_type" : "String", 282 "jni_type" : "jstring", "jni_name" : "n_%(n)s", 283 "jni_var" : 'const char* utf_%(n)s = env->GetStringUTFChars(%(n)s, 0); String n_%(n)s( utf_%(n)s ? utf_%(n)s : "" ); env->ReleaseStringUTFChars(%(n)s, utf_%(n)s)', 284 "suffix" : "Ljava_lang_String_2"}, 285 "c_string": { "j_type" : "String", "jn_type" : "String", 286 "jni_type" : "jstring", "jni_name" : "n_%(n)s.c_str()", 287 "jni_var" : 'const char* utf_%(n)s = env->GetStringUTFChars(%(n)s, 0); String n_%(n)s( utf_%(n)s ? utf_%(n)s : "" ); env->ReleaseStringUTFChars(%(n)s, utf_%(n)s)', 288 "suffix" : "Ljava_lang_String_2"}, 289"TermCriteria": { "j_type" : "TermCriteria", "jn_args" : (("int", ".type"), ("int", ".maxCount"), ("double", ".epsilon")), 290 "jni_var" : "TermCriteria %(n)s(%(n)s_type, %(n)s_maxCount, %(n)s_epsilon)", "jni_type" : "jdoubleArray", 291 "suffix" : "IID"}, 292"CvTermCriteria": { "j_type" : "TermCriteria", "jn_args" : (("int", ".type"), ("int", ".maxCount"), ("double", ".epsilon")), 293 "jni_var" : "TermCriteria %(n)s(%(n)s_type, %(n)s_maxCount, %(n)s_epsilon)", "jni_type" : "jdoubleArray", 294 "suffix" : "IID"}, 295 "Vec2d" : { "j_type" : "double[]", "jn_args" : (("double", ".val[0]"), ("double", ".val[1]")), 296 "jn_type" : "double[]", 297 "jni_var" : "Vec2d %(n)s(%(n)s_val0, %(n)s_val1)", "jni_type" : "jdoubleArray", 298 "suffix" : "DD"}, 299 "Vec3d" : { "j_type" : "double[]", "jn_args" : (("double", ".val[0]"), ("double", ".val[1]"), ("double", ".val[2]")), 300 "jn_type" : "double[]", 301 "jni_var" : "Vec3d %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2)", "jni_type" : "jdoubleArray", 302 "suffix" : "DDD"}, 303 304} 305 306# { class : { func : {j_code, jn_code, cpp_code} } } 307ManualFuncs = { 308 'Core' : 309 { 310 'minMaxLoc' : { 311 'j_code' : """ 312 // manual port 313 public static class MinMaxLocResult { 314 public double minVal; 315 public double maxVal; 316 public Point minLoc; 317 public Point maxLoc; 318 319 public MinMaxLocResult() { 320 minVal=0; maxVal=0; 321 minLoc=new Point(); 322 maxLoc=new Point(); 323 } 324 } 325 326 // C++: minMaxLoc(Mat src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray()) 327 328 //javadoc: minMaxLoc(src, mask) 329 public static MinMaxLocResult minMaxLoc(Mat src, Mat mask) { 330 MinMaxLocResult res = new MinMaxLocResult(); 331 long maskNativeObj=0; 332 if (mask != null) { 333 maskNativeObj=mask.nativeObj; 334 } 335 double resarr[] = n_minMaxLocManual(src.nativeObj, maskNativeObj); 336 res.minVal=resarr[0]; 337 res.maxVal=resarr[1]; 338 res.minLoc.x=resarr[2]; 339 res.minLoc.y=resarr[3]; 340 res.maxLoc.x=resarr[4]; 341 res.maxLoc.y=resarr[5]; 342 return res; 343 } 344 345 //javadoc: minMaxLoc(src) 346 public static MinMaxLocResult minMaxLoc(Mat src) { 347 return minMaxLoc(src, null); 348 } 349 350""", 351 'jn_code' : 352""" private static native double[] n_minMaxLocManual(long src_nativeObj, long mask_nativeObj);\n""", 353 'cpp_code' : 354""" 355// C++: minMaxLoc(Mat src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray()) 356JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Core_n_1minMaxLocManual (JNIEnv*, jclass, jlong, jlong); 357 358JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Core_n_1minMaxLocManual 359 (JNIEnv* env, jclass, jlong src_nativeObj, jlong mask_nativeObj) 360{ 361 try { 362 LOGD("Core::n_1minMaxLoc()"); 363 jdoubleArray result; 364 result = env->NewDoubleArray(6); 365 if (result == NULL) { 366 return NULL; /* out of memory error thrown */ 367 } 368 369 Mat& src = *((Mat*)src_nativeObj); 370 371 double minVal, maxVal; 372 Point minLoc, maxLoc; 373 if (mask_nativeObj != 0) { 374 Mat& mask = *((Mat*)mask_nativeObj); 375 minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc, mask); 376 } else { 377 minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc); 378 } 379 380 jdouble fill[6]; 381 fill[0]=minVal; 382 fill[1]=maxVal; 383 fill[2]=minLoc.x; 384 fill[3]=minLoc.y; 385 fill[4]=maxLoc.x; 386 fill[5]=maxLoc.y; 387 388 env->SetDoubleArrayRegion(result, 0, 6, fill); 389 390 return result; 391 392 } catch(const cv::Exception& e) { 393 LOGD("Core::n_1minMaxLoc() catched cv::Exception: %s", e.what()); 394 jclass je = env->FindClass("org/opencv/core/CvException"); 395 if(!je) je = env->FindClass("java/lang/Exception"); 396 env->ThrowNew(je, e.what()); 397 return NULL; 398 } catch (...) { 399 LOGD("Core::n_1minMaxLoc() catched unknown exception (...)"); 400 jclass je = env->FindClass("java/lang/Exception"); 401 env->ThrowNew(je, "Unknown exception in JNI code {core::minMaxLoc()}"); 402 return NULL; 403 } 404} 405 406""", 407 }, # minMaxLoc 408 409 410## "checkRange" : #TBD 411## {'j_code' : '/* TBD: checkRange() */', 'jn_code' : '', 'cpp_code' : '' }, 412 413 "checkHardwareSupport" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 414 "setUseOptimized" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 415 "useOptimized" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 416 417 }, # Core 418 419 'Imgproc' : 420 { 421 'getTextSize' : 422 { 423 'j_code' : 424 """ 425 // C++: Size getTextSize(const String& text, int fontFace, double fontScale, int thickness, int* baseLine); 426 //javadoc:getTextSize(text, fontFace, fontScale, thickness, baseLine) 427 public static Size getTextSize(String text, int fontFace, double fontScale, int thickness, int[] baseLine) { 428 if(baseLine != null && baseLine.length != 1) 429 throw new java.lang.IllegalArgumentException("'baseLine' must be 'int[1]' or 'null'."); 430 Size retVal = new Size(n_getTextSize(text, fontFace, fontScale, thickness, baseLine)); 431 return retVal; 432 } 433 """, 434 'jn_code' : 435 """ private static native double[] n_getTextSize(String text, int fontFace, double fontScale, int thickness, int[] baseLine);\n""", 436 'cpp_code' : 437 """ 438 // C++: Size getTextSize(const String& text, int fontFace, double fontScale, int thickness, int* baseLine); 439 JNIEXPORT jdoubleArray JNICALL Java_org_opencv_imgproc_Imgproc_n_1getTextSize (JNIEnv*, jclass, jstring, jint, jdouble, jint, jintArray); 440 441 JNIEXPORT jdoubleArray JNICALL Java_org_opencv_imgproc_Imgproc_n_1getTextSize 442 (JNIEnv* env, jclass, jstring text, jint fontFace, jdouble fontScale, jint thickness, jintArray baseLine) 443 { 444 try { 445 LOGD("Core::n_1getTextSize()"); 446 jdoubleArray result; 447 result = env->NewDoubleArray(2); 448 if (result == NULL) { 449 return NULL; /* out of memory error thrown */ 450 } 451 452 const char* utf_text = env->GetStringUTFChars(text, 0); 453 String n_text( utf_text ? utf_text : "" ); 454 env->ReleaseStringUTFChars(text, utf_text); 455 456 int _baseLine; 457 int* pbaseLine = 0; 458 459 if (baseLine != NULL) 460 pbaseLine = &_baseLine; 461 462 cv::Size rsize = cv::getTextSize(n_text, (int)fontFace, (double)fontScale, (int)thickness, pbaseLine); 463 464 jdouble fill[2]; 465 fill[0]=rsize.width; 466 fill[1]=rsize.height; 467 468 env->SetDoubleArrayRegion(result, 0, 2, fill); 469 470 if (baseLine != NULL) { 471 jint jbaseLine = (jint)(*pbaseLine); 472 env->SetIntArrayRegion(baseLine, 0, 1, &jbaseLine); 473 } 474 475 return result; 476 477 } catch(const cv::Exception& e) { 478 LOGD("Imgproc::n_1getTextSize() catched cv::Exception: %s", e.what()); 479 jclass je = env->FindClass("org/opencv/core/CvException"); 480 if(!je) je = env->FindClass("java/lang/Exception"); 481 env->ThrowNew(je, e.what()); 482 return NULL; 483 } catch (...) { 484 LOGD("Imgproc::n_1getTextSize() catched unknown exception (...)"); 485 jclass je = env->FindClass("java/lang/Exception"); 486 env->ThrowNew(je, "Unknown exception in JNI code {core::getTextSize()}"); 487 return NULL; 488 } 489 } 490 """, 491 }, # getTextSize 492 493 }, # Imgproc 494 495 'Highgui' : 496 { 497 "namedWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 498 "destroyWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 499 "destroyAllWindows" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 500 "startWindowThread" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 501 "setWindowProperty" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 502 "getWindowProperty" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 503 "getTrackbarPos" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 504 "setTrackbarPos" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 505 "imshow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 506 "waitKey" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 507 "moveWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 508 "resizeWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' }, 509 }, # Highgui 510} 511 512# { class : { func : { arg_name : {"ctype" : ctype, "attrib" : [attrib]} } } } 513func_arg_fix = { 514 '' : { 515 'randu' : { 'low' : {"ctype" : 'double'}, 516 'high' : {"ctype" : 'double'} }, 517 'randn' : { 'mean' : {"ctype" : 'double'}, 518 'stddev' : {"ctype" : 'double'} }, 519 'inRange' : { 'lowerb' : {"ctype" : 'Scalar'}, 520 'upperb' : {"ctype" : 'Scalar'} }, 521 'goodFeaturesToTrack' : { 'corners' : {"ctype" : 'vector_Point'} }, 522 'findFundamentalMat' : { 'points1' : {"ctype" : 'vector_Point2f'}, 523 'points2' : {"ctype" : 'vector_Point2f'} }, 524 'cornerSubPix' : { 'corners' : {"ctype" : 'vector_Point2f'} }, 525 'minEnclosingCircle' : { 'points' : {"ctype" : 'vector_Point2f'} }, 526 'findHomography' : { 'srcPoints' : {"ctype" : 'vector_Point2f'}, 527 'dstPoints' : {"ctype" : 'vector_Point2f'} }, 528 'solvePnP' : { 'objectPoints' : {"ctype" : 'vector_Point3f'}, 529 'imagePoints' : {"ctype" : 'vector_Point2f'}, 530 'distCoeffs' : {"ctype" : 'vector_double' } }, 531 'solvePnPRansac' : { 'objectPoints' : {"ctype" : 'vector_Point3f'}, 532 'imagePoints' : {"ctype" : 'vector_Point2f'}, 533 'distCoeffs' : {"ctype" : 'vector_double' } }, 534 'calcOpticalFlowPyrLK' : { 'prevPts' : {"ctype" : 'vector_Point2f'}, 535 'nextPts' : {"ctype" : 'vector_Point2f'}, 536 'status' : {"ctype" : 'vector_uchar'}, 537 'err' : {"ctype" : 'vector_float'} }, 538 'fitEllipse' : { 'points' : {"ctype" : 'vector_Point2f'} }, 539 'fillPoly' : { 'pts' : {"ctype" : 'vector_vector_Point'} }, 540 'polylines' : { 'pts' : {"ctype" : 'vector_vector_Point'} }, 541 'fillConvexPoly' : { 'points' : {"ctype" : 'vector_Point'} }, 542 'boundingRect' : { 'points' : {"ctype" : 'vector_Point'} }, 543 'approxPolyDP' : { 'curve' : {"ctype" : 'vector_Point2f'}, 544 'approxCurve' : {"ctype" : 'vector_Point2f'} }, 545 'arcLength' : { 'curve' : {"ctype" : 'vector_Point2f'} }, 546 'pointPolygonTest' : { 'contour' : {"ctype" : 'vector_Point2f'} }, 547 'minAreaRect' : { 'points' : {"ctype" : 'vector_Point2f'} }, 548 'getAffineTransform' : { 'src' : {"ctype" : 'vector_Point2f'}, 549 'dst' : {"ctype" : 'vector_Point2f'} }, 550 'hconcat' : { 'src' : {"ctype" : 'vector_Mat'} }, 551 'vconcat' : { 'src' : {"ctype" : 'vector_Mat'} }, 552 'undistortPoints' : { 'src' : {"ctype" : 'vector_Point2f'}, 553 'dst' : {"ctype" : 'vector_Point2f'} }, 554 'checkRange' : {'pos' : {"ctype" : '*'} }, 555 'meanStdDev' : { 'mean' : {"ctype" : 'vector_double'}, 556 'stddev' : {"ctype" : 'vector_double'} }, 557 'drawContours' : {'contours' : {"ctype" : 'vector_vector_Point'} }, 558 'findContours' : {'contours' : {"ctype" : 'vector_vector_Point'} }, 559 'convexityDefects' : { 'contour' : {"ctype" : 'vector_Point'}, 560 'convexhull' : {"ctype" : 'vector_int'}, 561 'convexityDefects' : {"ctype" : 'vector_Vec4i'} }, 562 'isContourConvex' : { 'contour' : {"ctype" : 'vector_Point'} }, 563 'convexHull' : { 'points' : {"ctype" : 'vector_Point'}, 564 'hull' : {"ctype" : 'vector_int'}, 565 'returnPoints' : {"ctype" : ''} }, 566 'projectPoints' : { 'objectPoints' : {"ctype" : 'vector_Point3f'}, 567 'imagePoints' : {"ctype" : 'vector_Point2f'}, 568 'distCoeffs' : {"ctype" : 'vector_double' } }, 569 'initCameraMatrix2D' : { 'objectPoints' : {"ctype" : 'vector_vector_Point3f'}, 570 'imagePoints' : {"ctype" : 'vector_vector_Point2f'} }, 571 'findChessboardCorners' : { 'corners' : {"ctype" : 'vector_Point2f'} }, 572 'drawChessboardCorners' : { 'corners' : {"ctype" : 'vector_Point2f'} }, 573 'mixChannels' : { 'dst' : {"attrib" : []} }, 574 }, # '', i.e. no class 575} # func_arg_fix 576 577def getLibVersion(version_hpp_path): 578 version_file = open(version_hpp_path, "rt").read() 579 major = re.search("^W*#\W*define\W+CV_VERSION_MAJOR\W+(\d+)\W*$", version_file, re.MULTILINE).group(1) 580 minor = re.search("^W*#\W*define\W+CV_VERSION_MINOR\W+(\d+)\W*$", version_file, re.MULTILINE).group(1) 581 revision = re.search("^W*#\W*define\W+CV_VERSION_REVISION\W+(\d+)\W*$", version_file, re.MULTILINE).group(1) 582 status = re.search("^W*#\W*define\W+CV_VERSION_STATUS\W+\"(.*?)\"\W*$", version_file, re.MULTILINE).group(1) 583 return (major, minor, revision, status) 584 585def libVersionBlock(): 586 (major, minor, revision, status) = getLibVersion( 587 (os.path.dirname(__file__) or '.') + '/../../core/include/opencv2/core/version.hpp') 588 version_str = '.'.join( (major, minor, revision) ) + status 589 version_suffix = ''.join( (major, minor, revision) ) 590 return """ 591 // these constants are wrapped inside functions to prevent inlining 592 private static String getVersion() { return "%(v)s"; } 593 private static String getNativeLibraryName() { return "opencv_java%(vs)s"; } 594 private static int getVersionMajor() { return %(ma)s; } 595 private static int getVersionMinor() { return %(mi)s; } 596 private static int getVersionRevision() { return %(re)s; } 597 private static String getVersionStatus() { return "%(st)s"; } 598 599 public static final String VERSION = getVersion(); 600 public static final String NATIVE_LIBRARY_NAME = getNativeLibraryName(); 601 public static final int VERSION_MAJOR = getVersionMajor(); 602 public static final int VERSION_MINOR = getVersionMinor(); 603 public static final int VERSION_REVISION = getVersionRevision(); 604 public static final String VERSION_STATUS = getVersionStatus(); 605""" % { 'v' : version_str, 'vs' : version_suffix, 'ma' : major, 'mi' : minor, 're' : revision, 'st': status } 606 607 608T_JAVA_START_INHERITED = """ 609// 610// This file is auto-generated. Please don't modify it! 611// 612package org.opencv.$module; 613 614$imports 615 616// C++: class $name 617//javadoc: $name 618public class $jname extends $base { 619 620 protected $jname(long addr) { super(addr); } 621 622""" 623 624T_JAVA_START_ORPHAN = """ 625// 626// This file is auto-generated. Please don't modify it! 627// 628package org.opencv.$module; 629 630$imports 631 632// C++: class $name 633//javadoc: $name 634public class $jname { 635 636 protected final long nativeObj; 637 protected $jname(long addr) { nativeObj = addr; } 638 639""" 640 641T_JAVA_START_MODULE = """ 642// 643// This file is auto-generated. Please don't modify it! 644// 645package org.opencv.$module; 646 647$imports 648 649public class $jname { 650""" 651 652T_CPP_MODULE = """ 653// 654// This file is auto-generated, please don't edit! 655// 656 657#define LOG_TAG "org.opencv.$m" 658 659#include "common.h" 660 661#include "opencv2/opencv_modules.hpp" 662#ifdef HAVE_OPENCV_$M 663 664#include <string> 665 666#include "opencv2/$m.hpp" 667 668$includes 669 670using namespace cv; 671 672/// throw java exception 673static void throwJavaException(JNIEnv *env, const std::exception *e, const char *method) { 674 std::string what = "unknown exception"; 675 jclass je = 0; 676 677 if(e) { 678 std::string exception_type = "std::exception"; 679 680 if(dynamic_cast<const cv::Exception*>(e)) { 681 exception_type = "cv::Exception"; 682 je = env->FindClass("org/opencv/core/CvException"); 683 } 684 685 what = exception_type + ": " + e->what(); 686 } 687 688 if(!je) je = env->FindClass("java/lang/Exception"); 689 env->ThrowNew(je, what.c_str()); 690 691 LOGE("%s caught %s", method, what.c_str()); 692 (void)method; // avoid "unused" warning 693} 694 695 696extern "C" { 697 698$code 699 700} // extern "C" 701 702#endif // HAVE_OPENCV_$M 703""" 704 705class GeneralInfo(): 706 def __init__(self, name, namespaces): 707 self.namespace, self.classpath, self.classname, self.name = self.parseName(name, namespaces) 708 709 def parseName(self, name, namespaces): 710 ''' 711 input: full name and available namespaces 712 returns: (namespace, classpath, classname, name) 713 ''' 714 name = name[name.find(" ")+1:].strip() # remove struct/class/const prefix 715 spaceName = "" 716 localName = name # <classes>.<name> 717 for namespace in sorted(namespaces, key=len, reverse=True): 718 if name.startswith(namespace + "."): 719 spaceName = namespace 720 localName = name.replace(namespace + ".", "") 721 break 722 pieces = localName.split(".") 723 if len(pieces) > 2: # <class>.<class>.<class>.<name> 724 return spaceName, ".".join(pieces[:-1]), pieces[-2], pieces[-1] 725 elif len(pieces) == 2: # <class>.<name> 726 return spaceName, pieces[0], pieces[0], pieces[1] 727 elif len(pieces) == 1: # <name> 728 return spaceName, "", "", pieces[0] 729 else: 730 return spaceName, "", "" # error?! 731 732 def fullName(self, isCPP=False): 733 result = ".".join([self.fullClass(), self.name]) 734 return result if not isCPP else result.replace(".", "::") 735 736 def fullClass(self, isCPP=False): 737 result = ".".join([f for f in [self.namespace] + self.classpath.split(".") if len(f)>0]) 738 return result if not isCPP else result.replace(".", "::") 739 740class ConstInfo(GeneralInfo): 741 def __init__(self, decl, addedManually=False, namespaces=[]): 742 GeneralInfo.__init__(self, decl[0], namespaces) 743 self.cname = self.name.replace(".", "::") 744 self.value = decl[1] 745 self.addedManually = addedManually 746 747 def __repr__(self): 748 return Template("CONST $name=$value$manual").substitute(name=self.name, 749 value=self.value, 750 manual="(manual)" if self.addedManually else "") 751 752 def isIgnored(self): 753 for c in const_ignore_list: 754 if re.match(c, self.name): 755 return True 756 return False 757 758class ClassPropInfo(): 759 def __init__(self, decl): # [f_ctype, f_name, '', '/RW'] 760 self.ctype = decl[0] 761 self.name = decl[1] 762 self.rw = "/RW" in decl[3] 763 764 def __repr__(self): 765 return Template("PROP $ctype $name").substitute(ctype=self.ctype, name=self.name) 766 767class ClassInfo(GeneralInfo): 768 def __init__(self, decl, namespaces=[]): # [ 'class/struct cname', ': base', [modlist] ] 769 GeneralInfo.__init__(self, decl[0], namespaces) 770 self.cname = self.name.replace(".", "::") 771 self.methods = [] 772 self.methods_suffixes = {} 773 self.consts = [] # using a list to save the occurence order 774 self.private_consts = [] 775 self.imports = set() 776 self.props= [] 777 self.jname = self.name 778 self.j_code = None # java code stream 779 self.jn_code = None # jni code stream 780 self.cpp_code = None # cpp code stream 781 for m in decl[2]: 782 if m.startswith("="): 783 self.jname = m[1:] 784 self.base = '' 785 if decl[1]: 786 #self.base = re.sub(r"\b"+self.jname+r"\b", "", decl[1].replace(":", "")).strip() 787 self.base = re.sub(r"^.*:", "", decl[1].split(",")[0]).strip().replace(self.jname, "") 788 789 def __repr__(self): 790 return Template("CLASS $namespace.$classpath.$name : $base").substitute(**self.__dict__) 791 792 def getAllImports(self, module): 793 return ["import %s;" % c for c in sorted(self.imports) if not c.startswith('org.opencv.'+module)] 794 795 def addImports(self, ctype): 796 if ctype.startswith('vector_vector'): 797 self.imports.add("org.opencv.core.Mat") 798 self.imports.add("org.opencv.utils.Converters") 799 self.imports.add("java.util.List") 800 self.imports.add("java.util.ArrayList") 801 self.addImports(ctype.replace('vector_vector', 'vector')) 802 elif ctype.startswith('vector'): 803 self.imports.add("org.opencv.core.Mat") 804 self.imports.add('java.util.ArrayList') 805 if type_dict[ctype]['j_type'].startswith('MatOf'): 806 self.imports.add("org.opencv.core." + type_dict[ctype]['j_type']) 807 else: 808 self.imports.add("java.util.List") 809 self.imports.add("org.opencv.utils.Converters") 810 self.addImports(ctype.replace('vector_', '')) 811 else: 812 j_type = '' 813 if ctype in type_dict: 814 j_type = type_dict[ctype]['j_type'] 815 elif ctype in ("Algorithm"): 816 j_type = ctype 817 if j_type in ( "CvType", "Mat", "Point", "Point3", "Range", "Rect", "RotatedRect", "Scalar", "Size", "TermCriteria", "Algorithm" ): 818 self.imports.add("org.opencv.core." + j_type) 819 if j_type == 'String': 820 self.imports.add("java.lang.String") 821 822 def getAllMethods(self): 823 result = [] 824 result.extend([fi for fi in sorted(self.methods) if fi.isconstructor]) 825 result.extend([fi for fi in sorted(self.methods) if not fi.isconstructor]) 826 return result 827 828 def addMethod(self, fi): 829 self.methods.append(fi) 830 831 def getConst(self, name): 832 for cand in self.consts + self.private_consts: 833 if cand.name == name: 834 return cand 835 return None 836 837 def addConst(self, constinfo): 838 # choose right list (public or private) 839 consts = self.consts 840 for c in const_private_list: 841 if re.match(c, constinfo.name): 842 consts = self.private_consts 843 break 844 consts.append(constinfo) 845 846 def initCodeStreams(self, Module): 847 self.j_code = StringIO() 848 self.jn_code = StringIO() 849 self.cpp_code = StringIO(); 850 if self.name != Module: 851 self.j_code.write(T_JAVA_START_INHERITED if self.base else T_JAVA_START_ORPHAN) 852 else: 853 self.j_code.write(T_JAVA_START_MODULE) 854 # misc handling 855 if self.name == 'Core': 856 self.imports.add("java.lang.String") 857 self.j_code.write(libVersionBlock()) 858 859 def cleanupCodeStreams(self): 860 self.j_code.close() 861 self.jn_code.close() 862 self.cpp_code.close() 863 864 def generateJavaCode(self, m, M): 865 return Template(self.j_code.getvalue() + "\n\n" + \ 866 self.jn_code.getvalue() + "\n}\n").substitute(\ 867 module = m, 868 name = self.name, 869 jname = self.jname, 870 imports = "\n".join(self.getAllImports(M)), 871 base = self.base) 872 873 def generateCppCode(self): 874 return self.cpp_code.getvalue() 875 876class ArgInfo(): 877 def __init__(self, arg_tuple): # [ ctype, name, def val, [mod], argno ] 878 self.pointer = False 879 ctype = arg_tuple[0] 880 if ctype.endswith("*"): 881 ctype = ctype[:-1] 882 self.pointer = True 883 if ctype == 'vector_Point2d': 884 ctype = 'vector_Point2f' 885 elif ctype == 'vector_Point3d': 886 ctype = 'vector_Point3f' 887 self.ctype = ctype 888 self.name = arg_tuple[1] 889 self.defval = arg_tuple[2] 890 self.out = "" 891 if "/O" in arg_tuple[3]: 892 self.out = "O" 893 if "/IO" in arg_tuple[3]: 894 self.out = "IO" 895 896 def __repr__(self): 897 return Template("ARG $ctype$p $name=$defval").substitute(ctype=self.ctype, 898 p=" *" if self.pointer else "", 899 name=self.name, 900 defval=self.defval) 901 902class FuncInfo(GeneralInfo): 903 def __init__(self, decl, namespaces=[]): # [ funcname, return_ctype, [modifiers], [args] ] 904 GeneralInfo.__init__(self, decl[0], namespaces) 905 self.cname = self.name.replace(".", "::") 906 self.jname = self.name 907 self.isconstructor = self.name == self.classname 908 if "[" in self.name: 909 self.jname = "getelem" 910 for m in decl[2]: 911 if m.startswith("="): 912 self.jname = m[1:] 913 self.static = ["","static"][ "/S" in decl[2] ] 914 self.ctype = re.sub(r"^CvTermCriteria", "TermCriteria", decl[1] or "") 915 self.args = [] 916 func_fix_map = func_arg_fix.get(self.classname, {}).get(self.jname, {}) 917 for a in decl[3]: 918 arg = a[:] 919 arg_fix_map = func_fix_map.get(arg[1], {}) 920 arg[0] = arg_fix_map.get('ctype', arg[0]) #fixing arg type 921 arg[3] = arg_fix_map.get('attrib', arg[3]) #fixing arg attrib 922 self.args.append(ArgInfo(arg)) 923 924 def __repr__(self): 925 return Template("FUNC <$ctype $namespace.$classpath.$name $args>").substitute(**self.__dict__) 926 927class JavaWrapperGenerator(object): 928 def __init__(self): 929 self.clear() 930 931 def clear(self): 932 self.namespaces = set(["cv"]) 933 self.classes = { "Mat" : ClassInfo([ 'class Mat', '', [], [] ], self.namespaces) } 934 self.module = "" 935 self.Module = "" 936 self.ported_func_list = [] 937 self.skipped_func_list = [] 938 self.def_args_hist = {} # { def_args_cnt : funcs_cnt } 939 940 def add_class(self, decl): 941 classinfo = ClassInfo(decl, namespaces=self.namespaces) 942 if classinfo.name in class_ignore_list: 943 logging.info('ignored: %s', classinfo) 944 return 945 name = classinfo.name 946 if self.isWrapped(name): 947 logging.warning('duplicated: %s', classinfo) 948 return 949 self.classes[name] = classinfo 950 if name in type_dict: 951 logging.warning('duplicated: %s', classinfo) 952 return 953 type_dict[name] = \ 954 { "j_type" : classinfo.jname, 955 "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), 956 "jni_name" : "(*("+classinfo.fullName(isCPP=True)+"*)%(n)s_nativeObj)", "jni_type" : "jlong", 957 "suffix" : "J" } 958 type_dict[name+'*'] = \ 959 { "j_type" : classinfo.jname, 960 "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), 961 "jni_name" : "("+classinfo.fullName(isCPP=True)+"*)%(n)s_nativeObj", "jni_type" : "jlong", 962 "suffix" : "J" } 963 964 # missing_consts { Module : { public : [[name, val],...], private : [[]...] } } 965 if name in missing_consts: 966 if 'private' in missing_consts[name]: 967 for (n, val) in missing_consts[name]['private']: 968 classinfo.private_consts.append( ConstInfo([n, val], addedManually=True) ) 969 if 'public' in missing_consts[name]: 970 for (n, val) in missing_consts[name]['public']: 971 classinfo.consts.append( ConstInfo([n, val], addedManually=True) ) 972 973 # class props 974 for p in decl[3]: 975 if True: #"vector" not in p[0]: 976 classinfo.props.append( ClassPropInfo(p) ) 977 else: 978 logging.warning("Skipped property: [%s]" % name, p) 979 980 if classinfo.base: 981 classinfo.addImports(classinfo.base) 982 type_dict["Ptr_"+name] = \ 983 { "j_type" : name, 984 "jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),), 985 "jni_name" : "Ptr<"+name+">(("+name+"*)%(n)s_nativeObj)", "jni_type" : "jlong", 986 "suffix" : "J" } 987 logging.info('ok: %s', classinfo) 988 989 def add_const(self, decl): # [ "const cname", val, [], [] ] 990 constinfo = ConstInfo(decl, namespaces=self.namespaces) 991 if constinfo.isIgnored(): 992 logging.info('ignored: %s', constinfo) 993 elif not self.isWrapped(constinfo.classname): 994 logging.info('class not found: %s', constinfo) 995 else: 996 ci = self.getClass(constinfo.classname) 997 duplicate = ci.getConst(constinfo.name) 998 if duplicate: 999 if duplicate.addedManually: 1000 logging.info('manual: %s', constinfo) 1001 else: 1002 logging.warning('duplicated: %s', constinfo) 1003 else: 1004 ci.addConst(constinfo) 1005 logging.info('ok: %s', constinfo) 1006 1007 def add_func(self, decl): 1008 fi = FuncInfo(decl, namespaces=self.namespaces) 1009 classname = fi.classname or self.Module 1010 if classname in class_ignore_list: 1011 logging.info('ignored: %s', fi) 1012 elif classname in ManualFuncs and fi.jname in ManualFuncs[classname]: 1013 logging.info('manual: %s', fi) 1014 elif not self.isWrapped(classname): 1015 logging.warning('not found: %s', fi) 1016 else: 1017 self.getClass(classname).addMethod(fi) 1018 logging.info('ok: %s', fi) 1019 # calc args with def val 1020 cnt = len([a for a in fi.args if a.defval]) 1021 self.def_args_hist[cnt] = self.def_args_hist.get(cnt, 0) + 1 1022 1023 def save(self, path, buf): 1024 f = open(path, "wt") 1025 f.write(buf) 1026 f.close() 1027 1028 def gen(self, srcfiles, module, output_path): 1029 self.clear() 1030 self.module = module 1031 self.Module = module.capitalize() 1032 parser = hdr_parser.CppHeaderParser() 1033 1034 self.add_class( ['class ' + self.Module, '', [], []] ) # [ 'class/struct cname', ':bases', [modlist] [props] ] 1035 1036 # scan the headers and build more descriptive maps of classes, consts, functions 1037 includes = []; 1038 for hdr in srcfiles: 1039 decls = parser.parse(hdr) 1040 self.namespaces = parser.namespaces 1041 logging.info("\n\n===== Header: %s =====", hdr) 1042 logging.info("Namespaces: %s", parser.namespaces) 1043 if decls: 1044 includes.append('#include "' + hdr + '"') 1045 for decl in decls: 1046 logging.info("\n--- Incoming ---\n%s", pformat(decl, 4)) 1047 name = decl[0] 1048 if name.startswith("struct") or name.startswith("class"): 1049 self.add_class(decl) 1050 elif name.startswith("const"): 1051 self.add_const(decl) 1052 else: # function 1053 self.add_func(decl) 1054 1055 logging.info("\n\n===== Generating... =====") 1056 moduleCppCode = StringIO() 1057 for ci in self.classes.values(): 1058 if ci.name == "Mat": 1059 continue 1060 ci.initCodeStreams(self.Module) 1061 self.gen_class(ci) 1062 classJavaCode = ci.generateJavaCode(self.module, self.Module) 1063 self.save("%s/%s+%s.java" % (output_path, module, ci.jname), classJavaCode) 1064 moduleCppCode.write(ci.generateCppCode()) 1065 ci.cleanupCodeStreams() 1066 self.save(output_path+"/"+module+".cpp", Template(T_CPP_MODULE).substitute(m = module, M = module.upper(), code = moduleCppCode.getvalue(), includes = "\n".join(includes))) 1067 self.save(output_path+"/"+module+".txt", self.makeReport()) 1068 1069 def makeReport(self): 1070 ''' 1071 Returns string with generator report 1072 ''' 1073 report = StringIO() 1074 total_count = len(self.ported_func_list)+ len(self.skipped_func_list) 1075 report.write("PORTED FUNCs LIST (%i of %i):\n\n" % (len(self.ported_func_list), total_count)) 1076 report.write("\n".join(self.ported_func_list)) 1077 report.write("\n\nSKIPPED FUNCs LIST (%i of %i):\n\n" % (len(self.skipped_func_list), total_count)) 1078 report.write("".join(self.skipped_func_list)) 1079 for i in self.def_args_hist.keys(): 1080 report.write("\n%i def args - %i funcs" % (i, self.def_args_hist[i])) 1081 return report.getvalue() 1082 1083 def fullTypeName(self, t): 1084 if self.isWrapped(t): 1085 return self.getClass(t).fullName(isCPP=True) 1086 else: 1087 return t 1088 1089 def gen_func(self, ci, fi, prop_name=''): 1090 logging.info("%s", fi) 1091 j_code = ci.j_code 1092 jn_code = ci.jn_code 1093 cpp_code = ci.cpp_code 1094 1095 # c_decl 1096 # e.g: void add(Mat src1, Mat src2, Mat dst, Mat mask = Mat(), int dtype = -1) 1097 if prop_name: 1098 c_decl = "%s %s::%s" % (fi.ctype, fi.classname, prop_name) 1099 else: 1100 decl_args = [] 1101 for a in fi.args: 1102 s = a.ctype or ' _hidden_ ' 1103 if a.pointer: 1104 s += "*" 1105 elif a.out: 1106 s += "&" 1107 s += " " + a.name 1108 if a.defval: 1109 s += " = "+a.defval 1110 decl_args.append(s) 1111 c_decl = "%s %s %s(%s)" % ( fi.static, fi.ctype, fi.cname, ", ".join(decl_args) ) 1112 1113 # java comment 1114 j_code.write( "\n //\n // C++: %s\n //\n\n" % c_decl ) 1115 # check if we 'know' all the types 1116 if fi.ctype not in type_dict: # unsupported ret type 1117 msg = "// Return type '%s' is not supported, skipping the function\n\n" % fi.ctype 1118 self.skipped_func_list.append(c_decl + "\n" + msg) 1119 j_code.write( " "*4 + msg ) 1120 logging.warning("SKIP:" + c_decl.strip() + "\t due to RET type" + fi.ctype) 1121 return 1122 for a in fi.args: 1123 if a.ctype not in type_dict: 1124 if not a.defval and a.ctype.endswith("*"): 1125 a.defval = 0 1126 if a.defval: 1127 a.ctype = '' 1128 continue 1129 msg = "// Unknown type '%s' (%s), skipping the function\n\n" % (a.ctype, a.out or "I") 1130 self.skipped_func_list.append(c_decl + "\n" + msg) 1131 j_code.write( " "*4 + msg ) 1132 logging.warning("SKIP:" + c_decl.strip() + "\t due to ARG type" + a.ctype + "/" + (a.out or "I")) 1133 return 1134 1135 self.ported_func_list.append(c_decl) 1136 1137 # jn & cpp comment 1138 jn_code.write( "\n // C++: %s\n" % c_decl ) 1139 cpp_code.write( "\n//\n// %s\n//\n" % c_decl ) 1140 1141 # java args 1142 args = fi.args[:] # copy 1143 suffix_counter = int(ci.methods_suffixes.get(fi.jname, -1)) 1144 while True: 1145 suffix_counter += 1 1146 ci.methods_suffixes[fi.jname] = suffix_counter 1147 # java native method args 1148 jn_args = [] 1149 # jni (cpp) function args 1150 jni_args = [ArgInfo([ "env", "env", "", [], "" ]), ArgInfo([ "cls", "", "", [], "" ])] 1151 j_prologue = [] 1152 j_epilogue = [] 1153 c_prologue = [] 1154 c_epilogue = [] 1155 if type_dict[fi.ctype]["jni_type"] == "jdoubleArray": 1156 fields = type_dict[fi.ctype]["jn_args"] 1157 c_epilogue.append( \ 1158 ("jdoubleArray _da_retval_ = env->NewDoubleArray(%(cnt)i); " + 1159 "jdouble _tmp_retval_[%(cnt)i] = {%(args)s}; " + 1160 "env->SetDoubleArrayRegion(_da_retval_, 0, %(cnt)i, _tmp_retval_);") % 1161 { "cnt" : len(fields), "args" : ", ".join(["_retval_" + f[1] for f in fields]) } ) 1162 if fi.classname and fi.ctype and not fi.static: # non-static class method except c-tor 1163 # adding 'self' 1164 jn_args.append ( ArgInfo([ "__int64", "nativeObj", "", [], "" ]) ) 1165 jni_args.append( ArgInfo([ "__int64", "self", "", [], "" ]) ) 1166 ci.addImports(fi.ctype) 1167 for a in args: 1168 if not a.ctype: # hidden 1169 continue 1170 ci.addImports(a.ctype) 1171 if "vector" in a.ctype: # pass as Mat 1172 jn_args.append ( ArgInfo([ "__int64", "%s_mat.nativeObj" % a.name, "", [], "" ]) ) 1173 jni_args.append ( ArgInfo([ "__int64", "%s_mat_nativeObj" % a.name, "", [], "" ]) ) 1174 c_prologue.append( type_dict[a.ctype]["jni_var"] % {"n" : a.name} + ";" ) 1175 c_prologue.append( "Mat& %(n)s_mat = *((Mat*)%(n)s_mat_nativeObj)" % {"n" : a.name} + ";" ) 1176 if "I" in a.out or not a.out: 1177 if a.ctype.startswith("vector_vector_"): 1178 j_prologue.append( "List<Mat> %(n)s_tmplm = new ArrayList<Mat>((%(n)s != null) ? %(n)s.size() : 0);" % {"n" : a.name } ) 1179 j_prologue.append( "Mat %(n)s_mat = Converters.%(t)s_to_Mat(%(n)s, %(n)s_tmplm);" % {"n" : a.name, "t" : a.ctype} ) 1180 else: 1181 if not type_dict[a.ctype]["j_type"].startswith("MatOf"): 1182 j_prologue.append( "Mat %(n)s_mat = Converters.%(t)s_to_Mat(%(n)s);" % {"n" : a.name, "t" : a.ctype} ) 1183 else: 1184 j_prologue.append( "Mat %s_mat = %s;" % (a.name, a.name) ) 1185 c_prologue.append( "Mat_to_%(t)s( %(n)s_mat, %(n)s );" % {"n" : a.name, "t" : a.ctype} ) 1186 else: 1187 if not type_dict[a.ctype]["j_type"].startswith("MatOf"): 1188 j_prologue.append( "Mat %s_mat = new Mat();" % a.name ) 1189 else: 1190 j_prologue.append( "Mat %s_mat = %s;" % (a.name, a.name) ) 1191 if "O" in a.out: 1192 if not type_dict[a.ctype]["j_type"].startswith("MatOf"): 1193 j_epilogue.append("Converters.Mat_to_%(t)s(%(n)s_mat, %(n)s);" % {"t" : a.ctype, "n" : a.name}) 1194 j_epilogue.append( "%s_mat.release();" % a.name ) 1195 c_epilogue.append( "%(t)s_to_Mat( %(n)s, %(n)s_mat );" % {"n" : a.name, "t" : a.ctype} ) 1196 else: 1197 fields = type_dict[a.ctype].get("jn_args", ((a.ctype, ""),)) 1198 if "I" in a.out or not a.out or self.isWrapped(a.ctype): # input arg, pass by primitive fields 1199 for f in fields: 1200 jn_args.append ( ArgInfo([ f[0], a.name + f[1], "", [], "" ]) ) 1201 jni_args.append( ArgInfo([ f[0], a.name + f[1].replace(".","_").replace("[","").replace("]",""), "", [], "" ]) ) 1202 if a.out and not self.isWrapped(a.ctype): # out arg, pass as double[] 1203 jn_args.append ( ArgInfo([ "double[]", "%s_out" % a.name, "", [], "" ]) ) 1204 jni_args.append ( ArgInfo([ "double[]", "%s_out" % a.name, "", [], "" ]) ) 1205 j_prologue.append( "double[] %s_out = new double[%i];" % (a.name, len(fields)) ) 1206 c_epilogue.append( \ 1207 "jdouble tmp_%(n)s[%(cnt)i] = {%(args)s}; env->SetDoubleArrayRegion(%(n)s_out, 0, %(cnt)i, tmp_%(n)s);" % 1208 { "n" : a.name, "cnt" : len(fields), "args" : ", ".join([a.name + f[1] for f in fields]) } ) 1209 if a.ctype in ('bool', 'int', 'long', 'float', 'double'): 1210 j_epilogue.append('if(%(n)s!=null) %(n)s[0] = (%(t)s)%(n)s_out[0];' % {'n':a.name,'t':a.ctype}) 1211 else: 1212 set_vals = [] 1213 i = 0 1214 for f in fields: 1215 set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" % 1216 {"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1], "i" : i} 1217 ) 1218 i += 1 1219 j_epilogue.append( "if("+a.name+"!=null){ " + "; ".join(set_vals) + "; } ") 1220 1221 1222 # java part: 1223 # private java NATIVE method decl 1224 # e.g. 1225 # private static native void add_0(long src1, long src2, long dst, long mask, int dtype); 1226 jn_code.write( Template(\ 1227 " private static native $type $name($args);\n").substitute(\ 1228 type = type_dict[fi.ctype].get("jn_type", "double[]"), \ 1229 name = fi.jname + '_' + str(suffix_counter), \ 1230 args = ", ".join(["%s %s" % (type_dict[a.ctype]["jn_type"], a.name.replace(".","_").replace("[","").replace("]","")) for a in jn_args]) 1231 ) ); 1232 1233 # java part: 1234 1235 #java doc comment 1236 f_name = fi.name 1237 if fi.classname: 1238 f_name = fi.classname + "::" + fi.name 1239 java_doc = "//javadoc: " + f_name + "(%s)" % ", ".join([a.name for a in args if a.ctype]) 1240 j_code.write(" "*4 + java_doc + "\n") 1241 1242 # public java wrapper method impl (calling native one above) 1243 # e.g. 1244 # public static void add( Mat src1, Mat src2, Mat dst, Mat mask, int dtype ) 1245 # { add_0( src1.nativeObj, src2.nativeObj, dst.nativeObj, mask.nativeObj, dtype ); } 1246 ret_type = fi.ctype 1247 if fi.ctype.endswith('*'): 1248 ret_type = ret_type[:-1] 1249 ret_val = type_dict[ret_type]["j_type"] + " retVal = " 1250 tail = "" 1251 ret = "return retVal;" 1252 if ret_type.startswith('vector'): 1253 tail = ")" 1254 j_type = type_dict[ret_type]["j_type"] 1255 if j_type.startswith('MatOf'): 1256 ret_val += j_type + ".fromNativeAddr(" 1257 else: 1258 ret_val = "Mat retValMat = new Mat(" 1259 j_prologue.append( j_type + ' retVal = new Array' + j_type+'();') 1260 j_epilogue.append('Converters.Mat_to_' + ret_type + '(retValMat, retVal);') 1261 elif ret_type.startswith("Ptr_"): 1262 ret_val = type_dict[fi.ctype]["j_type"] + " retVal = new " + type_dict[ret_type]["j_type"] + "(" 1263 tail = ")" 1264 elif ret_type == "void": 1265 ret_val = "" 1266 ret = "return;" 1267 elif ret_type == "": # c-tor 1268 if fi.classname and ci.base: 1269 ret_val = "super( " 1270 tail = " )" 1271 else: 1272 ret_val = "nativeObj = " 1273 ret = "return;" 1274 elif self.isWrapped(ret_type): # wrapped class 1275 ret_val = type_dict[ret_type]["j_type"] + " retVal = new " + self.getClass(ret_type).jname + "(" 1276 tail = ")" 1277 elif "jn_type" not in type_dict[ret_type]: 1278 ret_val = type_dict[fi.ctype]["j_type"] + " retVal = new " + type_dict[ret_type]["j_type"] + "(" 1279 tail = ")" 1280 1281 static = "static" 1282 if fi.classname: 1283 static = fi.static 1284 1285 j_args = [] 1286 for a in args: 1287 if not a.ctype: #hidden 1288 continue 1289 jt = type_dict[a.ctype]["j_type"] 1290 if a.out and a.ctype in ('bool', 'int', 'long', 'float', 'double'): 1291 jt += '[]' 1292 j_args.append( jt + ' ' + a.name ) 1293 1294 j_code.write( Template(\ 1295""" public $static $j_type $j_name($j_args) 1296 { 1297 $prologue 1298 $ret_val$jn_name($jn_args_call)$tail; 1299 $epilogue 1300 $ret 1301 } 1302 1303""" 1304 ).substitute(\ 1305 ret = ret, \ 1306 ret_val = ret_val, \ 1307 tail = tail, \ 1308 prologue = "\n ".join(j_prologue), \ 1309 epilogue = "\n ".join(j_epilogue), \ 1310 static=static, \ 1311 j_type=type_dict[fi.ctype]["j_type"], \ 1312 j_name=fi.jname, \ 1313 j_args=", ".join(j_args), \ 1314 jn_name=fi.jname + '_' + str(suffix_counter), \ 1315 jn_args_call=", ".join( [a.name for a in jn_args] ),\ 1316 ) 1317 ) 1318 1319 1320 # cpp part: 1321 # jni_func(..) { _retval_ = cv_func(..); return _retval_; } 1322 ret = "return _retval_;" 1323 default = "return 0;" 1324 if fi.ctype == "void": 1325 ret = "return;" 1326 default = "return;" 1327 elif not fi.ctype: # c-tor 1328 ret = "return (jlong) _retval_;" 1329 elif fi.ctype.startswith('vector'): # c-tor 1330 ret = "return (jlong) _retval_;" 1331 elif fi.ctype == "String": 1332 ret = "return env->NewStringUTF(_retval_.c_str());" 1333 default = 'return env->NewStringUTF("");' 1334 elif self.isWrapped(fi.ctype): # wrapped class: 1335 ret = "return (jlong) new %s(_retval_);" % self.fullTypeName(fi.ctype) 1336 elif fi.ctype.startswith('Ptr_'): 1337 c_prologue.append("typedef Ptr<%s> %s;" % (self.fullTypeName(fi.ctype[4:]), fi.ctype)) 1338 ret = "return (jlong)(new %(ctype)s(_retval_));" % { 'ctype':fi.ctype } 1339 elif self.isWrapped(ret_type): # pointer to wrapped class: 1340 ret = "return (jlong) _retval_;" 1341 elif type_dict[fi.ctype]["jni_type"] == "jdoubleArray": 1342 ret = "return _da_retval_;" 1343 1344 # hack: replacing func call with property set/get 1345 name = fi.name 1346 if prop_name: 1347 if args: 1348 name = prop_name + " = " 1349 else: 1350 name = prop_name + ";//" 1351 1352 cvname = fi.fullName(isCPP=True) 1353 retval = self.fullTypeName(fi.ctype) + " _retval_ = " 1354 if fi.ctype == "void": 1355 retval = "" 1356 elif fi.ctype == "String": 1357 retval = "cv::" + retval 1358 elif fi.ctype.startswith('vector'): 1359 retval = type_dict[fi.ctype]['jni_var'] % {"n" : '_ret_val_vector_'} + " = " 1360 c_epilogue.append("Mat* _retval_ = new Mat();") 1361 c_epilogue.append(fi.ctype+"_to_Mat(_ret_val_vector_, *_retval_);") 1362 if len(fi.classname)>0: 1363 if not fi.ctype: # c-tor 1364 retval = fi.fullClass(isCPP=True) + "* _retval_ = " 1365 cvname = "new " + fi.fullClass(isCPP=True) 1366 elif fi.static: 1367 cvname = fi.fullName(isCPP=True) 1368 else: 1369 cvname = ("me->" if not self.isSmartClass(fi.classname) else "(*me)->") + name 1370 c_prologue.append(\ 1371 "%(cls)s* me = (%(cls)s*) self; //TODO: check for NULL" \ 1372 % { "cls" : self.smartWrap(fi.classname, fi.fullClass(isCPP=True))} \ 1373 ) 1374 cvargs = [] 1375 for a in args: 1376 if a.pointer: 1377 jni_name = "&%(n)s" 1378 else: 1379 jni_name = "%(n)s" 1380 if not a.out and not "jni_var" in type_dict[a.ctype]: 1381 # explicit cast to C type to avoid ambiguous call error on platforms (mingw) 1382 # where jni types are different from native types (e.g. jint is not the same as int) 1383 jni_name = "(%s)%s" % (a.ctype, jni_name) 1384 if not a.ctype: # hidden 1385 jni_name = a.defval 1386 cvargs.append( type_dict[a.ctype].get("jni_name", jni_name) % {"n" : a.name}) 1387 if "vector" not in a.ctype : 1388 if ("I" in a.out or not a.out or self.isWrapped(a.ctype)) and "jni_var" in type_dict[a.ctype]: # complex type 1389 c_prologue.append(type_dict[a.ctype]["jni_var"] % {"n" : a.name} + ";") 1390 if a.out and "I" not in a.out and not self.isWrapped(a.ctype) and a.ctype: 1391 c_prologue.append("%s %s;" % (a.ctype, a.name)) 1392 1393 rtype = type_dict[fi.ctype].get("jni_type", "jdoubleArray") 1394 clazz = ci.jname 1395 cpp_code.write ( Template( \ 1396""" 1397JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname ($argst); 1398 1399JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname 1400 ($args) 1401{ 1402 static const char method_name[] = "$module::$fname()"; 1403 try { 1404 LOGD("%s", method_name); 1405 $prologue 1406 $retval$cvname( $cvargs ); 1407 $epilogue$ret 1408 } catch(const std::exception &e) { 1409 throwJavaException(env, &e, method_name); 1410 } catch (...) { 1411 throwJavaException(env, 0, method_name); 1412 } 1413 $default 1414} 1415 1416 1417""" ).substitute( \ 1418 rtype = rtype, \ 1419 module = self.module, \ 1420 clazz = clazz.replace('_', '_1'), \ 1421 fname = (fi.jname + '_' + str(suffix_counter)).replace('_', '_1'), \ 1422 args = ", ".join(["%s %s" % (type_dict[a.ctype].get("jni_type"), a.name) for a in jni_args]), \ 1423 argst = ", ".join([type_dict[a.ctype].get("jni_type") for a in jni_args]), \ 1424 prologue = "\n ".join(c_prologue), \ 1425 epilogue = " ".join(c_epilogue) + ("\n " if c_epilogue else ""), \ 1426 ret = ret, \ 1427 cvname = cvname, \ 1428 cvargs = ", ".join(cvargs), \ 1429 default = default, \ 1430 retval = retval, \ 1431 ) ) 1432 1433 # processing args with default values 1434 if not args or not args[-1].defval: 1435 break 1436 while args and args[-1].defval: 1437 # 'smart' overloads filtering 1438 a = args.pop() 1439 if a.name in ('mask', 'dtype', 'ddepth', 'lineType', 'borderType', 'borderMode', 'criteria'): 1440 break 1441 1442 1443 1444 def gen_class(self, ci): 1445 logging.info("%s", ci) 1446 # constants 1447 if ci.private_consts: 1448 logging.info("%s", ci.private_consts) 1449 ci.j_code.write(""" 1450 private static final int 1451 %s;\n\n""" % (",\n"+" "*12).join(["%s = %s" % (c.name, c.value) for c in ci.private_consts]) 1452 ) 1453 if ci.consts: 1454 logging.info("%s", ci.consts) 1455 ci.j_code.write(""" 1456 public static final int 1457 %s;\n\n""" % (",\n"+" "*12).join(["%s = %s" % (c.name, c.value) for c in ci.consts]) 1458 ) 1459 # methods 1460 for fi in ci.getAllMethods(): 1461 self.gen_func(ci, fi) 1462 # props 1463 for pi in ci.props: 1464 # getter 1465 getter_name = ci.fullName() + ".get_" + pi.name 1466 fi = FuncInfo( [getter_name, pi.ctype, [], []], self.namespaces ) # [ funcname, return_ctype, [modifiers], [args] ] 1467 self.gen_func(ci, fi, pi.name) 1468 if pi.rw: 1469 #setter 1470 setter_name = ci.fullName() + ".set_" + pi.name 1471 fi = FuncInfo( [ setter_name, "void", [], [ [pi.ctype, pi.name, "", [], ""] ] ], self.namespaces) 1472 self.gen_func(ci, fi, pi.name) 1473 1474 # manual ports 1475 if ci.name in ManualFuncs: 1476 for func in ManualFuncs[ci.name].keys(): 1477 ci.j_code.write ( ManualFuncs[ci.name][func]["j_code"] ) 1478 ci.jn_code.write( ManualFuncs[ci.name][func]["jn_code"] ) 1479 ci.cpp_code.write( ManualFuncs[ci.name][func]["cpp_code"] ) 1480 1481 if ci.name != self.Module: 1482 # finalize() 1483 ci.j_code.write( 1484""" 1485 @Override 1486 protected void finalize() throws Throwable { 1487 delete(nativeObj); 1488 } 1489""" ) 1490 1491 ci.jn_code.write( 1492""" 1493 // native support for java finalize() 1494 private static native void delete(long nativeObj); 1495""" ) 1496 1497 # native support for java finalize() 1498 ci.cpp_code.write( \ 1499""" 1500// 1501// native support for java finalize() 1502// static void %(cls)s::delete( __int64 self ) 1503// 1504JNIEXPORT void JNICALL Java_org_opencv_%(module)s_%(j_cls)s_delete(JNIEnv*, jclass, jlong); 1505 1506JNIEXPORT void JNICALL Java_org_opencv_%(module)s_%(j_cls)s_delete 1507 (JNIEnv*, jclass, jlong self) 1508{ 1509 delete (%(cls)s*) self; 1510} 1511 1512""" % {"module" : module, "cls" : self.smartWrap(ci.name, ci.fullName(isCPP=True)), "j_cls" : ci.jname.replace('_', '_1')} 1513 ) 1514 1515 def getClass(self, classname): 1516 return self.classes[classname or self.Module] 1517 1518 def isWrapped(self, classname): 1519 name = classname or self.Module 1520 return name in self.classes 1521 1522 def isSmartClass(self, classname): 1523 ''' 1524 Check if class stores Ptr<T>* instead of T* in nativeObj field 1525 ''' 1526 return self.isWrapped(classname) and self.classes[classname].base 1527 1528 def smartWrap(self, name, fullname): 1529 ''' 1530 Wraps fullname with Ptr<> if needed 1531 ''' 1532 if self.isSmartClass(name): 1533 return "Ptr<" + fullname + ">" 1534 return fullname 1535 1536 1537if __name__ == "__main__": 1538 if len(sys.argv) < 4: 1539 print("Usage:\n", \ 1540 os.path.basename(sys.argv[0]), \ 1541 "<full path to hdr_parser.py> <module name> <C++ header> [<C++ header>...]") 1542 print("Current args are: ", ", ".join(["'"+a+"'" for a in sys.argv])) 1543 exit(0) 1544 1545 dstdir = "." 1546 hdr_parser_path = os.path.abspath(sys.argv[1]) 1547 if hdr_parser_path.endswith(".py"): 1548 hdr_parser_path = os.path.dirname(hdr_parser_path) 1549 sys.path.append(hdr_parser_path) 1550 import hdr_parser 1551 module = sys.argv[2] 1552 srcfiles = sys.argv[3:] 1553 logging.basicConfig(filename='%s/%s.log' % (dstdir, module), format=None, filemode='w', level=logging.INFO) 1554 handler = logging.StreamHandler() 1555 handler.setLevel(logging.WARNING) 1556 logging.getLogger().addHandler(handler) 1557 #print("Generating module '" + module + "' from headers:\n\t" + "\n\t".join(srcfiles)) 1558 generator = JavaWrapperGenerator() 1559 generator.gen(srcfiles, module, dstdir) 1560