use crate::check_rs2_error;
use anyhow::Result;
use realsense_sys as sys;
use std::ptr::NonNull;
use thiserror::Error;
#[derive(Error, Debug, Clone, PartialEq)]
pub enum ProcessingBlockOptionError {
#[error("Option not supported: {0}")]
OptionNotSupported(String),
#[error("Invalid option value: {0}")]
InvalidValue(String),
#[error("Failed to set option: {0}")]
SetOptionFailed(String),
#[error("Failed to get option: {0}")]
GetOptionFailed(String),
}
pub trait OptionsExt {
fn set_option(
&mut self,
option: sys::rs2_option,
value: f32,
) -> Result<(), ProcessingBlockOptionError>;
fn get_option(&self, option: sys::rs2_option) -> Result<f32, ProcessingBlockOptionError>;
fn supports_option(&self, option: sys::rs2_option) -> bool;
fn get_option_range(
&self,
option: sys::rs2_option,
) -> Result<(f32, f32, f32, f32), ProcessingBlockOptionError>;
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct SpatialFilterOptions {
pub smooth_alpha: Option<f32>,
pub smooth_delta: Option<f32>,
pub magnitude: Option<f32>,
pub holes_fill: Option<f32>,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct TemporalFilterOptions {
pub smooth_alpha: Option<f32>,
pub smooth_delta: Option<f32>,
pub persistence_control: Option<f32>,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct HoleFillingOptions {
pub holes_fill: Option<f32>,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct ThresholdOptions {
pub min_distance: Option<f32>,
pub max_distance: Option<f32>,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct DecimationOptions {
pub filter_magnitude: Option<f32>,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct ColorizerOptions {
pub color_scheme: Option<f32>,
pub histogram_equalization: Option<f32>,
pub min_distance: Option<f32>,
pub max_distance: Option<f32>,
}
pub fn set_processing_block_option(
block: NonNull<sys::rs2_processing_block>,
option: sys::rs2_option,
value: f32,
) -> Result<(), ProcessingBlockOptionError> {
unsafe {
let mut err = std::ptr::null_mut::<sys::rs2_error>();
let is_supported =
sys::rs2_supports_option(block.as_ptr() as *const sys::rs2_options, option, &mut err);
if !err.is_null() {
check_rs2_error!(err, |kind, context| {
ProcessingBlockOptionError::SetOptionFailed(format!("{:?}: {}", kind, context))
})?;
}
if is_supported == 0 {
return Err(ProcessingBlockOptionError::OptionNotSupported(format!(
"Option {:?} not supported",
option
)));
}
sys::rs2_set_option(
block.as_ptr() as *const sys::rs2_options,
option,
value,
&mut err,
);
check_rs2_error!(err, |kind, context| {
ProcessingBlockOptionError::SetOptionFailed(format!("{:?}: {}", kind, context))
})?;
Ok(())
}
}
pub fn get_processing_block_option(
block: NonNull<sys::rs2_processing_block>,
option: sys::rs2_option,
) -> Result<f32, ProcessingBlockOptionError> {
unsafe {
let mut err = std::ptr::null_mut::<sys::rs2_error>();
let is_supported =
sys::rs2_supports_option(block.as_ptr() as *const sys::rs2_options, option, &mut err);
if !err.is_null() {
check_rs2_error!(err, |kind, context| {
ProcessingBlockOptionError::GetOptionFailed(format!("{:?}: {}", kind, context))
})?;
}
if is_supported == 0 {
return Err(ProcessingBlockOptionError::OptionNotSupported(format!(
"Option {:?} not supported",
option
)));
}
let value =
sys::rs2_get_option(block.as_ptr() as *const sys::rs2_options, option, &mut err);
check_rs2_error!(err, |kind, context| {
ProcessingBlockOptionError::GetOptionFailed(format!("{:?}: {}", kind, context))
})?;
Ok(value)
}
}
pub fn get_processing_block_option_range(
block: NonNull<sys::rs2_processing_block>,
option: sys::rs2_option,
) -> Result<(f32, f32, f32, f32), ProcessingBlockOptionError> {
unsafe {
let mut err = std::ptr::null_mut::<sys::rs2_error>();
let mut min = 0.0f32;
let mut max = 0.0f32;
let mut step = 0.0f32;
let mut default = 0.0f32;
sys::rs2_get_option_range(
block.as_ptr() as *const sys::rs2_options,
option,
&mut min,
&mut max,
&mut step,
&mut default,
&mut err,
);
check_rs2_error!(err, |kind, context| {
ProcessingBlockOptionError::GetOptionFailed(format!("{:?}: {}", kind, context))
})?;
Ok((min, max, step, default))
}
}