use core::*;
use failure::Error;
use std::ffi::CString;
use std::mem;
use std::ops::{BitAnd, BitOr, BitXor, Not};
use std::os::raw::{c_char, c_double, c_int};
use std::path::Path;
use std::slice;
use *;
#[derive(Clone, Copy, Debug)]
pub enum CMat {}
impl CMat {
pub(crate) fn new() -> *mut CMat {
unsafe { cv_mat_new() }
}
}
extern "C" {
fn cv_mat_new() -> *mut CMat;
fn cv_mat_from_file_storage(path: *const c_char, section: *const c_char) -> *mut CMat;
fn cv_mat_new_with_size(rows: c_int, cols: c_int, t: c_int) -> *mut CMat;
fn cv_mat_zeros(rows: c_int, cols: c_int, t: c_int) -> *mut CMat;
fn cv_mat_from_buffer(rows: c_int, cols: c_int, t: CvType, buffer: *const u8) -> *mut CMat;
fn cv_mat_is_valid(mat: *mut CMat) -> bool;
fn cv_mat_rows(cmat: *const CMat) -> c_int;
fn cv_mat_cols(cmat: *const CMat) -> c_int;
fn cv_mat_depth(cmat: *const CMat) -> c_int;
fn cv_mat_channels(cmat: *const CMat) -> c_int;
fn cv_mat_data(cmat: *const CMat) -> *const u8;
fn cv_mat_total(cmat: *const CMat) -> usize;
fn cv_mat_step1(cmat: *const CMat, i: c_int) -> usize;
fn cv_mat_elem_size(cmat: *const CMat) -> usize;
fn cv_mat_elem_size1(cmat: *const CMat) -> usize;
fn cv_mat_type(cmat: *const CMat) -> CvType;
fn cv_mat_roi(cmat: *const CMat, rect: Rect) -> *mut CMat;
fn cv_mat_flip(src: *mut CMat, code: c_int);
fn cv_mat_drop(mat: *mut CMat);
fn cv_mat_eye(rows: c_int, cols: c_int, cv_type: CvType) -> *mut CMat;
fn cv_mat_in_range(cmat: *const CMat, lowerb: Scalar, upperb: Scalar, dst: *mut CMat);
fn cv_mat_min_max_loc(
cmat: *const CMat,
min: *mut f64,
max: *mut f64,
min_loc: *mut Point2i,
max_loc: *mut Point2i,
cmask: *const CMat,
);
fn cv_mat_mix_channels(
cmat: *const CMat,
nsrcs: usize,
dst: *mut CMat,
ndsts: usize,
from_to: *const c_int,
npairs: usize,
);
fn cv_mat_normalize(csrc: *const CMat, cdst: *mut CMat, alpha: c_double, beta: c_double, norm_type: NormType);
fn cv_mat_bitwise_and(src1: *const CMat, src2: *const CMat, dst: *mut CMat);
fn cv_mat_bitwise_not(src: *const CMat, dst: *mut CMat);
fn cv_mat_bitwise_or(src1: *const CMat, src2: *const CMat, dst: *mut CMat);
fn cv_mat_bitwise_xor(src1: *const CMat, src2: *const CMat, dst: *mut CMat);
fn cv_mat_count_non_zero(src: *const CMat) -> c_int;
fn cv_mat_copy_make_border(
src: *const CMat,
dst: *mut CMat,
top: c_int,
bottom: c_int,
left: c_int,
right: c_int,
border_type: c_int,
color: Scalar,
) -> c_int;
}
#[derive(Debug)]
pub struct Mat {
pub(crate) inner: *mut CMat,
pub cols: c_int,
pub rows: c_int,
pub depth: c_int,
pub channels: c_int,
}
unsafe impl Send for CMat {}
unsafe impl Send for Mat {}
impl Into<CMat> for Mat {
fn into(self) -> CMat {
unsafe { *self.inner }
}
}
impl Mat {
pub fn from_file_storage<P: AsRef<Path>>(path: P, section: &str) -> Result<Mat, Error> {
let path = path_to_cstring(path)?;
let section = CString::new(section)?;
let path = path.as_ptr();
let section = section.as_ptr();
let result = unsafe { cv_mat_from_file_storage(path, section) };
Ok(Mat::from_raw(result))
}
#[inline]
pub(crate) fn from_raw(raw: *mut CMat) -> Mat {
Mat {
inner: raw,
rows: unsafe { cv_mat_rows(raw) },
cols: unsafe { cv_mat_cols(raw) },
depth: unsafe { cv_mat_depth(raw) },
channels: unsafe { cv_mat_channels(raw) },
}
}
pub fn new() -> Mat {
let m = CMat::new();
Mat::from_raw(m)
}
pub fn from_buffer(rows: c_int, cols: c_int, cv_type: CvType, buf: &[u8]) -> Mat {
let raw = unsafe { cv_mat_from_buffer(rows, cols, cv_type, buf.as_ptr()) };
Mat::from_raw(raw)
}
pub fn with_size(rows: c_int, cols: c_int, t: c_int) -> Self {
let m = unsafe { cv_mat_new_with_size(rows, cols, t) };
Mat::from_raw(m)
}
pub fn zeros(rows: c_int, cols: c_int, t: c_int) -> Self {
let m = unsafe { cv_mat_zeros(rows, cols, t) };
Mat::from_raw(m)
}
pub fn data(&self) -> &[u8] {
let bytes = unsafe { cv_mat_data(self.inner) };
let len = self.total() * self.elem_size();
unsafe { slice::from_raw_parts(bytes, len) }
}
pub fn total(&self) -> usize {
unsafe { cv_mat_total(self.inner) }
}
pub fn elem_size(&self) -> usize {
unsafe { cv_mat_elem_size(self.inner) }
}
pub fn elem_size1(&self) -> usize {
unsafe { cv_mat_elem_size1(self.inner) }
}
pub fn step1(&self, i: c_int) -> usize {
unsafe { cv_mat_step1(self.inner, i) }
}
pub fn size(&self) -> Size2i {
Size2i::new(self.cols, self.rows)
}
pub fn is_valid(&self) -> bool {
unsafe { cv_mat_is_valid(self.inner) }
}
pub fn roi(&self, rect: Rect) -> Mat {
let cmat = unsafe { cv_mat_roi(self.inner, rect) };
Mat::from_raw(cmat)
}
pub fn flip(&mut self, code: FlipCode) {
let code = match code {
FlipCode::XAxis => 0,
FlipCode::YAxis => 1,
FlipCode::XYAxis => -1,
};
unsafe {
cv_mat_flip(self.inner, code);
}
}
pub fn cv_type(&self) -> CvType {
unsafe { cv_mat_type(self.inner) }
}
pub fn eye(rows: i32, cols: i32, cv_type: CvType) -> Mat {
let result = unsafe { cv_mat_eye(rows, cols, cv_type) };
Mat::from_raw(result)
}
pub fn at<T: FromBytes>(&self, i0: i32) -> T {
let data = self.data();
let size = self.size();
let pos = {
if size.height == 1 {
i0 as usize
} else if size.width == 1 {
i0 as usize * (self.step1(1) * self.elem_size1())
} else {
unimplemented! {};
}
};
let byte = &data[pos];
let ptr: *const _ = byte;
let slice = unsafe { slice::from_raw_parts(ptr, mem::size_of::<T>()) };
T::from_bytes(slice)
}
pub fn at2<T: FromBytes>(&self, i0: i32, i1: i32) -> T {
let data = self.data();
let pos = i0 as usize * self.step1(0) * self.elem_size1() + i1 as usize * self.step1(1) * self.elem_size1();
let byte = &data[pos];
let ptr: *const _ = byte;
let slice = unsafe { slice::from_raw_parts(ptr, mem::size_of::<T>()) };
T::from_bytes(slice)
}
pub fn at3<T: FromBytes>(&self, i0: i32, i1: i32, i2: i32) -> T {
let data = self.data();
let pos = i0 as usize * self.step1(0) * self.elem_size1()
+ i1 as usize * self.step1(1) * self.elem_size1()
+ i2 as usize;
let byte = &data[pos];
let ptr: *const _ = byte;
let slice = unsafe { slice::from_raw_parts(ptr, mem::size_of::<T>()) };
T::from_bytes(slice)
}
pub fn in_range(&self, lowerb: Scalar, upperb: Scalar) -> Mat {
let m = CMat::new();
unsafe { cv_mat_in_range(self.inner, lowerb, upperb, m) }
Mat::from_raw(m)
}
pub fn min_max_loc(&self, mask: &Mat) -> (f64, f64, Point2i, Point2i) {
let mut min = 0.0;
let mut max = 0.0;
let mut min_loc = Point2i::new(0, 0);
let mut max_loc = Point2i::new(0, 0);
unsafe { cv_mat_min_max_loc(self.inner, &mut min, &mut max, &mut min_loc, &mut max_loc, mask.inner) }
(min, max, min_loc, max_loc)
}
pub fn mix_channels<T: AsRef<[(c_int, c_int)]>>(&self, nsrcs: usize, ndsts: usize, from_to: T) -> Mat {
let m = Mat::with_size(self.rows, self.cols, self.depth);
let slice = from_to.as_ref();
let ptr = slice.as_ptr() as *const c_int;
unsafe {
cv_mat_mix_channels(self.inner, nsrcs, m.inner, ndsts, ptr, slice.len());
}
m
}
pub fn normalize(&self, alpha: f64, beta: f64, t: NormType) -> Mat {
let m = CMat::new();
unsafe { cv_mat_normalize(self.inner, m, alpha, beta, t) }
Mat::from_raw(m)
}
pub fn count_non_zero(&self) -> c_int {
unsafe { cv_mat_count_non_zero(self.inner) }
}
pub fn copy_make_border(
&self,
top: i32,
bottom: i32,
left: i32,
right: i32,
type_: BorderType,
color: Scalar,
) -> Mat {
let m = CMat::new();
unsafe {
cv_mat_copy_make_border(self.inner, m, top, bottom, left, right, type_ as i32, color);
}
Mat::from_raw(m)
}
}
#[derive(Debug, Copy, Clone)]
pub enum BorderType {
Constant = 0,
Replicate = 1,
Reflect = 2,
Wrap = 3,
Reflect101 = 4,
Transparent = 5,
Isolated = 16,
}
impl BorderType {
#[allow(non_upper_case_globals)]
pub const Default: BorderType = BorderType::Reflect101;
}
impl Drop for Mat {
fn drop(&mut self) {
unsafe {
cv_mat_drop(self.inner);
}
}
}
impl BitAnd for Mat {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
let m = CMat::new();
unsafe { cv_mat_bitwise_and(self.inner, rhs.inner, m) }
Self::from_raw(m)
}
}
impl<'a> BitAnd for &'a Mat {
type Output = Mat;
fn bitand(self, rhs: &'a Mat) -> Self::Output {
let m = CMat::new();
unsafe { cv_mat_bitwise_and(self.inner, rhs.inner, m) }
Mat::from_raw(m)
}
}
impl BitOr for Mat {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
let m = CMat::new();
unsafe { cv_mat_bitwise_or(self.inner, rhs.inner, m) }
Mat::from_raw(m)
}
}
impl<'a> BitOr for &'a Mat {
type Output = Mat;
fn bitor(self, rhs: &'a Mat) -> Self::Output {
let m = CMat::new();
unsafe { cv_mat_bitwise_or(self.inner, rhs.inner, m) }
Mat::from_raw(m)
}
}
impl BitXor for Mat {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self::Output {
let m = CMat::new();
unsafe { cv_mat_bitwise_xor(self.inner, rhs.inner, m) }
Mat::from_raw(m)
}
}
impl<'a> BitXor for &'a Mat {
type Output = Mat;
fn bitxor(self, rhs: &'a Mat) -> Self::Output {
let m = CMat::new();
unsafe { cv_mat_bitwise_xor(self.inner, rhs.inner, m) }
Mat::from_raw(m)
}
}
impl Not for Mat {
type Output = Self;
fn not(self) -> Self::Output {
let m = CMat::new();
unsafe { cv_mat_bitwise_not(self.inner, m) }
Mat::from_raw(m)
}
}
impl Clone for Mat {
fn clone(&self) -> Self {
Mat::from_buffer(self.rows, self.cols, self.cv_type(), self.data())
}
}
impl<'a> Not for &'a Mat {
type Output = Mat;
fn not(self) -> Self::Output {
let m = CMat::new();
unsafe { cv_mat_bitwise_not(self.inner, m) }
Mat::from_raw(m)
}
}