diff --git a/modules/c/CMakeLists.txt b/modules/c/CMakeLists.txt new file mode 100644 index 0000000000..7328996507 --- /dev/null +++ b/modules/c/CMakeLists.txt @@ -0,0 +1,110 @@ +set(the_description "C Wrappers") + +set(module_dependencies opencv_core opencv_contrib opencv_flann opencv_ml opencv_imgproc opencv_calib3d opencv_features2d opencv_video opencv_objdetect opencv_highgui opencv_photo opencv_legacy opencv_stitching opencv_superres opencv_ts opencv_nonfree) + +ocv_add_module(c ${module_dependencies}) + +set(OPENCV_MODULE_TYPE STATIC) + +set(opencv_hdrs + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core.hpp" + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/base.hpp" + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/types.hpp" + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/persistence.hpp" + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/utility.hpp" + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/mat.hpp" + "${OPENCV_MODULE_opencv_flann_LOCATION}/include/opencv2/flann/miniflann.hpp" + "${OPENCV_MODULE_opencv_imgproc_LOCATION}/include/opencv2/imgproc.hpp" + "${OPENCV_MODULE_opencv_video_LOCATION}/include/opencv2/video/background_segm.hpp" + "${OPENCV_MODULE_opencv_video_LOCATION}/include/opencv2/video/tracking.hpp" + "${OPENCV_MODULE_opencv_photo_LOCATION}/include/opencv2/photo.hpp" + "${OPENCV_MODULE_opencv_highgui_LOCATION}/include/opencv2/highgui.hpp" + "${OPENCV_MODULE_opencv_ml_LOCATION}/include/opencv2/ml.hpp" + "${OPENCV_MODULE_opencv_features2d_LOCATION}/include/opencv2/features2d.hpp" + "${OPENCV_MODULE_opencv_calib3d_LOCATION}/include/opencv2/calib3d.hpp" + "${OPENCV_MODULE_opencv_objdetect_LOCATION}/include/opencv2/objdetect.hpp" + "${OPENCV_MODULE_opencv_contrib_LOCATION}/include/opencv2/contrib.hpp" + "${OPENCV_MODULE_opencv_stitching_LOCATION}/include/opencv2/stitching.hpp" + "${OPENCV_MODULE_opencv_superres_LOCATION}/include/opencv2/superres.hpp" + "${OPENCV_MODULE_opencv_ts_LOCATION}/include/opencv2/ts.hpp" + "${OPENCV_MODULE_opencv_bioinspired_LOCATION}/include/opencv2/bioinspired.hpp" +) + +set(opencv_hdr_dirs + "${OPENCV_MODULE_opencv_core_LOCATION}/include/" + "${OPENCV_MODULE_opencv_flann_LOCATION}/include/" + "${OPENCV_MODULE_opencv_imgproc_LOCATION}/include/" + "${OPENCV_MODULE_opencv_video_LOCATION}/include/" + "${OPENCV_MODULE_opencv_photo_LOCATION}/include/" + "${OPENCV_MODULE_opencv_highgui_LOCATION}/include/" + "${OPENCV_MODULE_opencv_ml_LOCATION}/include/" + "${OPENCV_MODULE_opencv_features2d_LOCATION}/include/" + "${OPENCV_MODULE_opencv_calib3d_LOCATION}/include/" + "${OPENCV_MODULE_opencv_objdetect_LOCATION}/include/" + "${OPENCV_MODULE_opencv_contrib_LOCATION}/include/" + "${OPENCV_MODULE_opencv_bioinspired_LOCATION}/include/" + "${OPENCV_MODULE_opencv_stitching_LOCATION}/include/" + "${OPENCV_MODULE_opencv_superres_LOCATION}/include/" + "${OPENCV_MODULE_opencv_ts_LOCATION}/include/" + "${OPENCV_MODULE_opencv_bioinspired_LOCATION}/include/" + "${OPENCV_MODULE_opencv_nonfree_LOCATION}/include/" +) + + +if(HAVE_opencv_nonfree) + list(APPEND opencv_hdrs "${OPENCV_MODULE_opencv_nonfree_LOCATION}/include/opencv2/nonfree/features2d.hpp" + "${OPENCV_MODULE_opencv_nonfree_LOCATION}/include/opencv2/nonfree.hpp" + ) +endif() + +set(c_wrapper_header + "${CMAKE_CURRENT_BINARY_DIR}/include/opencv2/c/opencv_generated.hpp" +) + +set(c_wrapper_source + "${CMAKE_CURRENT_BINARY_DIR}/src/opencv_generated.cpp" +) + +file(GLOB headers "include/opencv2/*.hpp" "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h" "include/opencv2/*.h") + +file(GLOB_RECURSE sources "src/*.cpp") + +ocv_set_module_sources(HEADERS ${headers} ${c_wrapper_header} SOURCES ${sources} ${c_wrapper_source}) + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/opencv2/c/) +file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/include/opencv2/c/ ) +add_custom_command( + OUTPUT ${c_wrapper_source} ${c_wrapper_header} + COMMAND ${CMAKE_COMMAND} -E copy ${OPENCV_MODULE_opencv_python_LOCATION}/src2/hdr_parser.py ${CMAKE_CURRENT_BINARY_DIR}/src/ + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/src/genc.py" "${CMAKE_CURRENT_BINARY_DIR}/src/" + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/src/genc.py" ${CMAKE_CURRENT_BINARY_DIR} ${opencv_hdrs} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/opencv_generated.hpp ${CMAKE_CURRENT_BINARY_DIR}/include/opencv2/c/ + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/opencv_generated.cpp ${CMAKE_CURRENT_BINARY_DIR}/src + COMMAND ${CMAKE_COMMAND} -E copy ${c_wrapper_header} ${CMAKE_BINARY_DIR}/include/opencv2/c/ + COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/opencv_generated.hpp ${CMAKE_CURRENT_BINARY_DIR}/opencv_generated.cpp + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/genc.py + DEPENDS ${OPENCV_MODULE_opencv_python_LOCATION}/src2/hdr_parser.py + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/include/opencv2/opencv.h + DEPENDS ${headers} + DEPENDS ${opencv_hdrs} +) + +ocv_module_include_directories("${CMAKE_CURRENT_BINARY_DIR}/include" + "${CMAKE_SOURCE_DIR}/include" + ${opencv_hdr_dirs}) +ocv_create_module() +target_link_libraries(${the_module} ${module_dependencies}) + +add_library("${the_module}Dyn" SHARED ${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES} "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp") +set_target_properties("${the_module}Dyn" PROPERTIES OUTPUT_NAME ${the_module}) +add_dependencies(${the_module} ${the_module}Dyn) + +if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(${the_module} PROPERTIES FOLDER "bindings") +endif() + +install(FILES ${c_wrapper_header} DESTINATION include/opencv2/c/) +install(FILES ${headers} DESTINATION include/opencv2/c/) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/opencv2/opencv.h DESTINATION include/opencv2/) +install(TARGETS ${the_module}Dyn LIBRARY DESTINATION lib) diff --git a/modules/c/include/opencv2/c/disablesmartptr.hpp b/modules/c/include/opencv2/c/disablesmartptr.hpp new file mode 100644 index 0000000000..8bbc658162 --- /dev/null +++ b/modules/c/include/opencv2/c/disablesmartptr.hpp @@ -0,0 +1,25 @@ +/* + * ===================================================================================== + * + * Filename: smartptr.hpp + * + * Description: Header to disable smart pointers. This enables use of the C++ api from C + * while leaving memory management up to the caller. This is good for + * binding to other languages, but will cause problems if you expect + * smart pointers to work as normal. + * + * Version: 1.0 + * Created: 04/24/2014 05:31:41 PM + * Revision: none + * Compiler: g++ + * + * Author: Arjun Comar + * Organization: + * + * ===================================================================================== + */ + +#include + +using namespace cv; + diff --git a/modules/c/include/opencv2/c/excluded_functions.hpp b/modules/c/include/opencv2/c/excluded_functions.hpp new file mode 100644 index 0000000000..1b950c3566 --- /dev/null +++ b/modules/c/include/opencv2/c/excluded_functions.hpp @@ -0,0 +1,34 @@ +/* + * ===================================================================================== + * + * Filename: excluded_functions.hpp + * + * Description: Functions that the generator outputs incorrectly, either by them entirely + * or by outputting them with incorrectly specified types. + * + * Version: 1.0 + * Created: 04/13/2014 12:00:46 AM + * Revision: none + * Compiler: g++ + * + * Author: Arjun Comar + * + * ===================================================================================== + */ + +#include + +extern "C" { +CvANN_MLP_TrainParams* cv_create_CvANN_MLP_TrainParams(); +CvANN_MLP_TrainParams* cv_create_CvANN_MLP_TrainParams4(TermCriteria* term_crit, int train_method, double param1, double param2); +void cv_randu2(Mat* dst, Scalar* low, Scalar* high); +void cv_goodFeaturesToTrack2(Mat* image, vector_Point2f* corners, int maxCorners, double qualityLevel, double minDistance, Mat* mask, int blockSize, bool useHarrisDetector, double k); +Mat* cv_create_Mat_as_vectort(vector_Point2f* vec, bool copyData); +Size* cv_RotatedRect_size(RotatedRect* self); +Point* cv_RotatedRect_center(RotatedRect* self); +RotatedRect* cv_create_RotatedRect(Point* center, Size* size, float angle); +void cv_inRangeS(Mat* src, Scalar* lowerb, Scalar* upperb, Mat* dst); +int cv_createTrackbar(String* trackbarname, String* winname, int* value, int count, TrackbarCallback onChange, void* userdata); +void cv_setMouseCallback(String* winname, MouseCallback onMouse, void* userdata); +} + diff --git a/modules/c/include/opencv2/c/mat.hpp b/modules/c/include/opencv2/c/mat.hpp new file mode 100644 index 0000000000..9eb4c89d19 --- /dev/null +++ b/modules/c/include/opencv2/c/mat.hpp @@ -0,0 +1,77 @@ +/* + * ===================================================================================== + * + * Filename: mat.hpp + * + * Description: Wrappers for the OpenCV Matrix class + * + * Version: 1.0 + * Created: 09/24/13 20:01:07 + * Revision: none + * Compiler: g++ + * + * Author: Arjun Comar + * + * ===================================================================================== + */ + +#include + +extern "C" { +Mat* cv_create_Mat(); +Mat* cv_create_Mat_typed(int rows, int cols, int type); +Mat* cv_create_Mat_with_data(int rows, int cols, int type, void* data); +Mat* cv_create_Mat_with_value(int rows, int cols, int type, Scalar* s); +Mat* cv_Mat_assign(Mat* self, Mat* m); +Mat* cv_Mat_assignVal(Mat* self, Scalar* s); +Mat* cv_Mat_getRow(Mat* self, int y); +Mat* cv_Mat_getCol(Mat* self, int x); +Mat* cv_Mat_getRowRange(Mat* self, int startrow, int endrow); +Mat* cv_Mat_getColRange(Mat* self, int startrow, int endrow); +Mat* cv_Mat_diag(Mat* self); +Mat* cv_Mat_diag_d(Mat* self, int d); +Mat* cv_create_diagMat(Mat* d); +Mat* cv_Mat_clone(Mat* self); +void cv_Mat_copyTo(Mat* self, Mat* m); +void cv_Mat_copyTo_masked(Mat* self, Mat* m, Mat* mask); +void cv_Mat_assignTo(Mat* self, Mat* m); +void cv_Mat_assignTo_t(Mat*self, Mat* m, int t); +void cv_Mat_convertTo(Mat* self,Mat* m, int rtype, double alpha, double beta); +Mat* cv_Mat_setTo(Mat*self, Scalar* value); +Mat* cv_Mat_setTo_masked(Mat* self, Scalar* value, Mat* mask); +Mat* cv_Mat_reshape(Mat* self, int cn); +Mat* cv_Mat_reshape_rows(Mat* self, int cn, int rows); +size_t cv_Mat_elemSize(Mat* self); +size_t cv_Mat_elemSize1(Mat* self); +int cv_Mat_type(Mat* self); +int cv_Mat_depth(Mat* self); +size_t cv_Mat_total(Mat* self); +bool cv_Mat_isContinuous(Mat* self); +int cv_Mat_channels(Mat* self); +int cv_Mat_rows(Mat* self); +int cv_Mat_cols(Mat* self); +int cv_Mat_empty(Mat* self); +Size* cv_Mat_size(Mat* self); +size_t cv_Mat_get_Step(Mat* self); +size_t cv_Mat_step1(Mat* self); +uchar* cv_Mat_ptr(Mat* self); +uchar* cv_Mat_ptr_index(Mat* self, int i); +Mat* cv_create_identity(int rows, int cols, int type); +Mat* cv_create_ones(int rows, int cols, int type); +Mat* cv_create_zeros(int rows, int cols, int type); +MatExpr* cv_Mat_transpose_mat(Mat* self); +MatExpr* cv_Mat_inv_mat(Mat* self, int method); +MatExpr* cv_Mat_add(Mat* m1, Mat* m2); +MatExpr* cv_Mat_mult(Mat* m1, Mat* m2); +Mat* force(MatExpr* expr); +MatExpr* promote(Mat* m); +MatExpr* cv_Mat_scale(MatExpr* m, double alpha); +double cv_Mat_dot(Mat* self, Mat* m); +Mat* cv_Mat_cross(Mat* self, Mat* m); +void cv_Mat_locateROI(Mat* self, Size* s, Point* p); +Mat* cv_Mat_adjustROI(Mat* self, int dtop, int dbottom, int dleft, int dright); +void cv_delete_Mat(Mat* self); +void cv_destruct_Mat(Mat* self); +void cv_delete_MatExpr(MatExpr* self); +void cv_destruct_MatExpr(MatExpr* self); +} diff --git a/modules/c/include/opencv2/c/point.hpp b/modules/c/include/opencv2/c/point.hpp new file mode 100644 index 0000000000..ed89e9922b --- /dev/null +++ b/modules/c/include/opencv2/c/point.hpp @@ -0,0 +1,37 @@ +/* + * ===================================================================================== + * + * Filename: point.hpp + * + * Description: Wrapper header for the OpenCV Point class(es) + * + * Version: 1.0 + * Created: 10/02/2013 11:54:37 AM + * Revision: none + * Compiler: g++ + * + * Author: Arjun Comar + * + * ===================================================================================== + */ + +#include + +#define ADD_POINT_FUNC_HEADERS(t, tn) \ + Point2##t * cv_create_Point2##t ( tn x, tn y); \ + Point3##t * cv_create_Point3##t ( tn x, tn y, tn z); \ + tn cv_Point2##t##_getX( Point2##t * self); \ + tn cv_Point2##t##_getY( Point2##t * self); \ + tn cv_Point3##t##_getX( Point3##t * self); \ + tn cv_Point3##t##_getY( Point3##t * self); \ + tn cv_Point3##t##_getZ( Point3##t * self); \ + tn cv_Point2##t##_dot( Point2##t * self, Point2##t * other); \ + tn cv_Point3##t##_dot( Point3##t * self, Point3##t * other); \ + Point3##t * cv_Point3##t##_cross(Point3##t * self, Point3##t * other); + +extern "C" { + ADD_POINT_FUNC_HEADERS(i, int); + ADD_POINT_FUNC_HEADERS(f, float); + ADD_POINT_FUNC_HEADERS(d, double); +} + diff --git a/modules/c/include/opencv2/c/rect.hpp b/modules/c/include/opencv2/c/rect.hpp new file mode 100644 index 0000000000..b8f8dd919b --- /dev/null +++ b/modules/c/include/opencv2/c/rect.hpp @@ -0,0 +1,19 @@ +#ifndef __CV_C_RECT_HPP__ +#define __CV_C_RECT_HPP__ +#include + +extern "C" { +Rect* cv_create_Rect(); +Rect* cv_create_Rect4(int x, int y, int width, int height); +Rect* cv_Rect_assignTo(Rect* self, Rect* r); +Rect* cv_Rect_clone(Rect* self); +Point* cv_Rect_tl(Rect* self); +Point* cv_Rect_br(Rect* self); +int cv_Rect_getX(Rect* self); +int cv_Rect_getY(Rect* self); +int cv_Rect_getWidth(Rect* self); +int cv_Rect_getHeight(Rect* self); +Size* cv_Rect_size(Rect* self); +int cv_Rect_contains(Rect* self, Point* pt); +} +#endif diff --git a/modules/c/include/opencv2/c/scalar.hpp b/modules/c/include/opencv2/c/scalar.hpp new file mode 100644 index 0000000000..302e47ac5a --- /dev/null +++ b/modules/c/include/opencv2/c/scalar.hpp @@ -0,0 +1,23 @@ +/* + * ===================================================================================== + * + * Filename: scalar.hpp + * + * Description: Wrappers for the OpenCV Matrix class + * + * Version: 1.0 + * Created: 03/17/14 18:85:00 + * Revision: none + * Compiler: g++ + * + * Author: Arjun Comar + * + * ===================================================================================== + */ + +#include + +extern "C" { +Scalar* cv_create_Scalar(double val0, double val1, double val2, double val3); +Scalar* cv_create_scalarAll(double val0123); +} diff --git a/modules/c/include/opencv2/c/size.hpp b/modules/c/include/opencv2/c/size.hpp new file mode 100644 index 0000000000..22e2aa61b3 --- /dev/null +++ b/modules/c/include/opencv2/c/size.hpp @@ -0,0 +1,16 @@ +#ifndef __CV_C_SIZE_HPP__ +#define __CV_C_SIZE_HPP__ +#include + +extern "C" { + Size2f* cv_create_Size2f(float width, float height); + Size* cv_create_Size(); + Size* cv_create_Size2(double width, double height); + Size* cv_Size_assignTo(Size* self, Size* other); + Size* cv_Size_fromPoint(Point* p); + double cv_Size_area(Size* self); + double cv_Size_width(Size* self); + double cv_Size_height(Size* self); +} +#endif + diff --git a/modules/c/include/opencv2/opencv.h b/modules/c/include/opencv2/opencv.h new file mode 100644 index 0000000000..ae35e1fef3 --- /dev/null +++ b/modules/c/include/opencv2/opencv.h @@ -0,0 +1,8 @@ +#ifndef __OPENCV_C_H +#define __OPENCV_C_H +#include +#include +#include +#include +#include +#endif //__OPENCV_C_H diff --git a/modules/c/src/excluded_functions.cpp b/modules/c/src/excluded_functions.cpp new file mode 100644 index 0000000000..56abb6a357 --- /dev/null +++ b/modules/c/src/excluded_functions.cpp @@ -0,0 +1,67 @@ +/* + * ===================================================================================== + * + * Filename: excluded_functions.cpp + * + * Description: Functions that the generator outputs incorrectly, either by them entirely + * or by outputting them with incorrectly specified types. + * + * Version: 1.0 + * Created: 04/13/2014 12:06:39 AM + * Revision: none + * Compiler: g++ + * + * Author: Arjun Comar + * + * ===================================================================================== + */ +#include + +extern "C" { + +CvANN_MLP_TrainParams* cv_create_CvANN_MLP_TrainParams() { + return new CvANN_MLP_TrainParams(); +} + +CvANN_MLP_TrainParams* cv_create_CvANN_MLP_TrainParams4(TermCriteria* term_crit, int train_method, double param1, double param2) { + return new CvANN_MLP_TrainParams(*term_crit, train_method, param1, param2); +} + +void cv_randu2(Mat* dst, Scalar* low, Scalar* high) { + cv::randu(*dst, *low, *high); +} + +void cv_goodFeaturesToTrack2(Mat* image, vector_Point2f* corners, int maxCorners, double qualityLevel, double minDistance, Mat* mask, int blockSize, bool useHarrisDetector, double k) { + cv::goodFeaturesToTrack(*image, *corners, maxCorners, qualityLevel, minDistance, *mask, blockSize, useHarrisDetector, k); +} + +Mat* cv_create_Mat_as_vectort(vector_Point2f* vec, bool copyData) { + return new Mat(*vec, copyData); +} + +Point* cv_RotatedRect_center(RotatedRect* self) { + return new Point(self->center); +} + +Size* cv_RotatedRect_size(RotatedRect* self) { + return new Size(self->size); +} + +RotatedRect* cv_create_RotatedRect(Point* center, Size* size, float angle) { + return new RotatedRect(*center, *size, angle); +} + +void cv_inRangeS(Mat* src, Scalar* lowerb, Scalar* upperb, Mat* dst) { + cv::inRange(*src, *lowerb, *upperb, *dst); +} + +int cv_createTrackbar(String* trackbarname, String* winname, int* value, int count, TrackbarCallback onChange, void* userdata) { + return cv::createTrackbar(*trackbarname, *winname, value, count, onChange, userdata); +} + +void cv_setMouseCallback(String* winname, MouseCallback onMouse, void* userdata) { + return cv::setMouseCallback(*winname, onMouse, userdata); +} + + +} diff --git a/modules/c/src/genc.py b/modules/c/src/genc.py new file mode 100755 index 0000000000..cb14fbb489 --- /dev/null +++ b/modules/c/src/genc.py @@ -0,0 +1,415 @@ +#!/usr/bin/python +from __future__ import print_function +import hdr_parser +import re +import sys + +if sys.version_info[0] >= 3: + from io import StringIO +else: + from cStringIO import StringIO + +_types = ["CvANN", "flann", "c"] # literally, underscore types. +namespaces = ["SimpleBlobDetector"] +empty_types = ["cvflann", "flann"] + +exceptions = {"distance_t": "flann_distance_t", + "algorithm_t": "flann_algorithm_t", + # The following was taken care of previously by _types, + # But for some reason, it doesn't work with the typedefs. + r"CvANN<(\w+?)<(\w+)>>": r"CvANN_\1_\2"} + +simple_types = ["int", "int64", "bool", "float", "double", + "char*", "char", "size_t", "c_string", "void"] + +excluded_functions = ["cv_randu2", + "cv_goodFeaturesToTrack2", + "cv_create_Mat_as_vectort", + "cv_RotatedRect_size", + "cv_RotatedRect_center", + "cv_create_RotatedRect", + "cv_inRangeS", + "cv_createTrackbar", + "cv_setMouseCallback"] + + +class TypeInfo(object): + _types = list(map(lambda t: re.compile(r"" + t + r"_(\w+)"), _types)) + generic_type = re.compile(r"(\w+?)_((\w{2,}))") + nss = list(zip(namespaces, map(lambda ns: re.compile(r"" + ns + r"_(\w+)"), + namespaces))) + empty_types = list(map(lambda et: re.compile(r"" + et + r"_(\w+)"), + empty_types)) + ptr = re.compile(r"Ptr_(\w+)") + + def __init__(self, name, decl): + self.name = name.replace("Ptr_", "") + self.cname = TypeInfo.gen_cname(self.name) + self.fields = {} + + if decl: + for p in decl[3]: + self.fields[p[1]] = p[0] + + @staticmethod + def gen_cname(name): + cname = name + # make basic substitutions to get rid of basic types + # and correct namespaces + for m in TypeInfo.empty_types: + cname = m.sub(r"\1", cname) + for ns, m in TypeInfo.nss: + cname = m.sub(r"" + ns + r"::\1", cname) + + if TypeInfo.ptr.match(cname): + TypeInfo.ptr.sub(r"\1*", cname) + + # fix templated types + while (TypeInfo.generic_type.search(cname) and + not any(t.match(cname) for t in TypeInfo._types)): + cname = TypeInfo.generic_type.sub(r"\1<\2>", cname) + + # fix any exceptional type issues and type1> issues + for e in exceptions: + cname = re.sub(e, exceptions[e], cname) + cname = re.sub(r"(\w+)<(\w+)<(\w+)>>", r"\1<\2<\3> >", cname) + return cname + + +class ConstInfo(object): + def __init__(self, name, val): + self.cname = name.replace(".", "::") + self.name = name.replace(".", "_") + self.name = re.sub(r"cv_([a-z])([A-Z])", r"cv_\1_\2", self.name) + self.name = self.name.upper() + if self.name.startswith("CV") and self.name[2] != "_": + self.name = "CV_" + self.name[2:] + self.value = val + self.isfractional = re.match(r"^d+?\.\d+?$", self.value) + + +class ArgInfo(object): + def __init__(self, arg_tuple): + self.tp = TypeInfo.ptr.sub(r"\1*", arg_tuple[0]) + self.truetp = arg_tuple[0] + self.name = arg_tuple[1] + self.defval = arg_tuple[2] + self.isarray = False + self.arraylen = 0 + self.arraycvt = None + self.inputarg = True + self.outputarg = False + self.returnarg = False + for m in arg_tuple[3]: + if m == "/O": + self.inputarg = False + self.outputarg = True + self.returnarg = True + elif m == "/IO": + self.inputarg = True + self.outputarg = True + self.returnarg = True + elif m.startswith("/A"): + self.isarray = True + self.arraylen = m[2:].strip() + elif m.startswith("/CA"): + self.isarray = True + self.arraycvt = m[2:].strip() + self.py_inputarg = False + self.py_outputarg = False + + def isbig(self): + return self.tp == "Mat" or self.tp == "vector_Mat" + + def crepr(self): + return "ArgInfo(\"%s\", %d)" % (self.name, self.outputarg) + + +class FuncInfo(object): + def __init__(self, classname, name, cname, + rettype, isconstructor, ismethod, args): + self.classname = classname + self.name = name + self.cname = cname + self.isconstructor = isconstructor + self.variants = [] + self.args = args + self.rettype = rettype + if ismethod: + self_arg = ArgInfo((classname + "*", "self", None, [])) + self.args = [self_arg] + self.args + self.ismethod = ismethod + + def get_wrapper_name(self): + name = self.name + if self.classname: + classname = self.classname + "_" + if "[" in name: + name = re.sub(r"operator\[\]", "getelem", name) + elif "(" in name: + name = re.sub(r"operator \(\)", "call", name) + else: + classname = "" + + if self.isconstructor: + return "cv_create_" + name + else: + return "cv_" + classname + name + + def get_wrapper_prototype(self): + full_fname = self.get_wrapper_name() + + ptr_template = self.rettype.startswith("Ptr_") + ptr = ptr_template or self.rettype.endswith("*") + s = "" if self.rettype in simple_types or ptr else "*" + if ptr_template: + rettype = TypeInfo.ptr.sub(r"\1*", self.rettype) + else: + rettype = self.rettype + s + ret = self.classname + "*" if self.isconstructor else rettype + + proto = "%s %s(" % (ret, full_fname) + for arg in self.args: + t = arg.tp + simple = t in simple_types + pointer = t.endswith("*") + if not simple and not pointer and arg.name != self or arg.isarray: + format_s = "%s* %s, " + else: + format_s = "%s %s, " + + proto += format_s % (t, arg.name) + + if proto.endswith("("): + return proto + ");" + else: + return proto[:-2] + ");" + + def fix_call(self, call): + if not call.endswith("("): + call = call[:-2] + + void = self.rettype == "void" + simple = self.rettype in simple_types + pointer = self.rettype.endswith("*") + # The following looks weird, but it's to deref the smart pointer + # and return the simple pointer. + if self.rettype.startswith("Ptr_"): + call = "&*" + call + elif not (void or simple or pointer or self.isconstructor): + call = "new " + self.rettype + "(" + call + ")" + + return call + ");" + + def gen_code(self): + proto = self.get_wrapper_prototype()[:-1] + code = "%s {\n" % (proto,) + + ret = "" if self.rettype == "void" else "return " + prefix = "" + postfix = self.cname + args = self.args + if self.isconstructor: + prefix = "new " + postfix = self.classname + elif self.ismethod: + prefix = "self->" + args = args[1:] + + call = prefix + "%s(" % (postfix,) + + for arg in args: + smart_ptr = arg.truetp.startswith("Ptr_") + name = arg.name + if smart_ptr: + name = "Ptr<" + arg.tp[:-1] + ">(" + arg.name + ")" + + simple = arg.tp in simple_types + ptr = arg.tp.endswith("*") + s = "" if simple or ptr else "*" + call += s + name + ", " + + call = self.fix_call(call) + code += "\t" + ret + call + code += "\n}\n" + + return code + + +class CWrapperGenerator(object): + def __init__(self): + self.clear() + + def clear(self): + self.funcs = {} + self.consts = {} + self.types = {} + self.source = StringIO() + self.header = StringIO() + + def add_const(self, name, decl): + constinfo = ConstInfo(name, decl[1]) + + i = 0 + while constinfo.name + str(i) in self.consts: + i += 1 + + constinfo.name += str(i) + self.consts[constinfo.name] = constinfo + + def add_func(self, decl): + classname = bareclassname = "" + name = decl[0] # looks like cv{.classname}*.func + dpos = name.rfind(".") + if dpos >= 0 and name[:dpos] != "cv": + classname = bareclassname = re.sub(r"^cv\.", "", name[:dpos]) + name = name[dpos + 1:] + dpos = classname.rfind(".") + if dpos >= 0: + bareclassname = classname[dpos + 1:] + classname = classname.replace(".", "_") + + cname = name + name = re.sub(r"^cv\.", "", name) + if name in excluded_functions: + return + + isconstructor = cname == bareclassname + ismethod = not isconstructor and bareclassname != "" + + cname = cname.replace(".", "::") + + args = list(map(ArgInfo, decl[3])) + for a in args: + self.add_type(a.tp, None) + + if name in self.funcs.keys(): + name = self.fix_overloaded_func(name, len(args)) + + self.funcs[name] = FuncInfo(bareclassname, name, cname, + decl[1], isconstructor, ismethod, args) + self.add_type(decl[1], None) + + def fix_overloaded_func(self, n, nargs): + name = n + + name += str(nargs) + + #ugly, but keeps with the old behavior and adds to it. + if name in self.funcs.keys(): + i = 0 + while True: + #overloaded function with the same number of args :/ + if not name + "_" + str(i) in self.funcs.keys(): + name += "_" + str(i) + break + else: + i += 1 + return name + + def add_type(self, name, decl): + typeinfo = TypeInfo(name, decl) + + if not typeinfo.name in self.types: + self.types[typeinfo.name] = typeinfo + + def save(self, path, name, buf): + f = open(path + "/" + name, "wt") + f.write(buf.getvalue()) + f.close() + + def gen_const_reg(self, constinfo): + self.header.write("#define %s %s\n" + % (constinfo.name, constinfo.cname)) + + def gen_typedef(self, typeinfo): + self.header.write("typedef %s %s;\n" + % (typeinfo.cname.replace("*", ""), + typeinfo.name.replace("*", ""))) + + def prep_src(self): + self.source.write("#include \n") + self.source.write("using namespace cv;\n") + self.source.write("using namespace std;\n") + self.source.write("using namespace flann;\n") + self.source.write("using namespace cvflann;\n") + self.source.write("extern \"C\" {\n") + + def prep_header(self): + self.header.write("#ifndef __OPENCV_GENERATED_HPP\n") + self.header.write("#define __OPENCV_GENERATED_HPP\n") + self.header.write("#include \n") + self.header.write("#include \n") + self.header.write("#include \n") + self.header.write("#include \n") + self.header.write("using namespace cv;\n") + self.header.write("using namespace std;\n") + self.header.write("using namespace flann;\n") + self.header.write("using namespace cvflann;\n") + self.header.write("extern \"C\" {\n") + self.header.write("typedef char* c_string;\n") + self.header.write("typedef SimpleBlobDetector::Params Params;\n") + self.header.write("typedef linemod::Detector Detector;\n") + + def finalize_and_write(self, output_path): + self.header.write("}\n") + self.header.write("#endif //__OPENCV_GENERATED_HPP") + self.source.write("}") + self.save(output_path, "opencv_generated.hpp", self.header) + self.save(output_path, "opencv_generated.cpp", self.source) + + def readHeaders(self, srcfiles): + parser = hdr_parser.CppHeaderParser() + + 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_type(name.replace("class ", "").strip(), decl) + elif name.startswith("const"): + self.add_const(name.replace("const ", "").strip(), decl) + else: + self.add_func(decl) + + def gen(self, srcfiles, output_path): + self.clear() + + if not srcfiles: + srcfiles = hdr_parser.opencv_hdr_list + self.readHeaders(srcfiles) + self.prep_header() + self.prep_src() + + typelist = list(self.types.items()) + typelist.sort() + for name, typeinfo in typelist: + if typeinfo.name != typeinfo.cname: + self.gen_typedef(typeinfo) + + constlist = list(self.consts.items()) + constlist.sort() + for name, const in constlist: + self.gen_const_reg(const) + + funclist = list(self.funcs.items()) + funclist.sort() + for name, func in funclist: + prototype = func.get_wrapper_prototype() + "\n" + code = func.gen_code() + self.header.write(prototype) + self.source.write(code) + + self.finalize_and_write(output_path) + + +if __name__ == "__main__": + srcfiles = None + dstdir = "." + if len(sys.argv) > 1: + dstdir = sys.argv[1] + if len(sys.argv) > 2: + srcfiles = sys.argv[2:] + + generator = CWrapperGenerator() + generator.gen(srcfiles, dstdir) diff --git a/modules/c/src/mat.cpp b/modules/c/src/mat.cpp new file mode 100644 index 0000000000..2879e5f367 --- /dev/null +++ b/modules/c/src/mat.cpp @@ -0,0 +1,255 @@ +/* + * ===================================================================================== + * + * Filename: mat.cpp + * + * Description: + * + * Version: 1.0 + * Created: 09/24/13 20:12:17 + * Revision: none + * Compiler: g++ + * + * Author: Arjun Comar + * Organization: + * + * ===================================================================================== + */ +#include + +extern "C" { + +Mat* cv_create_Mat() { + return new Mat(); +} + +Mat* cv_create_Mat_typed(int rows, int cols, int type) { + return new Mat(rows, cols, type); +} + +Mat* cv_create_Mat_with_data(int rows, int cols, int type, void* data) { + return new Mat(rows, cols, type, data); +} + +Mat* cv_create_Mat_with_value(int rows, int cols, int type, Scalar* s) { + return new Mat(rows, cols, type, *s); +} + + +Mat* cv_Mat_assign(Mat* self, Mat* m) { + *self = *m; + return self; +} + +Mat* cv_Mat_assignVal(Mat* self, Scalar* s) { + *self = *s; + return self; +} + +Mat* cv_Mat_getRow(Mat* self, int y) { + return new Mat(self->row(y)); +} + +Mat* cv_Mat_getCol(Mat* self, int x) { + return new Mat(self->col(x)); +} + +Mat* cv_Mat_getRowRange(Mat* self, int startrow, int endrow) { + return new Mat(self->rowRange(startrow, endrow)); +} + +Mat* cv_Mat_getColRange(Mat* self, int startcol, int endrow) { + return new Mat(self->colRange(startcol, endrow)); +} + +Mat* cv_Mat_diag(Mat* self) { + return new Mat(self->diag()); +} + +Mat* cv_Mat_diag_d(Mat* self, int d) { + return new Mat(self->diag(d)); +} + +Mat* cv_create_diagMat(Mat* d) { + return new Mat(Mat::diag(*d)); +} + +Mat* cv_Mat_clone(Mat* self) { + return new Mat(self->clone()); +} + +void cv_Mat_copyTo(Mat* self, Mat* m) { + self->copyTo(*m); +} + +void cv_Mat_copyTo_masked(Mat* self, Mat* m, Mat* mask) { + self->copyTo(*m, *mask); +} + +void cv_Mat_assignTo(Mat* self, Mat* m) { + self->assignTo(*m); +} + +void cv_Mat_assignTo_t(Mat*self, Mat* m, int t) { + self->assignTo(*m, t); +} + +void cv_Mat_convertTo(Mat* self,Mat* m, int rtype, double alpha, double beta) { + self->convertTo(*m, rtype, alpha, beta); +} + +Mat* cv_Mat_setTo(Mat* self, Scalar* value) { + Mat* m = new Mat; + *m = *value; + return new Mat(self->setTo(*m)); +} + +Mat* cv_Mat_setTo_masked(Mat* self, Scalar* value, Mat* mask) { + Mat* m = new Mat; + *m = *value; + return new Mat(self->setTo(*m, *mask)); +} + +Mat* cv_Mat_reshape(Mat* self, int cn) { + return new Mat(self->reshape(cn)); +} + +Mat* cv_Mat_reshape_rows(Mat* self, int cn, int rows) { + return new Mat(self->reshape(cn, rows)); +} + +size_t cv_Mat_elemSize(Mat* self) { + return self->elemSize(); +} + +size_t cv_Mat_elemSize1(Mat* self) { + return self->elemSize1(); +} + +int cv_Mat_type(Mat* self) { + return self->type(); +} + +int cv_Mat_depth(Mat* self) { + return self->depth(); +} + +size_t cv_Mat_total(Mat* self) { + return self->total(); +} + +bool cv_Mat_isContinuous(Mat* self) { + return self->isContinuous(); +} + +int cv_Mat_channels(Mat* self) { + return self->channels(); +} + +int cv_Mat_rows(Mat* self) { + return self->rows; +} + +int cv_Mat_cols(Mat* self) { + return self->cols; +} + +int cv_Mat_empty(Mat* self) { + return self->empty(); +} + +Size* cv_Mat_size(Mat* self) { + return new Size(self->size()); +} + +size_t cv_Mat_get_Step(Mat* self) { + return self->step; +} + +size_t cv_Mat_step1(Mat* self) { + return self->step1(); +} + +uchar* cv_Mat_ptr(Mat* self) { + return self->ptr(); +} + +uchar* cv_Mat_ptr_index(Mat* self, int i) { + return self->ptr(i); +} + +Mat* cv_create_identity(int rows, int cols, int type) { + return new Mat(Mat::eye(rows, cols, type)); +} + +Mat* cv_create_ones(int rows, int cols, int type) { + return new Mat(Mat::ones(rows, cols, type)); +} + +Mat* cv_create_zeros(int rows, int cols, int type) { + return new Mat(Mat::zeros(rows, cols, type)); +} + +MatExpr* cv_Mat_transpose_mat(Mat* self) { + return new MatExpr(self->t()); +} + +MatExpr* cv_Mat_inv_mat(Mat* self, int method) { + return new MatExpr(self->inv(method)); +} + +MatExpr* cv_Mat_add(Mat* m1, Mat* m2) { + return new MatExpr(*m1 + *m2); +} + +MatExpr* cv_Mat_mult(Mat* m1, Mat* m2) { + return new MatExpr(*m1 * *m2); +} + +Mat* force(MatExpr* expr) { + Mat* p = new Mat; + *p = *expr; + return p; +} + +MatExpr* promote(Mat* m) { + return new MatExpr(*m); +} + +MatExpr* cv_Mat_scale(MatExpr* m, double alpha) { + return new MatExpr(*m * alpha); +} + +double cv_Mat_dot(Mat* self, Mat* m) { + return self->dot(*m); +} + +Mat* cv_Mat_cross(Mat* self, Mat* m) { + return new Mat(self->cross(*m)); +} + +void cv_Mat_locateROI(Mat* self, Size* s, Point* p) { + self->locateROI(*s, *p); +} + +Mat* cv_Mat_adjustROI(Mat* self, int dtop, int dbottom, int dleft, int dright) { + return new Mat(self->adjustROI(dtop, dbottom, dleft, dright)); +} + +void cv_delete_Mat(Mat* self) { + delete self; +} + +void cv_destruct_Mat(Mat* self) { + self->~Mat(); +} + +void cv_delete_MatExpr(MatExpr* self) { + delete self; +} + +void cv_destruct_MatExpr(MatExpr* self) { + self->~MatExpr(); +} + +} diff --git a/modules/c/src/point.cpp b/modules/c/src/point.cpp new file mode 100644 index 0000000000..7ddf0424ef --- /dev/null +++ b/modules/c/src/point.cpp @@ -0,0 +1,39 @@ +#include + +#define ADD_POINT_FUNC_IMPL(t, tn) \ + Point2##t * cv_create_Point2##t ( tn x, tn y) { \ + return new Point2##t (x, y);\ + } \ + Point3##t * cv_create_Point3##t ( tn x, tn y, tn z) { \ + return new Point3##t (x, y, z);\ + } \ + tn cv_Point2##t##_getX( Point2##t * self) { \ + return self->x;\ + }\ + tn cv_Point2##t##_getY( Point2##t * self) { \ + return self->y;\ + }\ + tn cv_Point3##t##_getX( Point3##t * self) { \ + return self->x;\ + }\ + tn cv_Point3##t##_getY( Point3##t * self) { \ + return self->y;\ + }\ + tn cv_Point3##t##_getZ( Point3##t * self) { \ + return self->z;\ + }\ + tn cv_Point2##t##_dot( Point2##t * self, Point2##t * other) { \ + return self->dot(*other);\ + }\ + tn cv_Point3##t##_dot( Point3##t * self, Point3##t * other) { \ + return self->dot(*other);\ + }\ + Point3##t * cv_Point3##t##_cross(Point3##t * self, Point3##t * other) { \ + return new Point3##t (self->cross(*other));\ + } + +extern "C" { + ADD_POINT_FUNC_IMPL(i, int); + ADD_POINT_FUNC_IMPL(f, float); + ADD_POINT_FUNC_IMPL(d, double); +} diff --git a/modules/c/src/rect.cpp b/modules/c/src/rect.cpp new file mode 100644 index 0000000000..fa6e3be083 --- /dev/null +++ b/modules/c/src/rect.cpp @@ -0,0 +1,41 @@ +#include + +extern "C" { +Rect* cv_create_Rect() { + return new Rect; +} +Rect* cv_create_Rect4(int x, int y, int width, int height) { + return new Rect(x, y, width, height); +} +Rect* cv_Rect_assignTo(Rect* self, Rect* r) { + *self = *r; + return self; +} +Rect* cv_Rect_clone(Rect* self) { + return new Rect(self->x, self->y, self->width, self->height); +} +Point* cv_Rect_tl(Rect* self) { + return new Point(self->tl()); +} +Point* cv_Rect_br(Rect* self) { + return new Point(self->br()); +} +int cv_Rect_getX(Rect* self) { + return self->x; +} +int cv_Rect_getY(Rect* self) { + return self->y; +} +int cv_Rect_getWidth(Rect* self) { + return self->width; +} +int cv_Rect_getHeight(Rect* self) { + return self->height; +} +Size* cv_Rect_size(Rect* self) { + return new Size(self->size()); +} +int cv_Rect_contains(Rect* self, Point* pt) { + return self->contains(*pt); +} +} diff --git a/modules/c/src/scalar.cpp b/modules/c/src/scalar.cpp new file mode 100644 index 0000000000..13af44487e --- /dev/null +++ b/modules/c/src/scalar.cpp @@ -0,0 +1,32 @@ +/* + * ===================================================================================== + * + * Filename: scalar.cpp + * + * Description: + * + * Version: 1.0 + * Created: 03/17/14 18:49:28 + * Revision: none + * Compiler: gcc + * + * Author: YOUR NAME (), + * Organization: + * + * ===================================================================================== + */ +#include + +extern "C" { + +Scalar* cv_create_Scalar(double val0, double val1, double val2, double val3) +{ + return new Scalar(val0, val1, val2, val3); +} + +Scalar* cv_create_scalarAll(double val0123) +{ + return new Scalar(Scalar::all(val0123)); +} + +} diff --git a/modules/c/src/size.cpp b/modules/c/src/size.cpp new file mode 100644 index 0000000000..ffdc231414 --- /dev/null +++ b/modules/c/src/size.cpp @@ -0,0 +1,27 @@ +#include + +extern "C" { + + Size* cv_create_Size() { + return new Size; + } + Size* cv_create_Size2(double width, double height) { + return new Size(width, height); + } + Size* cv_Size_assignTo(Size* self, Size* other) { + *self = *other; + return self; + } + Size* cv_Size_fromPoint(Point* p) { + return new Size(*p); + } + double cv_Size_area(Size* self) { + return self->area(); + } + double cv_Size_width(Size* self) { + return self->width; + } + double cv_Size_height(Size* self) { + return self->height; + } +} diff --git a/modules/haskell/CMakeLists.txt b/modules/haskell/CMakeLists.txt new file mode 100644 index 0000000000..50fb63e822 --- /dev/null +++ b/modules/haskell/CMakeLists.txt @@ -0,0 +1,166 @@ +set(the_description "Haskell Bindings") + +if(NOT ANDROID AND NOT IOS) + +if(CMAKE_HOST_WIN32) + set(GHC_NAME ghc.exe) + set(CABAL_NAME cabal.exe) +else() + set(GHC_NAME ghc) + set(CABAL_NAME cabal) +endif() + +find_host_program(GHC_EXECUTABLE NAMES ${GHC_NAME} + PATHS "/usr/bin" #TODO: Figure out where ghc/cabal are installed on other systems. + NO_DEFAULT_PATH +) + +find_host_program(GHC_EXECUTABLE NAMES ${GHC_NAME}) + +if(GHC_EXECUTABLE) + execute_process(COMMAND ${GHC_EXECUTABLE} --version + RESULT_VARIABLE GHC_ERROR_LEVEL + OUTPUT_VARIABLE GHC_VERSION_FULL + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(GHC_ERROR_LEVEL) + unset(GHC_EXECUTABLE) + unset(GHC_EXECUTABLE CACHE) + else() + string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" GHC_VERSION "${GHC_VERSION_FULL}") + set(GHC_VERSION "${GHC_VERSION}" CACHE INTERNAL "Detected ghc version") + endif() +endif() + +find_host_program(CABAL_EXECUTABLE NAMES ${CABAL_NAME} + PATHS "/usr/bin" + NO_DEFAULT_PATH +) + +find_host_program(CABAL_EXECUTABLE NAMES ${CABAL_NAME}) + +if(CABAL_EXECUTABLE) + execute_process(COMMAND ${CABAL_EXECUTABLE} --version + RESULT_VARIABLE CABAL_ERROR_LEVEL + OUTPUT_VARIABLE CABAL_VERSION_FULL + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(CABAL_ERROR_LEVEL) + unset(CABAL_EXECUTABLE) + unset(CABAL_EXECUTABLE CACHE) + else() + string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" CABAL_VERSION "${CABAL_VERSION_FULL}") + set(CABAL_VERSION "${CABAL_VERSION}" CACHE INTERNAL "Detected cabal version") + endif() +endif() + +if(GHC_EXECUTABLE AND CABAL_EXECUTABLE) + +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/OpenCV") +set(opencv_hdrs + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core.hpp" + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/base.hpp" + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/types.hpp" + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/persistence.hpp" + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/utility.hpp" + "${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/mat.hpp" + "${OPENCV_MODULE_opencv_flann_LOCATION}/include/opencv2/flann/miniflann.hpp" + "${OPENCV_MODULE_opencv_imgproc_LOCATION}/include/opencv2/imgproc.hpp" + "${OPENCV_MODULE_opencv_video_LOCATION}/include/opencv2/video/background_segm.hpp" + "${OPENCV_MODULE_opencv_video_LOCATION}/include/opencv2/video/tracking.hpp" + "${OPENCV_MODULE_opencv_photo_LOCATION}/include/opencv2/photo.hpp" + "${OPENCV_MODULE_opencv_highgui_LOCATION}/include/opencv2/highgui.hpp" + "${OPENCV_MODULE_opencv_ml_LOCATION}/include/opencv2/ml.hpp" + "${OPENCV_MODULE_opencv_features2d_LOCATION}/include/opencv2/features2d.hpp" + "${OPENCV_MODULE_opencv_calib3d_LOCATION}/include/opencv2/calib3d.hpp" + "${OPENCV_MODULE_opencv_objdetect_LOCATION}/include/opencv2/objdetect.hpp" + "${OPENCV_MODULE_opencv_contrib_LOCATION}/include/opencv2/contrib.hpp" + "${OPENCV_MODULE_opencv_superres_LOCATION}/include/opencv2/superres.hpp" + "${OPENCV_MODULE_opencv_bioinspired_LOCATION}/include/opencv2/bioinspired.hpp" +) + +set(opencv_hdr_dirs + "${OPENCV_MODULE_opencv_core_LOCATION}/include/" + "${OPENCV_MODULE_opencv_flann_LOCATION}/include/" + "${OPENCV_MODULE_opencv_imgproc_LOCATION}/include/" + "${OPENCV_MODULE_opencv_video_LOCATION}/include/" + "${OPENCV_MODULE_opencv_photo_LOCATION}/include/" + "${OPENCV_MODULE_opencv_highgui_LOCATION}/include/" + "${OPENCV_MODULE_opencv_ml_LOCATION}/include/" + "${OPENCV_MODULE_opencv_features2d_LOCATION}/include/" + "${OPENCV_MODULE_opencv_calib3d_LOCATION}/include/" + "${OPENCV_MODULE_opencv_objdetect_LOCATION}/include/" + "${OPENCV_MODULE_opencv_contrib_LOCATION}/include/" + "${OPENCV_MODULE_opencv_stitching_LOCATION}/include/" + "${OPENCV_MODULE_opencv_superres_LOCATION}/include/" + "${OPENCV_MODULE_opencv_ts_LOCATION}/include/" + "${OPENCV_MODULE_opencv_bioinspired_LOCATION}/include/" + "${OPENCV_MODULE_opencv_nonfree_LOCATION}/include/" + ) +if(HAVE_opencv_nonfree) + list(APPEND opencv_hdrs "${OPENCV_MODULE_opencv_nonfree_LOCATION}/include/opencv2/nonfree/features2d.hpp" + "${OPENCV_MODULE_opencv_nonfree_LOCATION}/include/opencv2/nonfree.hpp") +endif() + +set(haskell_generated_sources + "${CMAKE_CURRENT_BINARY_DIR}/OpenCV/Types.hsc" + "${CMAKE_CURRENT_BINARY_DIR}/OpenCV/Funcs.hsc" + "${CMAKE_CURRENT_BINARY_DIR}/OpenCV/Consts.hsc" +) + +set(haskell_sources + "${CMAKE_CURRENT_BINARY_DIR}/OpenCV/Mat.hsc" + "${CMAKE_CURRENT_BINARY_DIR}/OpenCV/Point.hsc" + "${CMAKE_CURRENT_BINARY_DIR}/OpenCV/Rect.hsc" +) + +set(haskell_build_files + "${CMAKE_CURRENT_BINARY_DIR}/OpenCV.hs" + "${CMAKE_CURRENT_BINARY_DIR}/Setup.hs" + "${CMAKE_CURRENT_BINARY_DIR}/opencv.cabal" + "${CMAKE_CURRENT_BINARY_DIR}/LICENSE" +) + +# Copy necessary files over to the build directory. +foreach(file_i ${haskell_sources}) + get_filename_component(name_i ${file_i} NAME) + if(NOT EXISTS ${file_i}) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/OpenCV/${name_i} ${CMAKE_CURRENT_BINARY_DIR}/OpenCV COPYONLY) + endif() +endforeach() + +foreach(file_i ${haskell_build_files}) + get_filename_component(name_i ${file_i} NAME) + if(NOT EXISTS ${file_i}) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/${name_i} ${CMAKE_CURRENT_BINARY_DIR}/ COPYONLY) + endif() +endforeach() + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src) +# generate ffi wrappers +add_custom_command( + OUTPUT ${haskell_generated_sources} + COMMAND ${CMAKE_COMMAND} -E copy "${OPENCV_MODULE_opencv_python_LOCATION}/src2/hdr_parser.py" "${CMAKE_CURRENT_BINARY_DIR}/src/" + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/src/genhsc.py" "${CMAKE_CURRENT_BINARY_DIR}/src/" + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/src/genhsc.py" "${CMAKE_CURRENT_BINARY_DIR}/OpenCV" ${opencv_hdrs} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/genhsc.py + DEPENDS ${OPENCV_MODULE_opencv_python_LOCATION}/src2/hdr_parser.py + DEPENDS ${opencv_hdrs} +) + +add_custom_target(haskell ALL + COMMAND ${CMAKE_COMMAND} -E echo Generating Haskell bindings if necessary. + DEPENDS ${haskell_generated_sources} + DEPENDS ${haskell_sources} + DEPENDS ${haskell_build_files} + DEPENDS opencv_c +) + +set(includes) +foreach(hdr ${opencv_hdr_dirs}) + list(APPEND includes "--extra-include-dirs=${hdr} ") +endforeach() + +install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_BINARY_DIR} ${CABAL_EXECUTABLE} install \"--global\" \"--with-gcc=${CMAKE_CXX_COMPILER}\" \"--extra-include-dirs=${CMAKE_BINARY_DIR}/include\" ${includes} \"--extra-lib-dirs=${CMAKE_BINARY_DIR}/lib\" \"--gcc-options=${CMAKE_C_FLAGS}${CMAKE_CXX_FLAGS}\")") +endif() +endif() diff --git a/modules/haskell/src/LICENSE b/modules/haskell/src/LICENSE new file mode 100644 index 0000000000..f577dfa3b9 --- /dev/null +++ b/modules/haskell/src/LICENSE @@ -0,0 +1,30 @@ +Copyright (c) 2013, Arjun Comar + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Arjun Comar nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/modules/haskell/src/OpenCV.hs b/modules/haskell/src/OpenCV.hs new file mode 100644 index 0000000000..45e8041fb6 --- /dev/null +++ b/modules/haskell/src/OpenCV.hs @@ -0,0 +1,15 @@ +module OpenCV( + module OpenCV.Types +, module OpenCV.Funcs +, module OpenCV.Mat +, module OpenCV.Consts +, module OpenCV.Point +, module OpenCV.Rect +) where + +import OpenCV.Types +import OpenCV.Funcs +import OpenCV.Mat +import OpenCV.Consts +import OpenCV.Point +import OpenCV.Rect diff --git a/modules/haskell/src/OpenCV/Mat.hsc b/modules/haskell/src/OpenCV/Mat.hsc new file mode 100644 index 0000000000..f2e71c230c --- /dev/null +++ b/modules/haskell/src/OpenCV/Mat.hsc @@ -0,0 +1,79 @@ +{-# LANGUAGE ForeignFunctionInterface #-} +#include +#include +module OpenCV.Mat where +#strict_import + +import OpenCV.Types +import Foreign + +#num CV_64FC1 +#num CV_32FC1 +#num CV_32SC1 +#num CV_16SC1 +#num CV_8SC1 +#num CV_8UC1 +#num CV_64FC3 +#num CV_32FC3 +#num CV_32SC3 +#num CV_16SC3 +#num CV_8SC3 +#num CV_8UC3 + +#opaque_t MatExpr + +#ccall cv_create_Mat , Ptr +#ccall cv_create_Mat_typed , CInt -> CInt -> CInt -> Ptr +#ccall cv_create_Mat_with_data , CInt -> CInt -> CInt -> Ptr a -> Ptr +#ccall cv_Mat_clone , Ptr -> IO (Ptr ) +#ccall cv_Mat_getRow , Ptr -> CInt -> Ptr +#ccall cv_Mat_getCol , Ptr -> CInt -> Ptr +#ccall cv_Mat_getRowRange , Ptr -> CInt -> CInt -> Ptr +#ccall cv_Mat_getColRange , Ptr -> CInt -> CInt -> Ptr +#ccall cv_Mat_elemSize , Ptr -> CSize +#ccall cv_Mat_elemSize1 , Ptr -> CSize +#ccall cv_Mat_type , Ptr -> CInt +#ccall cv_Mat_depth , Ptr -> CInt +#ccall cv_Mat_total , Ptr -> CSize +#ccall cv_Mat_isContinuous , Ptr -> CInt +#ccall cv_Mat_channels , Ptr -> CInt +#ccall cv_Mat_rows , Ptr -> CInt +#ccall cv_Mat_cols , Ptr -> CInt +#ccall cv_Mat_empty , Ptr -> CInt +#ccall cv_Mat_size , Ptr -> Ptr +#ccall cv_Mat_step1 , Ptr -> CSize +#ccall cv_Mat_ptr , Ptr -> Ptr CUChar +#ccall cv_Mat_ptr_index , Ptr -> CInt -> Ptr CUChar + +#ccall cv_Mat_assign , Ptr -> Ptr -> IO (Ptr ) +#ccall cv_Mat_assignVal , Ptr -> Ptr -> IO (Ptr ) +#ccall cv_Mat_copyTo , Ptr -> Ptr -> IO () +#ccall cv_Mat_copyTo_masked , Ptr -> Ptr -> Ptr -> IO () +#ccall cv_Mat_assignTo , Ptr -> Ptr -> IO () +#ccall cv_Mat_assignTo_t , Ptr -> Ptr -> CInt -> IO () +#ccall cv_Mat_setTo , Ptr -> Ptr -> IO (Ptr ) +#ccall cv_Mat_setTo_masked , Ptr -> Ptr -> Ptr -> IO (Ptr ) + +#ccall cv_Mat_reshape , Ptr -> CInt -> IO (Ptr ) +#ccall cv_Mat_reshape_rows , Ptr -> CInt -> CInt -> IO (Ptr ) + +#ccall cv_Mat_diag , Ptr -> Ptr +#ccall cv_Mat_diag_d , Ptr -> CInt -> Ptr +#ccall cv_create_diagMat , Ptr -> Ptr +#ccall cv_create_identity , CInt -> CInt -> CInt -> Ptr +#ccall cv_create_ones , CInt -> CInt -> CInt -> Ptr +#ccall cv_create_zeros , CInt -> CInt -> CInt -> Ptr + +#ccall promote , Ptr -> Ptr +#ccall force , Ptr -> IO (Ptr ) +#ccall cv_Mat_transpose_mat , Ptr -> Ptr +#ccall cv_Mat_inv_mat , Ptr -> CInt -> Ptr +#ccall cv_Mat_add , Ptr -> Ptr -> Ptr +#ccall cv_Mat_mult , Ptr -> Ptr -> Ptr +#ccall cv_Mat_scale , Ptr -> CDouble -> Ptr + +#ccall cv_Mat_dot , Ptr -> Ptr -> CDouble +#ccall cv_Mat_cross , Ptr -> Ptr -> Ptr + +#ccall cv_Mat_locateROI , Ptr -> Ptr -> Ptr -> IO () +#ccall cv_Mat_adjustROI , Ptr -> CInt -> CInt -> CInt -> CInt -> IO (Ptr ) diff --git a/modules/haskell/src/OpenCV/Point.hsc b/modules/haskell/src/OpenCV/Point.hsc new file mode 100644 index 0000000000..080c42815d --- /dev/null +++ b/modules/haskell/src/OpenCV/Point.hsc @@ -0,0 +1,48 @@ +{-# LANGUAGE ForeignFunctionInterface #-} +#include +#include + +module OpenCV.Point where +#strict_import + +import OpenCV.Types + +#opaque_t Point3i +#opaque_t Point3f +#opaque_t Point3d + +#ccall cv_create_Point2i , CInt -> CInt -> IO (Ptr ) +#ccall cv_Point2i_getX , Ptr -> IO CInt +#ccall cv_Point2i_getY , Ptr -> IO CInt +#ccall cv_Point2i_dot , Ptr -> Ptr -> IO CInt + +#ccall cv_create_Point2f , CFloat -> CFloat -> IO (Ptr ) +#ccall cv_Point2f_getX , Ptr -> IO CFloat +#ccall cv_Point2f_getY , Ptr -> IO CFloat +#ccall cv_Point2f_dot , Ptr -> Ptr -> IO CFloat + +#ccall cv_create_Point2d , CDouble -> CDouble -> IO (Ptr ) +#ccall cv_Point2d_getX , Ptr -> IO CDouble +#ccall cv_Point2d_getY , Ptr -> IO CDouble +#ccall cv_Point2d_dot , Ptr -> Ptr -> IO CDouble + +#ccall cv_create_Point3i , CInt -> CInt -> CInt -> IO (Ptr ) +#ccall cv_Point3i_getX , Ptr -> IO CInt +#ccall cv_Point3i_getY , Ptr -> IO CInt +#ccall cv_Point3i_getZ , Ptr -> IO CInt +#ccall cv_Point3i_dot , Ptr -> Ptr -> IO CInt +#ccall cv_Point3i_cross , Ptr -> Ptr -> IO (Ptr ) + +#ccall cv_create_Point3f , CFloat -> CFloat -> CFloat -> IO (Ptr ) +#ccall cv_Point3f_getX , Ptr -> IO CFloat +#ccall cv_Point3f_getY , Ptr -> IO CFloat +#ccall cv_Point3f_getZ , Ptr -> IO CFloat +#ccall cv_Point3f_dot , Ptr -> Ptr -> IO CFloat +#ccall cv_Point3f_cross , Ptr -> Ptr -> IO (Ptr ) + +#ccall cv_create_Point3d , CDouble -> CDouble -> CDouble -> IO (Ptr ) +#ccall cv_Point3d_getX , Ptr -> IO CDouble +#ccall cv_Point3d_getY , Ptr -> IO CDouble +#ccall cv_Point3d_getZ , Ptr -> IO CDouble +#ccall cv_Point3d_dot , Ptr -> Ptr -> IO CDouble +#ccall cv_Point3d_cross , Ptr -> Ptr -> IO (Ptr ) diff --git a/modules/haskell/src/OpenCV/Rect.hsc b/modules/haskell/src/OpenCV/Rect.hsc new file mode 100644 index 0000000000..b361a3f5eb --- /dev/null +++ b/modules/haskell/src/OpenCV/Rect.hsc @@ -0,0 +1,22 @@ +{-# LANGUAGE ForeignFunctionInterface #-} +#include +#include + +module OpenCV.Rect where +#strict_import + +import OpenCV.Types + +#ccall cv_create_Rect , IO (Ptr ) +#ccall cv_create_Rect4 , CInt -> CInt -> CInt -> CInt -> IO (Ptr ) +#ccall cv_Rect_assignTo , Ptr -> Ptr -> IO (Ptr ) +#ccall cv_Rect_clone , Ptr -> IO (Ptr ) + +#ccall cv_Rect_tl , Ptr -> IO (Ptr ) +#ccall cv_Rect_br , Ptr -> IO (Ptr ) +#ccall cv_Rect_getX , Ptr -> IO CInt +#ccall cv_Rect_getY , Ptr -> IO CInt +#ccall cv_Rect_getWidth , Ptr -> IO CInt +#ccall cv_Rect_getHeight , Ptr -> IO CInt +#ccall cv_Rect_size , Ptr -> IO (Ptr ) +#ccall cv_Rect_contains , Ptr -> Ptr -> IO CInt diff --git a/modules/haskell/src/Setup.hs b/modules/haskell/src/Setup.hs new file mode 100644 index 0000000000..c9bc4f05ee --- /dev/null +++ b/modules/haskell/src/Setup.hs @@ -0,0 +1,8 @@ +import Distribution.Simple + +main :: IO () +main = defaultMainWithHooks simpleUserHooks { + -- The following hook prevents cabal from checking to see if generated cpp header and + -- source files actually compile before completing configuration. + postConf = postConf emptyUserHooks } + diff --git a/modules/haskell/src/genhsc.py b/modules/haskell/src/genhsc.py new file mode 100644 index 0000000000..1c3752d20e --- /dev/null +++ b/modules/haskell/src/genhsc.py @@ -0,0 +1,330 @@ +#!/usr/bin/python +from __future__ import print_function +import hdr_parser +import sys +import re + +if sys.version_info[0] >= 3: + from io import StringIO +else: + from cStringIO import StringIO + +simple_types = {"int": "CInt", + "int64": "CLong", + "bool": "CInt", + "float": "CFloat", + "double": "CDouble", + "char*": "CString", + "char": "CChar", + "size_t": "CSize", + "c_string": "CString", + "void": "()"} +exceptions = {"flann_Index": "Index", + "SimpleBlobDetector_Params": "Params", + "cvflann_flann_distance_t": "flann_distance_t", + "cvflann_flann_algorithm_t": "flann_algorithm_t", + "flann_IndexParams": "IndexParams", + "flann_SearchParams": "SearchParams"} + + +class TypeInfo(object): + ptr = re.compile(r"Ptr_(\w+)") + + def __init__(self, name, decl): + self.name = name.replace("Ptr_", "") + self.fields = {} + + if decl: + for p in decl[3]: + self.fields[p[1]] = p[0] + + +class ArgInfo(object): + def __init__(self, arg_tuple): + self.tp = TypeInfo.ptr.sub(r"\1*", arg_tuple[0]) + self.truetp = arg_tuple[0] + self.name = arg_tuple[1] + self.defval = arg_tuple[2] + self.isarray = False + self.arraylen = 0 + self.arraycvt = None + self.inputarg = True + self.outputarg = False + self.returnarg = False + for m in arg_tuple[3]: + if m == "/O": + self.inputarg = False + self.outputarg = True + self.returnarg = True + elif m == "/IO": + self.inputarg = True + self.outputarg = True + self.returnarg = True + elif m.startswith("/A"): + self.isarray = True + self.arraylen = m[2:].strip() + elif m.startswith("/CA"): + self.isarray = True + self.arraycvt = m[2:].strip() + self.py_inputarg = False + self.py_outputarg = False + + def isbig(self): + return self.tp == "Mat" or self.tp == "vector_Mat" + + def crepr(self): + return "ArgInfo(\"%s\", %d)" % (self.name, self.outputarg) + + +class ConstInfo(object): + def __init__(self, name, val): + self.cname = name.replace(".", "::") + self.name = name.replace(".", "_") + self.name = re.sub(r"cv_([a-z])([A-Z])", r"cv_\1_\2", self.name) + self.name = self.name.upper() + if self.name.startswith("CV") and self.name[2] != "_": + self.name = "CV_" + self.name[2:] + self.value = val + self.isfractional = re.match(r"^d+?\.\d+?$", self.value) + + +class FuncInfo(object): + def __init__(self, classname, name, cname, + rettype, isconstructor, ismethod, args): + self.classname = classname + self.name = name + self.cname = cname + self.isconstructor = isconstructor + self.variants = [] + self.args = args + self.rettype = rettype + if ismethod: + self_arg = ArgInfo((classname + "*", "self", None, [])) + self.args = [self_arg] + self.args + self.ismethod = ismethod + + def get_wrapper_name(self): + name = self.name + if self.classname: + classname = self.classname + "_" + if "[" in name: + name = re.sub(r"operator\[\]", "getelem", name) + elif "(" in name: + name = re.sub(r"operator \(\)", "call", name) + else: + classname = "" + + if self.isconstructor: + return "cv_create_" + name + else: + return "cv_" + classname + name + + +def toHSType(t): + if t in simple_types: + return simple_types[t] + # check if we have a pointer to a simple_type + elif t[:-1] in simple_types: + return "Ptr " + simple_types[t[:-1]] + + t = re.sub(r"Ptr_(\w+)", r"\1*", t) + + if t in exceptions: + t = exceptions[t] + elif t[:-1] in exceptions: + t = exceptions[t[:-1]] + + ptr = t.endswith("*") + t = "<" + t + ">" + if ptr: + t = re.sub(r"<(\w+)\*>", r"Ptr <\1>", t) + else: + t = re.sub(r"(.+)", r"Ptr \1", t) + + return t + + +class HSCWrapperGen(object): + def __init__(self): + self.types = {} + self.funcs = {} + self.consts = {} + self.gentypes = {} + self.hsc_types = StringIO() + self.hsc_funcs = StringIO() + self.hsc_consts = StringIO() + + def gen_const(self, constinfo): + if constinfo.isfractional: + self.hsc_consts.write("#fractional %s\n" % constinfo.cname,) + else: + self.hsc_consts.write("#num %s\n" % constinfo.name,) + + def gen_type(self, typeinfo): + if not typeinfo.name: + return None + + name = typeinfo.name.replace("cv.", "") + name = name.replace("*", "") + name = name.replace("struct ", "") + name = name.replace(".", "_") + name = name.replace("Ptr_", "") + + if name in exceptions: + name = exceptions[name] + + if not (name in self.gentypes or name in simple_types): + self.hsc_types.write("#opaque_t %s\n" % name) + self.gentypes[name] = typeinfo + + def gen_func(self, func): + code = "#ccall %s , " % (func.get_wrapper_name(),) + for a in func.args: + code += "%s -> " % toHSType(a.tp) + + ret = func.classname + "*" if func.isconstructor else func.rettype + hsc_ret = toHSType(ret) + if " " in hsc_ret: + hsc_ret = "(" + hsc_ret + ")" + code += "IO %s\n" % hsc_ret + + self.hsc_funcs.write(code) + + def prep_hsc(self): + for hsc in [self.hsc_types, self.hsc_consts, self.hsc_funcs]: + hsc.write("{-# LANGUAGE ForeignFunctionInterface #-}\n") + hsc.write("#include \n") + hsc.write("#include \n") + + self.hsc_types.write("module OpenCV.Types where\n") + self.hsc_consts.write("module OpenCV.Consts where\n") + self.hsc_funcs.write("module OpenCV.Funcs where\n") + + for hsc in [self.hsc_types, self.hsc_consts, self.hsc_funcs]: + hsc.write("#strict_import\n") + hsc.write("import Foreign.C\n") + hsc.write("import Foreign.C.Types\n") + + self.hsc_funcs.write("import OpenCV.Types\n") + + def add_type(self, name, decl): + typeinfo = TypeInfo(name, decl) + + if not typeinfo.name in self.types: + self.types[typeinfo.name] = typeinfo + + def add_func(self, decl): + classname = bareclassname = "" + name = decl[0] # looks like cv{.classname}*.func + dpos = name.rfind(".") + if dpos >= 0 and name[:dpos] != "cv": + classname = bareclassname = re.sub(r"^cv\.", "", name[:dpos]) + name = name[dpos + 1:] + dpos = classname.rfind(".") + if dpos >= 0: + bareclassname = classname[dpos + 1:] + classname = classname.replace(".", "_") + + cname = name + name = re.sub(r"^cv\.", "", name) + isconstructor = cname == bareclassname + ismethod = not isconstructor and bareclassname != "" + + cname = cname.replace(".", "::") + + args = list(map(ArgInfo, decl[3])) + for a in args: + self.add_type(a.tp, None) + + if name in self.funcs.keys(): + name = self.fix_overloaded_func(name, len(args)) + + self.funcs[name] = FuncInfo(bareclassname, name, cname, + decl[1], isconstructor, ismethod, args) + self.add_type(decl[1], None) + + def fix_overloaded_func(self, n, nargs): + name = n + + name += str(nargs) + + #ugly, but keeps with the old behavior and adds to it. + if name in self.funcs.keys(): + i = 0 + while True: + #overloaded function with the same number of args :/ + if not name + "_" + str(i) in self.funcs.keys(): + name += "_" + str(i) + break + else: + i += 1 + return name + + def add_const(self, name, decl): + constinfo = ConstInfo(name, decl[1]) + + i = 0 + while constinfo.name + str(i) in self.consts: + i += 1 + + constinfo.name += str(i) + self.consts[constinfo.name] = constinfo + + def readHeaders(self, srcfiles): + parser = hdr_parser.CppHeaderParser() + + 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_type(name.replace("class ", "").strip(), decl) + elif name.startswith("const"): + self.add_const(name.replace("const ", "").strip(), decl) + else: + self.add_func(decl) + + def save(self, dstdir, outfile, buf): + f = open(dstdir + outfile + ".hsc", "wt") + f.write(buf.getvalue()) + f.close() + + def gen(self, srcfiles, dstdir): + if not srcfiles: + srcfiles = hdr_parser.opencv_hdr_list + self.readHeaders(srcfiles) + self.prep_hsc() + + # Generate the code for consts, types, and functions + constlist = list(self.consts.items()) + constlist.sort() + for n, c in constlist: + self.gen_const(c) + + typelist = list(self.types.items()) + typelist.sort() + for n, t in typelist: + self.gen_type(t) + + funclist = list(self.funcs.items()) + funclist.sort() + for n, f in funclist: + self.gen_func(f) + + if not dstdir.endswith("/"): + dstdir += "/" + + self.save(dstdir, "Types", self.hsc_types) + self.save(dstdir, "Consts", self.hsc_consts) + self.save(dstdir, "Funcs", self.hsc_funcs) + +if __name__ == "__main__": + hscdstdir = "OpenCV/" + headers = None + if len(sys.argv) > 1: + hscdstdir = sys.argv[1] + if len(sys.argv) > 2: + headers = sys.argv[2:] + + hsc = HSCWrapperGen() + hsc.gen(headers, hscdstdir) diff --git a/modules/haskell/src/opencv.cabal b/modules/haskell/src/opencv.cabal new file mode 100644 index 0000000000..7ee20dcfab --- /dev/null +++ b/modules/haskell/src/opencv.cabal @@ -0,0 +1,48 @@ +name: opencv +version: 3.0.0 +synopsis: Haskell Bindings for OpenCV +homepage: www.github.com/itseez/opencv.git +license: BSD3 +license-file: LICENSE +author: Arjun Comar +maintainer: nrujac@gmail.com +category: AI, Machine Vision +build-type: Custom +cabal-version: >=1.10 + +source-repository head + type: git + location: git://github.com/itseez/opencv.git + +library + extra-libraries: opencv_c + , opencv_core + , opencv_flann + , opencv_imgproc + , opencv_video + , opencv_photo + , opencv_highgui + , opencv_ml + , opencv_features2d + , opencv_calib3d + , opencv_objdetect + , opencv_contrib + , opencv_stitching + , opencv_superres + , opencv_ts + if os(linux) + cc-options: -fpermissive -std=c++11 + else + cc-options: -fpermissive + ghc-options: -pgml g++ + exposed-modules: OpenCV + other-modules: OpenCV.Types + , OpenCV.Consts + , OpenCV.Funcs + , OpenCV.Mat + , OpenCV.Point + , OpenCV.Rect + build-depends: base >=4.6 && <5 + , bindings-DSL >= 1.0.20 && < 1.1 + , Cabal >=1.10 + default-language: Haskell2010