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 gathers 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
710    pub fn get_name(&self) -> Result<String, Error> {
711        if self.0.name_overflow {
712            Ok(
713                unsafe { CString::from_raw(self.0.name_in_case_of_overflow as *mut c_char) }
714                    .to_string_lossy()
715                    .to_string(),
716            )
717        } else {
718            Ok(CStr::from_bytes_until_nul(
719                &self.0.name.iter().map(|&i| i as u8).collect::<Vec<_>>(),
720            )?
721            .to_string_lossy()
722            .to_string())
723        }
724    }
725
726    pub fn get_content_file_type(&self) -> Result<String, Error> {
727        Ok(CStr::from_bytes_until_nul(&self.0.content_file_type)?
728            .to_string_lossy()
729            .to_string())
730    }
731}
732
733impl Drop for AttachmentInfo {
734    fn drop(&mut self) {
735        if self.0.name_overflow {
736            unsafe { libCZI_Free(self.0.name_in_case_of_overflow) }
737        }
738    }
739}
740
741impl FileHeaderInfo {
742    pub fn new(guid: [u8; 16], major_version: i32, minor_version: i32) -> Self {
743        Self(FileHeaderInfoInterop {
744            guid,
745            majorVersion: major_version,
746            minorVersion: minor_version,
747        })
748    }
749    pub fn get_guid(&self) -> [u8; 16] {
750        self.0.guid
751    }
752    pub fn get_major_version(&self) -> i32 {
753        self.0.majorVersion
754    }
755    pub fn get_minor_version(&self) -> i32 {
756        self.0.minorVersion
757    }
758    pub fn set_guid(&mut self, guid: [u8; 16]) {
759        self.0.guid = guid
760    }
761    pub fn set_major_version(&mut self, major_version: i32) {
762        self.0.majorVersion = major_version
763    }
764    pub fn set_minor_version(&mut self, minor_version: i32) {
765        self.0.minorVersion = minor_version
766    }
767}
768
769impl AddSubBlockInfo {
770    #[allow(clippy::too_many_arguments)]
771    pub fn new(
772        coordinate: Coordinate,
773        m_index_valid: u8,
774        m_index: i32,
775        x: i32,
776        y: i32,
777        logical_width: i32,
778        logical_height: i32,
779        physical_width: i32,
780        physical_height: i32,
781        pixel_type: PixelType,
782        compression_mode_raw: i32,
783        data: &[u8],
784        metadata: &[u8],
785        attachment: &[u8],
786    ) -> Self {
787        let data = ManuallyDrop::new(data.to_vec());
788        let metadata = ManuallyDrop::new(metadata.to_vec());
789        let attachment = ManuallyDrop::new(attachment.to_vec());
790
791        Self(AddSubBlockInfoInterop {
792            coordinate: coordinate.0,
793            m_index_valid,
794            m_index,
795            x,
796            y,
797            logical_width,
798            logical_height,
799            physical_width,
800            physical_height,
801            pixel_type: pixel_type as i32,
802            compression_mode_raw,
803            size_data: data.len() as u32,
804            data: data.as_ptr() as *const c_void,
805            stride: 1,
806            size_metadata: metadata.len() as u32,
807            metadata: metadata.as_ptr() as *const c_void,
808            size_attachment: attachment.len() as u32,
809            attachment: attachment.as_ptr() as *const c_void,
810        })
811    }
812    pub fn get_coordinate(&self) -> Coordinate {
813        Coordinate(self.0.coordinate)
814    }
815    pub fn get_m_index_valid(&self) -> u8 {
816        self.0.m_index_valid
817    }
818    pub fn get_m_index(&self) -> i32 {
819        self.0.m_index
820    }
821    pub fn get_x(&self) -> i32 {
822        self.0.x
823    }
824    pub fn get_y(&self) -> i32 {
825        self.0.y
826    }
827    pub fn get_logical_width(&self) -> i32 {
828        self.0.logical_width
829    }
830    pub fn get_logical_height(&self) -> i32 {
831        self.0.logical_height
832    }
833    pub fn get_physical_width(&self) -> i32 {
834        self.0.physical_width
835    }
836    pub fn get_physical_height(&self) -> i32 {
837        self.0.physical_height
838    }
839    pub fn get_pixel_type(&self) -> Result<PixelType, Error> {
840        PixelType::try_from(self.0.pixel_type)
841    }
842    pub fn get_compression_mode_raw(&self) -> i32 {
843        self.0.compression_mode_raw
844    }
845    pub fn get_size_data(&self) -> u32 {
846        self.0.size_data
847    }
848    pub fn get_data(&self) -> Vec<u8> {
849        unsafe {
850            Vec::from_raw_parts(
851                self.0.data as *mut u8,
852                self.0.size_data as usize,
853                self.0.size_data as usize,
854            )
855        }
856    }
857    pub fn get_size_metadata(&self) -> u32 {
858        self.0.size_metadata
859    }
860    pub fn get_metadata(&self) -> Vec<u8> {
861        unsafe {
862            Vec::from_raw_parts(
863                self.0.metadata as *mut u8,
864                self.0.size_metadata as usize,
865                self.0.size_metadata as usize,
866            )
867        }
868    }
869    pub fn get_size_attachment(&self) -> u32 {
870        self.0.size_attachment
871    }
872    pub fn get_attachment(&self) -> Vec<u8> {
873        unsafe {
874            Vec::from_raw_parts(
875                self.0.attachment as *mut u8,
876                self.0.attachment as usize,
877                self.0.attachment as usize,
878            )
879        }
880    }
881    pub fn set_coordinate(&mut self, coordinate: Coordinate) {
882        self.0.coordinate = coordinate.0
883    }
884    pub fn set_m_index_valid(&mut self, m_index_valid: u8) {
885        self.0.m_index_valid = m_index_valid
886    }
887    pub fn set_m_index(&mut self, m_index: i32) {
888        self.0.m_index = m_index
889    }
890    pub fn set_x(&mut self, x: i32) {
891        self.0.x = x
892    }
893    pub fn set_y(&mut self, y: i32) {
894        self.0.y = y
895    }
896    pub fn set_logical_width(&mut self, logical_width: i32) {
897        self.0.logical_width = logical_width
898    }
899    pub fn set_logical_height(&mut self, logical_height: i32) {
900        self.0.logical_height = logical_height
901    }
902    pub fn set_physical_width(&mut self, physical_width: i32) {
903        self.0.physical_width = physical_width
904    }
905    pub fn set_physical_height(&mut self, physical_height: i32) {
906        self.0.physical_height = physical_height
907    }
908    pub fn set_pixel_type(&mut self, pixel_type: PixelType) {
909        self.0.pixel_type = pixel_type as i32
910    }
911    pub fn set_compression_mode_raw(&mut self, compression_mode_raw: i32) {
912        self.0.compression_mode_raw = compression_mode_raw
913    }
914    pub fn set_data(&mut self, data: &[u8]) {
915        let data = ManuallyDrop::new(data.to_vec());
916        self.0.data = data.as_ptr() as *const c_void;
917        self.0.size_data = data.len() as u32;
918    }
919    pub fn set_metadata(&mut self, metadata: &[u8]) {
920        let metadata = ManuallyDrop::new(metadata.to_vec());
921        self.0.metadata = metadata.as_ptr() as *const c_void;
922        self.0.size_metadata = metadata.len() as u32;
923    }
924    pub fn set_attachment(&mut self, attachment: &[u8]) {
925        let attachment = ManuallyDrop::new(attachment.to_vec());
926        self.0.attachment = attachment.as_ptr() as *const c_void;
927        self.0.size_attachment = attachment.len() as u32;
928    }
929}
930
931impl AddAttachmentInfo {
932    pub fn new(
933        guid: [u8; 16],
934        content_file_type: [u8; 8],
935        name: [u8; 80],
936        attachment_data: &[u8],
937    ) -> Self {
938        let attachment_data = ManuallyDrop::new(attachment_data.to_vec());
939        Self(AddAttachmentInfoInterop {
940            guid,
941            contentFileType: content_file_type,
942            name,
943            size_attachment_data: attachment_data.len() as u32,
944            attachment_data: attachment_data.as_ptr() as *const c_void,
945        })
946    }
947    pub fn get_guid(&self) -> [u8; 16] {
948        self.0.guid
949    }
950    pub fn get_content_file_type(&self) -> [u8; 8] {
951        self.0.contentFileType
952    }
953    pub fn get_name(&self) -> [u8; 80] {
954        self.0.name
955    }
956    pub fn get_size_attachment_data(&self) -> u32 {
957        self.0.size_attachment_data
958    }
959    pub fn get_attachment_data(&self) -> Vec<u8> {
960        unsafe {
961            Vec::from_raw_parts(
962                self.0.attachment_data as *mut u8,
963                self.0.attachment_data as usize,
964                self.0.attachment_data as usize,
965            )
966        }
967    }
968    pub fn set_guid(&mut self, guid: [u8; 16]) {
969        self.0.guid = guid
970    }
971    pub fn set_content_file_type(&mut self, content_file_type: [u8; 8]) {
972        self.0.contentFileType = content_file_type
973    }
974    pub fn set_name(&mut self, name: [u8; 80]) {
975        self.0.name = name
976    }
977    pub fn set_attachment_data(&mut self, attachment_data: &[u8]) {
978        let attachment_data = ManuallyDrop::new(attachment_data.to_vec());
979        self.0.attachment_data = attachment_data.as_ptr() as *const c_void;
980        self.0.size_attachment_data = attachment_data.len() as u32;
981    }
982}
983
984impl WriteMetadataInfo {
985    pub fn new(metadata: &[u8]) -> Self {
986        let metadata = ManuallyDrop::new(metadata.to_vec());
987        Self(WriteMetadataInfoInterop {
988            size_metadata: metadata.len() as u32,
989            metadata: metadata.as_ptr() as *const c_void,
990        })
991    }
992    pub fn get_size_metadata(&self) -> u32 {
993        self.0.size_metadata
994    }
995    pub fn get_metadata(&self) -> Vec<u8> {
996        unsafe {
997            Vec::from_raw_parts(
998                self.0.metadata as *mut u8,
999                self.0.metadata as usize,
1000                self.0.metadata as usize,
1001            )
1002        }
1003    }
1004    pub fn set_metadata(&mut self, metadata: &[u8]) {
1005        let metadata = ManuallyDrop::new(metadata.to_vec());
1006        self.0.metadata = metadata.as_ptr() as *const c_void;
1007        self.0.size_metadata = metadata.len() as u32;
1008    }
1009}
1010
1011impl AccessorOptions {
1012    pub fn new<S: AsRef<str>>(
1013        back_ground_color_r: f32,
1014        back_ground_color_g: f32,
1015        back_ground_color_b: f32,
1016        sort_by_m: bool,
1017        use_visibility_check_optimization: bool,
1018        additional_parameters: S,
1019    ) -> Result<Self, Error> {
1020        let additional_parameters =
1021            ManuallyDrop::new(CString::new(additional_parameters.as_ref())?);
1022        Ok(Self(AccessorOptionsInterop {
1023            back_ground_color_r,
1024            back_ground_color_g,
1025            back_ground_color_b,
1026            sort_by_m,
1027            use_visibility_check_optimization,
1028            additional_parameters: additional_parameters.as_ptr(),
1029        }))
1030    }
1031    pub fn get_background_color_r(&self) -> f32 {
1032        self.0.back_ground_color_r
1033    }
1034    pub fn get_background_color_g(&self) -> f32 {
1035        self.0.back_ground_color_g
1036    }
1037    pub fn get_background_color_b(&self) -> f32 {
1038        self.0.back_ground_color_b
1039    }
1040    pub fn get_sort_by_m(&self) -> bool {
1041        self.0.sort_by_m
1042    }
1043    pub fn get_use_visibility_check_optimization(&self) -> bool {
1044        self.0.use_visibility_check_optimization
1045    }
1046    pub fn get_additional_parameters(&self) -> String {
1047        unsafe { CStr::from_ptr(self.0.additional_parameters) }
1048            .to_string_lossy()
1049            .to_string()
1050    }
1051    pub fn set_background_color_r(&mut self, back_ground_color_r: f32) {
1052        self.0.back_ground_color_r = back_ground_color_r
1053    }
1054    pub fn set_background_color_g(&mut self, back_ground_color_g: f32) {
1055        self.0.back_ground_color_g = back_ground_color_g
1056    }
1057    pub fn set_background_color_b(&mut self, back_ground_color_b: f32) {
1058        self.0.back_ground_color_b = back_ground_color_b
1059    }
1060    pub fn set_sort_by_m(&mut self, sort_by_m: bool) {
1061        self.0.sort_by_m = sort_by_m
1062    }
1063    pub fn set_use_visibility_check_optimization(
1064        &mut self,
1065        use_visibility_check_optimization: bool,
1066    ) {
1067        self.0.use_visibility_check_optimization = use_visibility_check_optimization
1068    }
1069    pub fn set_additional_parameters<S: AsRef<str>>(
1070        &mut self,
1071        additional_parameters: S,
1072    ) -> Result<(), Error> {
1073        let additional_parameters =
1074            ManuallyDrop::new(CString::new(additional_parameters.as_ref())?);
1075        self.0.additional_parameters = additional_parameters.as_ptr();
1076        Ok(())
1077    }
1078}
1079
1080impl CompositionChannelInfo {
1081    #[allow(clippy::too_many_arguments)]
1082    pub fn new(
1083        weight: f32,
1084        enable_tinting: u8,
1085        tinting_color_r: u8,
1086        tinting_color_g: u8,
1087        tinting_color_b: u8,
1088        black_point: f32,
1089        white_point: f32,
1090        look_up_table_element_count: i32,
1091        look_up_table: &[u8],
1092    ) -> Self {
1093        let mut look_up_table = ManuallyDrop::new(look_up_table.to_vec());
1094        Self(CompositionChannelInfoInterop {
1095            weight,
1096            enable_tinting,
1097            tinting_color_r,
1098            tinting_color_g,
1099            tinting_color_b,
1100            black_point,
1101            white_point,
1102            look_up_table_element_count,
1103            ptr_look_up_table: look_up_table.as_mut_ptr(),
1104        })
1105    }
1106    pub fn get_weight(&self) -> f32 {
1107        self.0.weight
1108    }
1109    pub fn get_enable_tinting(&self) -> u8 {
1110        self.0.enable_tinting
1111    }
1112    pub fn get_tinting_color_r(&self) -> u8 {
1113        self.0.tinting_color_r
1114    }
1115    pub fn get_tinting_color_g(&self) -> u8 {
1116        self.0.tinting_color_g
1117    }
1118    pub fn get_tinting_color_b(&self) -> u8 {
1119        self.0.tinting_color_b
1120    }
1121    pub fn get_black_point(&self) -> f32 {
1122        self.0.black_point
1123    }
1124    pub fn get_white_point(&self) -> f32 {
1125        self.0.white_point
1126    }
1127    pub fn get_look_up_table_element_count(&self) -> i32 {
1128        self.0.look_up_table_element_count
1129    }
1130    #[allow(clippy::unnecessary_cast)]
1131    pub fn get_look_up_table(&self) -> Vec<u8> {
1132        unsafe {
1133            Vec::from_raw_parts(
1134                self.0.ptr_look_up_table as *mut u8,
1135                self.0.look_up_table_element_count as usize,
1136                self.0.look_up_table_element_count as usize,
1137            )
1138        }
1139    }
1140    pub fn set_weight(&mut self, weight: f32) {
1141        self.0.weight = weight
1142    }
1143    pub fn set_enable_tinting(&mut self, enable_tinting: u8) {
1144        self.0.enable_tinting = enable_tinting
1145    }
1146    pub fn set_tinting_color_r(&mut self, tinting_color_r: u8) {
1147        self.0.tinting_color_r = tinting_color_r
1148    }
1149    pub fn set_tinting_color_g(&mut self, tinting_color_g: u8) {
1150        self.0.tinting_color_g = tinting_color_g
1151    }
1152    pub fn set_tinting_color_b(&mut self, tinting_color_b: u8) {
1153        self.0.tinting_color_b = tinting_color_b
1154    }
1155    pub fn set_black_point(&mut self, black_point: f32) {
1156        self.0.black_point = black_point
1157    }
1158    pub fn set_white_point(&mut self, white_point: f32) {
1159        self.0.white_point = white_point
1160    }
1161    pub fn set_look_up_table_element_count(&mut self, look_up_table_element_count: i32) {
1162        self.0.look_up_table_element_count = look_up_table_element_count
1163    }
1164    pub fn set_look_up_table(&mut self, look_up_table: &[u8]) {
1165        let mut look_up_table = ManuallyDrop::new(look_up_table.to_vec());
1166        self.0.ptr_look_up_table = look_up_table.as_mut_ptr();
1167        self.0.look_up_table_element_count = look_up_table.len() as i32;
1168    }
1169}
1170
1171impl ScalingInfo {
1172    pub fn new(scale_x: f64, scale_y: f64, scale_z: f64) -> Self {
1173        Self(ScalingInfoInterop {
1174            scale_x,
1175            scale_y,
1176            scale_z,
1177        })
1178    }
1179    pub fn get_scale_x(&self) -> f64 {
1180        self.0.scale_x
1181    }
1182    pub fn get_scale_y(&self) -> f64 {
1183        self.0.scale_y
1184    }
1185    pub fn get_scale_z(&self) -> f64 {
1186        self.0.scale_z
1187    }
1188    pub fn set_scale_x(&mut self, scale_x: f64) {
1189        self.0.scale_x = scale_x
1190    }
1191    pub fn set_scale_y(&mut self, scale_y: f64) {
1192        self.0.scale_y = scale_y
1193    }
1194    pub fn set_scale_z(&mut self, scale_z: f64) {
1195        self.0.scale_z = scale_z
1196    }
1197}