use bytes::{self, ByteOrder};
use mat::*;
use std::mem;
use std::os::raw::c_int;
pub(crate) enum CTermCriteria {}
extern "C" {
fn cv_term_criteria_new(t: TermType, count: c_int, epsilon: f64) -> *mut CTermCriteria;
fn cv_term_criteria_drop(criteria: *mut CTermCriteria);
}
#[derive(Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct KeyPoint {
pub point: Point2f,
pub size: f32,
pub angle: f32,
pub response: f32,
pub octave: c_int,
pub class_id: c_int,
}
#[derive(Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct Scalar {
v0: c_int,
v1: c_int,
v2: c_int,
v3: c_int,
}
impl Scalar {
pub fn new(v0: c_int, v1: c_int, v2: c_int, v3: c_int) -> Self {
Scalar {
v0: v0,
v1: v1,
v2: v2,
v3: v3,
}
}
pub fn all(v: c_int) -> Self {
Scalar {
v0: v,
v1: v,
v2: v,
v3: v,
}
}
}
#[derive(Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct Point2i {
pub x: c_int,
pub y: c_int,
}
impl Point2i {
pub fn new(x: c_int, y: c_int) -> Self {
Point2i { x: x, y: y }
}
}
#[derive(Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct Point2f {
pub x: f32,
pub y: f32,
}
impl Point2f {
pub fn new(x: f32, y: f32) -> Self {
Point2f { x: x, y: y }
}
}
#[derive(Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct Size2i {
pub width: c_int,
pub height: c_int,
}
impl Size2i {
pub fn new(width: c_int, height: c_int) -> Self {
Size2i {
width: width,
height: height,
}
}
}
#[derive(Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct Size2f {
pub width: f32,
pub height: f32,
}
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
#[repr(C)]
pub struct Rect {
pub x: c_int,
pub y: c_int,
pub width: c_int,
pub height: c_int,
}
impl Rect {
pub fn new(x: c_int, y: c_int, width: c_int, height: c_int) -> Self {
Rect {
x: x,
y: y,
width: width,
height: height,
}
}
pub fn scale(&self, ratio: f32) -> Rect {
let new_x = ((1.0 - ratio) * (self.width as f32) / 2.0) as c_int + self.x;
let new_y = ((1.0 - ratio) * (self.height as f32) / 2.0) as c_int + self.y;
let new_w = ((self.width as f32) * ratio) as c_int;
let new_h = ((self.height as f32) * ratio) as c_int;
Rect {
x: new_x,
y: new_y,
width: new_w,
height: new_h,
}
}
pub fn normalize_to_mat(&self, mat: &Mat) -> Rect2f {
Rect2f {
x: (self.x as f32) / (mat.cols as f32),
y: (self.y as f32) / (mat.rows as f32),
width: (self.width as f32) / (mat.cols as f32),
height: (self.height as f32) / (mat.rows as f32),
}
}
}
#[derive(Default, Debug, Clone, Copy)]
pub struct Rect2f {
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
}
impl Rect2f {
pub fn normalize_to_mat(&self, mat: &Mat) -> Rect {
Rect {
x: (self.x * mat.cols as f32) as c_int,
y: (self.y * mat.rows as f32) as c_int,
width: (self.width * mat.cols as f32) as c_int,
height: (self.height * mat.rows as f32) as c_int,
}
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum LineType {
Filled = -1,
Line4 = 4,
Line8 = 8,
LineAA = 16,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum FlipCode {
XAxis,
YAxis,
XYAxis,
}
pub trait FromBytes {
fn from_bytes(bytes: &[u8]) -> Self;
}
impl<T: FromBytes> FromBytes for (T, T, T) {
fn from_bytes(bytes: &[u8]) -> (T, T, T) {
let size = mem::size_of::<T>();
(
T::from_bytes(&bytes[(0 * size)..(1 * size)]),
T::from_bytes(&bytes[(1 * size)..(2 * size)]),
T::from_bytes(&bytes[(2 * size)..(3 * size)]),
)
}
}
impl FromBytes for u8 {
fn from_bytes(bytes: &[u8]) -> u8 {
bytes[0]
}
}
impl FromBytes for i8 {
fn from_bytes(bytes: &[u8]) -> i8 {
bytes[0] as i8
}
}
impl FromBytes for u16 {
#[cfg(target_endian = "big")]
fn from_bytes(bytes: &[u8]) -> u16 {
bytes::BigEndian::read_u16(bytes)
}
#[cfg(target_endian = "little")]
fn from_bytes(bytes: &[u8]) -> u16 {
bytes::LittleEndian::read_u16(bytes)
}
}
impl FromBytes for i16 {
#[cfg(target_endian = "big")]
fn from_bytes(bytes: &[u8]) -> i16 {
bytes::BigEndian::read_i16(bytes)
}
#[cfg(target_endian = "little")]
fn from_bytes(bytes: &[u8]) -> i16 {
bytes::LittleEndian::read_i16(bytes)
}
}
impl FromBytes for f32 {
#[cfg(target_endian = "big")]
fn from_bytes(bytes: &[u8]) -> f32 {
bytes::BigEndian::read_f32(bytes)
}
#[cfg(target_endian = "little")]
fn from_bytes(bytes: &[u8]) -> f32 {
bytes::LittleEndian::read_f32(bytes)
}
}
impl FromBytes for i32 {
#[cfg(target_endian = "big")]
fn from_bytes(bytes: &[u8]) -> i32 {
bytes::BigEndian::read_i32(bytes)
}
#[cfg(target_endian = "little")]
fn from_bytes(bytes: &[u8]) -> i32 {
bytes::LittleEndian::read_i32(bytes)
}
}
impl FromBytes for f64 {
#[cfg(target_endian = "big")]
fn from_bytes(bytes: &[u8]) -> f64 {
bytes::BigEndian::read_f64(bytes)
}
#[cfg(target_endian = "little")]
fn from_bytes(bytes: &[u8]) -> f64 {
bytes::LittleEndian::read_f64(bytes)
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum CvType {
Cv8UC1 = 0,
Cv8SC1 = 1,
Cv16UC1 = 2,
Cv16SC1 = 3,
Cv32SC1 = 4,
Cv32FC1 = 5,
Cv64FC1 = 6,
Cv8UC2 = 8,
Cv8UC3 = 16,
Cv8SC3 = 17,
Cv16UC3 = 18,
Cv16SC3 = 19,
Cv32SC3 = 20,
Cv32FC3 = 21,
Cv64FC3 = 22,
}
#[derive(Default, Debug, Clone, Copy)]
#[repr(C)]
pub struct RotatedRect {
center: Point2f,
size: Size2f,
angle: f32,
}
impl RotatedRect {
pub fn points(&self) -> [Point2f; 4] {
let angle = self.angle * ::std::f32::consts::PI / 180.0;
let b = angle.cos() * 0.5;
let a = angle.sin() * 0.5;
let mut pts: [Point2f; 4] = [Point2f::default(); 4];
pts[0].x = self.center.x - a * self.size.height - b * self.size.width;
pts[0].y = self.center.y + b * self.size.height - a * self.size.width;
pts[1].x = self.center.x + a * self.size.height - b * self.size.width;
pts[1].y = self.center.y - b * self.size.height - a * self.size.width;
pts[2].x = 2.0 * self.center.x - pts[0].x;
pts[2].y = 2.0 * self.center.y - pts[0].y;
pts[3].x = 2.0 * self.center.x - pts[1].x;
pts[3].y = 2.0 * self.center.y - pts[1].y;
pts
}
pub fn bounding_rect(&self) -> Rect {
let pt = self.points();
let x = pt.iter().map(|p| p.x).fold(0. / 0., f32::min).floor() as c_int;
let y = pt.iter().map(|p| p.y).fold(0. / 0., f32::min).floor() as c_int;
let width = pt.iter().map(|p| p.x).fold(0. / 0., f32::max).ceil() as c_int - x + 1;
let height = pt.iter().map(|p| p.y).fold(0. / 0., f32::max).ceil() as c_int - y + 1;
Rect::new(x, y, width, height)
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum NormType {
Inf = 1,
L1 = 2,
L2 = 4,
L2Sqr = 5,
Hamming = 6,
Hamming2 = 7,
Relative = 8,
MinMax = 32,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum TermType {
Count = 1,
EPS = 2,
}
#[derive(Debug)]
pub struct TermCriteria {
pub(crate) c_criteria: *mut CTermCriteria,
}
impl TermCriteria {
pub fn new(t: TermType, max_count: c_int, epsilon: f64) -> Self {
let c_criteria = unsafe { cv_term_criteria_new(t, max_count, epsilon) };
TermCriteria { c_criteria: c_criteria }
}
}
impl Drop for TermCriteria {
fn drop(&mut self) {
unsafe {
cv_term_criteria_drop(self.c_criteria);
}
}
}