210 lines
5.5 KiB
Rust
210 lines
5.5 KiB
Rust
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<f64>),
|
|
Xml(String),
|
|
Unknown(Vec<u8>),
|
|
}
|
|
|
|
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<Self, Error> {
|
|
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<Self, Error> {
|
|
Ok(Self::Xml(
|
|
CStr::from_bytes_until_nul(raw)?
|
|
.to_string_lossy()
|
|
.to_string(),
|
|
))
|
|
}
|
|
|
|
pub fn try_into_float(&self) -> Result<Vec<f64>, 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<String, Error> {
|
|
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<Dimension> {
|
|
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<i32> for Dimension {
|
|
type Error = Error;
|
|
|
|
fn try_from(dimension: i32) -> Result<Self, Error> {
|
|
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<i32> for RawDataType {
|
|
type Error = Error;
|
|
|
|
fn try_from(raw_data_type: i32) -> Result<Self, Error> {
|
|
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<i32> for PixelType {
|
|
type Error = Error;
|
|
|
|
fn try_from(pixel_type: i32) -> Result<Self, Error> {
|
|
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::Pointer>) -> Self;
|
|
|
|
fn as_mut_ptr(&self) -> *mut Self::Pointer
|
|
where
|
|
Self: Sized;
|
|
|
|
fn as_ptr(&self) -> *const Self::Pointer
|
|
where
|
|
Self: Sized;
|
|
}
|