Skip to main content

libczirw_sys/
misc.rs

1use crate::error::Error;
2use std::ffi::CStr;
3use std::mem::MaybeUninit;
4
5pub fn lib_czi_error(code: std::ffi::c_int) -> Result<(), Error> {
6    match code {
7        0 => Ok(()),
8        1 => Err(Error::LibCziApiInvalidArgument),
9        2 => Err(Error::LibCziApiInvalidHandle),
10        3 => Err(Error::LibCziApiOutOfMemory),
11        4 => Err(Error::LibCziApiIndexOutOfRange),
12        20 => Err(Error::LibCziApiLockUnlockSemanticViolated),
13        50 => Err(Error::LibCziApiUnspecifiedError),
14        _ => Err(Error::LibCziApiUnknownError(code as usize)),
15    }
16}
17
18/// container for some types of attachment data
19pub enum AttachmentData {
20    Float(Vec<f64>),
21    Xml(String),
22    Unknown(Vec<u8>),
23}
24
25impl AttachmentData {
26    pub fn attachment_type(&self) -> &str {
27        match self {
28            Self::Float(_) => "float",
29            Self::Xml(_) => "xml",
30            Self::Unknown(_) => "unknown",
31        }
32    }
33
34    pub(crate) fn from_float(raw: &[u8]) -> Result<Self, Error> {
35        if raw.len() < 8 {
36            Err(Error::MalformedData)
37        } else {
38            let number = u32::from_le_bytes(raw[4..8].try_into().unwrap()) as usize;
39            if raw.len() < 8 * number + 8 {
40                Err(Error::MalformedData)
41            } else {
42                let mut data = Vec::with_capacity(number);
43                for i in 0..number {
44                    data.push(f64::from_le_bytes(
45                        raw[8 + 8 * i..16 + 8 * i].try_into().unwrap(),
46                    ));
47                }
48                Ok(Self::Float(data))
49            }
50        }
51    }
52
53    pub(crate) fn from_xml(raw: &[u8]) -> Result<Self, Error> {
54        Ok(Self::Xml(
55            CStr::from_bytes_until_nul(raw)?
56                .to_string_lossy()
57                .to_string(),
58        ))
59    }
60
61    pub fn try_into_float(&self) -> Result<Vec<f64>, Error> {
62        if let AttachmentData::Float(data) = self {
63            Ok(data.clone())
64        } else {
65            Err(Error::InvalidAttachmentType(
66                self.attachment_type().to_string(),
67            ))
68        }
69    }
70
71    pub fn try_into_xml(&self) -> Result<String, Error> {
72        if let AttachmentData::Xml(data) = self {
73            Ok(data.clone())
74        } else {
75            Err(Error::InvalidAttachmentType(
76                self.attachment_type().to_string(),
77            ))
78        }
79    }
80}
81
82#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
83pub enum Dimension {
84    /// The Z-dimension.
85    Z = 1,
86    /// The C-dimension ("channel").
87    C = 2,
88    /// The T-dimension ("time").
89    T = 3,
90    /// The R-dimension ("rotation").
91    R = 4,
92    /// The S-dimension ("scene").
93    S = 5,
94    /// The I-dimension ("illumination").
95    I = 6,
96    /// The H-dimension ("phase").
97    H = 7,
98    /// The V-dimension ("view").
99    V = 8,
100    /// The B-dimension ("block") - its use is deprecated.
101    B = 9,
102}
103
104impl Dimension {
105    pub fn vec_from_bitflags(bit_flags: u32) -> Vec<Dimension> {
106        let mut bit_flags = bit_flags;
107        let mut dimensions = Vec::with_capacity(9);
108        for i in 1..=9 {
109            if (bit_flags & 1) > 0 {
110                dimensions.push(Dimension::try_from(i).expect("i must be 0 <= i <= 9"));
111            }
112            bit_flags >>= 1;
113        }
114        dimensions
115    }
116
117    pub fn is_valid(&self, v: u32) -> bool {
118        v & (*self as u32).pow(2) > 0
119    }
120}
121
122impl TryFrom<i32> for Dimension {
123    type Error = Error;
124
125    fn try_from(dimension: i32) -> Result<Self, Error> {
126        match dimension {
127            1 => Ok(Dimension::Z),
128            2 => Ok(Dimension::C),
129            3 => Ok(Dimension::T),
130            4 => Ok(Dimension::R),
131            5 => Ok(Dimension::S),
132            6 => Ok(Dimension::I),
133            7 => Ok(Dimension::H),
134            8 => Ok(Dimension::V),
135            9 => Ok(Dimension::B),
136            _ => Err(Error::UnknownDimension(dimension.to_string())),
137        }
138    }
139}
140
141/// enum for SubBlock.get_raw_data
142#[derive(Clone, Debug)]
143pub enum RawDataType {
144    Data = 0,
145    Metadata = 1,
146}
147
148impl TryFrom<i32> for RawDataType {
149    type Error = Error;
150
151    fn try_from(raw_data_type: i32) -> Result<Self, Error> {
152        match raw_data_type {
153            0 => Ok(RawDataType::Data),
154            1 => Ok(RawDataType::Metadata),
155            _ => Err(Error::UnknownDataType(raw_data_type)),
156        }
157    }
158}
159
160/// pixel type
161#[derive(Clone, Debug)]
162pub enum PixelType {
163    Gray8 = 0,
164    Gray16 = 1,
165    Gray32Float = 2,
166    Bgr24 = 3,
167    Bgr48 = 4,
168    Bgr96Float = 8,
169    Bgra32 = 9,
170    Gray64ComplexFloat = 10,
171    Bgr192ComplexFloat = 11,
172    Gray32 = 12,
173    Gray64Float = 13,
174}
175
176impl TryFrom<i32> for PixelType {
177    type Error = Error;
178
179    fn try_from(pixel_type: i32) -> Result<Self, Error> {
180        match pixel_type {
181            0 => Ok(PixelType::Gray8),
182            1 => Ok(PixelType::Gray16),
183            2 => Ok(PixelType::Gray32Float),
184            3 => Ok(PixelType::Bgr24),
185            4 => Ok(PixelType::Bgr48),
186            8 => Ok(PixelType::Bgr96Float),
187            9 => Ok(PixelType::Bgra32),
188            10 => Ok(PixelType::Gray64ComplexFloat),
189            11 => Ok(PixelType::Bgr192ComplexFloat),
190            12 => Ok(PixelType::Gray32),
191            13 => Ok(PixelType::Gray64Float),
192            _ => Err(Error::UnknownPixelType(pixel_type)),
193        }
194    }
195}
196
197pub trait Ptr {
198    type Pointer;
199
200    unsafe fn assume_init(ptr: MaybeUninit<Self::Pointer>) -> Self;
201
202    fn as_mut_ptr(&self) -> *mut Self::Pointer
203    where
204        Self: Sized;
205
206    fn as_ptr(&self) -> *const Self::Pointer
207    where
208        Self: Sized;
209}