use crate::error::Error; use std::ffi::CStr; use std::mem::MaybeUninit; pub fn lib_czi_error(code: std::ffi::c_int) -> Result<(), Error> { match code { 0 => Ok(()), 1 => Err(Error::LibCziApiInvalidArgument), 2 => Err(Error::LibCziApiInvalidHandle), 3 => Err(Error::LibCziApiOutOfMemory), 4 => Err(Error::LibCziApiIndexOutOfRange), 20 => Err(Error::LibCziApiLockUnlockSemanticViolated), 50 => Err(Error::LibCziApiUnspecifiedError), _ => Err(Error::LibCziApiUnknownError(code as usize)), } } /// container for some types of attachment data pub enum AttachmentData { Float(Vec), Xml(String), Unknown(Vec), } impl AttachmentData { pub fn attachment_type(&self) -> &str { match self { Self::Float(_) => "float", Self::Xml(_) => "xml", Self::Unknown(_) => "unknown", } } pub(crate) fn from_float(raw: &[u8]) -> Result { if raw.len() < 8 { Err(Error::MalformedData) } else { let number = u32::from_le_bytes(raw[4..8].try_into().unwrap()) as usize; if raw.len() < 8 * number + 8 { Err(Error::MalformedData) } else { let mut data = Vec::with_capacity(number); for i in 0..number { data.push(f64::from_le_bytes( raw[8 + 8 * i..16 + 8 * i].try_into().unwrap(), )); } Ok(Self::Float(data)) } } } pub(crate) fn from_xml(raw: &[u8]) -> Result { Ok(Self::Xml( CStr::from_bytes_until_nul(raw)? .to_string_lossy() .to_string(), )) } pub fn try_into_float(&self) -> Result, Error> { if let AttachmentData::Float(data) = self { Ok(data.clone()) } else { Err(Error::InvalidAttachmentType( self.attachment_type().to_string(), )) } } pub fn try_into_xml(&self) -> Result { if let AttachmentData::Xml(data) = self { Ok(data.clone()) } else { Err(Error::InvalidAttachmentType( self.attachment_type().to_string(), )) } } } #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] pub enum Dimension { /// The Z-dimension. Z = 1, /// The C-dimension ("channel"). C = 2, /// The T-dimension ("time"). T = 3, /// The R-dimension ("rotation"). R = 4, /// The S-dimension ("scene"). S = 5, /// The I-dimension ("illumination"). I = 6, /// The H-dimension ("phase"). H = 7, /// The V-dimension ("view"). V = 8, /// The B-dimension ("block") - its use is deprecated. B = 9, } impl Dimension { pub fn vec_from_bitflags(bit_flags: u32) -> Vec { let mut bit_flags = bit_flags; let mut dimensions = Vec::with_capacity(9); for i in 1..=9 { if (bit_flags & 1) > 0 { dimensions.push(Dimension::try_from(i).expect("i must be 0 <= i <= 9")); } bit_flags >>= 1; } dimensions } pub fn is_valid(&self, v: u32) -> bool { v & (*self as u32).pow(2) > 0 } } impl TryFrom for Dimension { type Error = Error; fn try_from(dimension: i32) -> Result { match dimension { 1 => Ok(Dimension::Z), 2 => Ok(Dimension::C), 3 => Ok(Dimension::T), 4 => Ok(Dimension::R), 5 => Ok(Dimension::S), 6 => Ok(Dimension::I), 7 => Ok(Dimension::H), 8 => Ok(Dimension::V), 9 => Ok(Dimension::B), _ => Err(Error::UnknownDimension(dimension.to_string())), } } } /// enum for SubBlock.get_raw_data #[derive(Clone, Debug)] pub enum RawDataType { Data = 0, Metadata = 1, } impl TryFrom for RawDataType { type Error = Error; fn try_from(raw_data_type: i32) -> Result { match raw_data_type { 0 => Ok(RawDataType::Data), 1 => Ok(RawDataType::Metadata), _ => Err(Error::UnknownDataType(raw_data_type)), } } } /// pixel type #[derive(Clone, Debug)] pub enum PixelType { Gray8 = 0, Gray16 = 1, Gray32Float = 2, Bgr24 = 3, Bgr48 = 4, Bgr96Float = 8, Bgra32 = 9, Gray64ComplexFloat = 10, Bgr192ComplexFloat = 11, Gray32 = 12, Gray64Float = 13, } impl TryFrom for PixelType { type Error = Error; fn try_from(pixel_type: i32) -> Result { match pixel_type { 0 => Ok(PixelType::Gray8), 1 => Ok(PixelType::Gray16), 2 => Ok(PixelType::Gray32Float), 3 => Ok(PixelType::Bgr24), 4 => Ok(PixelType::Bgr48), 8 => Ok(PixelType::Bgr96Float), 9 => Ok(PixelType::Bgra32), 10 => Ok(PixelType::Gray64ComplexFloat), 11 => Ok(PixelType::Bgr192ComplexFloat), 12 => Ok(PixelType::Gray32), 13 => Ok(PixelType::Gray64Float), _ => Err(Error::UnknownPixelType(pixel_type)), } } } pub trait Ptr { type Pointer; unsafe fn assume_init(ptr: MaybeUninit) -> Self; fn as_mut_ptr(&self) -> *mut Self::Pointer where Self: Sized; fn as_ptr(&self) -> *const Self::Pointer where Self: Sized; }