From b5d73111ebc2fe47c2e8ad5bcd60f5f98677b5cf Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Thu, 23 Jun 2011 15:51:51 +0000 Subject: [PATCH] Added new module for Java API --- android/CMakeCache.android.initial.cmake | 2 +- modules/CMakeLists.txt | 1 + modules/java/CMakeLists.txt | 99 ++++ modules/java/android/.classpath | 7 + modules/java/android/.project | 33 ++ modules/java/android/AndroidManifest.xml | 15 + modules/java/android/default.properties | 12 + modules/java/gen_java.py | 558 ++++++++++++++++++++++ modules/java/srccpp/Mat.cpp | 583 +++++++++++++++++++++++ modules/java/srccpp/utils.cpp | 81 ++++ modules/java/srcjava/Mat.java | 408 ++++++++++++++++ modules/java/srcjava/Point.java | 47 ++ modules/java/srcjava/Point3.java | 56 +++ modules/java/srcjava/Rect.java | 76 +++ modules/java/srcjava/Scalar.java | 73 +++ modules/java/srcjava/Size.java | 49 ++ modules/java/srcjava/utils.java | 19 + 17 files changed, 2118 insertions(+), 1 deletion(-) create mode 100644 modules/java/CMakeLists.txt create mode 100644 modules/java/android/.classpath create mode 100644 modules/java/android/.project create mode 100644 modules/java/android/AndroidManifest.xml create mode 100644 modules/java/android/default.properties create mode 100644 modules/java/gen_java.py create mode 100644 modules/java/srccpp/Mat.cpp create mode 100644 modules/java/srccpp/utils.cpp create mode 100644 modules/java/srcjava/Mat.java create mode 100644 modules/java/srcjava/Point.java create mode 100644 modules/java/srcjava/Point3.java create mode 100644 modules/java/srcjava/Rect.java create mode 100644 modules/java/srcjava/Scalar.java create mode 100644 modules/java/srcjava/Size.java create mode 100644 modules/java/srcjava/utils.java diff --git a/android/CMakeCache.android.initial.cmake b/android/CMakeCache.android.initial.cmake index 8f7e90c259..d10b53406f 100644 --- a/android/CMakeCache.android.initial.cmake +++ b/android/CMakeCache.android.initial.cmake @@ -97,4 +97,4 @@ SET( ENABLE_SSE42 OFF CACHE INTERNAL "" FORCE ) SET( ENABLE_SSSE3 OFF CACHE INTERNAL "" FORCE ) #Set output folder to ${CMAKE_BINARY_DIR} -set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_BINARY_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" ) \ No newline at end of file +set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_BINARY_DIR} CACHE PATH "root for library output, set this to change where android libs are compiled to" ) diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 77bb7d1a82..ed5fad7fe3 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -5,6 +5,7 @@ if(ANDROID) endif() add_subdirectory(androidcamera) + add_subdirectory(java) endif() add_subdirectory(calib3d) diff --git a/modules/java/CMakeLists.txt b/modules/java/CMakeLists.txt new file mode 100644 index 0000000000..3c33f81386 --- /dev/null +++ b/modules/java/CMakeLists.txt @@ -0,0 +1,99 @@ +# ---------------------------------------------------------------------------- +# CMake file for java support +# ---------------------------------------------------------------------------- +project(opencv_java) + +SET(OPENCV_JAVA_MODULES objdetect features2d imgproc video highgui ml core) +SET(OPENCV_EXTRA_JAVA_MODULES calib3d contrib legacy flann) +IF(ANDROID AND NOT BUILD_SHARED_LIBS) + LIST(APPEND OPENCV_EXTRA_JAVA_MODULES androidcamera) +ENDIF() + +SET(GEN_JAVA "${CMAKE_CURRENT_SOURCE_DIR}/gen_java.py") +SET(HDR_PARSER "${CMAKE_CURRENT_SOURCE_DIR}/../python/src2/hdr_parser.py") + +foreach(module ${OPENCV_JAVA_MODULES}) + IF(${module} STREQUAL core) + SET (module_cppheaders "${CMAKE_CURRENT_SOURCE_DIR}/../${module}/include/opencv2/${module}/${module}.hpp") + SET (module_cheaders "") + ELSE() + FILE(GLOB module_cheaders "${CMAKE_CURRENT_SOURCE_DIR}/../${module}/include/opencv2/${module}/*.h") + FILE(GLOB module_cppheaders "${CMAKE_CURRENT_SOURCE_DIR}/../${module}/include/opencv2/${module}/*.hpp") + ENDIF() + list(SORT module_cheaders) + list(SORT module_cppheaders) + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${module}.java + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${module}.cpp + COMMAND ${PYTHON_EXECUTABLE} -B "${GEN_JAVA}" "${HDR_PARSER}" ${module} ${module_cheaders} ${module_cppheaders} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${GEN_JAVA} + DEPENDS ${HDR_PARSER} + DEPENDS ${module_headers} + ) +endforeach() + +set(target "opencv_java") +include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +FILE(GLOB handwrittren_cpp_sources "${CMAKE_CURRENT_SOURCE_DIR}/srccpp/*.cpp") + +SET (generated_cpp_sources "") +SET (generated_java_sources "") +SET (dependent_libs "") +SET (dependent_extra_libs "") + +foreach(module ${OPENCV_JAVA_MODULES}) + LIST(APPEND generated_cpp_sources "${CMAKE_CURRENT_BINARY_DIR}/${module}.cpp") + LIST(APPEND generated_java_sources "${CMAKE_CURRENT_BINARY_DIR}/${module}.java") + LIST(APPEND dependent_libs opencv_${module}) + include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../${module}/include") +endforeach() + +foreach(module ${OPENCV_EXTRA_JAVA_MODULES}) + LIST(APPEND dependent_extra_libs opencv_${module}) + include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../${module}/include") +endforeach() + +#SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L/home/andreyk/OpenCV2/trunk/opencv/android/build/libs/armeabi-v7a") + +add_library(${target} SHARED ${handwrittren_cpp_sources} ${generated_cpp_sources}) + +target_link_libraries(${target} ${dependent_libs} ${dependent_extra_libs} ${OPENCV_LINKER_LIBS}) +if(ANDROID) + target_link_libraries(${target} jnigraphics) +endif() + +#add_dependencies(${the_target} ${dependent_extra_libs} ${dependent_libs}) + +# Additional target properties +set_target_properties(${target} PROPERTIES + OUTPUT_NAME "${target}" + ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH} + RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} + INSTALL_NAME_DIR lib + ) + +add_custom_target(opecv_java_api ALL DEPENDS ${target}) + +IF(ANDROID) + # create Android library project in build folder + add_custom_command(TARGET opecv_java_api COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/res") + + FILE(GLOB android_lib_project_files "${CMAKE_CURRENT_SOURCE_DIR}/android/*") + foreach(lib_file ${android_lib_project_files}) + if(NOT IS_DIRECTORY ${lib_file}) + add_custom_command(TARGET opecv_java_api COMMAND ${CMAKE_COMMAND} -E copy "${lib_file}" "${CMAKE_BINARY_DIR}" DEPENDS "${lib_file}") + endif() + endforeach() +ENDIF() + +FILE(GLOB java_project_files "${CMAKE_CURRENT_SOURCE_DIR}/srcjava/*.java") +SET(JAVA_OUTPUT_DIR "${CMAKE_BINARY_DIR}/src/org/opencv") +add_custom_command(TARGET opecv_java_api COMMAND ${CMAKE_COMMAND} -E make_directory "${JAVA_OUTPUT_DIR}") + +foreach(java_file ${java_project_files} ${generated_java_sources}) + add_custom_command(TARGET opecv_java_api COMMAND ${CMAKE_COMMAND} -E copy "${java_file}" "${JAVA_OUTPUT_DIR}" DEPENDS "${java_file}" DEPENDS "${JAVA_OUTPUT_DIR}") +endforeach() + diff --git a/modules/java/android/.classpath b/modules/java/android/.classpath new file mode 100644 index 0000000000..6e9239ff0d --- /dev/null +++ b/modules/java/android/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/modules/java/android/.project b/modules/java/android/.project new file mode 100644 index 0000000000..b87567554a --- /dev/null +++ b/modules/java/android/.project @@ -0,0 +1,33 @@ + + + OpenCVJavaAPI + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/modules/java/android/AndroidManifest.xml b/modules/java/android/AndroidManifest.xml new file mode 100644 index 0000000000..664b68a076 --- /dev/null +++ b/modules/java/android/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/modules/java/android/default.properties b/modules/java/android/default.properties new file mode 100644 index 0000000000..863e850239 --- /dev/null +++ b/modules/java/android/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +android.library=true +# Project target. +target=android-8 diff --git a/modules/java/gen_java.py b/modules/java/gen_java.py new file mode 100644 index 0000000000..f6a4c11861 --- /dev/null +++ b/modules/java/gen_java.py @@ -0,0 +1,558 @@ +import sys, re, os.path +from string import Template + +try: + from cStringIO import StringIO +except: + from StringIO import StringIO + +ctype2j = { + # c : (j, jn, jni, jni code) + "" : ("", "long", "jlong", ""), # c-tor + "void" : ("void", "void", "void", ""), + "bool" : ("boolean", "boolean","jboolean", "Z"), + "int" : ("int", "int", "jint", "I"), + "long" : ("int", "int", "jint", "I"), + "float" : ("float", "float", "jfloat", "F"), + "double" : ("double", "double", "jdouble", "D"), + "size_t" : ("long", "long", "jlong", "J"), + "env" : ("", "", "JNIEnv*", ""), # dummy 'env' + "cls" : ("", "", "jclass", ""), # dummy 'cls' +# + "Mat" : ("Mat", (("size_t", ".nativeObj"),), "*%(n)s", "J"), + "Point" : ("Point", (("double", ".x"), ("double", ".y")), "cv::Point((int)%(n)s_x, (int)%(n)s_y)", "DD"), + "Point2f" : ("Point", (("double", ".x"), ("double", ".y")), "cv::Point2f((float)%(n)s_x, (float)%(n)s_y)", "DD"), + "Point2d" : ("Point", (("double", ".x"), ("double", ".y")), "cv::Point2d(%(n)s_x, %(n)s_y)", "DD"), + "Point3i" : ("Point", (("double", ".x"), ("double", ".y"), ("double", ".z")),\ + "cv::Point3i((int)%(n)s_x, (int)%(n)s_y, (int)%(n)s_z)", "DDD"), + "Point3f" : ("Point", (("double", ".x"), ("double", ".y"), ("double", ".z")),\ + "cv::Point3f((float)%(n)s_x, (float)%(n)s_y, (float)%(n)s_z)", "DDD"), + "Point3d" : ("Point", (("double", ".x"), ("double", ".y"), ("double", ".z")),\ + "cv::Point3d(%(n)s_x, %(n)s_y, %(n)s_z)", "DDD"), + "Rect" : ("Rect", (("int", ".x"), ("int", ".y"), ("int", ".width"), ("int", ".height")), \ + "cv::Rect(%(n)s_x, %(n)s_y, %(n)s_width, %(n)s_height)", "IIII"), + "Size" : ("Size", (("int", ".width"), ("int", ".height")), "cv::Size(%(n)s_width, %(n)s_height)", "II"), + "Scalar" : ("Scalar", (("double", ".v0"), ("double", ".v1"), ("double", ".v2"), ("double", ".v3")),\ + "cv::Scalar(%(n)s_v0, %(n)s_v1, %(n)s_v2, %(n)s_v3)", "DDDD"), + +} + +class ConstInfo(object): + def __init__(self, cname, name, val): +## self.name = re.sub(r"^cv\.", "", name).replace(".", "_") + self.cname = cname + self.name = re.sub(r"^Cv", "", name) + #self.name = re.sub(r"([a-z])([A-Z])", r"\1_\2", name) + #self.name = self.name.upper() + self.value = val + + +class ClassInfo(object): + def __init__(self, decl): # [ 'class/struct cname', [bases], [modlist] ] + name = decl[0] + name = name[name.find(" ")+1:].strip() + self.cname = self.name = self.jname = re.sub(r"^cv\.", "", name) + self.cname =self.cname.replace(".", "::") + self.jname = re.sub(r"^Cv", "", self.jname) + self.methods = {} + self.consts = [] # using a list to save the occurence order + for m in decl[2]: + if m.startswith("="): + self.jname = m[1:] + + +class ArgInfo(object): + def __init__(self, arg_tuple): # [ ctype, name, def val, [mod], argno ] + self.ctype = arg_tuple[0] + self.name = arg_tuple[1] + self.defval = arg_tuple[2] + self.out = "/O" in arg_tuple[3] or "/IO" in arg_tuple[3] + +## def isbig(self): +## return self.ctype == "Mat" or self.ctype == "vector_Mat" + + +class FuncInfo(object): + def __init__(self, decl): # [ funcname, return_ctype, [modifiers], [args] ] + name = re.sub(r"^cv\.", "", decl[0]) + self.cname = name.replace(".", "::") + classname = "" + dpos = name.rfind(".") + if dpos >= 0: + classname = name[:dpos] + name = name[dpos+1:] + self.classname = classname + self.jname = self.name = name + if "[" in name: + self.jname = "getelem" + for m in decl[2]: + if m.startswith("="): + self.jname = m[1:] + self.jn_name = "n_" + self.jname + self.jni_name= re.sub(r"_", "_1", self.jn_name) + if self.classname: + self.jni_name = "00024" + self.classname + "_" + self.jni_name + self.static = ["","static"][ "/S" in decl[2] ] + self.ctype = decl[1] or "" + self.args = [] + self.jni_suffix = "__" + if self.classname and self.ctype and not self.static: # non-static class methods except c-tors + self.jni_suffix += "J" # artifical 'self' + for a in decl[3]: + ai = ArgInfo(a) + self.args.append(ai) + self.jni_suffix += ctype2j.get(ai.ctype, ["","","",""])[3] + + + +class FuncFamilyInfo(object): + def __init__(self, decl): # [ funcname, return_ctype, [modifiers], [args] ] + self.funcs = [] + self.funcs.append( FuncInfo(decl) ) + self.jname = self.funcs[0].jname + self.isconstructor = self.funcs[0].name == self.funcs[0].classname + + + + def add_func(self, fi): + self.funcs.append( fi ) + + +class JavaWrapperGenerator(object): + def __init__(self): + self.clear() + + def clear(self): + self.classes = { "Mat" : ClassInfo([ 'class Mat', [], [] ]) } + self.funcs = {} + self.consts = [] # using a list to save the occurence order + self.module = "" + self.java_code = StringIO() + self.cpp_code = StringIO() + self.ported_func_counter = 0 + self.func_counter = 0 + + def add_class(self, decl): + classinfo = ClassInfo(decl) + if classinfo.name in self.classes: + print "Generator error: class %s (%s) is duplicated" % \ + (classinfo.name, classinfo.cname) + sys.exit(-1) + self.classes[classinfo.name] = classinfo + if classinfo.name in ctype2j: + print "Duplicated class: " + classinfo.name + sys.exit(-1) + ctype2j[classinfo.name] = (classinfo.jname, (("size_t", ".nativeObj"),), "*%(n)s", "J") + + + def add_const(self, decl): # [ "const cname", val, [], [] ] + consts = self.consts + name = decl[0].replace("const ", "").strip() + name = re.sub(r"^cv\.", "", name) + cname = name.replace(".", "::") + # check if it's a class member + dpos = name.rfind(".") + if dpos >= 0: + classname = name[:dpos] + name = name[dpos+1:] + if classname in self.classes: + consts = self.classes[classname].consts + else: + # this class isn't wrapped + # skipping this const + return + constinfo = ConstInfo(cname, name, decl[1]) + # checking duplication + for c in consts: + if c.name == constinfo.name: + print "Generator error: constant %s (%s) is duplicated" \ + % (constinfo.name, constinfo.cname) + sys.exit(-1) + consts.append(constinfo) + + def add_func(self, decl): + ffi = FuncFamilyInfo(decl) + func_map = self.funcs + classname = ffi.funcs[0].classname + if classname: + if classname in self.classes: + func_map = self.classes[classname].methods + else: + print "Generator error: the class %s for method %s is missing" % \ + (classname, ffi.jname) + sys.exit(-1) + if ffi.jname in func_map: + func_map[ffi.jname].add_func(ffi.funcs[0]) + else: + func_map[ffi.jname] = ffi + + def save(self, path, name, buf): + f = open(path + "/" + name, "wt") + f.write(buf.getvalue()) + f.close() + + def gen(self, srcfiles, module, output_path): + self.clear() + self.module = module + parser = hdr_parser.CppHeaderParser() + + # step 1: scan the headers and build more descriptive maps of classes, consts, functions + for hdr in srcfiles: + decls = parser.parse(hdr) + for decl in decls: + name = decl[0] + if name.startswith("struct") or name.startswith("class"): + self.add_class(decl) + pass + elif name.startswith("const"): + self.add_const(decl) + else: # function + self.add_func(decl) + pass + + # java module header + self.java_code.write(\ +"""package org.opencv; + +public class %(module)s { + + //Load the native jni library + static { + System.loadLibrary("opencv_java"); + } + + public static final int + CV_8U = 0, + CV_8S = 1, + CV_16U = 2, + CV_16S = 3, + CV_32S = 4, + CV_32F = 5, + CV_64F = 6, + CV_USRTYPE1 = 7, + IPL_BORDER_CONSTANT = 0, + IPL_BORDER_REPLICATE = 1, + IPL_BORDER_REFLECT = 2, + IPL_BORDER_WRAP = 3, + IPL_BORDER_REFLECT_101 = 4, + IPL_BORDER_TRANSPARENT = 5; +""" % {"module" : module} ) + + # cpp module header + self.cpp_code.write(\ +"""// This file is auto-generated, please don't edit! + +#include + +""" % {"module" : module}) + self.cpp_code.write( "\n".join(['#include "opencv2/%s/%s"' % (module, os.path.basename(f)) \ + for f in srcfiles]) ) + self.cpp_code.write("\n\n") + + # step 2: generate the code for global constants + self.gen_consts() + + # step 3: generate the code for all the global functions + self.gen_funcs() + + # step 4: generate code for the classes + #self.gen_classes() # !!! tempory disabled !!! + + # java module tail + self.java_code.write("}\n") + + self.save(output_path, module+".java", self.java_code) + self.save(output_path, module+".cpp", self.cpp_code) + + print "Done %i of %i funcs." % (self.ported_func_counter, self.func_counter) + + + def gen_consts(self): + # generate the code for global constants + if self.consts: + self.java_code.write(""" + public static final int + """ + """, + """.join(["%s = %s" % (c.name, c.value) for c in self.consts]) + \ + ";\n\n") + + + def gen_func(self, fi, isoverload): + self.func_counter += 1 + + # java part & cpp part: + # // c_decl + # e.g: + # // void add(Mat src1, Mat src2, Mat dst, Mat mask = Mat(), int dtype = -1) + c_decl = "%s %s %s(%s)" % \ + ( fi.static, fi.ctype, fi.cname, \ + ", ".join(a.ctype + " " + a.name + [""," = "+a.defval][bool(a.defval)] for a in fi.args) ) + indent = "" + if fi.classname: + indent = " " * 4 + self.java_code.write( "\n %s// %s\n" % (indent, c_decl) ) + self.cpp_code.write( "\n//\n//%s\n//\n" % c_decl ) + # check if we 'know' all the types + if fi.ctype and fi.ctype!="Mat" and fi.ctype[0].isupper(): # ret val is class, NYI (TODO!) + self.java_code.write( " %s// Return type '%s' is not yet supported, skipping the function\n\n"\ + % (indent, fi.ctype) ) + print "SKIP:", c_decl, "\n\tdue to RET type", fi.ctype + return + types = [fi.ctype] + types.extend([a.ctype for a in fi.args]) + for t in types: + if t not in ctype2j: + self.java_code.write( " %s// Unknown type '%s', skipping the function\n\n" % (indent, t) ) + print "SKIP:", c_decl, "\n\tdue to ARG type", t + return + for a in fi.args: + if a.ctype[0].isupper() and a.ctype != "Mat" and a.out: # C++ reference to a class (gcc disallows temp obj reference) + self.java_code.write( " %s// Unknown type '%s&', skipping the function\n\n" % (indent, t) ) + print "SKIP:", c_decl, "\n\tdue to ARG type", a.ctype + "&" + return + if fi.cname == "minEnclosingCircle": + self.java_code.write( " %s// Temporary skipping the function %s\n\n" % (indent, fi.cname) ) + print "SKIP:", c_decl, "\n\tdue to Temporary filtering" + return + + self.ported_func_counter += 1 + # java args + args = fi.args[:] + if args and args[-1].defval: + isoverload = True + suffix = fi.jni_suffix + + while True: + + # java native method args + jn_args = [] + if fi.classname and fi.ctype and not fi.static: # non-static class method except c-tor + jn_args.append(ArgInfo([ "size_t", "nativeObj", "", [], "" ])) # adding 'this' + for a in args: + if a.ctype[0].isupper(): # Point/Rect/... + #"Point" : ("Point", [["int", ".x"], ["int", ".y"]], ...) + fields = ctype2j[a.ctype][1] + for f in fields: + jn_args.append( ArgInfo([ f[0], a.name + f[1], "", [], "" ]) ) + else: + jn_args.append(a) + + # jni (cpp) function args + jni_args = [ArgInfo([ "env", "env", "", [], "" ]), ArgInfo([ "cls", "cls", "", [], "" ])] + if fi.classname and fi.ctype and not fi.static: + jni_args.append(ArgInfo([ "size_t", "self", "", [], "" ])) + for a in args: + if a.ctype[0].isupper(): # Point/Rect/... + #"Point" : ("Point", [["int", ".x"], ["int", ".y"]], ...) + fields = ctype2j[a.ctype][1] + for f in fields: + jni_args.append( ArgInfo([ f[0], a.name + f[1].replace(".","_"), "", [], "" ]) ) + else: + jni_args.append(a) + + # java part: + # private java NATIVE method decl + # e.g. + # private static native void n_add(long src1, long src2, long dst, long mask, int dtype); + jn_type = "" + if fi.ctype == "Mat": + jn_type = "long" + elif fi.ctype[0].isupper(): + jn_type = "NYI" # TODO: NYI + else: + jn_type = ctype2j[fi.ctype][1] + + self.java_code.write( Template(\ + " ${indent}private static native $jn_type $jn_name($jn_args);\n").substitute(\ + indent = indent, \ + jn_type=jn_type, \ + jn_name=fi.jn_name, \ + jn_args=", ".join(["%s %s" % (ctype2j[a.ctype][1], a.name.replace(".","_")) for a in jn_args]) + ) ); + + # java part: + # public java wrapper method impl (calling native one above) + # e.g. + # public static void add( Mat src1, Mat src2, Mat dst, Mat mask, int dtype ) + # { n_add( src1.nativeObj, src2.nativeObj, dst.nativeObj, mask.nativeObj, dtype ); } + impl_code = " return $jn_name($jn_args_call); " + if fi.ctype == "void": + impl_code = " $jn_name($jn_args_call); " + elif fi.ctype == "": # c-tor + impl_code = " nativeObj = $jn_name($jn_args_call); " + elif fi.ctype in self.classes: # wrapped class + impl_code = " return new %s( $jn_name($jn_args_call) ); " % \ + self.classes[fi.ctype].jname + + static = "static" + if fi.classname: + static = fi.static + + self.java_code.write( Template(\ + " ${indent}public $static $j_type $j_name($j_args)").substitute(\ + indent = indent, \ + static=static, \ + j_type=ctype2j[fi.ctype][0], \ + j_name=fi.jname, \ + j_args=", ".join(["%s %s" % (ctype2j[a.ctype][0], a.name) for a in args]) \ + ) ) + + self.java_code.write( Template("\n $indent{ " + impl_code + " }\n").substitute(\ + indent = indent, \ + jn_name=fi.jn_name, \ + jn_args_call=", ".join([a.name + ["",".nativeObj"][ctype2j[a.ctype][0]=="Mat"] for a in jn_args])\ + ) ) + + # cpp part: + # jni_func(..) { return cv_func(..); } + ret = "return " + if fi.ctype == "void": + ret = "" + elif fi.ctype == "Mat": + ret = "return (jlong) new cv::Mat" + elif fi.ctype[0].isupper(): + ret = NYI # NYI + + cvname = "cv::" + fi.name + j2cvargs = [] + if fi.classname: + if not fi.ctype: # c-tor + cvname = "(jlong) new cv::" + fi.classname + elif fi.static: + cvname = "cv::%s::%s" % (fi.classname, fi.name) + else: + cvname = "%s->%s" % ("me", fi.name) + j2cvargs.append(\ + "cv::%s* me = (cv::%s*) self; //TODO: check for NULL" % \ + (fi.classname, fi.classname) \ + ) + cvargs = [] + for a in args: + cva = a.name + if a.ctype[0].isupper(): # Point/Rect/... + # "Point" : ("Point", (("int", ".x"), ("int", ".y")), "Point(%(n)s_x, %(n)s_y)", "II") + # Point(p_x, p_y) + cva = ctype2j[a.ctype][2] % {"n" : a.name} + if a.ctype == "Mat": + j2cvargs.append("cv::Mat* %s = (cv::Mat*) %s_nativeObj; //TODO: check for NULL"\ + % (a.name, a.name)) + pass + cvargs.append(cva) + + rtype = "NYI" + if fi.ctype == "Mat": + rtype = "jlong" + elif fi.ctype[0].isupper(): + rtype = "NYI" # TODO: NYI + else: + rtype = ctype2j[fi.ctype][2] + + self.cpp_code.write ( Template( \ +""" +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_$fname + ($args); + +#ifdef __cplusplus +} +#endif + +JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_$fname + ($args) +{ + $j2cv + $ret( $cvname( $cvargs ) ); +} + +""" ).substitute( \ + rtype = rtype, \ + module = self.module, \ + fname = fi.jni_name + ["",suffix][isoverload], \ + args = ", ".join(["%s %s" % (ctype2j[a.ctype][2], a.name) for a in jni_args]), \ + j2cv = "\n ".join([a for a in j2cvargs]), \ + ret = ret, \ + cvname = cvname, \ + cvargs = ", ".join([a for a in cvargs]), \ + ) ) + + # processing args with default values + if args and args[-1].defval: + a = args.pop() + suffix = suffix[0:-len(ctype2j[a.ctype][3])] + else: + break + + + + def gen_funcs(self): + # generate the code for all the global functions + indent = "\t" + fflist = self.funcs.items() + fflist.sort() + for name, ffi in fflist: + assert not ffi.funcs[0].classname, "Error: global func is a class member - "+name + for fi in ffi.funcs: + self.gen_func(fi, len(ffi.funcs)>1) + + + def gen_classes(self): + # generate code for the classes (their methods and consts) + indent = "\t" + indent_m = indent + "\t" + classlist = self.classes.items() + classlist.sort() + for name, ci in classlist: + self.java_code.write( "\n" + indent + "// class %s" % (ci.cname) + "\n" ) + self.java_code.write( indent + "public static class %s {\n\n" % (ci.jname) ) + + # self + self.java_code.write( indent_m + "protected final long nativeObj;\n" ) + self.java_code.write( indent_m + "protected %s(long addr) { nativeObj = addr; }\n\n" \ + % name ); + # constants + if ci.consts: + prefix = "\n" + indent_m + "\t\t" + s = indent_m + "public static final int" + prefix +\ + ("," + prefix).join(["%s = %s" % (c.name, c.value) for c in ci.consts]) + ";\n\n" + self.java_code.write( s ) + # c-tors + fflist = ci.methods.items() + fflist.sort() + for n, ffi in fflist: + if ffi.isconstructor: + for fi in ffi.funcs: + self.gen_func(fi, len(ffi.funcs)>1) + self.java_code.write( "\n" ) + for n, ffi in fflist: + if not ffi.isconstructor: + for fi in ffi.funcs: + self.gen_func(fi, len(ffi.funcs)>1) + + self.java_code.write( "\n" + indent + "}\n\n" ) + + +if __name__ == "__main__": + if len(sys.argv) < 4: + print "Usage:\n", \ + os.path.basename(sys.argv[0]), \ + " [...]" + print "Current args are: ", ", ".join(["'"+a+"'" for a in sys.argv]) + exit(0) + + dstdir = "." + hdr_parser_path = os.path.abspath(sys.argv[1]) + if hdr_parser_path.endswith(".py"): + hdr_parser_path = os.path.dirname(hdr_parser_path) + sys.path.append(hdr_parser_path) + import hdr_parser + module = sys.argv[2] + srcfiles = sys.argv[3:] + print "Generating module '" + module + "' from headers:\n\t" + "\n\t".join(srcfiles) + generator = JavaWrapperGenerator() + generator.gen(srcfiles, module, dstdir) + + + diff --git a/modules/java/srccpp/Mat.cpp b/modules/java/srccpp/Mat.cpp new file mode 100644 index 0000000000..3ca2a39fee --- /dev/null +++ b/modules/java/srccpp/Mat.cpp @@ -0,0 +1,583 @@ +#include + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_opencv_Mat + * Method: nCreateMat + * Signature: (III)J + */ +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nCreateMat__III + (JNIEnv *, jclass, jint, jint, jint); + +/* + * Class: org_opencv_Mat + * Method: nCreateMat + * Signature: (IIIDDDD)J + */ +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nCreateMat__IIIDDDD + (JNIEnv *, jclass, jint, jint, jint, jdouble, jdouble, jdouble, jdouble); + +/* + * Class: org_opencv_Mat + * Method: nDispose + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_opencv_Mat_nDispose + (JNIEnv *, jclass, jlong); + +/* + * Class: org_opencv_Mat + * Method: nType + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nType + (JNIEnv *, jclass, jlong); + +/* + * Class: org_opencv_Mat + * Method: nRows + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nRows + (JNIEnv *, jclass, jlong); + +/* + * Class: org_opencv_Mat + * Method: nCols + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nCols + (JNIEnv *, jclass, jlong); + +/* + * Class: org_opencv_Mat + * Method: nData + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nData + (JNIEnv *, jclass, jlong); + +/* + * Class: org_opencv_Mat + * Method: nIsEmpty + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_org_opencv_Mat_nIsEmpty + (JNIEnv *, jclass, jlong); + +/* + * Class: org_opencv_Mat + * Method: nIsCont + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_org_opencv_Mat_nIsCont + (JNIEnv *, jclass, jlong); + +/* + * Class: org_opencv_Mat + * Method: nIsSubmat + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_org_opencv_Mat_nIsSubmat + (JNIEnv *, jclass, jlong); + +/* + * Class: org_opencv_Mat + * Method: nSubmat + * Signature: (JIIII)J + */ +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nSubmat + (JNIEnv *, jclass, jlong, jint, jint, jint, jint); + +/* + * Class: org_opencv_Mat + * Method: nClone + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nClone + (JNIEnv *, jclass, jlong); + +/* + * Class: org_opencv_Mat + * Method: nPutD + * Signature: (JIII[D)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nPutD + (JNIEnv *, jclass, jlong, jint, jint, jint, jdoubleArray); + +/* + * Class: org_opencv_Mat + * Method: nPutF + * Signature: (JIII[F)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nPutF + (JNIEnv *, jclass, jlong, jint, jint, jint, jfloatArray); + +/* + * Class: org_opencv_Mat + * Method: nPutI + * Signature: (JIII[I)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nPutI + (JNIEnv *, jclass, jlong, jint, jint, jint, jintArray); + +/* + * Class: org_opencv_Mat + * Method: nPutS + * Signature: (JIII[S)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nPutS + (JNIEnv *, jclass, jlong, jint, jint, jint, jshortArray); + +/* + * Class: org_opencv_Mat + * Method: nPutB + * Signature: (JIII[B)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nPutB + (JNIEnv *, jclass, jlong, jint, jint, jint, jbyteArray); + +/* + * Class: org_opencv_Mat + * Method: nGetB + * Signature: (JIII[B)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nGetB + (JNIEnv *, jclass, jlong, jint, jint, jint, jbyteArray); + +/* + * Class: org_opencv_Mat + * Method: nGetS + * Signature: (JIII[S)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nGetS + (JNIEnv *, jclass, jlong, jint, jint, jint, jshortArray); + +/* + * Class: org_opencv_Mat + * Method: nGetI + * Signature: (JIII[I)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nGetI + (JNIEnv *, jclass, jlong, jint, jint, jint, jintArray); + +/* + * Class: org_opencv_Mat + * Method: nGetF + * Signature: (JIII[F)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nGetF + (JNIEnv *, jclass, jlong, jint, jint, jint, jfloatArray); + +/* + * Class: org_opencv_Mat + * Method: nGetD + * Signature: (JIII[D)I + */ +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nGetD + (JNIEnv *, jclass, jlong, jint, jint, jint, jdoubleArray); + +/* + * Class: org_opencv_Mat + * Method: nSetTo + * Signature: (JDDDD)V + */ +JNIEXPORT void JNICALL Java_org_opencv_Mat_nSetTo + (JNIEnv *, jclass, jlong, jdouble, jdouble, jdouble, jdouble); + +/* + * Class: org_opencv_Mat + * Method: nCopyTo + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_org_opencv_Mat_nCopyTo + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: org_opencv_Mat + * Method: nDot + * Signature: (JJ)D + */ +JNIEXPORT jdouble JNICALL Java_org_opencv_Mat_nDot + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: org_opencv_Mat + * Method: nCross + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nCross + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: org_opencv_Mat + * Method: nInv + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nInv + (JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} +#endif + + +#include "opencv2/core/core.hpp" + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nType + (JNIEnv* env, jclass cls, jlong self) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + return me->type( ); +} + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nRows + (JNIEnv* env, jclass cls, jlong self) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + return me->rows; +} + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nCols + (JNIEnv* env, jclass cls, jlong self) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + return me->cols; +} + +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nData + (JNIEnv* env, jclass cls, jlong self) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + return (jlong) me->data; +} + +JNIEXPORT jboolean JNICALL Java_org_opencv_Mat_nIsEmpty + (JNIEnv* env, jclass cls, jlong self) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + return me->empty(); +} + +JNIEXPORT jboolean JNICALL Java_org_opencv_Mat_nIsCont + (JNIEnv* env, jclass cls, jlong self) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + return me->isContinuous(); +} + +JNIEXPORT jboolean JNICALL Java_org_opencv_Mat_nIsSubmat + (JNIEnv* env, jclass cls, jlong self) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + return me->isSubmatrix(); +} + +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nSubmat + (JNIEnv* env, jclass cls, jlong self, jint r1, jint r2, jint c1, jint c2) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + return (jlong) new cv::Mat(*me, cv::Range(r1, r2>0 ? r2 : me->rows), cv::Range(c1, c2>0 ? c2 : me->cols)); +} + +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nClone + (JNIEnv* env, jclass cls, jlong self) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + cv::Mat* it = new cv::Mat(); + me->copyTo(*it); + return (jlong) it; +} + +// unlike other nPut()-s this one (with double[]) should convert input values to correct type +#define PUT_ITEM(T, R, C) for(int ch=0; chchannels() & count>0; ch++,count--) *((T*)me->ptr(R, C)+ch) = cv::saturate_cast(*(src+ch)) +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nPutD + (JNIEnv* env, jclass cls, jlong self, jint row, jint col, jint count, jdoubleArray vals) +{ + cv::Mat* me = (cv::Mat*) self; + if(! self) 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; ccols & 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; + } + src++; + } + + for(r=row+1; rrows & count>0; r++) + for(c=0; ccols & 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; + } + src++; + } + + env->ReleasePrimitiveArrayCritical(vals, values, 0); + return res; +} + + +template static int mat_put(cv::Mat* m, int row, int col, int count, char* buff) +{ + if(! m) return 0; + if(! buff) return 0; + + int rest = ((m->rows - row) * m->cols - col) * m->channels() * sizeof(T); + if(count>rest) count = rest; + int res = count; + + if( m->isContinuous() ) + { + memcpy(m->ptr(row, col), buff, count); + } else { + // row by row + int num = (m->cols - col - 1) * m->channels() * sizeof(T); // 1st partial row + if(countptr(row++, col); + while(count>0){ + memcpy(data, buff, num); + count -= num; + buff += num; + num = m->cols * m->channels() * sizeof(T); + if(countptr(row++, 0); + } + } + return res; +} + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nPutB + (JNIEnv* env, jclass cls, jlong self, jint row, jint col, jint count, jbyteArray vals) +{ + cv::Mat* me = (cv::Mat*) self; + if(! self) return 0; // no native object behind + if(me->depth() != CV_8U && me->depth() != CV_8S) return 0; // incompatible type + if(me->rows<=row || me->cols<=col) return 0; // indexes out of range + + char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0); + int res = mat_put(me, row, col, count, values); + env->ReleasePrimitiveArrayCritical(vals, values, 0); + return res; +} + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nPutS + (JNIEnv* env, jclass cls, jlong self, jint row, jint col, jint count, jshortArray vals) +{ + cv::Mat* me = (cv::Mat*) self; + if(! self) return 0; // no native object behind + if(me->depth() != CV_8U && me->depth() != CV_8S) return 0; // incompatible type + if(me->rows<=row || me->cols<=col) return 0; // indexes out of range + + char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0); + int res = mat_put(me, row, col, count, values); + env->ReleasePrimitiveArrayCritical(vals, values, 0); + return res; +} + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nPutI + (JNIEnv* env, jclass cls, jlong self, jint row, jint col, jint count, jintArray vals) +{ + cv::Mat* me = (cv::Mat*) self; + if(! self) return 0; // no native object behind + if(me->depth() != CV_8U && me->depth() != CV_8S) return 0; // incompatible type + if(me->rows<=row || me->cols<=col) return 0; // indexes out of range + + char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0); + int res = mat_put(me, row, col, count, values); + env->ReleasePrimitiveArrayCritical(vals, values, 0); + return res; +} + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nPutF + (JNIEnv* env, jclass cls, jlong self, jint row, jint col, jint count, jfloatArray vals) +{ + cv::Mat* me = (cv::Mat*) self; + if(! self) return 0; // no native object behind + if(me->depth() != CV_8U && me->depth() != CV_8S) return 0; // incompatible type + if(me->rows<=row || me->cols<=col) return 0; // indexes out of range + + char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0); + int res = mat_put(me, row, col, count, values); + env->ReleasePrimitiveArrayCritical(vals, values, 0); + return res; +} + + + +template int mat_get(cv::Mat* m, int row, int col, int count, char* buff) +{ + if(! m) return 0; + if(! buff) return 0; + + int rest = ((m->rows - row) * m->cols - col) * m->channels() * sizeof(T); + if(count>rest) count = rest; + int res = count; + + if( m->isContinuous() ) + { + memcpy(buff, m->ptr(row, col), count); + } else { + // row by row + int num = (m->cols - col - 1) * m->channels() * sizeof(T); // 1st partial row + if(countptr(row++, col); + while(count>0){ + memcpy(buff, data, num); + count -= num; + buff += num; + num = m->cols * m->channels() * sizeof(T); + if(countptr(row++, 0); + } + } + return res; +} + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nGetB + (JNIEnv* env, jclass cls, jlong self, jint row, jint col, jint count, jbyteArray vals) +{ + cv::Mat* me = (cv::Mat*) self; + if(! self) return 0; // no native object behind + if(me->depth() != CV_8U && me->depth() != CV_8S) return 0; // incompatible type + if(me->rows<=row || me->cols<=col) return 0; // indexes out of range + + char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0); + int res = mat_get(me, row, col, count, values); + env->ReleasePrimitiveArrayCritical(vals, values, 0); + return res; +} + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nGetS + (JNIEnv* env, jclass cls, jlong self, jint row, jint col, jint count, jshortArray vals) +{ + cv::Mat* me = (cv::Mat*) self; + if(! self) return 0; // no native object behind + if(me->depth() != CV_8U && me->depth() != CV_8S) return 0; // incompatible type + if(me->rows<=row || me->cols<=col) return 0; // indexes out of range + + char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0); + int res = mat_get(me, row, col, count, values); + env->ReleasePrimitiveArrayCritical(vals, values, 0); + return res; +} + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nGetI + (JNIEnv* env, jclass cls, jlong self, jint row, jint col, jint count, jintArray vals) +{ + cv::Mat* me = (cv::Mat*) self; + if(! self) return 0; // no native object behind + if(me->depth() != CV_8U && me->depth() != CV_8S) return 0; // incompatible type + if(me->rows<=row || me->cols<=col) return 0; // indexes out of range + + char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0); + int res = mat_get(me, row, col, count, values); + env->ReleasePrimitiveArrayCritical(vals, values, 0); + return res; +} + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nGetF + (JNIEnv* env, jclass cls, jlong self, jint row, jint col, jint count, jfloatArray vals) +{ + cv::Mat* me = (cv::Mat*) self; + if(! self) return 0; // no native object behind + if(me->depth() != CV_8U && me->depth() != CV_8S) return 0; // incompatible type + if(me->rows<=row || me->cols<=col) return 0; // indexes out of range + + char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0); + int res = mat_get(me, row, col, count, values); + env->ReleasePrimitiveArrayCritical(vals, values, 0); + return res; +} + +JNIEXPORT jint JNICALL Java_org_opencv_Mat_nGetD + (JNIEnv* env, jclass cls, jlong self, jint row, jint col, jint count, jdoubleArray vals) +{ + cv::Mat* me = (cv::Mat*) self; + if(! self) return 0; // no native object behind + if(me->depth() != CV_8U && me->depth() != CV_8S) return 0; // incompatible type + if(me->rows<=row || me->cols<=col) return 0; // indexes out of range + + char* values = (char*)env->GetPrimitiveArrayCritical(vals, 0); + int res = mat_get(me, row, col, count, values); + env->ReleasePrimitiveArrayCritical(vals, values, 0); + return res; +} + + +JNIEXPORT void JNICALL Java_org_opencv_Mat_nSetTo + (JNIEnv* env, jclass cls, jlong self, jdouble v0, jdouble v1, jdouble v2, jdouble v3) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + me->setTo( cv::Scalar(v0, v1, v2, v3), cv::Mat() ); +} + +JNIEXPORT void JNICALL Java_org_opencv_Mat_nCopyTo + (JNIEnv* env, jclass cls, jlong self, jlong m) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + cv::Mat* _m = (cv::Mat*) m; //TODO: check for NULL + me->copyTo( *_m ); +} + +JNIEXPORT jdouble JNICALL Java_org_opencv_Mat_nDot + (JNIEnv* env, jclass cls, jlong self, jlong m) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + cv::Mat* _m = (cv::Mat*) m; //TODO: check for NULL + return me->dot( *_m ); +} + +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nCross + (JNIEnv* env, jclass cls, jlong self, jlong it) +{ + return 0; //NYI +} + +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nInv + (JNIEnv* env, jclass cls, jlong self) +{ + return 0; //NYI +} + +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nCreateMat__III + (JNIEnv* env, jclass cls, jint _rows, jint _cols, jint _type) +{ + return (jlong) new cv::Mat( _rows, _cols, _type ); +} + +JNIEXPORT jlong JNICALL Java_org_opencv_Mat_nCreateMat__IIIDDDD + (JNIEnv* env, jclass cls, jint _rows, jint _cols, jint _type, jdouble v0, jdouble v1, jdouble v2, jdouble v3) +{ + return (jlong) new cv::Mat( _rows, _cols, _type, cv::Scalar(v0, v1, v2, v3) ); +} + +JNIEXPORT void JNICALL Java_org_opencv_Mat_nDispose + (JNIEnv* env, jclass cls, jlong self) +{ + cv::Mat* me = (cv::Mat*) self; //TODO: check for NULL + delete me; +} + diff --git a/modules/java/srccpp/utils.cpp b/modules/java/srccpp/utils.cpp new file mode 100644 index 0000000000..2d016a03f2 --- /dev/null +++ b/modules/java/srccpp/utils.cpp @@ -0,0 +1,81 @@ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Class: org_opencv_utils + * Method: nBitmapToMat(Bitmap b) + * Signature: (L)J + */ +JNIEXPORT jlong JNICALL Java_org_opencv_utils_nBitmapToMat + (JNIEnv *, jclass, jobject); + +/* + * Class: org_opencv_utils + * Method: nBitmapToMat(long m, Bitmap b) + * Signature: (JL)Z + */ +JNIEXPORT jboolean JNICALL Java_org_opencv_utils_nMatToBitmap + (JNIEnv *, jclass, jlong, jobject); + + + +#ifdef __cplusplus +} +#endif + +#include "opencv2/core/core.hpp" + +#include + +JNIEXPORT jlong JNICALL Java_org_opencv_utils_nBitmapToMat + (JNIEnv * env, jclass cls, jobject bitmap) +{ + AndroidBitmapInfo info; + void* pixels; + cv::Mat* m = NULL; + + if ( AndroidBitmap_getInfo(env, bitmap, &info) < 0 ) + return 0; // can't get info + + if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) + return 0; // incompatible format + + if ( AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0 ) + return 0; // can't get pixels + + m = new cv::Mat(info.height, info.width, CV_8UC4); + memcpy(m->data, pixels, info.height * info.width * 4); + + AndroidBitmap_unlockPixels(env, bitmap); + + return (jlong)m; +} + +JNIEXPORT jboolean JNICALL Java_org_opencv_utils_nMatToBitmap + (JNIEnv * env, jclass cls, jlong m, jobject bitmap) +{ + AndroidBitmapInfo info; + void* pixels; + cv::Mat* mat = (cv::Mat*) m; + + if ( m == 0 ) + return false; // no native Mat behind + + if ( AndroidBitmap_getInfo(env, bitmap, &info) < 0 ) + return false; // can't get info + + if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) + return false; // incompatible format + + if ( AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0 ) + return false; // can't get pixels + + memcpy(pixels, mat->data, info.height * info.width * 4); + + AndroidBitmap_unlockPixels(env, bitmap); + + return true; +} diff --git a/modules/java/srcjava/Mat.java b/modules/java/srcjava/Mat.java new file mode 100644 index 0000000000..27ed864099 --- /dev/null +++ b/modules/java/srcjava/Mat.java @@ -0,0 +1,408 @@ +package org.opencv; + +public class Mat { + + public static class CvType { + + // predefined type constants + public static final CvType + CV_8UC1 = CV_8UC(1), CV_8UC2 = CV_8UC(2), CV_8UC3 = CV_8UC(3), CV_8UC4 = CV_8UC(4), + CV_8SC1 = CV_8SC(1), CV_8SC2 = CV_8SC(2), CV_8SC3 = CV_8SC(3), CV_8SC4 = CV_8SC(4), + CV_16UC1 = CV_16UC(1), CV_16UC2 = CV_16UC(2), CV_16UC3 = CV_16UC(3), CV_16UC4 = CV_16UC(4), + CV_16SC1 = CV_16SC(1), CV_16SC2 = CV_16SC(2), CV_16SC3 = CV_16SC(3), CV_16SC4 = CV_16SC(4), + CV_32SC1 = CV_32SC(1), CV_32SC2 = CV_32SC(2), CV_32SC3 = CV_32SC(3), CV_32SC4 = CV_32SC(4), + CV_32FC1 = CV_32FC(1), CV_32FC2 = CV_32FC(2), CV_32FC3 = CV_32FC(3), CV_32FC4 = CV_32FC(4), + CV_64FC1 = CV_64FC(1), CV_64FC2 = CV_64FC(2), CV_64FC3 = CV_64FC(3), CV_64FC4 = CV_64FC(4); + + // type depth constants + public static final int CV_8U = 0, + CV_8S = 1, + CV_16U = 2, + CV_16S = 3, + CV_32S = 4, + CV_32F = 5, + CV_64F = 6, + CV_USRTYPE1=7; + + private static final int CV_CN_MAX = 512, CV_CN_SHIFT = 3, CV_DEPTH_MAX = (1 << CV_CN_SHIFT); + + private final int value; + + protected CvType(int depth, int channels) { + if(channels<=0 || channels>=CV_CN_MAX) { + throw new java.lang.UnsupportedOperationException( + "Channels count should be 1.." + (CV_CN_MAX-1) ); + } + if(depth<0 || depth>=CV_DEPTH_MAX) { + throw new java.lang.UnsupportedOperationException( + "Data type depth should be 0.." + (CV_DEPTH_MAX-1) ); + } + value = (depth & (CV_DEPTH_MAX-1)) + ((channels-1) << CV_CN_SHIFT); + } + + protected CvType(int val) { value = val; } + + public static final CvType CV_8UC(int ch) { return new CvType(CV_8U, ch); } + + public static final CvType CV_8SC(int ch) { return new CvType(CV_8S, ch); } + + public static final CvType CV_16UC(int ch) { return new CvType(CV_16U, ch); } + + public static final CvType CV_16SC(int ch) { return new CvType(CV_16S, ch); } + + public static final CvType CV_32SC(int ch) { return new CvType(CV_32S, ch); } + + public static final CvType CV_32FC(int ch) { return new CvType(CV_32F, ch); } + + public static final CvType CV_64FC(int ch) { return new CvType(CV_64F, ch); } + + public final int toInt() { return value; } + + public final int channels() { return (value >> CV_CN_SHIFT) + 1; } + + public final int depth() { return value & (CV_DEPTH_MAX-1); } + + public final boolean isInteger() { return depth() < CV_32F; } + + public final int CV_ELEM_SIZE() { + int depth = value & (CV_DEPTH_MAX-1); + switch (depth) { + case CV_8U: + case CV_8S: + return channels(); + case CV_16U: + case CV_16S: + return 2 * channels(); + case CV_32S: + case CV_32F: + return 4 * channels(); + case CV_64F: + return 8 * channels(); + default: + throw new java.lang.UnsupportedOperationException( + "Unsupported CvType value: " + value ); + } + } + + @Override + public final String toString() { + String s; + switch (depth()) { + case CV_8U: + s = "CV_8U"; + break; + case CV_8S: + s = "CV_8S"; + break; + case CV_16U: + s = "CV_16U"; + break; + case CV_16S: + s = "CV_16S"; + break; + case CV_32S: + s = "CV_32S"; + break; + case CV_32F: + s = "CV_32F"; + break; + case CV_64F: + s = "CV_64F"; + break; + default: + s = "CV_USRTYPE1"; + } + + return s + "(" + channels() + ")"; + } + + // hashCode() has to be overridden if equals() is + @Override + public final int hashCode() { return value; } + + @Override + public final boolean equals(Object obj) { + if (this == obj) return true; + if ( !(obj instanceof CvType) ) return false; + CvType other = (CvType) obj; + return value == other.value; + } + } + + protected Mat(long nativeMat) { + /*if(nativeMat == 0) + throw new java.lang.UnsupportedOperationException("Native object address is NULL");*/ + this.nativeObj = nativeMat; + } + + public Mat(int rows, int cols, CvType type) { + this( nCreateMat(rows, cols, type.toInt()) ); + } + + public Mat(int rows, int cols, CvType type, double v0, double v1, double v2, double v3) { + this( nCreateMat(rows, cols, type.toInt(), v0, v1, v2, v3) ); + } + + public Mat(int rows, int cols, CvType type, double v0, double v1, double v2) { + this( nCreateMat(rows, cols, type.toInt(), v0, v1, v2, 0) ); + } + + public Mat(int rows, int cols, CvType type, double v0, double v1) { + this( nCreateMat(rows, cols, type.toInt(), v0, v1, 0, 0) ); + } + + public Mat(int rows, int cols, CvType type, double v0) { + this( nCreateMat(rows, cols, type.toInt(), v0, 0, 0, 0) ); + } + + public void dispose() { + if(nativeObj != 0) + nDispose(nativeObj); + nativeObj = 0; + } + + @Override + protected void finalize() throws Throwable { + dispose(); + super.finalize(); + } + + @Override + public String toString() { + if(nativeObj == 0) return "Mat [ nativeObj=NULL ]"; + return "Mat [ " + + rows() + "*" + cols() + "*" + type() + + ", isCont=" + isContinuous() + ", isSubmat=" + isSubmatrix() + + ", nativeObj=0x" + Long.toHexString(nativeObj) + + ", dataAddr=0x" + Long.toHexString(dataAddr()) + + " ]"; + } + + public boolean empty() { + if(nativeObj == 0) return true; + return nIsEmpty(nativeObj); +} + + private void checkNull() { + if(nativeObj == 0) + throw new java.lang.UnsupportedOperationException("Native object address is NULL"); + } + + public CvType type() { + checkNull(); + return new CvType( nType(nativeObj) ); + } + public int depth() { return type().depth(); } + public int channels() { return type().channels(); } + public int elemSize() { return type().CV_ELEM_SIZE(); } + + public int rows() { + if(nativeObj == 0) + return 0; + return nRows(nativeObj); + } + public int height() { return rows(); } + public int cols() { + if(nativeObj == 0) + return 0; + return nCols(nativeObj); + } + public int width() { return cols(); } + public int total() { return rows() * cols(); } + + public long dataAddr() { + if(nativeObj == 0) + return 0; + return nData(nativeObj); + } + + public boolean isContinuous() { + if(nativeObj == 0) + return false; // maybe throw an exception instead? + return nIsCont(nativeObj); + } + + public boolean isSubmatrix() { + if(nativeObj == 0) + return false; // maybe throw an exception instead? + return nIsSubmat(nativeObj); + } + + public Mat submat(int rowStart, int rowEnd, int colStart, int colEnd) { + checkNull(); + return new Mat( nSubmat(nativeObj, rowStart, rowEnd, colStart, colEnd) ); + } + public Mat rowRange(int start, int end) { return submat(start, end, 0, -1); } + public Mat row(int num) { return submat(num, num+1, 0, -1); } + public Mat colRange(int start, int end) { return submat(0, -1, start, end); } + public Mat col(int num) { return submat(0, -1, num, num+1); } + + public Mat clone() { + checkNull(); + return new Mat( nClone(nativeObj) ); + } + + public int put(int row, int col, double...data) { + checkNull(); + if(data != null) + return nPutD(nativeObj, row, col, data.length, data); + else + return 0; + } + + public int put(int row, int col, float[] data) { + checkNull(); + if(data != null) { + CvType t = type(); + if(t.depth() == CvType.CV_32F) { + return nPutF(nativeObj, row, col, data.length, data); + } + throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t); + } else return 0; + } + + public int put(int row, int col, int[] data) { + checkNull(); + if(data != null) { + CvType t = type(); + if(t.depth() == CvType.CV_32S) { + return nPutI(nativeObj, row, col, data.length, data); + } + throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t); + } else return 0; + } + + public int put(int row, int col, short[] data) { + checkNull(); + if(data != null) { + CvType t = type(); + if(t.depth() == CvType.CV_16U || t.depth() == CvType.CV_16S) { + return nPutS(nativeObj, row, col, data.length, data); + } + throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t); + } else return 0; + } + + public int put(int row, int col, byte[] data) { + checkNull(); + if(data != null) { + CvType t = type(); + if(t.depth() == CvType.CV_8U || t.depth() == CvType.CV_8S) { + return nPutB(nativeObj, row, col, data.length, data); + } + throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t); + } else return 0; + } + + public int get(int row, int col, byte[] data) { + checkNull(); + CvType t = type(); + if(t.depth() == CvType.CV_8U || t.depth() == CvType.CV_8S) { + return nGetB(nativeObj, row, col, data.length, data); + } + throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t); + } + + public int get(int row, int col, short[] data) { + checkNull(); + CvType t = type(); + if(t.depth() == CvType.CV_16U || t.depth() == CvType.CV_16S) { + return nGetS(nativeObj, row, col, data.length, data); + } + throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t); + } + + public int get(int row, int col, int[] data) { + checkNull(); + CvType t = type(); + if(t.depth() == CvType.CV_32S) { + return nGetI(nativeObj, row, col, data.length, data); + } + throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t); + } + + public int get(int row, int col, float[] data) { + checkNull(); + CvType t = type(); + if(t.depth() == CvType.CV_32F) { + return nGetF(nativeObj, row, col, data.length, data); + } + throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t); + } + + public int get(int row, int col, double[] data) { + checkNull(); + CvType t = type(); + if(t.depth() == CvType.CV_64F) { + return nGetD(nativeObj, row, col, data.length, data); + } + throw new java.lang.UnsupportedOperationException("Mat data type is not compatible: " + t); + } + + + public void setTo(double v0, double v1, double v2, double v3) { + checkNull(); + nSetTo(nativeObj, v0, v1, v2, v3); + } + public void setTo(double v0, double v1, double v2) { setTo(v0, v1, v2, 0); } + public void setTo(double v0, double v1) { setTo(v0, v1, 0, 0); } + public void setTo(double v0) { setTo(v0, 0, 0, 0); } + + public void copyTo(Mat m) { + checkNull(); + if(m.nativeObj == 0) + throw new java.lang.UnsupportedOperationException("Destination native object address is NULL"); + nCopyTo(nativeObj, m.nativeObj); + } + + public double dot(Mat m) { + checkNull(); + return nDot(nativeObj, m.nativeObj); + } + + public Mat cross(Mat m) { + checkNull(); + return new Mat( nCross(nativeObj, m.nativeObj) ); + } + + public Mat inv() { + checkNull(); + return new Mat( nInv(nativeObj) ); + } + + public long getNativeObjAddr() { + return nativeObj; + } + + // native stuff + static { System.loadLibrary("opencv_java"); } + protected long nativeObj; + private static native long nCreateMat(int rows, int cols, int type); + private static native long nCreateMat(int rows, int cols, int type, double v0, double v1, double v2, double v3); + private static native void nDispose(long self); + private static native int nType(long self); + private static native int nRows(long self); + private static native int nCols(long self); + private static native long nData(long self); + private static native boolean nIsEmpty(long self); + private static native boolean nIsCont(long self); + private static native boolean nIsSubmat(long self); + private static native long nSubmat(long self, int rowStart, int rowEnd, int colStart, int colEnd); + private static native long nClone(long self); + private static native int nPutD(long self, int row, int col, int count, double[] data); + private static native int nPutF(long self, int row, int col, int count, float[] data); + private static native int nPutI(long self, int row, int col, int count, int[] data); + private static native int nPutS(long self, int row, int col, int count, short[] data); + private static native int nPutB(long self, int row, int col, int count, byte[] data); + private static native int nGetB(long self, int row, int col, int count, byte[] vals); + private static native int nGetS(long self, int row, int col, int count, short[] vals); + private static native int nGetI(long self, int row, int col, int count, int[] vals); + private static native int nGetF(long self, int row, int col, int count, float[] vals); + private static native int nGetD(long self, int row, int col, int count, double[] vals); + private static native void nSetTo(long self, double v0, double v1, double v2, double v3); + private static native void nCopyTo(long self, long mat); + private static native double nDot(long self, long mat); + private static native long nCross(long self, long mat); + private static native long nInv(long self); + +} diff --git a/modules/java/srcjava/Point.java b/modules/java/srcjava/Point.java new file mode 100644 index 0000000000..22a448779b --- /dev/null +++ b/modules/java/srcjava/Point.java @@ -0,0 +1,47 @@ +package org.opencv; + +public class Point { + + public double x, y; + + public Point(double x, double y) { + this.x = x; + this.y = y; + } + + public Point() { + this(0, 0); + } + + public Point clone() { + return new Point(x, y); + } + + public double dot(Point p) { + return x * p.x + y * p.y; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + temp = Double.doubleToLongBits(x); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(y); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if ( ! (obj instanceof Point) ) return false; + Point it = (Point) obj; + return x == it.x && y == it.y; + } + + public boolean inside(Rect r) { + return r.contains(this); + } +} diff --git a/modules/java/srcjava/Point3.java b/modules/java/srcjava/Point3.java new file mode 100644 index 0000000000..b010c6806e --- /dev/null +++ b/modules/java/srcjava/Point3.java @@ -0,0 +1,56 @@ +package org.opencv; + +public class Point3 { + + public double x, y, z; + + public Point3(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Point3() { + this(0, 0, 0); + } + + public Point3(Point p) { + x = p.x; + y = p.y; + z = 0; + } + + public Point3 clone() { + return new Point3(x, y, z); + } + + public double dot(Point3 p) { + return x * p.x + y * p.y + z * p.z; + } + + public Point3 cross(Point3 p) { + return new Point3(y * p.z - z * p.y, z * p.x - x * p.z, x * p.y - y * p.x); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + temp = Double.doubleToLongBits(x); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(y); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(z); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof Point3)) return false; + Point3 it = (Point3) obj; + return x == it.x && y == it.y && z == it.z; + } +} diff --git a/modules/java/srcjava/Rect.java b/modules/java/srcjava/Rect.java new file mode 100644 index 0000000000..721dbf6f8c --- /dev/null +++ b/modules/java/srcjava/Rect.java @@ -0,0 +1,76 @@ +package org.opencv; + +public class Rect { + + int x, y, width, height; + + public Rect(int x, int y, int width, int height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + public Rect() { + this(0, 0, 0, 0); + } + + public Rect(Point p1, Point p2) { + x = (int) (p1.x < p2.x ? p1.x : p2.x); + y = (int) (p1.y < p2.y ? p1.y : p2.y); + width = (int) (p1.x > p2.x ? p1.x : p2.x) - x; + height = (int) (p1.y > p2.y ? p1.y : p2.y) - y; + } + + public Rect(Point p, Size s) { + this((int)p.x, (int)p.y, s.width, s.height); + } + + public Rect clone() { + return new Rect(x, y, width, height); + } + + public Point tl() { + return new Point(x, y); + } + + public Point br() { + return new Point(x + width, y + height); + } + + public Size size() { + return new Size(width, height); + } + + public double area() { + return width * height; + } + + public boolean contains(Point p) { + return x <= p.x && p.x < x + width && y <= p.y && p.y < y + height; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + temp = Double.doubleToLongBits(height); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(width); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(x); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(y); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof Rect)) return false; + Rect it = (Rect) obj; + return x == it.x && y == it.y && width == it.width && height == it.height; + } +} diff --git a/modules/java/srcjava/Scalar.java b/modules/java/srcjava/Scalar.java new file mode 100644 index 0000000000..a91268f15b --- /dev/null +++ b/modules/java/srcjava/Scalar.java @@ -0,0 +1,73 @@ +package org.opencv; + +public class Scalar { + + public double v0, v1, v2, v3; + + public Scalar(double v0, double v1, double v2, double v3) { + this.v0 = v0; + this.v1 = v1; + this.v2 = v2; + this.v3 = v3; + } + + public Scalar(double v0, double v1, double v2) { + this(v0, v1, v2, 0); + } + + public Scalar(double v0, double v1) { + this(v0, v1, 0, 0); + } + + public Scalar(double v0) { + this(v0, 0, 0, 0); + } + + public static Scalar all(double v) { + return new Scalar(v, v, v, v); + } + + public Scalar clone() { + return new Scalar(v0, v1, v2, v3); + } + + public Scalar mul(Scalar it, double scale) { + return new Scalar( v0 * it.v0 * scale, v1 * it.v1 * scale, + v2 * it.v2 * scale, v3 * it.v3 * scale ); + } + + public Scalar mul(Scalar it) { + return mul(it, 1); + } + public Scalar conj() { + return new Scalar(v0, -v1, -v2, -v3); + } + + public boolean isReal() { + return v1 == 0 && v2 == 0 && v3 == 0; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + temp = Double.doubleToLongBits(v0); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(v1); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(v2); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(v3); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof Scalar)) return false; + Scalar it = (Scalar) obj; + return v0 == it.v0 && v1 == it.v1 && v2 == it.v2 && v3 == it.v3; + } +} diff --git a/modules/java/srcjava/Size.java b/modules/java/srcjava/Size.java new file mode 100644 index 0000000000..55e29d7457 --- /dev/null +++ b/modules/java/srcjava/Size.java @@ -0,0 +1,49 @@ +package org.opencv; + +public class Size { + + public int width, height; + + public Size(int width, int height) { + this.width = width; + this.height = height; + } + + public Size() { + this(0, 0); + } + + public Size(Point p) { + width = (int) p.x; + height = (int) p.y; + } + + public double area() { + return width * height; + } + + public Size clone() { + return new Size(width, height); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + temp = Double.doubleToLongBits(height); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(width); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof Size)) return false; + Size it = (Size) obj; + return width == it.width && height == it.height; + } + +} diff --git a/modules/java/srcjava/utils.java b/modules/java/srcjava/utils.java new file mode 100644 index 0000000000..8f3d397774 --- /dev/null +++ b/modules/java/srcjava/utils.java @@ -0,0 +1,19 @@ +package org.opencv; + +import android.graphics.Bitmap; + +public class utils { + + public static Mat BitmapToMat(Bitmap b) { + return new Mat( nBitmapToMat(b) ); + } + + public static boolean MatToBitmap(Mat m, Bitmap b) { + return nMatToBitmap(m.nativeObj, b); + } + + // native stuff + static { System.loadLibrary("opencv_java"); } + private static native long nBitmapToMat(Bitmap b); + private static native boolean nMatToBitmap(long m, Bitmap b); +}