extern crate libc;
use array::Array;
use defines::{AfError, BorderType, CannyThresholdType, ColorSpace, Connectivity, InterpType, YCCStd, MomentType};
use error::HANDLE_ERROR;
use util::{AfArray, DimT, HasAfEnum, MutAfArray};
use self::libc::{uint8_t, c_uint, c_int, c_float, c_double, c_char};
use std::ffi::CString;
#[allow(dead_code)]
extern {
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: uint8_t) -> c_int;
fn af_transform(out: MutAfArray, input: AfArray, trans: AfArray,
odim0: DimT, odim1: DimT, method: uint8_t, is_inverse: c_int) -> c_int;
fn af_rotate(out: MutAfArray, input: AfArray, theta: c_float, crop: c_int,
method: uint8_t) -> c_int;
fn af_translate(out: MutAfArray, input: AfArray, trans0: c_float, trans1: c_float,
odim0: DimT, odim1: DimT, method: uint8_t) -> c_int;
fn af_scale(out: MutAfArray, input: AfArray, scale0: c_float, scale1: c_float,
odim0: DimT, odim1: DimT, method: uint8_t) -> c_int;
fn af_skew(out: MutAfArray, input: AfArray, skew0: c_float, skew1: c_float,
odim0: DimT, odim1: DimT, method: uint8_t, 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: uint8_t, aftype: uint8_t) -> 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: uint8_t) -> c_int;
fn af_medfilt1(out: MutAfArray, input: AfArray, wlen: DimT, etype: uint8_t) -> c_int;
fn af_minfilt(out: MutAfArray, input: AfArray,
wlen: DimT, wwid: DimT, etype: uint8_t) -> c_int;
fn af_maxfilt(out: MutAfArray, input: AfArray,
wlen: DimT, wwid: DimT, etype: uint8_t) -> 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: uint8_t, fromspace: uint8_t) -> 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;
}
#[allow(unused_mut)]
pub fn gradient(input: &Array) -> (Array, Array) {
unsafe {
let mut dx: i64 = 0;
let mut dy: i64 = 0;
let err_val = af_gradient(&mut dx as MutAfArray, &mut dy as MutAfArray,
input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
(Array::from(dx), Array::from(dy))
}
}
#[allow(unused_mut)]
pub fn load_image(filename: String, is_color: bool) -> Array {
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
unsafe {
let mut temp: i64 = 0;
let err_val = af_load_image(&mut temp as MutAfArray, cstr_param.as_ptr(), is_color as c_int);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn load_image_native(filename: String) -> Array {
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
unsafe {
let mut temp: i64 = 0;
let err_val = af_load_image_native(&mut temp as MutAfArray, cstr_param.as_ptr());
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn save_image(filename: String, input: &Array) {
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(filename: String, input: &Array) {
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(input: &Array, odim0: i64, odim1: i64,
method: InterpType) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_resize(&mut temp as MutAfArray, input.get() as AfArray,
odim0 as DimT, odim1 as DimT, method as uint8_t);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn transform(input: &Array, trans: &Array, odim0: i64, odim1: i64,
method: InterpType, is_inverse: bool) -> Array {
unsafe {
let mut temp: i64 = 0;
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 uint8_t, is_inverse as c_int);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn rotate(input: &Array, theta: f64, crop: bool,
method: InterpType) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_rotate(&mut temp as MutAfArray, input.get() as AfArray,
theta as c_float, crop as c_int, method as uint8_t);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn translate(input: &Array, trans0: f32, trans1: f32,
odim0: i64, odim1: i64, method: InterpType) -> Array {
unsafe {
let mut temp: i64 = 0;
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 uint8_t);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn scale(input: &Array, scale0: f32, scale1: f32,
odim0: i64, odim1: i64, method: InterpType) -> Array {
unsafe {
let mut temp: i64 = 0;
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 uint8_t);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn skew(input: &Array, skew0: f32, skew1: f32, odim0: i64, odim1: i64,
method: InterpType, is_inverse: bool) -> Array {
unsafe {
let mut temp: i64 = 0;
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 uint8_t, is_inverse as c_int);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn histogram(input: &Array, nbins: u32,
minval: f64, maxval: f64) -> Array {
unsafe {
let mut temp: i64 = 0;
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));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn dilate(input: &Array, mask: &Array) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_dilate(&mut temp as MutAfArray,
input.get() as AfArray, mask.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn erode(input: &Array, mask: &Array) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_erode(&mut temp as MutAfArray,
input.get() as AfArray, mask.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn dilate3(input: &Array, mask: &Array) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_dilate3(&mut temp as MutAfArray,
input.get() as AfArray, mask.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn erode3(input: &Array, mask: &Array) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_erode3(&mut temp as MutAfArray,
input.get() as AfArray, mask.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn bilateral(input: &Array, spatial_sigma: f32, chromatic_sigma: f32,
iscolor: bool) -> Array {
unsafe {
let mut temp: i64 = 0;
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));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn mean_shift(input: &Array, spatial_sigma: f32, chromatic_sigma: f32,
iter: u32, iscolor: bool) -> Array {
unsafe {
let mut temp: i64 = 0;
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));
Array::from(temp)
}
}
macro_rules! filt_func_def {
($doc_str: expr, $fn_name: ident, $ffi_name: ident) => (
#[doc=$doc_str]
#[allow(unused_mut)]
pub fn $fn_name(input: &Array, wlen: u64, wwid: u64,
etype: BorderType) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = $ffi_name(&mut temp as MutAfArray, input.get() as AfArray,
wlen as DimT, wwid as DimT, etype as uint8_t);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
)
}
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 {
unsafe {
let mut temp: i64 = 0;
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));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn color_space(input: &Array,
tospace: ColorSpace, fromspace: ColorSpace) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_color_space(&mut temp as MutAfArray, input.get() as AfArray,
tospace as uint8_t, fromspace as uint8_t);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn regions<OutType: HasAfEnum>(input: &Array, conn: Connectivity) -> Array {
unsafe {
let otype = OutType::get_af_dtype();
let mut temp: i64 = 0;
let err_val = af_regions(&mut temp as MutAfArray, input.get() as AfArray,
conn as uint8_t, otype as uint8_t);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(unused_mut)]
pub fn sobel(input: &Array, ker_size: u32) -> (Array, Array) {
unsafe {
let mut dx: i64 = 0;
let mut dy: i64 = 0;
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));
(Array::from(dx), Array::from(dy))
}
}
#[allow(unused_mut)]
pub fn hist_equal(input: &Array, hist: &Array) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_hist_equal(&mut temp as MutAfArray,
input.get() as AfArray, hist.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
macro_rules! grayrgb_func_def {
($doc_str: expr, $fn_name: ident, $ffi_name: ident) => (
#[doc=$doc_str]
#[allow(unused_mut)]
pub fn $fn_name(input: &Array, r: f32, g: f32, b: f32) -> Array {
unsafe {
let mut temp: i64 = 0;
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));
Array::from(temp)
}
}
)
}
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(input: &Array) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = $ffi_name(&mut temp as MutAfArray, input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
)
}
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(input: &Array,
wx: i64, wy: i64,
sx: i64, sy: i64,
px: i64, py: i64,
is_column: bool) -> Array {
unsafe {
let mut temp: i64 = 0;
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));
Array::from(temp)
}
}
pub fn wrap(input: &Array,
ox: i64, oy: i64, wx: i64, wy: i64,
sx: i64, sy: i64, px: i64, py: i64,
is_column: bool) -> Array {
unsafe {
let mut temp: i64 = 0;
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));
Array::from(temp)
}
}
pub fn sat(input: &Array) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_sat(&mut temp as MutAfArray, input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
pub fn rgb2ycbcr(input: &Array, standard: YCCStd) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_rgb2ycbcr(&mut temp as MutAfArray, input.get() as AfArray,
standard as c_int);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
pub fn ycbcr2rgb(input: &Array, standard: YCCStd) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_ycbcr2rgb(&mut temp as MutAfArray, input.get() as AfArray,
standard as c_int);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
pub fn is_imageio_available() -> bool {
unsafe {
let mut temp: i32 = 0;
af_is_image_io_available(&mut temp as *mut c_int);
temp > 0 }
}
pub fn transform_coords(tf: &Array, d0: f32, d1: f32) -> Array {
unsafe {
let mut temp: i64 = 0;
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));
Array::from(temp)
}
}
pub fn moments(input: &Array, moment: MomentType) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_moments(&mut temp as MutAfArray,
input.get() as AfArray,
moment as c_int);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
pub fn moments_all(input: &Array, moment: MomentType) -> f64 {
unsafe {
let mut temp: f64 = 0.0;
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(input: &Array, wlen: u64, etype: BorderType) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_medfilt1(&mut temp as MutAfArray, input.get() as AfArray,
wlen as DimT, etype as uint8_t);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
pub fn canny(input: &Array, threshold_type: CannyThresholdType, low: f32, hight: f32,
sobel_window: u32, is_fast: bool) -> Array {
unsafe {
let mut temp: i64 = 0;
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));
Array::from(temp)
}
}