mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
cmake: Java/Android SDK refactoring
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
set(MODULE_NAME "java_bindings_generator")
|
||||
set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE)
|
||||
ocv_add_module(${MODULE_NAME} INTERNAL)
|
||||
|
||||
set(OPENCV_JAVA_SIGNATURES_FILE "${CMAKE_CURRENT_BINARY_DIR}/opencv_java_signatures.json" CACHE INTERNAL "")
|
||||
set(OPENCV_JAVA_BINDINGS_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "")
|
||||
|
||||
file(REMOVE_RECURSE "${OPENCV_JAVA_BINDINGS_DIR}/gen")
|
||||
file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_java_source") # force re-run after CMake
|
||||
|
||||
# This file is included from a subdirectory
|
||||
set(JAVA_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
include(${JAVA_SOURCE_DIR}/common.cmake)
|
||||
|
||||
set(__remap_config "") # list of remapped ".in" files (configure_file)
|
||||
set(__remap_targets "")
|
||||
|
||||
macro(ocv_remap_files files_list_var)
|
||||
set(target_dir "${OpenCV_BINARY_DIR}/configured")
|
||||
foreach(f ${${files_list_var}})
|
||||
if(NOT "${f}" MATCHES "^(.*)\\.in$")
|
||||
continue()
|
||||
endif()
|
||||
set(f_ "${CMAKE_MATCH_1}")
|
||||
file(RELATIVE_PATH rel_path0 "${OpenCV_SOURCE_DIR}" "${f}")
|
||||
file(RELATIVE_PATH rel_path1 "${OpenCV_SOURCE_DIR}" "${f_}")
|
||||
set(__target_file "${target_dir}/${rel_path1}")
|
||||
configure_file("${f}" "${__target_file}" @ONLY)
|
||||
if(__remap_config)
|
||||
set(__remap_config "${__remap_config},\n")
|
||||
endif()
|
||||
set(__remap_config "${__remap_config} { \"src\": \"${rel_path0}\", \"target\": \"${__target_file}\" }")
|
||||
list(APPEND __remap_targets "${__target_file}")
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
# common files
|
||||
file(GLOB_RECURSE deps "${CMAKE_CURRENT_SOURCE_DIR}/src/*" "${CMAKE_CURRENT_SOURCE_DIR}/android*/*" "${CMAKE_CURRENT_SOURCE_DIR}/templates/*")
|
||||
ocv_remap_files(deps)
|
||||
|
||||
set(__modules_config "") # list of OpenCV modules
|
||||
foreach(m ${OPENCV_JAVA_MODULES})
|
||||
set(module_java_dir "${OPENCV_MODULE_${m}_LOCATION}/misc/java")
|
||||
list(APPEND deps ${OPENCV_MODULE_${m}_HEADERS})
|
||||
file(GLOB_RECURSE misc_files "${module_java_dir}/*")
|
||||
list(APPEND deps ${misc_files})
|
||||
|
||||
string(REGEX REPLACE "^opencv_" "" m_ "${m}")
|
||||
if(__modules_config)
|
||||
set(__modules_config "${__modules_config},\n")
|
||||
endif()
|
||||
file(RELATIVE_PATH rel_path "${OpenCV_SOURCE_DIR}" "${OPENCV_MODULE_${m}_LOCATION}")
|
||||
set(__modules_config "${__modules_config} { \"name\": \"${m_}\", \"location\": \"${rel_path}\" }")
|
||||
|
||||
ocv_remap_files(misc_files)
|
||||
endforeach(m)
|
||||
|
||||
set(CONFIG_FILE "${CMAKE_CURRENT_BINARY_DIR}/gen_java.json")
|
||||
set(__config_str "\
|
||||
{
|
||||
\"rootdir\": \"${OpenCV_SOURCE_DIR}\",
|
||||
\"modules\": [
|
||||
${__modules_config}
|
||||
],
|
||||
\"files_remap\": [
|
||||
${__remap_config}
|
||||
]
|
||||
}
|
||||
")
|
||||
if(EXISTS "${CONFIG_FILE}")
|
||||
file(READ "${CONFIG_FILE}" __content)
|
||||
else()
|
||||
set(__content "")
|
||||
endif()
|
||||
if(NOT "${__content}" STREQUAL "${__config_str}")
|
||||
file(WRITE "${CONFIG_FILE}" "${__config_str}")
|
||||
file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_java_source")
|
||||
endif()
|
||||
unset(__config_str)
|
||||
|
||||
set(java_generated_files
|
||||
# "${OPENCV_JAVA_SIGNATURES_FILE}"
|
||||
"${OPENCV_DEPHELPER}/gen_opencv_java_source"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${java_generated_files}
|
||||
COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${JAVA_SOURCE_DIR}/generator/gen_java.py" -p "${JAVA_SOURCE_DIR}/../python/src2/gen2.py" -c "${CONFIG_FILE}"
|
||||
COMMAND ${CMAKE_COMMAND} -E touch "${OPENCV_DEPHELPER}/gen_opencv_java_source"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
DEPENDS "${JAVA_SOURCE_DIR}/generator/gen_java.py"
|
||||
"${JAVA_SOURCE_DIR}/../python/src2/gen2.py"
|
||||
"${JAVA_SOURCE_DIR}/../python/src2/hdr_parser.py"
|
||||
# don't, result of file(WRITE): "${CMAKE_CURRENT_BINARY_DIR}/gen_java.json"
|
||||
${deps} ${__remap_targets}
|
||||
# not allowed (file(WRITE) result): "${CONFIG_FILE}"
|
||||
COMMENT "Generate files for Java bindings"
|
||||
)
|
||||
|
||||
add_custom_target(gen_opencv_java_source DEPENDS ${java_generated_files}
|
||||
SOURCES "${JAVA_SOURCE_DIR}/generator/gen_java.py"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/gen_java.json"
|
||||
)
|
||||
+196
-175
@@ -1,8 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, re, os.path
|
||||
import sys, re, os.path, errno, fnmatch
|
||||
import json
|
||||
import logging
|
||||
from shutil import copyfile
|
||||
from pprint import pformat
|
||||
from string import Template
|
||||
|
||||
@@ -11,6 +12,26 @@ if sys.version_info[0] >= 3:
|
||||
else:
|
||||
from cStringIO import StringIO
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# list of modules + files remap
|
||||
config = None
|
||||
ROOT_DIR = None
|
||||
FILES_REMAP = {}
|
||||
def checkFileRemap(path):
|
||||
path = os.path.realpath(path)
|
||||
if path in FILES_REMAP:
|
||||
return FILES_REMAP[path]
|
||||
assert path[-3:] != '.in', path
|
||||
return path
|
||||
|
||||
total_files = 0
|
||||
updated_files = 0
|
||||
|
||||
module_imports = []
|
||||
module_j_code = None
|
||||
module_jn_code = None
|
||||
|
||||
# list of class names, which should be skipped by wrapper generator
|
||||
# the list is loaded from misc/java/gen_dict.json defined for the module and its dependencies
|
||||
class_ignore_list = []
|
||||
@@ -52,136 +73,25 @@ ManualFuncs = {}
|
||||
# { class : { func : { arg_name : {"ctype" : ctype, "attrib" : [attrib]} } } }
|
||||
func_arg_fix = {}
|
||||
|
||||
def getLibVersion(version_hpp_path):
|
||||
version_file = open(version_hpp_path, "rt").read()
|
||||
major = re.search("^W*#\W*define\W+CV_VERSION_MAJOR\W+(\d+)\W*$", version_file, re.MULTILINE).group(1)
|
||||
minor = re.search("^W*#\W*define\W+CV_VERSION_MINOR\W+(\d+)\W*$", version_file, re.MULTILINE).group(1)
|
||||
revision = re.search("^W*#\W*define\W+CV_VERSION_REVISION\W+(\d+)\W*$", version_file, re.MULTILINE).group(1)
|
||||
status = re.search("^W*#\W*define\W+CV_VERSION_STATUS\W+\"(.*?)\"\W*$", version_file, re.MULTILINE).group(1)
|
||||
return (major, minor, revision, status)
|
||||
def read_contents(fname):
|
||||
with open(fname, 'r') as f:
|
||||
data = f.read()
|
||||
return data
|
||||
|
||||
def libVersionBlock():
|
||||
(major, minor, revision, status) = getLibVersion(
|
||||
(os.path.dirname(__file__) or '.') + '/../../core/include/opencv2/core/version.hpp')
|
||||
version_str = '.'.join( (major, minor, revision) ) + status
|
||||
version_suffix = ''.join( (major, minor, revision) )
|
||||
return """
|
||||
// these constants are wrapped inside functions to prevent inlining
|
||||
private static String getVersion() { return "%(v)s"; }
|
||||
private static String getNativeLibraryName() { return "opencv_java%(vs)s"; }
|
||||
private static int getVersionMajor() { return %(ma)s; }
|
||||
private static int getVersionMinor() { return %(mi)s; }
|
||||
private static int getVersionRevision() { return %(re)s; }
|
||||
private static String getVersionStatus() { return "%(st)s"; }
|
||||
def mkdir_p(path):
|
||||
''' mkdir -p '''
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc:
|
||||
if exc.errno == errno.EEXIST and os.path.isdir(path):
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
|
||||
public static final String VERSION = getVersion();
|
||||
public static final String NATIVE_LIBRARY_NAME = getNativeLibraryName();
|
||||
public static final int VERSION_MAJOR = getVersionMajor();
|
||||
public static final int VERSION_MINOR = getVersionMinor();
|
||||
public static final int VERSION_REVISION = getVersionRevision();
|
||||
public static final String VERSION_STATUS = getVersionStatus();
|
||||
""" % { 'v' : version_str, 'vs' : version_suffix, 'ma' : major, 'mi' : minor, 're' : revision, 'st': status }
|
||||
|
||||
|
||||
T_JAVA_START_INHERITED = """
|
||||
//
|
||||
// This file is auto-generated. Please don't modify it!
|
||||
//
|
||||
package org.opencv.$module;
|
||||
|
||||
$imports
|
||||
|
||||
$docs
|
||||
$annotation
|
||||
public class $jname extends $base {
|
||||
|
||||
protected $jname(long addr) { super(addr); }
|
||||
|
||||
"""
|
||||
|
||||
T_JAVA_START_ORPHAN = """
|
||||
//
|
||||
// This file is auto-generated. Please don't modify it!
|
||||
//
|
||||
package org.opencv.$module;
|
||||
|
||||
$imports
|
||||
|
||||
$docs
|
||||
$annotation
|
||||
public class $jname {
|
||||
|
||||
protected final long nativeObj;
|
||||
protected $jname(long addr) { nativeObj = addr; }
|
||||
|
||||
public long getNativeObjAddr() { return nativeObj; }
|
||||
"""
|
||||
|
||||
T_JAVA_START_MODULE = """
|
||||
//
|
||||
// This file is auto-generated. Please don't modify it!
|
||||
//
|
||||
package org.opencv.$module;
|
||||
|
||||
$imports
|
||||
|
||||
$docs
|
||||
$annotation
|
||||
public class $jname {
|
||||
"""
|
||||
|
||||
T_CPP_MODULE = """
|
||||
//
|
||||
// This file is auto-generated, please don't edit!
|
||||
//
|
||||
|
||||
#define LOG_TAG "org.opencv.$m"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
#ifdef HAVE_OPENCV_$M
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "opencv2/$m.hpp"
|
||||
|
||||
$includes
|
||||
|
||||
using namespace cv;
|
||||
|
||||
/// throw java exception
|
||||
static void throwJavaException(JNIEnv *env, const std::exception *e, const char *method) {
|
||||
std::string what = "unknown exception";
|
||||
jclass je = 0;
|
||||
|
||||
if(e) {
|
||||
std::string exception_type = "std::exception";
|
||||
|
||||
if(dynamic_cast<const cv::Exception*>(e)) {
|
||||
exception_type = "cv::Exception";
|
||||
je = env->FindClass("org/opencv/core/CvException");
|
||||
}
|
||||
|
||||
what = exception_type + ": " + e->what();
|
||||
}
|
||||
|
||||
if(!je) je = env->FindClass("java/lang/Exception");
|
||||
env->ThrowNew(je, what.c_str());
|
||||
|
||||
LOGE("%s caught %s", method, what.c_str());
|
||||
(void)method; // avoid "unused" warning
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
$code
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // HAVE_OPENCV_$M
|
||||
"""
|
||||
T_JAVA_START_INHERITED = read_contents(os.path.join(SCRIPT_DIR, 'templates/java_class_inherited.prolog'))
|
||||
T_JAVA_START_ORPHAN = read_contents(os.path.join(SCRIPT_DIR, 'templates/java_class.prolog'))
|
||||
T_JAVA_START_MODULE = read_contents(os.path.join(SCRIPT_DIR, 'templates/java_module.prolog'))
|
||||
T_CPP_MODULE = Template(read_contents(os.path.join(SCRIPT_DIR, 'templates/cpp_module.template')))
|
||||
|
||||
class GeneralInfo():
|
||||
def __init__(self, type, decl, namespaces):
|
||||
@@ -195,7 +105,7 @@ class GeneralInfo():
|
||||
else:
|
||||
docstring=""
|
||||
if len(decl)>5 and decl[5]:
|
||||
logging.info('docstring: %s', decl[5])
|
||||
#logging.info('docstring: %s', decl[5])
|
||||
if re.search("(@|\\\\)deprecated", decl[5]):
|
||||
self.annotation.append("@Deprecated")
|
||||
|
||||
@@ -335,9 +245,13 @@ class ClassInfo(GeneralInfo):
|
||||
else:
|
||||
self.j_code.write(T_JAVA_START_MODULE)
|
||||
# misc handling
|
||||
if self.name == 'Core':
|
||||
self.imports.add("java.lang.String")
|
||||
self.j_code.write(libVersionBlock())
|
||||
if self.name == Module:
|
||||
for i in module_imports or []:
|
||||
self.imports.add(i)
|
||||
if module_j_code:
|
||||
self.j_code.write(module_j_code)
|
||||
if module_jn_code:
|
||||
self.jn_code.write(module_jn_code)
|
||||
|
||||
def cleanupCodeStreams(self):
|
||||
self.j_code.close()
|
||||
@@ -411,6 +325,7 @@ class FuncInfo(GeneralInfo):
|
||||
|
||||
class JavaWrapperGenerator(object):
|
||||
def __init__(self):
|
||||
self.cpp_files = []
|
||||
self.clear()
|
||||
|
||||
def clear(self):
|
||||
@@ -506,11 +421,18 @@ class JavaWrapperGenerator(object):
|
||||
self.def_args_hist[cnt] = self.def_args_hist.get(cnt, 0) + 1
|
||||
|
||||
def save(self, path, buf):
|
||||
f = open(path, "wt")
|
||||
f.write(buf)
|
||||
f.close()
|
||||
global total_files, updated_files
|
||||
total_files += 1
|
||||
if os.path.exists(path):
|
||||
with open(path, "rt") as f:
|
||||
content = f.read()
|
||||
if content == buf:
|
||||
return
|
||||
with open(path, "wt") as f:
|
||||
f.write(buf)
|
||||
updated_files += 1
|
||||
|
||||
def gen(self, srcfiles, module, output_path, common_headers):
|
||||
def gen(self, srcfiles, module, output_path, output_jni_path, output_java_path, common_headers):
|
||||
self.clear()
|
||||
self.module = module
|
||||
self.Module = module.capitalize()
|
||||
@@ -534,7 +456,7 @@ class JavaWrapperGenerator(object):
|
||||
else:
|
||||
logging.info("Ignore header: %s", hdr)
|
||||
for decl in decls:
|
||||
logging.info("\n--- Incoming ---\n%s", pformat(decl, 4))
|
||||
logging.info("\n--- Incoming ---\n%s", pformat(decl[:5], 4)) # without docstring
|
||||
name = decl[0]
|
||||
if name.startswith("struct") or name.startswith("class"):
|
||||
self.add_class(decl)
|
||||
@@ -545,17 +467,21 @@ class JavaWrapperGenerator(object):
|
||||
|
||||
logging.info("\n\n===== Generating... =====")
|
||||
moduleCppCode = StringIO()
|
||||
package_path = os.path.join(output_java_path, module)
|
||||
mkdir_p(package_path)
|
||||
for ci in self.classes.values():
|
||||
if ci.name == "Mat":
|
||||
continue
|
||||
ci.initCodeStreams(self.Module)
|
||||
self.gen_class(ci)
|
||||
classJavaCode = ci.generateJavaCode(self.module, self.Module)
|
||||
self.save("%s/%s+%s.java" % (output_path, module, ci.jname), classJavaCode)
|
||||
self.save("%s/%s/%s.java" % (output_java_path, module, ci.jname), classJavaCode)
|
||||
moduleCppCode.write(ci.generateCppCode())
|
||||
ci.cleanupCodeStreams()
|
||||
self.save(output_path+"/"+module+".cpp", Template(T_CPP_MODULE).substitute(m = module, M = module.upper(), code = moduleCppCode.getvalue(), includes = "\n".join(includes)))
|
||||
self.save(output_path+"/"+module+".txt", self.makeReport())
|
||||
cpp_file = os.path.abspath(os.path.join(output_jni_path, module + ".inl.hpp"))
|
||||
self.cpp_files.append(cpp_file)
|
||||
self.save(cpp_file, T_CPP_MODULE.substitute(m = module, M = module.upper(), code = moduleCppCode.getvalue(), includes = "\n".join(includes)))
|
||||
self.save(os.path.join(output_path, module+".txt"), self.makeReport())
|
||||
|
||||
def makeReport(self):
|
||||
'''
|
||||
@@ -734,7 +660,7 @@ class JavaWrapperGenerator(object):
|
||||
|
||||
if(j_signature in j_signatures):
|
||||
if args:
|
||||
pop(args)
|
||||
args.pop()
|
||||
continue
|
||||
else:
|
||||
break
|
||||
@@ -1078,17 +1004,55 @@ JNIEXPORT void JNICALL Java_org_opencv_%(module)s_%(j_cls)s_delete
|
||||
return "Ptr<" + fullname + ">"
|
||||
return fullname
|
||||
|
||||
def finalize(self, output_jni_path):
|
||||
list_file = os.path.join(output_jni_path, "opencv_jni.hpp")
|
||||
self.save(list_file, '\n'.join(['#include "%s"' % f for f in self.cpp_files]))
|
||||
|
||||
|
||||
def copy_java_files(java_files_dir, java_base_path):
|
||||
global total_files, updated_files
|
||||
java_files = []
|
||||
re_filter = re.compile(r'^.+\.(java|aidl)(.in)?$')
|
||||
for root, dirnames, filenames in os.walk(java_files_dir):
|
||||
java_files += [os.path.join(root, filename) for filename in filenames if re_filter.match(filename)]
|
||||
java_files = [f.replace('\\', '/') for f in java_files]
|
||||
|
||||
re_package = re.compile(r'^package +(.+);$')
|
||||
re_prefix = re.compile(r'^.+[\+/]([^\+]+).(java|aidl)(.in)?$')
|
||||
for java_file in java_files:
|
||||
src = checkFileRemap(java_file)
|
||||
with open(src, 'r') as f:
|
||||
package_line = f.readline()
|
||||
m = re_prefix.match(java_file)
|
||||
target_fname = (m.group(1) + '.' + m.group(2)) if m else os.path.basename(java_file)
|
||||
m = re_package.match(package_line)
|
||||
if m:
|
||||
package = m.group(1)
|
||||
package_path = package.replace('.', '/')
|
||||
else:
|
||||
package_path = 'org/opencv/' + module
|
||||
#print(java_file, package_path, target_fname)
|
||||
dest = os.path.join(java_base_path, os.path.join(package_path, target_fname))
|
||||
assert dest[-3:] != '.in', dest + ' | ' + target_fname
|
||||
mkdir_p(os.path.dirname(dest))
|
||||
total_files += 1
|
||||
if (not os.path.exists(dest)) or (os.stat(src).st_mtime - os.stat(dest).st_mtime > 1):
|
||||
copyfile(src, dest)
|
||||
updated_files += 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# initialize logger
|
||||
logging.basicConfig(filename='gen_java.log', format=None, filemode='w', level=logging.INFO)
|
||||
handler = logging.StreamHandler()
|
||||
handler.setLevel(logging.WARNING)
|
||||
logging.getLogger().addHandler(handler)
|
||||
|
||||
# parse command line parameters
|
||||
import argparse
|
||||
arg_parser = argparse.ArgumentParser(description='OpenCV Java Wrapper Generator')
|
||||
arg_parser.add_argument('-p', '--parser', required=True, help='OpenCV header parser')
|
||||
arg_parser.add_argument('-m', '--module', required=True, help='OpenCV module name')
|
||||
arg_parser.add_argument('-s', '--srcfiles', required=True, nargs='+', help='Source headers to be wrapped')
|
||||
arg_parser.add_argument('-c', '--common', nargs='*', help='Common headers')
|
||||
arg_parser.add_argument('-t', '--gendict', nargs='*', help='Custom module dictionaries for C++ to Java conversion')
|
||||
arg_parser.add_argument('-c', '--config', required=True, help='OpenCV modules config')
|
||||
|
||||
args=arg_parser.parse_args()
|
||||
|
||||
@@ -1099,38 +1063,95 @@ if __name__ == "__main__":
|
||||
sys.path.append(hdr_parser_path)
|
||||
import hdr_parser
|
||||
|
||||
module = args.module
|
||||
srcfiles = args.srcfiles
|
||||
common_headers= args.common
|
||||
gen_dict_files = args.gendict
|
||||
with open(args.config) as f:
|
||||
config = json.load(f)
|
||||
|
||||
dstdir = "."
|
||||
ROOT_DIR = config['rootdir']; assert os.path.exists(ROOT_DIR)
|
||||
FILES_REMAP = { os.path.realpath(os.path.join(ROOT_DIR, f['src'])): f['target'] for f in config['files_remap'] }
|
||||
logging.info("\nRemapped configured files (%d):\n%s", len(FILES_REMAP), pformat(FILES_REMAP))
|
||||
|
||||
# initialize logger
|
||||
logging.basicConfig(filename='%s/%s.log' % (dstdir, module), format=None, filemode='w', level=logging.INFO)
|
||||
handler = logging.StreamHandler()
|
||||
handler.setLevel(logging.WARNING)
|
||||
logging.getLogger().addHandler(handler)
|
||||
dstdir = "./gen"
|
||||
jni_path = os.path.join(dstdir, 'cpp'); mkdir_p(jni_path)
|
||||
java_base_path = os.path.join(dstdir, 'java'); mkdir_p(java_base_path)
|
||||
java_test_base_path = os.path.join(dstdir, 'test'); mkdir_p(java_test_base_path)
|
||||
|
||||
# load dictionaries
|
||||
for gdf in gen_dict_files:
|
||||
with open(gdf) as f:
|
||||
gen_type_dict = json.load(f)
|
||||
if "class_ignore_list" in gen_type_dict:
|
||||
class_ignore_list += gen_type_dict["class_ignore_list"]
|
||||
if "const_ignore_list" in gen_type_dict:
|
||||
const_ignore_list += gen_type_dict["const_ignore_list"]
|
||||
if "const_private_list" in gen_type_dict:
|
||||
const_private_list += gen_type_dict["const_private_list"]
|
||||
if "missing_consts" in gen_type_dict:
|
||||
missing_consts.update(gen_type_dict["missing_consts"])
|
||||
if "type_dict" in gen_type_dict:
|
||||
type_dict.update(gen_type_dict["type_dict"])
|
||||
if "ManualFuncs" in gen_type_dict:
|
||||
ManualFuncs.update(gen_type_dict["ManualFuncs"])
|
||||
if "func_arg_fix" in gen_type_dict:
|
||||
func_arg_fix.update(gen_type_dict["func_arg_fix"])
|
||||
for (subdir, target_subdir) in [('src/java', 'java'), ('android/java', None), ('android-21/java', None)]:
|
||||
if target_subdir is None:
|
||||
target_subdir = subdir
|
||||
java_files_dir = os.path.join(SCRIPT_DIR, subdir)
|
||||
if os.path.exists(java_files_dir):
|
||||
target_path = os.path.join(dstdir, target_subdir); mkdir_p(target_path)
|
||||
copy_java_files(java_files_dir, target_path)
|
||||
|
||||
# launch Java Wrapper generator
|
||||
generator = JavaWrapperGenerator()
|
||||
generator.gen(srcfiles, module, dstdir, common_headers)
|
||||
|
||||
gen_dict_files = []
|
||||
|
||||
print("JAVA: Processing OpenCV modules: %d" % len(config['modules']))
|
||||
for e in config['modules']:
|
||||
(module, module_location) = (e['name'], os.path.join(ROOT_DIR, e['location']))
|
||||
logging.info("\n=== MODULE: %s (%s) ===\n" % (module, module_location))
|
||||
|
||||
java_path = os.path.join(java_base_path, 'org/opencv')
|
||||
mkdir_p(java_path)
|
||||
|
||||
module_imports = []
|
||||
module_j_code = None
|
||||
module_jn_code = None
|
||||
srcfiles = []
|
||||
common_headers = []
|
||||
|
||||
misc_location = os.path.join(module_location, 'misc/java')
|
||||
|
||||
srcfiles_fname = os.path.join(misc_location, 'filelist')
|
||||
if os.path.exists(srcfiles_fname):
|
||||
with open(srcfiles_fname) as f:
|
||||
srcfiles = [os.path.join(module_location, str(l).strip()) for l in f.readlines() if str(l).strip()]
|
||||
else:
|
||||
re_bad = re.compile(r'(private|.inl.hpp$|_inl.hpp$|.details.hpp$|_winrt.hpp$|/cuda/)')
|
||||
# .h files before .hpp
|
||||
h_files = []
|
||||
hpp_files = []
|
||||
for root, dirnames, filenames in os.walk(os.path.join(module_location, 'include')):
|
||||
h_files += [os.path.join(root, filename) for filename in fnmatch.filter(filenames, '*.h')]
|
||||
hpp_files += [os.path.join(root, filename) for filename in fnmatch.filter(filenames, '*.hpp')]
|
||||
srcfiles = h_files + hpp_files
|
||||
srcfiles = [f for f in srcfiles if not re_bad.search(f.replace('\\', '/'))]
|
||||
logging.info("\nFiles (%d):\n%s", len(srcfiles), pformat(srcfiles))
|
||||
|
||||
common_headers_fname = os.path.join(misc_location, 'filelist_common')
|
||||
if os.path.exists(common_headers_fname):
|
||||
with open(common_headers_fname) as f:
|
||||
common_headers = [os.path.join(module_location, str(l).strip()) for l in f.readlines() if str(l).strip()]
|
||||
logging.info("\nCommon headers (%d):\n%s", len(common_headers), pformat(common_headers))
|
||||
|
||||
gendict_fname = os.path.join(misc_location, 'gen_dict.json')
|
||||
if os.path.exists(gendict_fname):
|
||||
with open(gendict_fname) as f:
|
||||
gen_type_dict = json.load(f)
|
||||
class_ignore_list += gen_type_dict.get("class_ignore_list", [])
|
||||
const_ignore_list += gen_type_dict.get("const_ignore_list", [])
|
||||
const_private_list += gen_type_dict.get("const_private_list", [])
|
||||
missing_consts.update(gen_type_dict.get("missing_consts", {}))
|
||||
type_dict.update(gen_type_dict.get("type_dict", {}))
|
||||
ManualFuncs.update(gen_type_dict.get("ManualFuncs", {}))
|
||||
func_arg_fix.update(gen_type_dict.get("func_arg_fix", {}))
|
||||
if 'module_j_code' in gen_type_dict:
|
||||
module_j_code = read_contents(checkFileRemap(os.path.join(misc_location, gen_type_dict['module_j_code'])))
|
||||
if 'module_jn_code' in gen_type_dict:
|
||||
module_jn_code = read_contents(checkFileRemap(os.path.join(misc_location, gen_type_dict['module_jn_code'])))
|
||||
module_imports += gen_type_dict.get("module_imports", [])
|
||||
|
||||
java_files_dir = os.path.join(misc_location, 'src/java')
|
||||
if os.path.exists(java_files_dir):
|
||||
copy_java_files(java_files_dir, java_base_path)
|
||||
|
||||
java_test_files_dir = os.path.join(misc_location, 'test')
|
||||
if os.path.exists(java_test_files_dir):
|
||||
copy_java_files(java_test_files_dir, java_test_base_path)
|
||||
|
||||
generator.gen(srcfiles, module, dstdir, jni_path, java_path, common_headers)
|
||||
generator.finalize(jni_path)
|
||||
|
||||
print('Generated files: %d (updated %d)' % (total_files, updated_files))
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#define LOG_TAG "org.opencv.core.Mat"
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include "common.h"
|
||||
#include "opencv2/core.hpp"
|
||||
|
||||
#define LOG_TAG "org.opencv.core.Mat"
|
||||
#include "common.h"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
/// throw java exception
|
||||
@@ -1777,67 +1778,6 @@ JNIEXPORT void JNICALL Java_org_opencv_core_Mat_n_1delete
|
||||
delete (Mat*) self;
|
||||
}
|
||||
|
||||
// unlike other nPut()-s this one (with double[]) should convert input values to correct type
|
||||
#define PUT_ITEM(T, R, C) { T*dst = (T*)me->ptr(R, C); for(int ch=0; ch<me->channels() && count>0; count--,ch++,src++,dst++) *dst = cv::saturate_cast<T>(*src); }
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutD
|
||||
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jdoubleArray vals);
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutD
|
||||
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jdoubleArray vals)
|
||||
{
|
||||
static const char method_name[] = "Mat::nPutD()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
cv::Mat* me = (cv::Mat*) self;
|
||||
if(!me || !me->data) return 0; // no native object behind
|
||||
if(me->rows<=row || me->cols<=col) return 0; // indexes out of range
|
||||
|
||||
int rest = ((me->rows - row) * me->cols - col) * me->channels();
|
||||
if(count>rest) count = rest;
|
||||
int res = count;
|
||||
double* values = (double*)env->GetPrimitiveArrayCritical(vals, 0);
|
||||
double* src = values;
|
||||
int r, c;
|
||||
for(c=col; c<me->cols && count>0; c++)
|
||||
{
|
||||
switch(me->depth()) {
|
||||
case CV_8U: PUT_ITEM(uchar, row, c); break;
|
||||
case CV_8S: PUT_ITEM(schar, row, c); break;
|
||||
case CV_16U: PUT_ITEM(ushort, row, c); break;
|
||||
case CV_16S: PUT_ITEM(short, row, c); break;
|
||||
case CV_32S: PUT_ITEM(int, row, c); break;
|
||||
case CV_32F: PUT_ITEM(float, row, c); break;
|
||||
case CV_64F: PUT_ITEM(double, row, c); break;
|
||||
}
|
||||
}
|
||||
|
||||
for(r=row+1; r<me->rows && count>0; r++)
|
||||
for(c=0; c<me->cols && count>0; c++)
|
||||
{
|
||||
switch(me->depth()) {
|
||||
case CV_8U: PUT_ITEM(uchar, r, c); break;
|
||||
case CV_8S: PUT_ITEM(schar, r, c); break;
|
||||
case CV_16U: PUT_ITEM(ushort, r, c); break;
|
||||
case CV_16S: PUT_ITEM(short, r, c); break;
|
||||
case CV_32S: PUT_ITEM(int, r, c); break;
|
||||
case CV_32F: PUT_ITEM(float, r, c); break;
|
||||
case CV_64F: PUT_ITEM(double, r, c); break;
|
||||
}
|
||||
}
|
||||
|
||||
env->ReleasePrimitiveArrayCritical(vals, values, 0);
|
||||
return res;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
|
||||
namespace {
|
||||
@@ -1963,6 +1903,66 @@ JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutF
|
||||
return java_mat_put(env, self, row, col, count, 0, vals);
|
||||
}
|
||||
|
||||
// unlike other nPut()-s this one (with double[]) should convert input values to correct type
|
||||
#define PUT_ITEM(T, R, C) { T*dst = (T*)me->ptr(R, C); for(int ch=0; ch<me->channels() && count>0; count--,ch++,src++,dst++) *dst = cv::saturate_cast<T>(*src); }
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutD
|
||||
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jdoubleArray vals);
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_core_Mat_nPutD
|
||||
(JNIEnv* env, jclass, jlong self, jint row, jint col, jint count, jdoubleArray vals)
|
||||
{
|
||||
static const char* method_name = JavaOpenCVTrait<jdoubleArray>::put;
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
cv::Mat* me = (cv::Mat*) self;
|
||||
if(!me || !me->data) return 0; // no native object behind
|
||||
if(me->rows<=row || me->cols<=col) return 0; // indexes out of range
|
||||
|
||||
int rest = ((me->rows - row) * me->cols - col) * me->channels();
|
||||
if(count>rest) count = rest;
|
||||
int res = count;
|
||||
double* values = (double*)env->GetPrimitiveArrayCritical(vals, 0);
|
||||
double* src = values;
|
||||
int r, c;
|
||||
for(c=col; c<me->cols && count>0; c++)
|
||||
{
|
||||
switch(me->depth()) {
|
||||
case CV_8U: PUT_ITEM(uchar, row, c); break;
|
||||
case CV_8S: PUT_ITEM(schar, row, c); break;
|
||||
case CV_16U: PUT_ITEM(ushort, row, c); break;
|
||||
case CV_16S: PUT_ITEM(short, row, c); break;
|
||||
case CV_32S: PUT_ITEM(int, row, c); break;
|
||||
case CV_32F: PUT_ITEM(float, row, c); break;
|
||||
case CV_64F: PUT_ITEM(double, row, c); break;
|
||||
}
|
||||
}
|
||||
|
||||
for(r=row+1; r<me->rows && count>0; r++)
|
||||
for(c=0; c<me->cols && count>0; c++)
|
||||
{
|
||||
switch(me->depth()) {
|
||||
case CV_8U: PUT_ITEM(uchar, r, c); break;
|
||||
case CV_8S: PUT_ITEM(schar, r, c); break;
|
||||
case CV_16U: PUT_ITEM(ushort, r, c); break;
|
||||
case CV_16S: PUT_ITEM(short, r, c); break;
|
||||
case CV_32S: PUT_ITEM(int, r, c); break;
|
||||
case CV_32F: PUT_ITEM(float, r, c); break;
|
||||
case CV_64F: PUT_ITEM(double, r, c); break;
|
||||
}
|
||||
}
|
||||
|
||||
env->ReleasePrimitiveArrayCritical(vals, values, 0);
|
||||
return res;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
template<typename T> static int mat_get(cv::Mat* m, int row, int col, int count, char* buff)
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
#ifndef __JAVA_COMMON_H__
|
||||
#define __JAVA_COMMON_H__
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#ifndef __OPENCV_JAVA_COMMON_H__
|
||||
#define __OPENCV_JAVA_COMMON_H__
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#if !defined(__ppc__)
|
||||
// to suppress warning from jni.h on OS X
|
||||
@@ -7,7 +16,9 @@
|
||||
#endif
|
||||
#include <jni.h>
|
||||
|
||||
#include "opencv2/java.hpp"
|
||||
} // extern "C"
|
||||
|
||||
#include "opencv_java.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
|
||||
#include "converters.h"
|
||||
@@ -17,4 +28,4 @@
|
||||
# pragma warning(disable:4800 4244)
|
||||
#endif
|
||||
|
||||
#endif //__JAVA_COMMON_H__
|
||||
#endif //__OPENCV_JAVA_COMMON_H__
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#define LOG_TAG "org.opencv.utils.Converters"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
#include "opencv2/core.hpp"
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#include "common.h"
|
||||
|
||||
// Include all generated JNI code
|
||||
#include "opencv_jni.hpp"
|
||||
@@ -4,9 +4,8 @@
|
||||
|
||||
// Author: abratchik
|
||||
|
||||
#ifndef JAVA_HPP
|
||||
#define JAVA_HPP
|
||||
|
||||
#undef LOGE
|
||||
#undef LOGD
|
||||
#ifdef __ANDROID__
|
||||
# include <android/log.h>
|
||||
# define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
|
||||
@@ -20,6 +19,8 @@
|
||||
# define LOGD(...)
|
||||
#endif
|
||||
|
||||
#ifndef OPENCV_JAVA_HPP
|
||||
#define OPENCV_JAVA_HPP
|
||||
|
||||
#define MATOFINT(ENV) static_cast<jclass>(ENV->NewGlobalRef(ENV->FindClass("org/opencv/core/MatOfInt")))
|
||||
#define GETNATIVEOBJ(ENV, CLS, MAT) ENV->GetLongField(MAT, ENV->GetFieldID(CLS, "nativeObj", "J"))
|
||||
@@ -34,16 +35,4 @@
|
||||
|
||||
#define CHECK_MAT(cond) if(!(cond)){ LOGD("FAILED: " #cond); return; }
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* JAVA_HPP */
|
||||
#endif // OPENCV_JAVA_HPP
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#define LOG_TAG "org.opencv.android.Utils"
|
||||
#include "common.h"
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
@@ -7,6 +8,9 @@
|
||||
#ifdef __ANDROID__
|
||||
#include <android/bitmap.h>
|
||||
|
||||
#define LOG_TAG "org.opencv.android.Utils"
|
||||
#include "common.h"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.logging.Logger;
|
||||
public class OpenCVNativeLoader implements OpenCVInterface {
|
||||
|
||||
public void init() {
|
||||
System.loadLibrary("opencv_java@LIB_NAME_SUFIX@");
|
||||
System.loadLibrary("opencv_java@OPENCV_JAVA_LIB_NAME_SUFFIX@");
|
||||
Logger.getLogger("org.opencv.osgi").log(Level.INFO, "Successfully loaded OpenCV native library.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// This file is auto-generated. Please don't modify it!
|
||||
//
|
||||
|
||||
#undef LOG_TAG
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
#ifdef HAVE_OPENCV_$M
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "opencv2/$m.hpp"
|
||||
|
||||
$includes
|
||||
|
||||
#define LOG_TAG "org.opencv.$m"
|
||||
#include "common.h"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
/// throw java exception
|
||||
#undef throwJavaException
|
||||
#define throwJavaException throwJavaException_$m
|
||||
static void throwJavaException(JNIEnv *env, const std::exception *e, const char *method) {
|
||||
std::string what = "unknown exception";
|
||||
jclass je = 0;
|
||||
|
||||
if(e) {
|
||||
std::string exception_type = "std::exception";
|
||||
|
||||
if(dynamic_cast<const cv::Exception*>(e)) {
|
||||
exception_type = "cv::Exception";
|
||||
je = env->FindClass("org/opencv/core/CvException");
|
||||
}
|
||||
|
||||
what = exception_type + ": " + e->what();
|
||||
}
|
||||
|
||||
if(!je) je = env->FindClass("java/lang/Exception");
|
||||
env->ThrowNew(je, what.c_str());
|
||||
|
||||
LOGE("%s caught %s", method, what.c_str());
|
||||
(void)method; // avoid "unused" warning
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
$code
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // HAVE_OPENCV_$M
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// This file is auto-generated. Please don't modify it!
|
||||
//
|
||||
package org.opencv.$module;
|
||||
|
||||
$imports
|
||||
|
||||
$docs
|
||||
$annotation
|
||||
public class $jname {
|
||||
|
||||
protected final long nativeObj;
|
||||
protected $jname(long addr) { nativeObj = addr; }
|
||||
|
||||
public long getNativeObjAddr() { return nativeObj; }
|
||||
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// This file is auto-generated. Please don't modify it!
|
||||
//
|
||||
package org.opencv.$module;
|
||||
|
||||
$imports
|
||||
|
||||
$docs
|
||||
$annotation
|
||||
public class $jname extends $base {
|
||||
|
||||
protected $jname(long addr) { super(addr); }
|
||||
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// This file is auto-generated. Please don't modify it!
|
||||
//
|
||||
package org.opencv.$module;
|
||||
|
||||
$imports
|
||||
|
||||
$docs
|
||||
$annotation
|
||||
public class $jname {
|
||||
Reference in New Issue
Block a user