#![deny(missing_docs)]
#![cfg_attr(docsrs, feature(doc_cfg))]
pub use controls::GenCamCtrl;
pub use refimage::GenericImage;
use refimage::GenericImageRef;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::hash::Hash;
use std::{fmt::Display, time::Duration};
use thiserror::Error;
pub use crate::property::{Property, PropertyError, PropertyType, PropertyValue};
pub mod controls;
#[cfg(feature = "dummy")]
#[cfg_attr(docsrs, doc(cfg(feature = "dummy")))]
pub mod dummy;
pub mod property;
#[cfg(feature = "server")]
#[cfg_attr(docsrs, doc(cfg(feature = "server")))]
pub mod server;
pub type GenCamResult<T> = std::result::Result<T, GenCamError>;
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Hash, Default)]
pub struct GenCamRoi {
pub x_min: u16,
pub y_min: u16,
pub width: u16,
pub height: u16,
}
impl Display for GenCamRoi {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"ROI: Origin = ({}, {}), Image Size = ({} x {})",
self.x_min, self.y_min, self.width, self.height
)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum GenCamState {
Idle,
Exposing(Option<Duration>),
ExposureFinished,
Downloading(Option<u32>),
Errored(GenCamError),
Unknown,
}
pub type AnyGenCam = Box<dyn GenCam>;
pub type AnyGenCamInfo = Box<dyn GenCamInfo>;
pub trait GenCamDriver {
fn available_devices(&self) -> usize;
fn list_devices(&mut self) -> GenCamResult<Vec<GenCamDescriptor>>;
fn connect_device(&mut self, descriptor: &GenCamDescriptor) -> GenCamResult<AnyGenCam>;
fn connect_first_device(&mut self) -> GenCamResult<AnyGenCam>;
}
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Default)]
pub struct GenCamDescriptor {
pub id: usize,
pub name: String,
pub vendor: String,
pub info: HashMap<String, PropertyValue>,
}
pub trait GenCam: Send + std::fmt::Debug {
fn info_handle(&self) -> Option<AnyGenCamInfo>;
fn info(&self) -> GenCamResult<&GenCamDescriptor>;
fn vendor(&self) -> &str;
fn camera_ready(&self) -> bool;
fn camera_name(&self) -> &str;
fn list_properties(&self) -> &HashMap<GenCamCtrl, Property>;
fn get_property(&self, name: GenCamCtrl) -> GenCamResult<(PropertyValue, bool)>;
fn set_property(
&mut self,
name: GenCamCtrl,
value: &PropertyValue,
auto: bool,
) -> GenCamResult<()>;
fn cancel_capture(&self) -> GenCamResult<()>;
fn is_capturing(&self) -> bool;
fn capture(&mut self) -> GenCamResult<GenericImageRef>;
fn start_exposure(&mut self) -> GenCamResult<()>;
fn download_image(&mut self) -> GenCamResult<GenericImageRef>;
fn image_ready(&self) -> GenCamResult<bool>;
fn camera_state(&self) -> GenCamResult<GenCamState>;
fn set_roi(&mut self, roi: &GenCamRoi) -> GenCamResult<&GenCamRoi>;
fn get_roi(&self) -> &GenCamRoi;
}
pub trait GenCamInfo: Send + Sync + std::fmt::Debug {
fn camera_ready(&self) -> bool;
fn camera_name(&self) -> &str;
fn cancel_capture(&self) -> GenCamResult<()>;
fn is_capturing(&self) -> bool;
fn camera_state(&self) -> GenCamResult<GenCamState>;
fn list_properties(&self) -> &HashMap<GenCamCtrl, Property>;
fn get_property(&self, name: GenCamCtrl) -> GenCamResult<(PropertyValue, bool)>;
fn set_property(
&mut self,
name: GenCamCtrl,
value: &PropertyValue,
auto: bool,
) -> GenCamResult<()>;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)]
#[non_exhaustive]
pub enum GenCamPixelBpp {
Bpp8 = 8,
Bpp10 = 10,
Bpp12 = 12,
Bpp16 = 16,
Bpp24 = 24,
Bpp32 = 32,
}
impl From<u32> for GenCamPixelBpp {
fn from(value: u32) -> Self {
match value {
8 => GenCamPixelBpp::Bpp8,
10 => GenCamPixelBpp::Bpp10,
12 => GenCamPixelBpp::Bpp12,
16 => GenCamPixelBpp::Bpp16,
24 => GenCamPixelBpp::Bpp24,
32 => GenCamPixelBpp::Bpp32,
_ => GenCamPixelBpp::Bpp8,
}
}
}
#[derive(Error, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum GenCamError {
#[error("Error: {0}")]
Message(String),
#[error("Access violation")]
AccessViolation,
#[error("Invalid index: {0}")]
InvalidIndex(i32),
#[error("Invalid ID: {0}")]
InvalidId(i32),
#[error("Invalid control type: {0}")]
InvalidControlType(String),
#[error("No cameras available")]
NoCamerasAvailable,
#[error("Camera not open for access")]
CameraClosed,
#[error("Camera already removed")]
CameraRemoved,
#[error("Invalid path: {0}")]
InvalidPath(String),
#[error("Invalid format: {0}")]
InvalidFormat(String),
#[error("Invalid size: {0}")]
InvalidSize(usize),
#[error("Invalid image type: {0}")]
InvalidImageType(String),
#[error("Operation timed out")]
TimedOut,
#[error("Invalid sequence")]
InvalidSequence,
#[error("Buffer too small: {0}")]
BufferTooSmall(usize),
#[error("Exposure already in progress")]
ExposureInProgress,
#[error("General error: {0}")]
GeneralError(String),
#[error("Invalid mode: {0}")]
InvalidMode(String),
#[error("Exposure failed: {0}")]
ExposureFailed(String),
#[error("Invalid value: {0}")]
InvalidValue(String),
#[error("Out of bounds: {0}")]
OutOfBounds(String),
#[error("Exposure not started.")]
ExposureNotStarted,
#[error("Property error: {control:?} - {error:?}")]
PropertyError {
control: GenCamCtrl,
error: PropertyError,
},
}