extern crate libc;
use self::libc::{c_char, c_double, c_float, c_int, c_uint};
use crate::array::Array;
use crate::defines::{AfError, BorderType, CannyThresholdType, ColorSpace, Connectivity};
use crate::defines::{DiffusionEq, FluxFn, InterpType, MomentType, YCCStd};
use crate::error::HANDLE_ERROR;
use crate::util::{AfArray, DimT, MutAfArray};
use crate::util::{EdgeComputable, GrayRGBConvertible, MomentsComputable, RealFloating};
use crate::util::{FloatingPoint, HasAfEnum, ImageFilterType, ImageNativeType, RealNumber};
use std::ffi::CString;
#[allow(dead_code)]
extern "C" {
fn af_cast(out: MutAfArray, arr: AfArray, aftype: c_uint) -> c_int;
fn af_gradient(dx: MutAfArray, dy: MutAfArray, arr: AfArray) -> c_int;
fn af_load_image(out: MutAfArray, filename: *const c_char, iscolor: c_int) -> c_int;
fn af_save_image(filename: *const c_char, input: AfArray) -> c_int;
fn af_load_image_native(out: MutAfArray, filename: *const c_char) -> c_int;
fn af_save_image_native(filename: *const c_char, input: AfArray) -> c_int;
fn af_resize(
out: MutAfArray,
input: AfArray,
odim0: DimT,
odim1: DimT,
method: c_uint,
) -> c_int;
fn af_transform(
out: MutAfArray,
input: AfArray,
trans: AfArray,
odim0: DimT,
odim1: DimT,
method: c_uint,
is_inverse: c_int,
) -> c_int;
fn af_rotate(
out: MutAfArray,
input: AfArray,
theta: c_float,
crop: c_int,
method: c_uint,
) -> c_int;
fn af_translate(
out: MutAfArray,
input: AfArray,
trans0: c_float,
trans1: c_float,
odim0: DimT,
odim1: DimT,
method: c_uint,
) -> c_int;
fn af_scale(
out: MutAfArray,
input: AfArray,
scale0: c_float,
scale1: c_float,
odim0: DimT,
odim1: DimT,
method: c_uint,
) -> c_int;
fn af_skew(
out: MutAfArray,
input: AfArray,
skew0: c_float,
skew1: c_float,
odim0: DimT,
odim1: DimT,
method: c_uint,
is_inverse: c_int,
) -> c_int;
fn af_histogram(
out: MutAfArray,
input: AfArray,
nbins: c_uint,
minval: c_double,
maxval: c_double,
) -> c_int;
fn af_dilate(out: MutAfArray, input: AfArray, mask: AfArray) -> c_int;
fn af_dilate3(out: MutAfArray, input: AfArray, mask: AfArray) -> c_int;
fn af_erode(out: MutAfArray, input: AfArray, mask: AfArray) -> c_int;
fn af_erode3(out: MutAfArray, input: AfArray, mask: AfArray) -> c_int;
fn af_regions(out: MutAfArray, input: AfArray, conn: c_uint, aftype: c_uint) -> c_int;
fn af_sobel_operator(dx: MutAfArray, dy: MutAfArray, i: AfArray, ksize: c_uint) -> c_int;
fn af_rgb2gray(out: MutAfArray, input: AfArray, r: c_float, g: c_float, b: c_float) -> c_int;
fn af_gray2rgb(out: MutAfArray, input: AfArray, r: c_float, g: c_float, b: c_float) -> c_int;
fn af_hist_equal(out: MutAfArray, input: AfArray, hist: AfArray) -> c_int;
fn af_hsv2rgb(out: MutAfArray, input: AfArray) -> c_int;
fn af_rgb2hsv(out: MutAfArray, input: AfArray) -> c_int;
fn af_bilateral(
out: MutAfArray,
input: AfArray,
sp_sig: c_float,
ch_sig: c_float,
iscolor: c_int,
) -> c_int;
fn af_mean_shift(
out: MutAfArray,
input: AfArray,
sp_sig: c_float,
ch_sig: c_float,
iter: c_uint,
iscolor: c_int,
) -> c_int;
fn af_medfilt(out: MutAfArray, input: AfArray, wlen: DimT, wwid: DimT, etype: c_uint) -> c_int;
fn af_medfilt1(out: MutAfArray, input: AfArray, wlen: DimT, etype: c_uint) -> c_int;
fn af_minfilt(out: MutAfArray, input: AfArray, wlen: DimT, wwid: DimT, etype: c_uint) -> c_int;
fn af_maxfilt(out: MutAfArray, input: AfArray, wlen: DimT, wwid: DimT, etype: c_uint) -> c_int;
fn af_gaussian_kernel(
out: MutAfArray,
rows: c_int,
cols: c_int,
sigma_r: c_double,
sigma_c: c_double,
) -> c_int;
fn af_color_space(out: MutAfArray, input: AfArray, tospace: c_uint, fromspace: c_uint)
-> c_int;
fn af_unwrap(
out: MutAfArray,
input: AfArray,
wx: DimT,
wy: DimT,
sx: DimT,
sy: DimT,
px: DimT,
py: DimT,
is_column: c_int,
) -> c_int;
fn af_wrap(
out: MutAfArray,
input: AfArray,
ox: DimT,
oy: DimT,
wx: DimT,
wy: DimT,
sx: DimT,
sy: DimT,
px: DimT,
py: DimT,
is_column: c_int,
) -> c_int;
fn af_sat(out: MutAfArray, input: AfArray) -> c_int;
fn af_ycbcr2rgb(out: MutAfArray, input: AfArray, stnd: c_int) -> c_int;
fn af_rgb2ycbcr(out: MutAfArray, input: AfArray, stnd: c_int) -> c_int;
fn af_is_image_io_available(out: *mut c_int) -> c_int;
fn af_transform_coordinates(out: MutAfArray, tf: AfArray, d0: c_float, d1: c_float) -> c_int;
fn af_moments(out: MutAfArray, input: AfArray, moment: c_int) -> c_int;
fn af_moments_all(out: *mut c_double, input: AfArray, moment: c_int) -> c_int;
fn af_canny(
out: MutAfArray,
input: AfArray,
thres_type: c_int,
low: c_float,
high: c_float,
swindow: c_uint,
is_fast: c_int,
) -> c_int;
fn af_anisotropic_diffusion(
out: MutAfArray,
input: AfArray,
dt: c_float,
K: c_float,
iters: c_uint,
fftype: c_int,
diff_kind: c_int,
) -> c_int;
}
#[allow(unused_mut)]
pub fn gradient<T>(input: &Array<T>) -> (Array<T>, Array<T>)
where
T: HasAfEnum + FloatingPoint,
{
let mut dx: i64 = 0;
let mut dy: i64 = 0;
unsafe {
let err_val = af_gradient(
&mut dx as MutAfArray,
&mut dy as MutAfArray,
input.get() as AfArray,
);
HANDLE_ERROR(AfError::from(err_val));
}
(dx.into(), dy.into())
}
#[allow(unused_mut)]
pub fn load_image<T>(filename: String, is_color: bool) -> Array<T>
where
T: HasAfEnum + RealNumber,
{
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
let trgt_type = T::get_af_dtype();
let mut img: i64 = 0;
unsafe {
let mut temp: i64 = 0;
let err1 = af_load_image(
&mut temp as MutAfArray,
cstr_param.as_ptr(),
is_color as c_int,
);
HANDLE_ERROR(AfError::from(err1));
let err2 = af_cast(&mut img as MutAfArray, temp as AfArray, trgt_type as c_uint);
HANDLE_ERROR(AfError::from(err2));
}
img.into()
}
#[allow(unused_mut)]
pub fn load_image_native<T>(filename: String) -> Array<T>
where
T: HasAfEnum + ImageNativeType,
{
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
let trgt_type = T::get_af_dtype();
let mut img: i64 = 0;
unsafe {
let mut temp: i64 = 0;
let err1 = af_load_image_native(&mut temp as MutAfArray, cstr_param.as_ptr());
HANDLE_ERROR(AfError::from(err1));
let err2 = af_cast(&mut img as MutAfArray, temp as AfArray, trgt_type as c_uint);
HANDLE_ERROR(AfError::from(err2));
}
img.into()
}
#[allow(unused_mut)]
pub fn save_image<T>(filename: String, input: &Array<T>)
where
T: HasAfEnum + RealNumber,
{
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
unsafe {
let err_val = af_save_image(cstr_param.as_ptr(), input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
}
#[allow(unused_mut)]
pub fn save_image_native<T>(filename: String, input: &Array<T>)
where
T: HasAfEnum + ImageNativeType,
{
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
unsafe {
let err_val = af_save_image_native(cstr_param.as_ptr(), input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
}
#[allow(unused_mut)]
pub fn resize<T: HasAfEnum>(
input: &Array<T>,
odim0: i64,
odim1: i64,
method: InterpType,
) -> Array<T> {
let mut temp: i64 = 0;
unsafe {
let err_val = af_resize(
&mut temp as MutAfArray,
input.get() as AfArray,
odim0 as DimT,
odim1 as DimT,
method as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn transform<T: HasAfEnum>(
input: &Array<T>,
trans: &Array<f32>,
odim0: i64,
odim1: i64,
method: InterpType,
is_inverse: bool,
) -> Array<T> {
let mut temp: i64 = 0;
unsafe {
let err_val = af_transform(
&mut temp as MutAfArray,
input.get() as AfArray,
trans.get() as AfArray,
odim0 as DimT,
odim1 as DimT,
method as c_uint,
is_inverse as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn rotate<T: HasAfEnum>(
input: &Array<T>,
theta: f64,
crop: bool,
method: InterpType,
) -> Array<T> {
let mut temp: i64 = 0;
unsafe {
let err_val = af_rotate(
&mut temp as MutAfArray,
input.get() as AfArray,
theta as c_float,
crop as c_int,
method as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn translate<T: HasAfEnum>(
input: &Array<T>,
trans0: f32,
trans1: f32,
odim0: i64,
odim1: i64,
method: InterpType,
) -> Array<T> {
let mut temp: i64 = 0;
unsafe {
let err_val = af_translate(
&mut temp as MutAfArray,
input.get() as AfArray,
trans0 as c_float,
trans1 as c_float,
odim0 as DimT,
odim1 as DimT,
method as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn scale<T: HasAfEnum>(
input: &Array<T>,
scale0: f32,
scale1: f32,
odim0: i64,
odim1: i64,
method: InterpType,
) -> Array<T> {
let mut temp: i64 = 0;
unsafe {
let err_val = af_scale(
&mut temp as MutAfArray,
input.get() as AfArray,
scale0 as c_float,
scale1 as c_float,
odim0 as DimT,
odim1 as DimT,
method as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn skew<T: HasAfEnum>(
input: &Array<T>,
skew0: f32,
skew1: f32,
odim0: i64,
odim1: i64,
method: InterpType,
is_inverse: bool,
) -> Array<T> {
let mut temp: i64 = 0;
unsafe {
let err_val = af_skew(
&mut temp as MutAfArray,
input.get() as AfArray,
skew0 as c_float,
skew1 as c_float,
odim0 as DimT,
odim1 as DimT,
method as c_uint,
is_inverse as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn histogram<T>(input: &Array<T>, nbins: u32, minval: f64, maxval: f64) -> Array<u32>
where
T: HasAfEnum + RealNumber,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_histogram(
&mut temp as MutAfArray,
input.get() as AfArray,
nbins as c_uint,
minval as c_double,
maxval as c_double,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn dilate<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_dilate(
&mut temp as MutAfArray,
input.get() as AfArray,
mask.get() as AfArray,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn erode<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_erode(
&mut temp as MutAfArray,
input.get() as AfArray,
mask.get() as AfArray,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn dilate3<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_dilate3(
&mut temp as MutAfArray,
input.get() as AfArray,
mask.get() as AfArray,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn erode3<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_erode3(
&mut temp as MutAfArray,
input.get() as AfArray,
mask.get() as AfArray,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn bilateral<T>(
input: &Array<T>,
spatial_sigma: f32,
chromatic_sigma: f32,
iscolor: bool,
) -> Array<T::AbsOutType>
where
T: HasAfEnum + ImageFilterType,
T::AbsOutType: HasAfEnum,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_bilateral(
&mut temp as MutAfArray,
input.get() as AfArray,
spatial_sigma as c_float,
chromatic_sigma as c_float,
iscolor as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn mean_shift<T>(
input: &Array<T>,
spatial_sigma: f32,
chromatic_sigma: f32,
iter: u32,
iscolor: bool,
) -> Array<T>
where
T: HasAfEnum + RealNumber,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_mean_shift(
&mut temp as MutAfArray,
input.get() as AfArray,
spatial_sigma as c_float,
chromatic_sigma as c_float,
iter as c_uint,
iscolor as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
macro_rules! filt_func_def {
($doc_str: expr, $fn_name: ident, $ffi_name: ident) => {
#[doc=$doc_str]
#[allow(unused_mut)]
pub fn $fn_name<T>(input: &Array<T>, wlen: u64, wwid: u64, etype: BorderType) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
let mut temp: i64 = 0;
unsafe {
let err_val = $ffi_name(
&mut temp as MutAfArray,
input.get() as AfArray,
wlen as DimT,
wwid as DimT,
etype as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
};
}
filt_func_def!("Median filter", medfilt, af_medfilt);
filt_func_def!(
"Box filter with minimum as box operation",
minfilt,
af_minfilt
);
filt_func_def!(
"Box filter with maximum as box operation",
maxfilt,
af_maxfilt
);
#[allow(unused_mut)]
pub fn gaussian_kernel(rows: i32, cols: i32, sigma_r: f64, sigma_c: f64) -> Array<f32> {
let mut temp: i64 = 0;
unsafe {
let err_val = af_gaussian_kernel(
&mut temp as MutAfArray,
rows as c_int,
cols as c_int,
sigma_r as c_double,
sigma_c as c_double,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn color_space<T>(input: &Array<T>, tospace: ColorSpace, fromspace: ColorSpace) -> Array<T>
where
T: HasAfEnum + RealNumber,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_color_space(
&mut temp as MutAfArray,
input.get() as AfArray,
tospace as c_uint,
fromspace as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn regions<OutType>(input: &Array<bool>, conn: Connectivity) -> Array<OutType>
where
OutType: HasAfEnum + RealNumber,
{
let otype = OutType::get_af_dtype();
let mut temp: i64 = 0;
unsafe {
let err_val = af_regions(
&mut temp as MutAfArray,
input.get() as AfArray,
conn as c_uint,
otype as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
#[allow(unused_mut)]
pub fn sobel<T>(input: &Array<T>, ker_size: u32) -> (Array<T::SobelOutType>, Array<T::SobelOutType>)
where
T: HasAfEnum + ImageFilterType,
T::SobelOutType: HasAfEnum,
{
let mut dx: i64 = 0;
let mut dy: i64 = 0;
unsafe {
let err_val = af_sobel_operator(
&mut dx as MutAfArray,
&mut dy as MutAfArray,
input.get() as AfArray,
ker_size as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
(dx.into(), dy.into())
}
#[allow(unused_mut)]
pub fn hist_equal<T>(input: &Array<T>, hist: &Array<u32>) -> Array<T>
where
T: HasAfEnum + RealNumber,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_hist_equal(
&mut temp as MutAfArray,
input.get() as AfArray,
hist.get() as AfArray,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
macro_rules! grayrgb_func_def {
($doc_str: expr, $fn_name: ident, $ffi_name: ident) => {
#[doc=$doc_str]
#[allow(unused_mut)]
pub fn $fn_name<T>(input: &Array<T>, r: f32, g: f32, b: f32) -> Array<T>
where
T: HasAfEnum + GrayRGBConvertible,
{
let mut temp: i64 = 0;
unsafe {
let err_val = $ffi_name(
&mut temp as MutAfArray,
input.get() as AfArray,
r as c_float,
g as c_float,
b as c_float,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
};
}
grayrgb_func_def!("Color(RGB) to Grayscale conversion", rgb2gray, af_rgb2gray);
grayrgb_func_def!("Grayscale to Color(RGB) conversion", gray2rgb, af_gray2rgb);
macro_rules! hsvrgb_func_def {
($doc_str: expr, $fn_name: ident, $ffi_name: ident) => {
#[doc=$doc_str]
#[allow(unused_mut)]
pub fn $fn_name<T>(input: &Array<T>) -> Array<T>
where
T: HasAfEnum + RealFloating,
{
let mut temp: i64 = 0;
unsafe {
let err_val = $ffi_name(&mut temp as MutAfArray, input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
};
}
hsvrgb_func_def!("HSV to RGB color space conversion", hsv2rgb, af_hsv2rgb);
hsvrgb_func_def!("RGB to HSV color space conversion", rgb2hsv, af_rgb2hsv);
pub fn unwrap<T: HasAfEnum>(
input: &Array<T>,
wx: i64,
wy: i64,
sx: i64,
sy: i64,
px: i64,
py: i64,
is_column: bool,
) -> Array<T> {
let mut temp: i64 = 0;
unsafe {
let err_val = af_unwrap(
&mut temp as MutAfArray,
input.get() as AfArray,
wx,
wy,
sx,
sy,
px,
py,
is_column as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn wrap<T: HasAfEnum>(
input: &Array<T>,
ox: i64,
oy: i64,
wx: i64,
wy: i64,
sx: i64,
sy: i64,
px: i64,
py: i64,
is_column: bool,
) -> Array<T> {
let mut temp: i64 = 0;
unsafe {
let err_val = af_wrap(
&mut temp as MutAfArray,
input.get() as AfArray,
ox,
oy,
wx,
wy,
sx,
sy,
px,
py,
is_column as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn sat<T>(input: &Array<T>) -> Array<T::AggregateOutType>
where
T: HasAfEnum + RealNumber,
T::AggregateOutType: HasAfEnum,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_sat(&mut temp as MutAfArray, input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn rgb2ycbcr<T>(input: &Array<T>, standard: YCCStd) -> Array<T>
where
T: HasAfEnum + RealFloating,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_rgb2ycbcr(
&mut temp as MutAfArray,
input.get() as AfArray,
standard as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn ycbcr2rgb<T>(input: &Array<T>, standard: YCCStd) -> Array<T>
where
T: HasAfEnum + RealFloating,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_ycbcr2rgb(
&mut temp as MutAfArray,
input.get() as AfArray,
standard as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn is_imageio_available() -> bool {
let mut temp: i32 = 0;
unsafe {
af_is_image_io_available(&mut temp as *mut c_int);
}
temp > 0 }
pub fn transform_coords<T>(tf: &Array<T>, d0: f32, d1: f32) -> Array<T>
where
T: HasAfEnum + RealFloating,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_transform_coordinates(
&mut temp as MutAfArray,
tf.get() as AfArray,
d0 as c_float,
d1 as c_float,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn moments<T>(input: &Array<T>, moment: MomentType) -> Array<f32>
where
T: HasAfEnum + MomentsComputable,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_moments(
&mut temp as MutAfArray,
input.get() as AfArray,
moment as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn moments_all<T>(input: &Array<T>, moment: MomentType) -> f64
where
T: HasAfEnum + MomentsComputable,
{
let mut temp: f64 = 0.0;
unsafe {
let err_val = af_moments_all(
&mut temp as *mut c_double,
input.get() as AfArray,
moment as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp
}
pub fn medfilt1<T>(input: &Array<T>, wlen: u64, etype: BorderType) -> Array<T>
where
T: HasAfEnum + ImageFilterType,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_medfilt1(
&mut temp as MutAfArray,
input.get() as AfArray,
wlen as DimT,
etype as c_uint,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn canny<T>(
input: &Array<T>,
threshold_type: CannyThresholdType,
low: f32,
hight: f32,
sobel_window: u32,
is_fast: bool,
) -> Array<bool>
where
T: HasAfEnum + EdgeComputable,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_canny(
&mut temp as MutAfArray,
input.get() as AfArray,
threshold_type as c_int,
low as c_float,
hight as c_float,
sobel_window as c_uint,
is_fast as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}
pub fn anisotropic_diffusion<T>(
img: &Array<T>,
dt: f32,
k: f32,
iters: u32,
fftype: FluxFn,
diff_kind: DiffusionEq,
) -> Array<T::AbsOutType>
where
T: HasAfEnum + EdgeComputable,
T::AbsOutType: HasAfEnum,
{
let mut temp: i64 = 0;
unsafe {
let err_val = af_anisotropic_diffusion(
&mut temp as MutAfArray,
img.get() as AfArray,
dt as c_float,
k as c_float,
iters as c_uint,
fftype as c_int,
diff_kind as c_int,
);
HANDLE_ERROR(AfError::from(err_val));
}
temp.into()
}