libczirw_sys/
interop.rs

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