Skip to main content

libczirw_sys/
interop.rs

1use crate::error::Error;
2use crate::handle::{InputStream, MemoryAllocation};
3use crate::misc::{PixelType, Ptr};
4use crate::sys::*;
5use std::borrow::Cow;
6use std::ffi::{CStr, CString, c_char, c_void};
7use std::fmt::Debug;
8use std::mem;
9use std::mem::{ManuallyDrop, MaybeUninit};
10
11/// This struct contains the version information of the libCZIApi-library. For versioning libCZI, SemVer2 (<https://semver.org/>) is used.
12/// Note that the value of the tweak version number does not have a meaning (as far as SemVer2 is concerned).
13#[derive(Clone, Debug)]
14pub struct LibCZIVersionInfo(pub(crate) LibCZIVersionInfoInterop);
15
16/// This struct gives information about the build of the libCZIApi-library.
17/// Note that all strings must be freed by the caller (using libCZI_Free).
18#[derive(Clone, Debug)]
19pub struct LibCZIBuildInformation(pub(crate) LibCZIBuildInformationInterop);
20
21#[derive(Clone, Debug)]
22pub struct InputStreamClassInfo(pub(crate) InputStreamClassInfoInterop);
23
24/// This structure gives additional information about an error that occurred in the external stream.
25#[derive(Clone, Debug)]
26pub struct ExternalStreamErrorInfo(pub(crate) ExternalStreamErrorInfoInterop);
27
28/// This structure contains information about externally provided functions for reading data from an input stream,
29/// and it is used to construct a stream-object to be used with libCZI.
30/// Note on lifetime: The function pointers must remain valid until the function 'close_function' is called. The lifetime
31/// may extend beyond calling the 'libCZI_ReleaseInputStream' function for the corresponding stream-object.
32#[derive(Clone, Debug)]
33pub struct ExternalInputStreamStruct(pub(crate) ExternalInputStreamStructInterop);
34
35/// This structure contains information about externally provided functions for writing data to an output stream,
36/// and it is used to construct a stream-object to be used with libCZI.
37/// Note on lifetime: The function pointers must remain valid until the function 'close_function' is called. The lifetime
38/// may extend beyond calling the 'libCZI_ReleaseOutputStream' function for the corresponding stream-object.
39#[derive(Clone, Debug)]
40pub struct ExternalOutputStreamStruct(pub(crate) ExternalOutputStreamStructInterop);
41
42/// This structure gather the information needed to create a reader object.
43#[derive(Clone, Debug)]
44pub struct ReaderOpenInfo(pub(crate) ReaderOpenInfoInterop);
45
46/// This structure describes a rectangle, given by its top-left corner and its width and height.
47#[derive(Clone, Debug)]
48pub struct IntRect(pub(crate) IntRectInterop);
49
50/// This structure describes a size, given by its width and height.
51#[derive(Clone, Debug)]
52pub struct IntSize(pub(crate) IntSizeInterop);
53
54/// This structure gives the bounds for a set of dimensions.
55/// The bit at position `i` in `dimensions_valid` indicates whether the interval for dimension `i+1` is valid. So, bit 0
56/// is corresponding to dimension 1 (=Z), bit 1 to dimension 2 (=C), and so on.
57/// In the fixed-sized arrays `start` and `size`, the start and size values for the dimensions are stored. The elements at
58/// position 0 corresponds to the first valid dimension, the element at position 1 to the second valid dimension, and so on.
59/// An example would be: `dimensions_valid` = 0b00000011, `start` = { 0, 2 }, `size` = { 5, 6 }. This would mean that the
60/// dimension 'Z' is valid, and the interval is [0, 5], and the dimension 'C' is valid, and the interval is [2, 8].
61#[derive(Clone, Debug)]
62pub struct DimBounds(pub(crate) DimBoundsInterop);
63
64/// This structure gives the coordinates (of a sub-block) for a set of dimension.
65/// The bit at position `i` in `dimensions_valid` indicates whether the coordinate for dimension `i+1` is valid. So, bit 0
66/// is corresponding to dimension 1 (=Z), bit 1 to dimension 2 (=C), and so on.
67/// In the fixed-sized array `value`, the coordinate for the dimensions is stored. The element at
68/// position 0 corresponds to the first valid dimension, the element at position 1 to the second valid dimension, and so on.
69/// An example would be: `dimensions_valid` = 0b00000011, `value` = { 0, 2 }. This would mean that the
70/// dimension 'Z' is valid, and the coordinate for 'Z' is 0, and the dimension 'C' is valid, and the coordinate for 'C' is 2.
71#[derive(Clone, Debug)]
72pub struct Coordinate(pub(crate) CoordinateInterop);
73
74/// This structure contains the bounding boxes for a scene.
75#[derive(Clone, Debug)]
76pub struct BoundingBoxes(pub(crate) BoundingBoxesInterop);
77
78/// This structure contains basic statistics about an CZI-document.
79#[derive(Clone, Debug)]
80pub struct SubBlockStatistics(pub(crate) SubBlockStatisticsInterop);
81
82/// This structure extends on the basic statistics about an CZI-document, and includes per-scene statistics.
83#[derive(Debug)]
84pub struct SubBlockStatisticsEx(pub(crate) SubBlockStatisticsInteropEx);
85
86#[derive(Clone, Debug)]
87pub struct MetadataAsXml(pub(crate) MetadataAsXmlInterop);
88
89/// Information about the bitmap represented by a bitmap-object.
90#[derive(Clone, Debug)]
91pub struct BitmapInfo(pub(crate) BitmapInfoInterop);
92
93/// This structure contains information about a locked bitmap-object, allowing direct
94/// access to the pixel data.
95#[derive(Clone, Debug)]
96pub struct BitmapLockInfo(pub(crate) BitmapLockInfoInterop);
97
98/// This structure contains the information about a sub-block.
99#[derive(Clone, Debug)]
100pub struct SubBlockInfo(pub(crate) SubBlockInfoInterop);
101
102/// This structure contains the information about an attachment.
103/// Note that performance reasons we use a fixed-size array for the name. In the rare case that the name is too long to fit into the
104/// fixed-size array, the 'overflow' field is set to true. In this case, the name is truncated and the 'overflow' field is set to true.
105/// In addition, the field 'name_in_case_of_overflow' then contains the full text, allocated with 'libCZI_AllocateString' (and responsibility
106/// for releasing the memory is with the caller).
107#[derive(Clone, Debug)]
108pub struct AttachmentInfo(pub(crate) AttachmentInfoInterop);
109
110/// This structure contains the information about file-header.
111#[derive(Clone, Debug)]
112pub struct FileHeaderInfo(pub(crate) FileHeaderInfoInterop);
113
114/// This structure is used to pass the subblock information to libCZIAPI, describing a subblock to be added to a CZI-file.
115#[derive(Clone, Debug)]
116pub struct AddSubBlockInfo(pub(crate) AddSubBlockInfoInterop);
117
118/// This structure is used to pass the attachment information to libCZIAPI, describing an attachment to be added to a CZI-file.
119#[derive(Clone, Debug)]
120pub struct AddAttachmentInfo(pub(crate) AddAttachmentInfoInterop);
121
122/// This structure is used to pass the metadata information to libCZIAPI.
123#[derive(Clone, Debug)]
124pub struct WriteMetadataInfo(pub(crate) WriteMetadataInfoInterop);
125
126/// This structure is used to pass the accessor options to libCZIAPI.
127#[derive(Clone, Debug)]
128pub struct AccessorOptions(pub(crate) AccessorOptionsInterop);
129
130/// This structure gathers all information about a channel for the purpose of multi-channel-composition.
131#[derive(Clone, Debug)]
132pub struct CompositionChannelInfo(pub(crate) CompositionChannelInfoInterop);
133
134/// This structure gathers the information about the scaling.
135#[derive(Clone, Debug)]
136pub struct ScalingInfo(pub(crate) ScalingInfoInterop);
137
138macro_rules! impl_ptr {
139    ($($n:ident: $t:ty: $s:ty $(,)?)*) => {
140        $(
141            impl Ptr for $t {
142                type Pointer = $s;
143
144                unsafe fn assume_init(ptr: MaybeUninit<Self::Pointer>) -> Self {
145                    Self(unsafe { ptr.assume_init() })
146                }
147
148                fn as_mut_ptr(&self) -> *mut Self::Pointer {
149                    // Box::into_raw(Box::new(self.0))
150                    &self.0 as *const _ as *mut _
151                }
152
153                fn as_ptr(&self) -> *const Self::Pointer {
154                    &self.0 as *const _ as *const _
155                    // Box::into_raw(Box::new(self.0)) as *const Self::Pointer
156                }
157            }
158        )*
159    };
160}
161
162impl_ptr! {
163    LibCZIVersionInfo: LibCZIVersionInfo: LibCZIVersionInfoInterop,
164    LibCZIBuildInformation: LibCZIBuildInformation: LibCZIBuildInformationInterop,
165    InputStreamClassInfo: InputStreamClassInfo: InputStreamClassInfoInterop,
166    ExternalStreamErrorInfo: ExternalStreamErrorInfo: ExternalStreamErrorInfoInterop,
167    ExternalInputStreamStruct: ExternalInputStreamStruct: ExternalInputStreamStructInterop,
168    ExternalOutputStreamStruct: ExternalOutputStreamStruct: ExternalOutputStreamStructInterop,
169    ReaderOpenInfo: ReaderOpenInfo: ReaderOpenInfoInterop,
170    IntRect: IntRect: IntRectInterop,
171    IntSize: IntSize: IntSizeInterop,
172    DimBounds: DimBounds: DimBoundsInterop,
173    Coordinate: Coordinate: CoordinateInterop,
174    BoundingBoxes: BoundingBoxes: BoundingBoxesInterop,
175    SubBlockStatistics: SubBlockStatistics: SubBlockStatisticsInterop,
176    SubBlockStatisticsEx: SubBlockStatisticsEx: SubBlockStatisticsInteropEx,
177    MetadataAsXml: MetadataAsXml: MetadataAsXmlInterop,
178    BitmapInfo: BitmapInfo: BitmapInfoInterop,
179    BitmapLockInfo: BitmapLockInfo: BitmapLockInfoInterop,
180    SubBlockInfo: SubBlockInfo: SubBlockInfoInterop,
181    AttachmentInfo: AttachmentInfo: AttachmentInfoInterop,
182    FileHeaderInfo: FileHeaderInfo: FileHeaderInfoInterop,
183    AddSubBlockInfo: AddSubBlockInfo: AddSubBlockInfoInterop,
184    AddAttachmentInfo: AddAttachmentInfo: AddAttachmentInfoInterop,
185    WriteMetadataInfo: WriteMetadataInfo: WriteMetadataInfoInterop,
186    AccessorOptions: AccessorOptions: AccessorOptionsInterop,
187    CompositionChannelInfo: CompositionChannelInfo: CompositionChannelInfoInterop,
188    ScalingInfo: ScalingInfo: ScalingInfoInterop,
189}
190
191impl LibCZIVersionInfo {
192    pub fn get_major(&self) -> i32 {
193        self.0.major
194    }
195    pub fn get_minor(&self) -> i32 {
196        self.0.minor
197    }
198    pub fn get_patch(&self) -> i32 {
199        self.0.patch
200    }
201    pub fn get_tweak(&self) -> i32 {
202        self.0.tweak
203    }
204}
205
206impl LibCZIBuildInformation {
207    pub fn get_compiler_information(&'_ self) -> Cow<'_, str> {
208        unsafe { CStr::from_ptr(self.0.compilerIdentification) }.to_string_lossy()
209    }
210    pub fn get_repository_url(&'_ self) -> Cow<'_, str> {
211        unsafe { CStr::from_ptr(self.0.repositoryUrl) }.to_string_lossy()
212    }
213    pub fn get_repository_branch(&'_ self) -> Cow<'_, str> {
214        unsafe { CStr::from_ptr(self.0.repositoryBranch) }.to_string_lossy()
215    }
216    pub fn get_repository_tag(&'_ self) -> Cow<'_, str> {
217        unsafe { CStr::from_ptr(self.0.repositoryTag) }.to_string_lossy()
218    }
219}
220
221impl Drop for LibCZIBuildInformation {
222    fn drop(&mut self) {
223        unsafe {
224            libCZI_Free(self.0.compilerIdentification as *mut c_void);
225            libCZI_Free(self.0.repositoryUrl as *mut c_void);
226            libCZI_Free(self.0.repositoryBranch as *mut c_void);
227            libCZI_Free(self.0.repositoryTag as *mut c_void);
228        }
229    }
230}
231
232impl InputStreamClassInfo {
233    pub fn get_name(&'_ self) -> Cow<'_, str> {
234        unsafe { CStr::from_ptr(self.0.name) }.to_string_lossy()
235    }
236    pub fn get_description(&'_ self) -> Cow<'_, str> {
237        unsafe { CStr::from_ptr(self.0.description) }.to_string_lossy()
238    }
239}
240
241impl Drop for InputStreamClassInfo {
242    fn drop(&mut self) {
243        unsafe {
244            libCZI_Free(self.0.name as *mut c_void);
245            libCZI_Free(self.0.description as *mut c_void);
246        }
247    }
248}
249
250impl ExternalStreamErrorInfo {
251    pub fn get_error_code(&self) -> i32 {
252        self.0.error_code
253    }
254
255    pub fn get_error_message(&self) -> MemoryAllocation {
256        MemoryAllocation(self.0.error_message)
257    }
258}
259
260// TODO
261impl ExternalInputStreamStruct {
262    /// A user parameter which is passed to the callback function.
263    pub fn get_opaque_handle1(&self) -> u64 {
264        self.0.opaque_handle1
265    }
266    /// A user parameter which is passed to the callback function.
267    pub fn get_opaque_handle2(&self) -> u64 {
268        self.0.opaque_handle2
269    }
270    pub fn set_opaque_handle1(&mut self, handle: u64) {
271        self.0.opaque_handle1 = handle;
272    }
273    pub fn set_opaque_handle2(&mut self, handle: u64) {
274        self.0.opaque_handle2 = handle;
275    }
276}
277
278// TODO
279impl ExternalOutputStreamStruct {
280    /// A user parameter which is passed to the callback function.
281    pub fn get_opaque_handle1(&self) -> u64 {
282        self.0.opaque_handle1
283    }
284    /// A user parameter which is passed to the callback function.
285    pub fn get_opaque_handle2(&self) -> u64 {
286        self.0.opaque_handle2
287    }
288    pub fn set_opaque_handle1(&mut self, handle: u64) {
289        self.0.opaque_handle1 = handle;
290    }
291    pub fn set_opaque_handle2(&mut self, handle: u64) {
292        self.0.opaque_handle2 = handle;
293    }
294}
295
296/// This structure gather the information needed to create a reader object.
297impl ReaderOpenInfo {
298    pub fn new(stream: &InputStream) -> Self {
299        Self(ReaderOpenInfoInterop {
300            streamObject: stream.handle(),
301        })
302    }
303    pub fn get_stream(&self) -> InputStream {
304        InputStream(self.0.streamObject)
305    }
306}
307
308/// This structure describes a rectangle, given by its top-left corner and its width and height.
309impl IntRect {
310    pub fn new(x: i32, y: i32, w: i32, h: i32) -> Self {
311        Self(IntRectInterop { x, y, w, h })
312    }
313    pub fn get_x(&self) -> i32 {
314        self.0.x
315    }
316    pub fn get_y(&self) -> i32 {
317        self.0.y
318    }
319    pub fn get_w(&self) -> i32 {
320        self.0.w
321    }
322    pub fn get_h(&self) -> i32 {
323        self.0.h
324    }
325    pub fn set_x(&mut self, x: i32) {
326        self.0.x = x;
327    }
328    pub fn set_y(&mut self, y: i32) {
329        self.0.y = y;
330    }
331    pub fn set_w(&mut self, w: i32) {
332        self.0.w = w;
333    }
334    pub fn set_h(&mut self, h: i32) {
335        self.0.h = h;
336    }
337}
338
339impl IntSize {
340    pub fn new(w: i32, h: i32) -> Self {
341        Self(IntSizeInterop { w, h })
342    }
343    pub fn get_w(&self) -> i32 {
344        self.0.w
345    }
346    pub fn get_h(&self) -> i32 {
347        self.0.h
348    }
349    pub fn set_w(&mut self, w: i32) {
350        self.0.w = w;
351    }
352    pub fn set_h(&mut self, h: i32) {
353        self.0.h = h;
354    }
355}
356
357impl DimBounds {
358    pub fn new(dimensions_valid: u32, start: [i32; 9], size: [i32; 9]) -> Self {
359        Self(DimBoundsInterop {
360            dimensions_valid,
361            start,
362            size,
363        })
364    }
365    pub fn get_dimensions_valid(&self) -> u32 {
366        self.0.dimensions_valid
367    }
368    pub fn get_start(&self) -> [i32; 9] {
369        self.0.start
370    }
371    pub fn get_size(&self) -> [i32; 9] {
372        self.0.size
373    }
374    pub fn set_dimensions_valid(&mut self, dimensions_valid: u32) {
375        self.0.dimensions_valid = dimensions_valid;
376    }
377    pub fn set_start(&mut self, start: [i32; 9]) {
378        self.0.start = start;
379    }
380    pub fn set_size(&mut self, size: [i32; 9]) {
381        self.0.size = size;
382    }
383}
384
385impl Coordinate {
386    pub fn new(dimensions_valid: u32, value: [i32; 9]) -> Self {
387        Self(CoordinateInterop {
388            dimensions_valid,
389            value,
390        })
391    }
392    pub fn get_dimensions_valid(&self) -> u32 {
393        self.0.dimensions_valid
394    }
395    pub fn get_value(&self) -> [i32; 9] {
396        self.0.value
397    }
398    pub fn set_dimensions_valid(&mut self, dimensions_valid: u32) {
399        self.0.dimensions_valid = dimensions_valid;
400    }
401    pub fn set_value(&mut self, value: [i32; 9]) {
402        self.0.value = value;
403    }
404}
405
406impl BoundingBoxes {
407    pub fn new(
408        scene_index: i32,
409        bounding_box: IntRectInterop,
410        bounding_box_layer0_only: IntRectInterop,
411    ) -> Self {
412        Self(BoundingBoxesInterop {
413            sceneIndex: scene_index,
414            bounding_box,
415            bounding_box_layer0_only,
416        })
417    }
418    pub fn get_scene_index(&self) -> i32 {
419        self.0.sceneIndex
420    }
421    pub fn get_bounding_box(&self) -> IntRectInterop {
422        self.0.bounding_box
423    }
424    pub fn get_bounding_box_layer0_only(&self) -> IntRectInterop {
425        self.0.bounding_box_layer0_only
426    }
427    pub fn set_scene_index(&mut self, scene_index: i32) {
428        self.0.sceneIndex = scene_index;
429    }
430    pub fn set_bounding_box(&mut self, bounding_box: IntRectInterop) {
431        self.0.bounding_box = bounding_box;
432    }
433    pub fn set_bounding_box_layer0_only(&mut self, bounding_box_layer0_only: IntRectInterop) {
434        self.0.bounding_box_layer0_only = bounding_box_layer0_only
435    }
436}
437
438impl SubBlockStatistics {
439    pub fn new(
440        sub_block_count: i32,
441        min_m_index: i32,
442        max_m_index: i32,
443        bounding_box: IntRect,
444        bounding_box_layer0: IntRect,
445        dim_bounds: DimBounds,
446    ) -> Self {
447        Self(SubBlockStatisticsInterop {
448            sub_block_count,
449            min_m_index,
450            max_m_index,
451            bounding_box: bounding_box.0,
452            bounding_box_layer0: bounding_box_layer0.0,
453            dim_bounds: dim_bounds.0,
454        })
455    }
456    pub fn get_sub_block_count(&self) -> i32 {
457        self.0.sub_block_count
458    }
459    pub fn get_min_m_index(&self) -> i32 {
460        self.0.min_m_index
461    }
462    pub fn get_max_m_index(&self) -> i32 {
463        self.0.max_m_index
464    }
465    pub fn get_bounding_box(&self) -> IntRect {
466        IntRect(self.0.bounding_box)
467    }
468    pub fn get_bounding_box_layer0(&self) -> IntRect {
469        IntRect(self.0.bounding_box_layer0)
470    }
471    pub fn get_dim_bounds(&self) -> DimBounds {
472        DimBounds(self.0.dim_bounds)
473    }
474    pub fn set_sub_block_count(&mut self, sub_block_count: i32) {
475        self.0.sub_block_count = sub_block_count;
476    }
477    pub fn set_min_m_index(&mut self, min_m_index: i32) {
478        self.0.min_m_index = min_m_index;
479    }
480    pub fn set_max_m_index(&mut self, max_m_index: i32) {
481        self.0.max_m_index = max_m_index;
482    }
483    pub fn set_bounding_box(&mut self, bounding_box: IntRect) {
484        self.0.bounding_box = bounding_box.0
485    }
486    pub fn set_bounding_box_layer0(&mut self, bounding_box_layer0: IntRect) {
487        self.0.bounding_box_layer0 = bounding_box_layer0.0
488    }
489    pub fn set_dim_bounds(&mut self, dim_bounds: DimBounds) {
490        self.0.dim_bounds = dim_bounds.0
491    }
492}
493
494impl SubBlockStatisticsEx {
495    // pub fn new(
496    //     sub_block_count: i32,
497    //     min_m_index: i32,
498    //     max_m_index: i32,
499    //     bounding_box: IntRect,
500    //     bounding_box_layer0: IntRect,
501    //     dim_bounds: DimBounds,
502    //     per_scenes_bounding_boxes: Vec<BoundingBoxes>
503    // ) -> Self {
504    //     Self(SubBlockStatisticsInteropEx {
505    //         sub_block_count,
506    //         min_m_index,
507    //         max_m_index,
508    //         bounding_box: bounding_box.0,
509    //         bounding_box_layer0: bounding_box_layer0.0,
510    //         dim_bounds: dim_bounds.0,
511    //         number_of_per_scenes_bounding_boxes: per_scenes_bounding_boxes.len() as i32,
512    //         per_scenes_bounding_boxes: unsafe { transmute::<Vec<BoundingBoxes>, __IncompleteArrayField<BoundingBoxesInterop>>(per_scenes_bounding_boxes) },
513    //     })
514    // }
515    pub fn get_sub_block_count(&self) -> i32 {
516        self.0.sub_block_count
517    }
518    pub fn get_min_m_index(&self) -> i32 {
519        self.0.min_m_index
520    }
521    pub fn get_max_m_index(&self) -> i32 {
522        self.0.max_m_index
523    }
524    pub fn get_bounding_box(&self) -> IntRect {
525        IntRect(self.0.bounding_box)
526    }
527    pub fn get_bounding_box_layer0(&self) -> IntRect {
528        IntRect(self.0.bounding_box_layer0)
529    }
530    pub fn get_dim_bounds(&self) -> DimBounds {
531        DimBounds(self.0.dim_bounds)
532    }
533    pub fn get_number_of_per_scenes_bounding_boxes(&self) -> i32 {
534        self.0.number_of_per_scenes_bounding_boxes
535    }
536    // pub fn get_per_scenes_bounding_boxes(&self) -> Vec<BoundingBoxes> {
537    //     unsafe { transmute(&self.0.per_scenes_bounding_boxes) }.clone()
538    // }
539    pub fn set_sub_block_count(&mut self, sub_block_count: i32) {
540        self.0.sub_block_count = sub_block_count;
541    }
542    pub fn set_min_m_index(&mut self, min_m_index: i32) {
543        self.0.min_m_index = min_m_index;
544    }
545    pub fn set_max_m_index(&mut self, max_m_index: i32) {
546        self.0.max_m_index = max_m_index;
547    }
548    pub fn set_bounding_box(&mut self, bounding_box: IntRect) {
549        self.0.bounding_box = bounding_box.0
550    }
551    pub fn set_bounding_box_layer0(&mut self, bounding_box_layer0: IntRect) {
552        self.0.bounding_box_layer0 = bounding_box_layer0.0
553    }
554    pub fn set_dim_bounds(&mut self, dim_bounds: DimBounds) {
555        self.0.dim_bounds = dim_bounds.0
556    }
557    pub fn set_number_of_per_scenes_bounding_boxes(
558        &mut self,
559        number_of_per_scenes_bounding_boxes: i32,
560    ) {
561        self.0.number_of_per_scenes_bounding_boxes = number_of_per_scenes_bounding_boxes;
562    }
563    // pub fn set_per_scenes_bounding_boxes(&mut self, per_scenes_bounding_boxes: Vec<BoundingBoxes>) {
564    //     self.0.number_of_per_scenes_bounding_boxes = per_scenes_bounding_boxes.len() as i32;
565    //     self.0.per_scenes_bounding_boxes = unsafe { transmute(per_scenes_bounding_boxes) };
566    // }
567}
568
569impl MetadataAsXml {
570    pub fn get_data(&self) -> Result<String, Error> {
571        let xml_data = unsafe {
572            Vec::from_raw_parts(
573                self.0.data as *mut u8,
574                self.0.size as usize,
575                self.0.size as usize,
576            )
577        };
578        Ok(String::from_utf8(xml_data)?)
579    }
580}
581
582impl Drop for MetadataAsXml {
583    fn drop(&mut self) {
584        unsafe {
585            libCZI_Free(Box::into_raw(Box::new(self.0.data)) as *mut c_void);
586        }
587    }
588}
589
590impl TryFrom<&MetadataAsXml> for String {
591    type Error = Error;
592
593    fn try_from(value: &MetadataAsXml) -> Result<Self, Self::Error> {
594        value.get_data()
595    }
596}
597
598impl BitmapInfo {
599    pub fn new(width: u32, height: u32, pixel_type: PixelType) -> Self {
600        Self(BitmapInfoInterop {
601            width,
602            height,
603            pixelType: pixel_type as i32,
604        })
605    }
606    pub fn get_width(&self) -> u32 {
607        self.0.width
608    }
609    pub fn get_height(&self) -> u32 {
610        self.0.height
611    }
612    pub fn get_pixel_type(&self) -> Result<PixelType, Error> {
613        PixelType::try_from(self.0.pixelType)
614    }
615    pub fn set_width(&mut self, width: u32) {
616        self.0.width = width;
617    }
618    pub fn set_height(&mut self, height: u32) {
619        self.0.height = height;
620    }
621    pub fn set_pixel_type(&mut self, pixel_type: PixelType) {
622        self.0.pixelType = pixel_type as i32;
623    }
624}
625
626impl BitmapLockInfo {
627    pub fn get_data_roi(&self) -> Vec<u8> {
628        let vec = unsafe {
629            Vec::from_raw_parts(
630                self.0.ptrDataRoi as *mut u8,
631                self.0.size as usize,
632                self.0.size as usize,
633            )
634        };
635        let res = vec.clone();
636        mem::forget(vec);
637        res
638    }
639
640    pub fn get_stride(&self) -> u32 {
641        self.0.stride
642    }
643
644    pub fn get_size(&self) -> u64 {
645        self.0.size
646    }
647}
648
649impl SubBlockInfo {
650    pub fn new(
651        compression_mode_raw: i32,
652        pixel_type: PixelType,
653        coordinate: Coordinate,
654        logical_rect: IntRect,
655        physical_size: IntSize,
656        m_index: i32,
657    ) -> Self {
658        Self(SubBlockInfoInterop {
659            compression_mode_raw,
660            pixel_type: pixel_type as i32,
661            coordinate: coordinate.0,
662            logical_rect: logical_rect.0,
663            physical_size: physical_size.0,
664            m_index,
665        })
666    }
667    pub fn get_compression_mode_raw(&self) -> i32 {
668        self.0.compression_mode_raw
669    }
670    pub fn get_pixel_type(&self) -> Result<PixelType, Error> {
671        PixelType::try_from(self.0.pixel_type)
672    }
673    pub fn get_coordinate(&self) -> Coordinate {
674        Coordinate(self.0.coordinate)
675    }
676    pub fn get_logical_rect(&self) -> IntRect {
677        IntRect(self.0.logical_rect)
678    }
679    pub fn get_physical_size(&self) -> IntSize {
680        IntSize(self.0.physical_size)
681    }
682    pub fn get_m_index(&self) -> i32 {
683        self.0.m_index
684    }
685    pub fn set_compression_mode_raw(&mut self, compression_mode_raw: i32) {
686        self.0.compression_mode_raw = compression_mode_raw
687    }
688    pub fn set_pixel_type(&mut self, pixel_type: PixelType) {
689        self.0.pixel_type = pixel_type as i32;
690    }
691    pub fn set_coordinate(&mut self, coordinate: Coordinate) {
692        self.0.coordinate = coordinate.0
693    }
694    pub fn set_logical_rect(&mut self, logical_rect: IntRect) {
695        self.0.logical_rect = logical_rect.0
696    }
697    pub fn set_physical_size(&mut self, physical_size: IntSize) {
698        self.0.physical_size = physical_size.0
699    }
700    pub fn set_m_index(&mut self, m_index: i32) {
701        self.0.m_index = m_index
702    }
703}
704
705impl AttachmentInfo {
706    pub fn get_guid(&self) -> [u8; 16] {
707        self.0.guid
708    }
709    pub fn get_content_file_type(&self) -> [u8; 9] {
710        self.0.content_file_type
711    }
712    pub fn get_name(&self) -> Result<String, Error> {
713        Ok(
714            CStr::from_bytes_until_nul(&self.0.name.iter().map(|&i| i as u8).collect::<Vec<_>>())?
715                .to_str()?
716                .to_string(),
717        )
718    }
719    pub fn get_name_overflow(&self) -> bool {
720        self.0.name_overflow
721    }
722    pub fn get_name_in_case_of_overflow(&self) -> Result<String, Error> {
723        Ok(
724            unsafe { CString::from_raw(self.0.name_in_case_of_overflow as *mut c_char) }
725                .to_str()?
726                .to_string(),
727        )
728    }
729}
730
731impl Drop for AttachmentInfo {
732    fn drop(&mut self) {
733        if self.0.name_overflow {
734            unsafe { libCZI_Free(self.0.name_in_case_of_overflow) }
735        }
736    }
737}
738
739impl FileHeaderInfo {
740    pub fn new(guid: [u8; 16], major_version: i32, minor_version: i32) -> Self {
741        Self(FileHeaderInfoInterop {
742            guid,
743            majorVersion: major_version,
744            minorVersion: minor_version,
745        })
746    }
747    pub fn get_guid(&self) -> [u8; 16] {
748        self.0.guid
749    }
750    pub fn get_major_version(&self) -> i32 {
751        self.0.majorVersion
752    }
753    pub fn get_minor_version(&self) -> i32 {
754        self.0.minorVersion
755    }
756    pub fn set_guid(&mut self, guid: [u8; 16]) {
757        self.0.guid = guid
758    }
759    pub fn set_major_version(&mut self, major_version: i32) {
760        self.0.majorVersion = major_version
761    }
762    pub fn set_minor_version(&mut self, minor_version: i32) {
763        self.0.minorVersion = minor_version
764    }
765}
766
767impl AddSubBlockInfo {
768    #[allow(clippy::too_many_arguments)]
769    pub fn new(
770        coordinate: Coordinate,
771        m_index_valid: u8,
772        m_index: i32,
773        x: i32,
774        y: i32,
775        logical_width: i32,
776        logical_height: i32,
777        physical_width: i32,
778        physical_height: i32,
779        pixel_type: PixelType,
780        compression_mode_raw: i32,
781        data: &[u8],
782        metadata: &[u8],
783        attachment: &[u8],
784    ) -> Self {
785        let data = ManuallyDrop::new(data.to_vec());
786        let metadata = ManuallyDrop::new(metadata.to_vec());
787        let attachment = ManuallyDrop::new(attachment.to_vec());
788
789        Self(AddSubBlockInfoInterop {
790            coordinate: coordinate.0,
791            m_index_valid,
792            m_index,
793            x,
794            y,
795            logical_width,
796            logical_height,
797            physical_width,
798            physical_height,
799            pixel_type: pixel_type as i32,
800            compression_mode_raw,
801            size_data: data.len() as u32,
802            data: data.as_ptr() as *const c_void,
803            stride: 1,
804            size_metadata: metadata.len() as u32,
805            metadata: metadata.as_ptr() as *const c_void,
806            size_attachment: attachment.len() as u32,
807            attachment: attachment.as_ptr() as *const c_void,
808        })
809    }
810    pub fn get_coordinate(&self) -> Coordinate {
811        Coordinate(self.0.coordinate)
812    }
813    pub fn get_m_index_valid(&self) -> u8 {
814        self.0.m_index_valid
815    }
816    pub fn get_m_index(&self) -> i32 {
817        self.0.m_index
818    }
819    pub fn get_x(&self) -> i32 {
820        self.0.x
821    }
822    pub fn get_y(&self) -> i32 {
823        self.0.y
824    }
825    pub fn get_logical_width(&self) -> i32 {
826        self.0.logical_width
827    }
828    pub fn get_logical_height(&self) -> i32 {
829        self.0.logical_height
830    }
831    pub fn get_physical_width(&self) -> i32 {
832        self.0.physical_width
833    }
834    pub fn get_physical_height(&self) -> i32 {
835        self.0.physical_height
836    }
837    pub fn get_pixel_type(&self) -> Result<PixelType, Error> {
838        PixelType::try_from(self.0.pixel_type)
839    }
840    pub fn get_compression_mode_raw(&self) -> i32 {
841        self.0.compression_mode_raw
842    }
843    pub fn get_size_data(&self) -> u32 {
844        self.0.size_data
845    }
846    pub fn get_data(&self) -> Vec<u8> {
847        unsafe {
848            Vec::from_raw_parts(
849                self.0.data as *mut u8,
850                self.0.size_data as usize,
851                self.0.size_data as usize,
852            )
853        }
854    }
855    pub fn get_size_metadata(&self) -> u32 {
856        self.0.size_metadata
857    }
858    pub fn get_metadata(&self) -> Vec<u8> {
859        unsafe {
860            Vec::from_raw_parts(
861                self.0.metadata as *mut u8,
862                self.0.size_metadata as usize,
863                self.0.size_metadata as usize,
864            )
865        }
866    }
867    pub fn get_size_attachment(&self) -> u32 {
868        self.0.size_attachment
869    }
870    pub fn get_attachment(&self) -> Vec<u8> {
871        unsafe {
872            Vec::from_raw_parts(
873                self.0.attachment as *mut u8,
874                self.0.attachment as usize,
875                self.0.attachment as usize,
876            )
877        }
878    }
879    pub fn set_coordinate(&mut self, coordinate: Coordinate) {
880        self.0.coordinate = coordinate.0
881    }
882    pub fn set_m_index_valid(&mut self, m_index_valid: u8) {
883        self.0.m_index_valid = m_index_valid
884    }
885    pub fn set_m_index(&mut self, m_index: i32) {
886        self.0.m_index = m_index
887    }
888    pub fn set_x(&mut self, x: i32) {
889        self.0.x = x
890    }
891    pub fn set_y(&mut self, y: i32) {
892        self.0.y = y
893    }
894    pub fn set_logical_width(&mut self, logical_width: i32) {
895        self.0.logical_width = logical_width
896    }
897    pub fn set_logical_height(&mut self, logical_height: i32) {
898        self.0.logical_height = logical_height
899    }
900    pub fn set_physical_width(&mut self, physical_width: i32) {
901        self.0.physical_width = physical_width
902    }
903    pub fn set_physical_height(&mut self, physical_height: i32) {
904        self.0.physical_height = physical_height
905    }
906    pub fn set_pixel_type(&mut self, pixel_type: PixelType) {
907        self.0.pixel_type = pixel_type as i32
908    }
909    pub fn set_compression_mode_raw(&mut self, compression_mode_raw: i32) {
910        self.0.compression_mode_raw = compression_mode_raw
911    }
912    pub fn set_data(&mut self, data: &[u8]) {
913        let data = ManuallyDrop::new(data.to_vec());
914        self.0.data = data.as_ptr() as *const c_void;
915        self.0.size_data = data.len() as u32;
916    }
917    pub fn set_metadata(&mut self, metadata: &[u8]) {
918        let metadata = ManuallyDrop::new(metadata.to_vec());
919        self.0.metadata = metadata.as_ptr() as *const c_void;
920        self.0.size_metadata = metadata.len() as u32;
921    }
922    pub fn set_attachment(&mut self, attachment: &[u8]) {
923        let attachment = ManuallyDrop::new(attachment.to_vec());
924        self.0.attachment = attachment.as_ptr() as *const c_void;
925        self.0.size_attachment = attachment.len() as u32;
926    }
927}
928
929impl AddAttachmentInfo {
930    pub fn new(
931        guid: [u8; 16],
932        content_file_type: [u8; 8],
933        name: [u8; 80],
934        attachment_data: &[u8],
935    ) -> Self {
936        let attachment_data = ManuallyDrop::new(attachment_data.to_vec());
937        Self(AddAttachmentInfoInterop {
938            guid,
939            contentFileType: content_file_type,
940            name,
941            size_attachment_data: attachment_data.len() as u32,
942            attachment_data: attachment_data.as_ptr() as *const c_void,
943        })
944    }
945    pub fn get_guid(&self) -> [u8; 16] {
946        self.0.guid
947    }
948    pub fn get_content_file_type(&self) -> [u8; 8] {
949        self.0.contentFileType
950    }
951    pub fn get_name(&self) -> [u8; 80] {
952        self.0.name
953    }
954    pub fn get_size_attachment_data(&self) -> u32 {
955        self.0.size_attachment_data
956    }
957    pub fn get_attachment_data(&self) -> Vec<u8> {
958        unsafe {
959            Vec::from_raw_parts(
960                self.0.attachment_data as *mut u8,
961                self.0.attachment_data as usize,
962                self.0.attachment_data as usize,
963            )
964        }
965    }
966    pub fn set_guid(&mut self, guid: [u8; 16]) {
967        self.0.guid = guid
968    }
969    pub fn set_content_file_type(&mut self, content_file_type: [u8; 8]) {
970        self.0.contentFileType = content_file_type
971    }
972    pub fn set_name(&mut self, name: [u8; 80]) {
973        self.0.name = name
974    }
975    pub fn set_attachment_data(&mut self, attachment_data: &[u8]) {
976        let attachment_data = ManuallyDrop::new(attachment_data.to_vec());
977        self.0.attachment_data = attachment_data.as_ptr() as *const c_void;
978        self.0.size_attachment_data = attachment_data.len() as u32;
979    }
980}
981
982impl WriteMetadataInfo {
983    pub fn new(metadata: &[u8]) -> Self {
984        let metadata = ManuallyDrop::new(metadata.to_vec());
985        Self(WriteMetadataInfoInterop {
986            size_metadata: metadata.len() as u32,
987            metadata: metadata.as_ptr() as *const c_void,
988        })
989    }
990    pub fn get_size_metadata(&self) -> u32 {
991        self.0.size_metadata
992    }
993    pub fn get_metadata(&self) -> Vec<u8> {
994        unsafe {
995            Vec::from_raw_parts(
996                self.0.metadata as *mut u8,
997                self.0.metadata as usize,
998                self.0.metadata as usize,
999            )
1000        }
1001    }
1002    pub fn set_metadata(&mut self, metadata: &[u8]) {
1003        let metadata = ManuallyDrop::new(metadata.to_vec());
1004        self.0.metadata = metadata.as_ptr() as *const c_void;
1005        self.0.size_metadata = metadata.len() as u32;
1006    }
1007}
1008
1009impl AccessorOptions {
1010    pub fn new<S: AsRef<str>>(
1011        back_ground_color_r: f32,
1012        back_ground_color_g: f32,
1013        back_ground_color_b: f32,
1014        sort_by_m: bool,
1015        use_visibility_check_optimization: bool,
1016        additional_parameters: S,
1017    ) -> Result<Self, Error> {
1018        let additional_parameters =
1019            ManuallyDrop::new(CString::new(additional_parameters.as_ref())?);
1020        Ok(Self(AccessorOptionsInterop {
1021            back_ground_color_r,
1022            back_ground_color_g,
1023            back_ground_color_b,
1024            sort_by_m,
1025            use_visibility_check_optimization,
1026            additional_parameters: additional_parameters.as_ptr(),
1027        }))
1028    }
1029    pub fn get_background_color_r(&self) -> f32 {
1030        self.0.back_ground_color_r
1031    }
1032    pub fn get_background_color_g(&self) -> f32 {
1033        self.0.back_ground_color_g
1034    }
1035    pub fn get_background_color_b(&self) -> f32 {
1036        self.0.back_ground_color_b
1037    }
1038    pub fn get_sort_by_m(&self) -> bool {
1039        self.0.sort_by_m
1040    }
1041    pub fn get_use_visibility_check_optimization(&self) -> bool {
1042        self.0.use_visibility_check_optimization
1043    }
1044    pub fn get_additional_parameters(&self) -> Result<String, Error> {
1045        Ok(unsafe { CStr::from_ptr(self.0.additional_parameters) }
1046            .to_str()?
1047            .to_string())
1048    }
1049    pub fn set_background_color_r(&mut self, back_ground_color_r: f32) {
1050        self.0.back_ground_color_r = back_ground_color_r
1051    }
1052    pub fn set_background_color_g(&mut self, back_ground_color_g: f32) {
1053        self.0.back_ground_color_g = back_ground_color_g
1054    }
1055    pub fn set_background_color_b(&mut self, back_ground_color_b: f32) {
1056        self.0.back_ground_color_b = back_ground_color_b
1057    }
1058    pub fn set_sort_by_m(&mut self, sort_by_m: bool) {
1059        self.0.sort_by_m = sort_by_m
1060    }
1061    pub fn set_use_visibility_check_optimization(
1062        &mut self,
1063        use_visibility_check_optimization: bool,
1064    ) {
1065        self.0.use_visibility_check_optimization = use_visibility_check_optimization
1066    }
1067    pub fn set_additional_parameters<S: AsRef<str>>(
1068        &mut self,
1069        additional_parameters: S,
1070    ) -> Result<(), Error> {
1071        let additional_parameters =
1072            ManuallyDrop::new(CString::new(additional_parameters.as_ref())?);
1073        self.0.additional_parameters = additional_parameters.as_ptr();
1074        Ok(())
1075    }
1076}
1077
1078impl CompositionChannelInfo {
1079    #[allow(clippy::too_many_arguments)]
1080    pub fn new(
1081        weight: f32,
1082        enable_tinting: u8,
1083        tinting_color_r: u8,
1084        tinting_color_g: u8,
1085        tinting_color_b: u8,
1086        black_point: f32,
1087        white_point: f32,
1088        look_up_table_element_count: i32,
1089        look_up_table: &[u8],
1090    ) -> Self {
1091        let mut look_up_table = ManuallyDrop::new(look_up_table.to_vec());
1092        Self(CompositionChannelInfoInterop {
1093            weight,
1094            enable_tinting,
1095            tinting_color_r,
1096            tinting_color_g,
1097            tinting_color_b,
1098            black_point,
1099            white_point,
1100            look_up_table_element_count,
1101            ptr_look_up_table: look_up_table.as_mut_ptr(),
1102        })
1103    }
1104    pub fn get_weight(&self) -> f32 {
1105        self.0.weight
1106    }
1107    pub fn get_enable_tinting(&self) -> u8 {
1108        self.0.enable_tinting
1109    }
1110    pub fn get_tinting_color_r(&self) -> u8 {
1111        self.0.tinting_color_r
1112    }
1113    pub fn get_tinting_color_g(&self) -> u8 {
1114        self.0.tinting_color_g
1115    }
1116    pub fn get_tinting_color_b(&self) -> u8 {
1117        self.0.tinting_color_b
1118    }
1119    pub fn get_black_point(&self) -> f32 {
1120        self.0.black_point
1121    }
1122    pub fn get_white_point(&self) -> f32 {
1123        self.0.white_point
1124    }
1125    pub fn get_look_up_table_element_count(&self) -> i32 {
1126        self.0.look_up_table_element_count
1127    }
1128    pub fn get_look_up_table(&self) -> Vec<u8> {
1129        unsafe {
1130            Vec::from_raw_parts(
1131                self.0.ptr_look_up_table,
1132                self.0.look_up_table_element_count as usize,
1133                self.0.look_up_table_element_count as usize,
1134            )
1135        }
1136    }
1137    pub fn set_weight(&mut self, weight: f32) {
1138        self.0.weight = weight
1139    }
1140    pub fn set_enable_tinting(&mut self, enable_tinting: u8) {
1141        self.0.enable_tinting = enable_tinting
1142    }
1143    pub fn set_tinting_color_r(&mut self, tinting_color_r: u8) {
1144        self.0.tinting_color_r = tinting_color_r
1145    }
1146    pub fn set_tinting_color_g(&mut self, tinting_color_g: u8) {
1147        self.0.tinting_color_g = tinting_color_g
1148    }
1149    pub fn set_tinting_color_b(&mut self, tinting_color_b: u8) {
1150        self.0.tinting_color_b = tinting_color_b
1151    }
1152    pub fn set_black_point(&mut self, black_point: f32) {
1153        self.0.black_point = black_point
1154    }
1155    pub fn set_white_point(&mut self, white_point: f32) {
1156        self.0.white_point = white_point
1157    }
1158    pub fn set_look_up_table_element_count(&mut self, look_up_table_element_count: i32) {
1159        self.0.look_up_table_element_count = look_up_table_element_count
1160    }
1161    pub fn set_look_up_table(&mut self, look_up_table: &[u8]) {
1162        let mut look_up_table = ManuallyDrop::new(look_up_table.to_vec());
1163        self.0.ptr_look_up_table = look_up_table.as_mut_ptr();
1164        self.0.look_up_table_element_count = look_up_table.len() as i32;
1165    }
1166}
1167
1168impl ScalingInfo {
1169    pub fn new(scale_x: f64, scale_y: f64, scale_z: f64) -> Self {
1170        Self(ScalingInfoInterop {
1171            scale_x,
1172            scale_y,
1173            scale_z,
1174        })
1175    }
1176    pub fn get_scale_x(&self) -> f64 {
1177        self.0.scale_x
1178    }
1179    pub fn get_scale_y(&self) -> f64 {
1180        self.0.scale_y
1181    }
1182    pub fn get_scale_z(&self) -> f64 {
1183        self.0.scale_z
1184    }
1185    pub fn set_scale_x(&mut self, scale_x: f64) {
1186        self.0.scale_x = scale_x
1187    }
1188    pub fn set_scale_y(&mut self, scale_y: f64) {
1189        self.0.scale_y = scale_y
1190    }
1191    pub fn set_scale_z(&mut self, scale_z: f64) {
1192        self.0.scale_z = scale_z
1193    }
1194}