1const CV_CN_MAX = 512
2const CV_CN_SHIFT = 3
3const CV_DEPTH_MAX = (1 << CV_CN_SHIFT)
4
5const CV_8U = 0
6const CV_8S = 1
7const CV_16U = 2
8const CV_16S = 3
9const CV_32S = 4
10const CV_32F = 5
11const CV_64F = 6
12
13const CV_MAT_DEPTH_MASK = (CV_DEPTH_MAX - 1)
14CV_MAT_DEPTH(flags) = ((flags) & CV_MAT_DEPTH_MASK)
15
16CV_MAKETYPE(depth,cn) = (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))
17CV_MAKE_TYPE = CV_MAKETYPE
18
19function cpp_to_julia(mat::CxxMat)
20    rets = jlopencv_core_Mat_mutable_data(mat)
21    if rets[2] == CV_MAKE_TYPE(CV_8U, rets[3])
22        dtype = UInt8
23    elseif rets[2]==CV_MAKE_TYPE(CV_8S, rets[3])
24        dtype = Int8
25    elseif rets[2]==CV_MAKE_TYPE(CV_16U, rets[3])
26        dtype = UInt16
27    elseif rets[2]==CV_MAKE_TYPE(CV_16S, rets[3])
28        dtype = Int16
29    elseif rets[2]==CV_MAKE_TYPE(CV_32S, rets[3])
30        dtype = Int32
31    elseif rets[2]==CV_MAKE_TYPE(CV_32F, rets[3])
32        dtype = Float32
33    elseif rets[2]==CV_MAKE_TYPE(CV_64F, rets[3])
34        dtype = Float64
35    else
36        error("Bad type returned from OpenCV")
37    end
38    steps = [rets[6]/sizeof(dtype), rets[7]/sizeof(dtype)]
39    # println(steps[1]/rets[3], steps[2]/rets[3]/rets[4])
40    #TODO: Implement views when steps do not result in continous memory
41    arr = Base.unsafe_wrap(Array{dtype, 3}, Ptr{dtype}(rets[1].cpp_object), (rets[3], rets[4], rets[5]))
42
43    #Preserve Mat so that array allocated by C++ isn't deallocated
44    return Mat{dtype}(mat, arr)
45end
46
47function julia_to_cpp(img::InputArray)
48    if typeof(img) <: CxxMat
49        return img
50    end
51    steps = 0
52    try
53        steps = strides(img)
54    catch
55        # Copy array since array is not strided
56        img = img[:, :, :]
57        steps = strides(img)
58    end
59
60    if steps[1] <= steps[2] <= steps[3] && steps[1]==1
61        steps_a = Array{size_t, 1}()
62        ndims_a = Array{Int32, 1}()
63        sz = sizeof(eltype(img))
64        push!(steps_a, UInt64(steps[3]*sz))
65        push!(steps_a, UInt64(steps[2]*sz))
66        push!(steps_a, UInt64(steps[1]*sz))
67
68        push!(ndims_a, Int32(size(img)[3]))
69        push!(ndims_a, Int32(size(img)[2]))
70        if eltype(img) == UInt8
71            return CxxMat(2, pointer(ndims_a), CV_MAKE_TYPE(CV_8U, size(img)[1]), Ptr{Nothing}(pointer(img)), pointer(steps_a))
72        elseif eltype(img) == UInt16
73            return CxxMat(2, pointer(ndims_a), CV_MAKE_TYPE(CV_16U, size(img)[1]), Ptr{Nothing}(pointer(img)), pointer(steps_a))
74        elseif eltype(img) == Int8
75            return CxxMat(2, pointer(ndims_a), CV_MAKE_TYPE(CV_8S, size(img)[1]), Ptr{Nothing}(pointer(img)), pointer(steps_a))
76        elseif eltype(img) == Int16
77            return CxxMat(2, pointer(ndims_a), CV_MAKE_TYPE(CV_16S, size(img)[1]), Ptr{Nothing}(pointer(img)), pointer(steps_a))
78        elseif eltype(img) == Int32
79            return CxxMat(2, pointer(ndims_a), CV_MAKE_TYPE(CV_32S, size(img)[1]), Ptr{Nothing}(pointer(img)), pointer(steps_a))
80        elseif eltype(img) == Float32
81            return CxxMat(2, pointer(ndims_a), CV_MAKE_TYPE(CV_32F, size(img)[1]), Ptr{Nothing}(pointer(img)), pointer(steps_a))
82        elseif eltype(img) == Float64
83            return CxxMat(2, pointer(ndims_a), CV_MAKE_TYPE(CV_64F, size(img)[1]), Ptr{Nothing}(pointer(img)), pointer(steps_a))
84        end
85    else
86        # Copy array, invalid config
87        return julia_to_cpp(img[:, :, :])
88    end
89end
90
91function julia_to_cpp(var::Array{T, 1}) where {T <: InputArray}
92    ret = CxxWrap.StdVector{CxxMat}()
93    for x in var
94        push!(ret, julia_to_cpp(x))
95    end
96    return ret
97end
98
99
100function cpp_to_julia(var::CxxWrap.StdVector{T}) where {T <: CxxMat}
101    ret = Array{Mat, 1}()
102    for x in var
103        push!(ret, cpp_to_julia(x))
104    end
105    return ret
106end
107