Skip to main content

libczirw_sys/
functions.rs

1use crate::error::Error;
2use crate::handle::*;
3use crate::interop::*;
4use crate::misc::*;
5use crate::sys::*;
6use std::ffi::{CStr, CString, c_char, c_int, c_ulong, c_void};
7use std::mem::{ManuallyDrop, MaybeUninit};
8use std::ops::Deref;
9
10/// Release the memory - this function is to be used for freeing memory allocated by the libCZIApi-library
11///  (and returned to the caller).
12///
13///  \\param  data    Pointer to the memory to be freed.
14pub fn free<T: Ptr>(data: T) {
15    let ptr = data.as_mut_ptr() as *mut c_void;
16    unsafe { libCZI_Free(ptr) };
17}
18
19/// Allocate memory of the specified size.
20///
21///  \\param          size    The size of the memory block to be allocated in bytes.
22///  \\param \[out\]    data    If successful, a pointer to the allocated memory is put here. The memory must be freed using 'libCZI_Free'.
23///
24///  \\returns    An error-code indicating success or failure of the operation.
25pub fn allocate_memory<T: Ptr>(size: usize) -> Result<MaybeUninit<T>, Error> {
26    let mut data = MaybeUninit::<T>::uninit();
27    let mut ptr = data.as_mut_ptr() as *mut c_void;
28    lib_czi_error(unsafe { libCZI_AllocateMemory(size as c_ulong, &mut ptr) })?;
29    Ok(data)
30}
31
32impl LibCZIVersionInfo {
33    /// Get version information about the libCZIApi-library.
34    ///
35    ///  \\param \[out\] version_info    If successful, the version information is put here.
36    ///
37    ///  \\returns    An error-code indicating success or failure of the operation.
38    pub fn get_lib_czi_version_info() -> Result<LibCZIVersionInfo, Error> {
39        let mut version_info = MaybeUninit::uninit();
40        let ptr = version_info.as_mut_ptr();
41        lib_czi_error(unsafe { libCZI_GetLibCZIVersionInfo(ptr) })?;
42        Ok(unsafe { LibCZIVersionInfo::assume_init(version_info) })
43    }
44}
45
46impl LibCZIBuildInformation {
47    /// Get information about the build of the libCZIApi-library.
48    ///
49    ///  \\param \[out\] build_info  If successful, the build information is put here. Note that all strings must be freed by the caller (using 'libCZI_Free').
50    ///
51    ///  \\returns    An error-code indicating success or failure of the operation.
52    pub fn get() -> Result<LibCZIBuildInformation, Error> {
53        let mut build_info = MaybeUninit::uninit();
54        let ptr = build_info.as_mut_ptr();
55        lib_czi_error(unsafe { libCZI_GetLibCZIBuildInformation(ptr) })?;
56        Ok(unsafe { LibCZIBuildInformation::assume_init(build_info) })
57    }
58}
59
60impl CziReader {
61    /// Create a new CZI-reader object.
62    ///
63    ///  \\param \[out\] reader_object If the operation is successful, a handle to the newly created reader object is put here.
64    ///
65    ///  \\returns    An error-code indicating success or failure of the operation.
66    pub fn create() -> Result<Self, Error> {
67        let mut reader = MaybeUninit::uninit();
68        let ptr = reader.as_mut_ptr();
69        lib_czi_error(unsafe { libCZI_CreateReader(ptr) })?;
70        Ok(unsafe { Self::assume_init(reader) })
71    }
72
73    /// Instruct the specified reader-object to open a CZI-document. The 'open_info' parameter contains
74    ///  a handle to a stream-object which is used to read the document.
75    ///
76    ///  \\param  reader_object A handle representing the reader-object.
77    ///  \\param  open_info     Parameters controlling the operation.
78    ///
79    ///  \\returns    An error-code indicating success or failure of the operation.
80    pub fn open(&self, open_info: ReaderOpenInfo) -> Result<(), Error> {
81        lib_czi_error(unsafe { libCZI_ReaderOpen(**self, open_info.as_ptr()) })?;
82        Ok(())
83    }
84
85    /// Get information about the file-header of the CZI document. The information is put into the 'file_header_info_interop' structure.
86    ///  This file_header_info_interop structure contains the GUID of the CZI document and the version levels of CZI.
87    ///
88    ///  \\param          reader_object               The reader object.
89    ///  \\param \[out\]    file_header_info_interop    If successful, the retrieved information is put here.
90    ///
91    ///  \\returns An error-code indicating success or failure of the operation.
92    pub fn get_file_header_info(&self) -> Result<FileHeaderInfo, Error> {
93        let mut file_header_info = MaybeUninit::uninit();
94        let ptr = file_header_info.as_mut_ptr();
95        lib_czi_error(unsafe { libCZI_ReaderGetFileHeaderInfo(**self, ptr) })?;
96        Ok(unsafe { FileHeaderInfo::assume_init(file_header_info) })
97    }
98
99    /// Reads the sub-block identified by the specified index. If there is no sub-block present (for the
100    ///  specified index) then the function returns 'LibCZIApi_ErrorCode_OK', but the 'sub_block_object'
101    ///  is set to 'kInvalidObjectHandle'.
102    ///
103    ///  \\param          reader_object       The reader object.
104    ///  \\param          index               Index of the sub-block.
105    ///  \\param \[out\]    sub_block_object    If successful, a handle to the sub-block object is put here; otherwise 'kInvalidObjectHandle'.
106    ///
107    ///  \\returns    An error-code indicating success or failure of the operation.
108    pub fn read_sub_block(&self, index: i32) -> Result<SubBlock, Error> {
109        let mut sub_block = MaybeUninit::uninit();
110        let ptr = sub_block.as_mut_ptr();
111        lib_czi_error(unsafe { libCZI_ReaderReadSubBlock(**self, index as c_int, ptr) })?;
112        Ok(unsafe { SubBlock::assume_init(sub_block) })
113    }
114
115    /// Get statistics about the sub-blocks in the CZI-document. This function provides a simple version of the statistics, the
116    ///  information retrieved does not include the per-scene statistics.
117    ///
118    ///  \\param          reader_object   The reader object.
119    ///  \\param \[out\]    statistics      If non-null, the simple statistics will be put here.
120    ///
121    ///  \\returns    An error-code indicating success or failure of the operation.
122    pub fn get_statistics_simple(&self) -> Result<SubBlockStatistics, Error> {
123        let mut statistics = MaybeUninit::uninit();
124        let ptr = statistics.as_mut_ptr();
125        lib_czi_error(unsafe { libCZI_ReaderGetStatisticsSimple(**self, ptr) })?;
126        Ok(unsafe { SubBlockStatistics::assume_init(statistics) })
127    }
128
129    /// Get extended statistics about the sub-blocks in the CZI-document. This function provides a more detailed version of the statistics,
130    ///  including the per-scene statistics. Note that the statistics is of variable size, and the semantic is as follows:
131    ///  - On input, the argument 'number_of_per_channel_bounding_boxes' must point to an integer which describes the size of the argument 'statistics'.
132    ///    This number gives how many elements the array 'per_scenes_bounding_boxes' in 'SubBlockStatisticsInteropEx' can hold. Only that number of
133    ///    per-scene information elements will be put into the 'statistics' structure at most, in any case.
134    ///  - On output, the argument 'number_of_per_channel_bounding_boxes' will be set to the number of per-channel bounding boxes that were actually
135    ///    available.
136    ///  - In the returned 'SubBlockStatisticsInteropEx' structure, the 'number_of_per_scenes_bounding_boxes' field will be set to the number of per-scene
137    ///    information that is put into this struct (which may be less than number of scenes that are available).
138    ///
139    ///  So, the caller is expected to check the returned 'number_of_per_channel_bounding_boxes' to see how many per-channel bounding boxes are available.
140    ///  If this number is greater than the number of elements (given with the 'number_of_per_scenes_bounding_boxes' value in the 'statistics' structure),
141    ///  then the caller should allocate a larger 'statistics' structure and call this function again (with an increased 'number_of_per_scenes_bounding_boxes').
142    ///
143    ///  \\param          reader_object                           The reader object.
144    ///  \\param \[out\]    statistics                              If non-null, the statistics will be put here.
145    ///  \\param \[in,out\] number_of_per_channel_bounding_boxes    On input, it gives the number of elements that can be put into the 'per_scenes_bounding_boxes' array.
146    ///                                                          On output, it gives the number of elements which are available.
147    ///
148    ///  \\returns    An error-code indicating success or failure of the operation.
149    pub fn get_statistics_ex(
150        &self,
151        number_of_per_channel_bounding_boxes: i32,
152    ) -> Result<(SubBlockStatisticsEx, i32), Error> {
153        let mut statistics = MaybeUninit::uninit();
154        let ptr = statistics.as_mut_ptr();
155        let number_of_per_channel_bounding_boxes =
156            Box::into_raw(Box::new(number_of_per_channel_bounding_boxes));
157        lib_czi_error(unsafe {
158            libCZI_ReaderGetStatisticsEx(**self, ptr, number_of_per_channel_bounding_boxes)
159        })?;
160        Ok(unsafe {
161            (
162                SubBlockStatisticsEx::assume_init(statistics),
163                *Box::from_raw(number_of_per_channel_bounding_boxes),
164            )
165        })
166    }
167
168    /// Get \"pyramid-statistics\" about the CZI-document. This function provides a JSON-formatted string which contains information about the pyramid.
169    ///  The JSON-schema is as follows:
170    ///  \\code
171    ///  {
172    ///      \"scenePyramidStatistics\": {
173    ///          \<sceneIndex\>: [
174    ///          {
175    ///              \"layerInfo\": {
176    ///              \"minificationFactor\": \<number\>,
177    ///              \"pyramidLayerNo\" : \<number\>
178    ///          },
179    ///          \"count\" : \<number\>
180    ///          }
181    ///      ]}
182    ///  }
183    ///  \\endcode
184    ///  It resembles the corresponding C++-structure 'PyramidStatistics' in the libCZI-library.
185    ///
186    ///  \\param          reader_object              The reader object.
187    ///  \\param \[out\]    pyramid_statistics_as_json If successful, a pointer to a JSON-formatted string is placed here. The caller
188    ///                                              is responsible for freeing this memory (by calling libCZI_Free).
189    ///
190    ///  \\returns An error-code indicating success or failure of the operation.
191    pub fn get_pyramid_statistics(&self) -> Result<String, Error> {
192        let mut ptr = MaybeUninit::<*mut c_char>::uninit();
193        lib_czi_error(unsafe { libCZI_ReaderGetPyramidStatistics(**self, ptr.as_mut_ptr()) })?;
194        let ptr = unsafe { ptr.assume_init() };
195        assert!(!ptr.is_null());
196        let statistics = unsafe { CStr::from_ptr(ptr) }
197            .to_string_lossy()
198            .into_owned();
199        unsafe { libCZI_Free(ptr as *mut c_void) };
200        Ok(statistics)
201    }
202
203    /// Create a metadata-segment object from the reader-object. The metadata-segment object can be used to retrieve the XML-metadata of the CZI-document.
204    ///
205    /// \\param          reader_object           The reader object.
206    /// \\param \[out\]    metadata_segment_object If successful, a handle to the metadata-segment object is put here.
207    ///
208    /// \\returns An error-code indicating success or failure of the operation.
209    pub fn get_metadata_segment(&self) -> Result<MetadataSegment, Error> {
210        let mut metadata_segment = MaybeUninit::uninit();
211        let ptr = metadata_segment.as_mut_ptr();
212        lib_czi_error(unsafe { libCZI_ReaderGetMetadataSegment(**self, ptr) })?;
213        Ok(unsafe { MetadataSegment::assume_init(metadata_segment) })
214    }
215
216    /// Get the number of attachments available.
217    ///
218    /// \\param          reader_object           The reader object.
219    /// \\param \[out\]    count                   The number of available attachments is put here.
220    /// \\returns    An error-code indicating success or failure of the operation.
221    pub fn get_attachment_count(&self) -> Result<i32, Error> {
222        let mut count = MaybeUninit::<c_int>::uninit();
223        lib_czi_error(unsafe { libCZI_ReaderGetAttachmentCount(**self, count.as_mut_ptr()) })?;
224        Ok(unsafe { count.assume_init() })
225    }
226
227    /// Get information about the attachment at the specified index. The information is put into the 'attachment_info_interop' structure.
228    /// If the index is not valid, then the function returns 'LibCZIApi_ErrorCode_IndexOutOfRange'.
229    ///
230    /// \\param          reader_object           The reader object.
231    /// \\param          index                   The index of the attachment to query information for.
232    /// \\param \[out\]    attachment_info_interop If successful, the retrieved information is put here.
233    ///
234    /// \\returns An error-code indicating success or failure of the operation.
235    pub fn get_attachment_info_from_directory(&self, index: i32) -> Result<AttachmentInfo, Error> {
236        let mut attachment_info = MaybeUninit::uninit();
237        let ptr = attachment_info.as_mut_ptr();
238        lib_czi_error(unsafe { libCZI_ReaderGetAttachmentInfoFromDirectory(**self, index, ptr) })?;
239        Ok(unsafe { AttachmentInfo::assume_init(attachment_info) })
240    }
241
242    /// Read the attachment with the specified index and create an attachment object representing it. If the specified index
243    /// is invalid, then the returned attachment-object handle will have the value 'kInvalidObjectHandle'.
244    /// \\param       reader_object              The reader object.
245    /// \\param       index                      The index of the attachment to get.
246    /// \\param \[out\] attachment_object          If successful and index is valid, a handle representing the attachment object is put here. If the index is
247    ///                                         invalid, then the handle will have the value 'kInvalidObjectHandle'.
248    /// \\returns  An error-code indicating success or failure of the operation.
249    pub fn read_attachment(&self, index: i32) -> Result<Attachment, Error> {
250        let mut attachment = MaybeUninit::uninit();
251        let ptr = attachment.as_mut_ptr();
252        lib_czi_error(unsafe { libCZI_ReaderReadAttachment(**self, index, ptr) })?;
253        Ok(unsafe { Attachment::assume_init(attachment) })
254    }
255
256    /// Release the specified reader-object. After this function is called, the handle is no
257    /// longer valid.
258    ///
259    /// \\param  reader_object   The reader object.
260    ///
261    /// \\returns    An error-code indicating success or failure of the operation.
262    pub fn release(&self) -> Result<(), Error> {
263        lib_czi_error(unsafe { libCZI_ReleaseReader(**self) })?;
264        Ok(())
265    }
266
267    /// Get information about the sub-block with the specified index. The information is put into the 'sub_block_info_interop' structure.
268    /// If the index is not valid, then the function returns 'LibCZIApi_ErrorCode_IndexOutOfRange'.
269    ///
270    /// \\param          reader_object           The reader object.
271    /// \\param          index                   The index of the attachment to query information for.
272    /// \\param \[out\]    sub_block_info_interop  If successful, the retrieved information is put here.
273    ///
274    /// \\returns An error-code indicating success or failure of the operation.
275    pub fn try_get_sub_block_info_for_index(&self, index: i32) -> Result<SubBlockInfo, Error> {
276        let mut sub_block_info = MaybeUninit::uninit();
277        let ptr = sub_block_info.as_mut_ptr();
278        lib_czi_error(unsafe { libCZI_TryGetSubBlockInfoForIndex(**self, index, ptr) })?;
279        Ok(unsafe { SubBlockInfo::assume_init(sub_block_info) })
280    }
281
282    /// Create a single channel scaling tile accessor.
283    ///
284    /// \\param reader_object            A handle representing the reader-object.
285    /// \\param accessor_object \[out\]    If the operation is successful, a handle to the newly created single-channel-scaling-tile-accessor is put here.
286    ///
287    /// \\returns    An error-code indicating success or failure of the operation.
288    pub fn create_single_channel_tile_accessor(
289        &self,
290    ) -> Result<SingleChannelScalingTileAccessor, Error> {
291        let mut accessor = MaybeUninit::uninit();
292        let ptr = accessor.as_mut_ptr();
293        lib_czi_error(unsafe { libCZI_CreateSingleChannelTileAccessor(**self, ptr) })?;
294        Ok(unsafe { SingleChannelScalingTileAccessor::assume_init(accessor) })
295    }
296}
297
298impl Drop for CziReader {
299    fn drop(&mut self) {
300        self.release().ok();
301    }
302}
303
304/// Get information about the stream class at the specified index.
305///
306/// \\param          index                   Zero-based index of the stream class to query information about.
307/// \\param \[out\]    input_stream_class_info If successful, information about the stream class is put here. Note that the strings in the structure
308///                                         must be freed (by the caller) using 'libCZI_Free'.
309///
310/// \\returns An error-code indicating success or failure of the operation.
311pub fn get_stream_classes_count(index: i32) -> Result<InputStreamClassInfo, Error> {
312    let mut input_stream_class_info = MaybeUninit::uninit();
313    let ptr = input_stream_class_info.as_mut_ptr();
314    lib_czi_error(unsafe { libCZI_GetStreamClassInfo(index, ptr) })?;
315    Ok(unsafe { InputStreamClassInfo::assume_init(input_stream_class_info) })
316}
317
318impl InputStream {
319    /// Create an input stream object of the specified type, using the specified JSON-formatted property bag and
320    /// the specified file identifier as input.
321    ///
322    /// \\param          stream_class_name       Name of the stream class to be instantiated.
323    /// \\param          creation_property_bag   JSON formatted string (containing additional parameters for the stream creation) in UTF8-encoding.
324    /// \\param          stream_identifier       The filename (or, more generally, a URI of some sort) identifying the file to be opened in UTF8-encoding.
325    /// \\param \[out\]    stream_object           If successful, a handle representing the newly created stream object is put here.
326    ///
327    /// \\returns    An error-code that indicates whether the operation is successful or not.
328    pub fn create(
329        stream_class_name: impl AsRef<str>,
330        creation_property_bag: impl AsRef<str>,
331        stream_identifier: impl AsRef<str>,
332    ) -> Result<Self, Error> {
333        let mut stream = MaybeUninit::uninit();
334        let ptr = stream.as_mut_ptr();
335        let stream_class_name = ManuallyDrop::new(CString::new(stream_class_name.as_ref())?);
336        let creation_property_bag =
337            ManuallyDrop::new(CString::new(creation_property_bag.as_ref())?);
338        let stream_identifier = ManuallyDrop::new(CString::new(stream_identifier.as_ref())?);
339        lib_czi_error(unsafe {
340            libCZI_CreateInputStream(
341                stream_class_name.as_ptr(),
342                creation_property_bag.as_ptr(),
343                stream_identifier.as_ptr(),
344                ptr,
345            )
346        })?;
347        Ok(unsafe { Self::assume_init(stream) })
348    }
349
350    /// Create an input stream object for a file identified by its filename, which is given as a wide string. Note that wchar_t on
351    /// Windows is 16-bit wide, and on Unix-like systems it is 32-bit wide.
352    ///
353    /// \\param  \[in\]    filename        Filename of the file which is to be opened (zero terminated wide string). Note that on Windows, this
354    ///                                 is a string with 16-bit code units, and on Unix-like systems it is typically a string with 32-bit code units.
355    ///
356    /// \\param  \[out\]   stream_object   The output stream object that will hold the created stream.
357    /// \\return         An error-code that indicates whether the operation is successful or not. Non-positive values indicates successful, positive values
358    ///                 indicates unsuccessful operation.
359    pub fn create_from_file_wide(file_name: Vec<u32>) -> Result<Self, Error> {
360        let mut stream = MaybeUninit::uninit();
361        let ptr = stream.as_mut_ptr();
362        lib_czi_error(unsafe { libCZI_CreateInputStreamFromFileWide(file_name.as_ptr(), ptr) })?;
363        Ok(unsafe { Self::assume_init(stream) })
364    }
365
366    /// Create an input stream object for a file identified by its filename, which is given as an UTF8-encoded string.
367    ///
368    /// \\param  \[in\]    filename        Filename of the file which is to be opened (in UTF8 encoding).
369    /// \\param  \[out\]   stream_object   The output stream object that will hold the created stream.
370    /// \\return         An error-code that indicates whether the operation is successful or not. Non-positive values indicates successful, positive values
371    ///                 indicates unsuccessful operation.
372    pub fn create_from_file_utf8<S: AsRef<str>>(file_name: S) -> Result<Self, Error> {
373        let mut stream = MaybeUninit::uninit();
374        let ptr = stream.as_mut_ptr();
375        let file_name = ManuallyDrop::new(CString::new(file_name.as_ref())?);
376        // let file_name = file_name.as_ref().as_bytes().to_vec();
377        lib_czi_error(unsafe {
378            libCZI_CreateInputStreamFromFileUTF8(file_name.as_ptr() as *const c_char, ptr)
379        })?;
380        Ok(unsafe { Self::assume_init(stream) })
381    }
382
383    /// Create an input stream object which is using externally provided functions for operation
384    /// and reading the data. Please refer to the documentation of
385    /// 'ExternalInputStreamStructInterop' for more information.
386    ///
387    /// \\param          external_input_stream_struct    Structure containing the information about the externally provided functions.
388    /// \\param \[out\]    stream_object                   If successful, the handle to the newly created input stream object is put here.
389    ///
390    /// \\returns    An error-code indicating success or failure of the operation.
391    pub fn create_from_external(
392        external_input_stream: ExternalInputStreamStruct,
393    ) -> Result<Self, Error> {
394        let mut stream = MaybeUninit::uninit();
395        let ptr = stream.as_mut_ptr();
396        lib_czi_error(unsafe {
397            libCZI_CreateInputStreamFromExternal(external_input_stream.as_ptr(), ptr)
398        })?;
399        Ok(unsafe { Self::assume_init(stream) })
400    }
401
402    /// Release the specified input stream object. After this function is called, the handle is no
403    /// longer valid. Note that calling this function will only decrement the usage count of the
404    /// underlying object; whereas the object itself (and the resources it holds) will only be
405    /// released when the usage count reaches zero.
406    ///
407    /// \\param  stream_object   The input stream object.
408    ///
409    /// \\returns    An error-code indicating success or failure of the operation.
410    pub fn release(&self) -> Result<(), Error> {
411        lib_czi_error(unsafe { libCZI_ReleaseInputStream(**self) })?;
412        Ok(())
413    }
414}
415
416impl Drop for InputStream {
417    fn drop(&mut self) {
418        self.release().ok();
419    }
420}
421
422impl SubBlock {
423    /// Create a bitmap object from the specified sub-block object. The bitmap object can be used to access the pixel
424    /// data contained in the sub-block. If the subblock contains compressed data, then decompression will be performed
425    /// in this call.
426    ///
427    /// \\param          sub_block_object The sub-block object.
428    /// \\param \[out\]    bitmap_object    If successful, the handle to the newly created bitmap object is put here.
429    ///
430    /// \\returns An error-code indicating success or failure of the operation.
431    pub fn create_bitmap(&self) -> Result<Bitmap, Error> {
432        let mut bitmap = MaybeUninit::uninit();
433        let ptr = bitmap.as_mut_ptr();
434        lib_czi_error(unsafe { libCZI_SubBlockCreateBitmap(**self, ptr) })?;
435        Ok(unsafe { Bitmap::assume_init(bitmap) })
436    }
437
438    /// Get Information about the sub-block.
439    ///
440    /// \\param       sub_block_object The sub-block object.
441    /// \\param \[out\] sub_block_info   If successful, information about the sub-block object is put here.
442    ///
443    /// \\returns An error-code indicating success or failure of the operation.
444    pub fn get_info(&self) -> Result<SubBlockInfo, Error> {
445        let mut sub_block_info = MaybeUninit::uninit();
446        let ptr = sub_block_info.as_mut_ptr();
447        lib_czi_error(unsafe { libCZI_SubBlockGetInfo(**self, ptr) })?;
448        Ok(unsafe { SubBlockInfo::assume_init(sub_block_info) })
449    }
450
451    /// Copy the raw data from the specified sub-block object to the specified memory buffer. The value of the 'size' parameter
452    /// on input is the size of the buffer pointed to by 'data'. On output, the value of 'size' is the actual size of the data. At most
453    /// the initial value of 'size' bytes are copied to the buffer. If the initial value of 'size' is zero (0) or 'data' is null, then
454    /// no data is copied.
455    /// For the 'type' parameter, the following values are valid: 0 (data) and 1 (metadata).
456    /// For 0 (data), the data is the raw pixel data of the bitmap. This data may be compressed.
457    /// For 1 (metadata), the data is the raw metadata in XML-format (UTF8-encoded).
458    ///
459    /// \\param          sub_block_object    The sub block object.
460    /// \\param          type                The type - 0 for \"pixel-data\", 1 for \"sub-block metadata\".
461    /// \\param \[in,out\] size                On input, the size of the memory block pointed to by 'data', on output the actual size of the available data.
462    /// \\param \[out\]    data                Pointer where the data is to be copied to. At most the initial content of 'size' bytes are copied.
463    ///
464    /// \\returns    An error-code indicating success or failure of the operation.
465    pub fn get_raw_data(&self, tp: RawDataType, size: i32) -> Result<(i32, Vec<u8>), Error> {
466        let mut data = Vec::<u8>::with_capacity(size as usize);
467        let size = Box::into_raw(Box::new(size as c_ulong));
468        lib_czi_error(unsafe {
469            libCZI_SubBlockGetRawData(**self, tp as c_int, size, data.as_mut_ptr() as *mut c_void)
470        })?;
471        Ok((unsafe { *Box::from_raw(size) as i32 }, data))
472    }
473
474    /// Release the specified sub-block object.
475    ///
476    /// \\param  sub_block_object The sub block object to be released.
477    ///
478    /// \\returns An error-code indicating success or failure of the operation.
479    pub fn release(&self) -> Result<(), Error> {
480        lib_czi_error(unsafe { libCZI_ReleaseSubBlock(**self) })?;
481        Ok(())
482    }
483}
484
485impl Drop for SubBlock {
486    fn drop(&mut self) {
487        self.release().ok();
488    }
489}
490
491impl Attachment {
492    /// Get information about the specified attachment object.
493    /// \\param attachment_object            The attachment object.
494    /// \\param \[out\]    attachment_info     Information about the attachment.
495    /// \\returns     An error-code indicating success or failure of the operation.
496    pub fn get_info(&self) -> Result<AttachmentInfo, Error> {
497        let mut attachment_info = MaybeUninit::uninit();
498        let ptr = attachment_info.as_mut_ptr();
499        lib_czi_error(unsafe { libCZI_AttachmentGetInfo(**self, ptr) })?;
500        Ok(unsafe { AttachmentInfo::assume_init(attachment_info) })
501    }
502
503    /// Copy the raw data from the specified attachment object to the specified memory buffer. The value of the 'size' parameter
504    /// on input is the size of the buffer pointed to by 'data'. On output, the value of 'size' is the actual size of the data. At most
505    /// the initial value of 'size' bytes are copied to the buffer. If the initial value of 'size' is zero (0) or 'data' is null, then
506    /// no data is copied.
507    /// \\param          attachment_object   The attachment object.
508    /// \\param \[in,out\] size                On input, the size of the memory block pointed to by 'data', on output the actual size of the available data.
509    /// \\param \[out\]    data                Pointer where the data is to be copied to. At most the initial content of 'size' bytes are copied.
510    ///
511    /// \\returns    An error-code indicating success or failure of the operation.
512    pub fn get_raw_data(&self, size: i32) -> Result<(i32, Vec<u8>), Error> {
513        let mut data = Vec::<u8>::with_capacity(size as usize);
514        let size = Box::into_raw(Box::new(size as c_ulong));
515        lib_czi_error(unsafe {
516            libCZI_AttachmentGetRawData(**self, size, data.as_mut_ptr() as *mut c_void)
517        })?;
518        Ok((unsafe { *Box::from_raw(size) as i32 }, data))
519    }
520
521    /// Release the specified attachment object.
522    ///
523    /// \\param  attachment_object The attachment object to be released.
524    ///
525    /// \\returns An error-code indicating success or failure of the operation.
526    pub fn release(&self) -> Result<(), Error> {
527        lib_czi_error(unsafe { libCZI_ReleaseAttachment(**self) })?;
528        Ok(())
529    }
530}
531
532impl Drop for Attachment {
533    fn drop(&mut self) {
534        self.release().ok();
535    }
536}
537
538impl Bitmap {
539    /// Get information about the specified bitmap object.
540    ///
541    /// \\param          bitmap_object The bitmap object.
542    /// \\param \[out\]    bitmap_info   If successful, information about the bitmap object is put here.
543    ///
544    /// \\returns An error-code indicating success or failure of the operation.
545    pub fn get_info(&self) -> Result<BitmapInfo, Error> {
546        let mut bitmap_info = MaybeUninit::uninit();
547        let ptr = bitmap_info.as_mut_ptr();
548        lib_czi_error(unsafe { libCZI_BitmapGetInfo(**self, ptr) })?;
549        Ok(unsafe { BitmapInfo::assume_init(bitmap_info) })
550    }
551
552    /// Locks the bitmap object. Once the bitmap is locked, the pixel data can be accessed. Memory access to the
553    /// pixel data must only occur while the bitmap is locked. The lock must be released by calling 'libCZI_BitmapUnlock'.
554    /// It is a fatal error if the bitmap is destroyed while still being locked. Calls to Lock and Unlock are counted, and
555    /// they must be balanced.
556    ///
557    /// \\param          bitmap_object The bitmap object.
558    /// \\param \[out\]    lockInfo      If successful, information about how to access the pixel data is put here.
559    ///
560    /// \\returns An error-code indicating success or failure of the operation.
561    pub fn lock(self) -> Result<LockedBitmap, Error> {
562        let mut bitmap_info = MaybeUninit::uninit();
563        let ptr = bitmap_info.as_mut_ptr();
564        lib_czi_error(unsafe { libCZI_BitmapLock(*self, ptr) })?;
565        let bitmap_lock_info = unsafe { BitmapLockInfo::assume_init(bitmap_info) };
566        Ok(LockedBitmap {
567            bitmap: self,
568            lock_info: bitmap_lock_info,
569        })
570    }
571
572    /// Release the specified bitmap object.
573    /// It is a fatal error trying to release a bitmap object that is still locked.
574    ///
575    /// \\param  bitmap_object The bitmap object.
576    ///
577    /// \\returns An error-code indicating success or failure of the operation.
578    pub fn release(&self) -> Result<(), Error> {
579        lib_czi_error(unsafe { libCZI_ReleaseBitmap(**self) })?;
580        Ok(())
581    }
582}
583
584impl TryFrom<&SubBlock> for Bitmap {
585    type Error = Error;
586
587    fn try_from(sub_block: &SubBlock) -> Result<Self, Error> {
588        sub_block.create_bitmap()
589    }
590}
591
592impl Drop for Bitmap {
593    fn drop(&mut self) {
594        self.release().ok();
595    }
596}
597
598/// Locked version of bitmap so that the data can be accessed
599pub struct LockedBitmap {
600    bitmap: Bitmap,
601    pub lock_info: BitmapLockInfo,
602}
603
604impl Deref for LockedBitmap {
605    type Target = Bitmap;
606
607    fn deref(&self) -> &Self::Target {
608        &self.bitmap
609    }
610}
611
612impl Drop for LockedBitmap {
613    fn drop(&mut self) {
614        unsafe { libCZI_BitmapUnlock(self.handle()) };
615    }
616}
617
618impl LockedBitmap {
619    /// Unlock the bitmap object. Once the bitmap is unlocked, the pixel data must not be accessed anymore.
620    ///
621    /// \\param  bitmap_object The bitmap object.
622    ///
623    /// \\returns An error-code indicating success or failure of the operation.
624    pub fn unlock(self) -> Result<Bitmap, Error> {
625        lib_czi_error(unsafe { libCZI_BitmapUnlock(**self) })?;
626        Ok(self.bitmap.clone())
627    }
628
629    /// Copy the pixel data from the specified bitmap object to the specified memory buffer. The specified
630    /// destination bitmap must have same width, height and pixel type as the source bitmap.
631    ///
632    /// \\param          bitmap_object The bitmap object.
633    /// \\param          width         The width of the destination bitmap.
634    /// \\param          height        The height of the destination bitmap.
635    /// \\param          pixel_type    The pixel type.
636    /// \\param          stride        The stride (given in bytes).
637    /// \\param \[out\]    ptr           Pointer to the memory location where the bitmap is to be copied to.
638    ///
639    /// \\returns A LibCZIApiErrorCode.
640    pub fn copy(
641        &self,
642        width: u32,
643        height: u32,
644        pixel_type: PixelType,
645        stride: u32,
646    ) -> Result<Bitmap, Error> {
647        let mut data = MaybeUninit::<Self>::uninit();
648        lib_czi_error(unsafe {
649            libCZI_BitmapCopyTo(
650                ***self,
651                width,
652                height,
653                pixel_type as i32,
654                stride,
655                data.as_mut_ptr() as *mut c_void,
656            )
657        })?;
658        Ok(unsafe { data.assume_init().unlock()? })
659    }
660}
661
662impl MetadataSegment {
663    /// Get the XML-metadata information from the specified metadata-segment object.
664    /// Note that the XML-metadata is returned as a pointer to the data (in the 'data' field of the 'MetadataAsXmlInterop' structure), which
665    /// must be freed by the caller using 'libCZI_Free'.
666    ///
667    /// \\param          metadata_segment_object The metadata segment object.
668    /// \\param \[out\]    metadata_as_xml_interop If successful, the XML-metadata information is put here.
669    ///
670    /// \\returns    An error-code indicating success or failure of the operation.
671    pub fn get_metadata_as_xml(&self) -> Result<MetadataAsXml, Error> {
672        let mut metadata_as_xml_interop = MaybeUninit::uninit();
673        let ptr = metadata_as_xml_interop.as_mut_ptr();
674        lib_czi_error(unsafe { libCZI_MetadataSegmentGetMetadataAsXml(**self, ptr) })?;
675        Ok(unsafe { MetadataAsXml::assume_init(metadata_as_xml_interop) })
676    }
677
678    /// Create a CZI-document-information object from the specified metadata-segment object.
679    ///
680    /// \\param          metadata_segment_object The metadata segment object.
681    /// \\param \[in,out\] czi_document_info       If successful, a handle to the newly created CZI-document-info object is put here.
682    ///
683    /// \\returns    An error-code indicating success or failure of the operation.
684    pub fn get_czi_document_info(&self) -> Result<CziDocumentInfo, Error> {
685        let mut czi_document = MaybeUninit::uninit();
686        let ptr = czi_document.as_mut_ptr();
687        lib_czi_error(unsafe { libCZI_MetadataSegmentGetCziDocumentInfo(**self, ptr) })?;
688        Ok(unsafe { CziDocumentInfo::assume_init(czi_document) })
689    }
690
691    /// Release the specified metadata-segment object.
692    ///
693    /// \\param  metadata_segment_object The metadata-segment object to be released.
694    ///
695    /// \\returns    An error-code indicating success or failure of the operation.
696    pub fn release(&self) -> Result<(), Error> {
697        lib_czi_error(unsafe { libCZI_ReleaseMetadataSegment(**self) })?;
698        Ok(())
699    }
700}
701
702impl Drop for MetadataSegment {
703    fn drop(&mut self) {
704        self.release().ok();
705    }
706}
707
708impl CziDocumentInfo {
709    /// Get \"general document information\" from the specified czi-document information object. The information is returned as a JSON-formatted string.
710    /// The JSON returned is an object, with the following possible key-value pairs:
711    /// \"name\" : \<name of the document\>, type string
712    /// \"title\" : \<title of the document\>, type string
713    /// \"user_name\" : \<user name\>, type string
714    /// \"description\" : \<description\>, type string
715    /// \"comment\" : \<comment\>, type string
716    /// \"keywords\" : \<keyword1\>,\<keyword2\>,...\", type string
717    /// \"rating\" : \<rating\>, type integer
718    /// \"creation_date\" : \<creation date\>, type string, conforming to ISO 8601
719    ///
720    /// \\param          czi_document_info           The CZI-document-info object.
721    /// \\param \[out\]    general_document_info_json  If successful, the general document information is put here. Note that the data must be freed using 'libCZI_Free' by the caller.
722    ///
723    /// \\returns    An error-code indicating success or failure of the operation.
724    pub fn get_general_document_info(&self) -> Result<String, Error> {
725        let mut ptr = MaybeUninit::<*mut c_char>::uninit();
726        lib_czi_error(unsafe {
727            libCZI_CziDocumentInfoGetGeneralDocumentInfo(
728                **self,
729                ptr.as_mut_ptr() as *mut *mut c_void,
730            )
731        })?;
732        let ptr = unsafe { ptr.assume_init() };
733        assert!(!ptr.is_null());
734        let info = unsafe { CStr::from_ptr(ptr) }
735            .to_string_lossy()
736            .into_owned();
737        unsafe { libCZI_Free(ptr as *mut c_void) };
738        Ok(info)
739    }
740
741    /// Get scaling information from the specified czi-document information object. The information gives the size of an image pixels.
742    ///
743    /// \\param          czi_document_info           Handle to the CZI-document-info object from which the scaling information will be retrieved.
744    /// \\param \[out\]    scaling_info_interop        If successful, the scaling information is put here.
745    ///
746    /// \\returns        An error-code indicating success or failure of the operation.
747    pub fn get_scaling_info(&self) -> Result<ScalingInfo, Error> {
748        let mut scaling_info_interop = MaybeUninit::uninit();
749        let ptr = scaling_info_interop.as_mut_ptr();
750        lib_czi_error(unsafe { libCZI_CziDocumentInfoGetScalingInfo(**self, ptr) })?;
751        Ok(unsafe { ScalingInfo::assume_init(scaling_info_interop) })
752    }
753
754    /// Get the display-settings from the document's XML-metadata. The display-settings are returned in the form of an object,
755    /// for which a handle is returned.
756    ///
757    /// \\param          czi_document_info       The CZI-document-info object.
758    /// \\param \[in,out\] display_settings_handle If successful, a handle to the display-settings object is put here.
759    ///
760    /// \\returns    An error-code indicating success or failure of the operation.
761    pub fn get_display_settings(&self) -> Result<DisplaySettings, Error> {
762        let mut display_settings = MaybeUninit::uninit();
763        let ptr = display_settings.as_mut_ptr();
764        lib_czi_error(unsafe { libCZI_CziDocumentInfoGetDisplaySettings(**self, ptr) })?;
765        Ok(unsafe { DisplaySettings::assume_init(display_settings) })
766    }
767
768    /// Get the dimension information from the document's XML-metadata. The information is returned as a JSON-formatted string.
769    ///
770    /// \\param          czi_document_info       Handle to the CZI-document-info object from which the dimension information will be retrieved.
771    /// \\param          dimension_index         Index of the dimension.
772    /// \\param \[out\]    dimension_info_json     If successful, the information is put here as JSON format. Note that the data must be freed using 'libCZI_Free' by the caller.
773    ///
774    /// \\returns        An error-code indicating success or failure of the operation.
775    pub fn get_dimension_info(&self, dimension_index: u32) -> Result<String, Error> {
776        let mut ptr = MaybeUninit::<*mut c_char>::uninit();
777        lib_czi_error(unsafe {
778            libCZI_CziDocumentInfoGetDimensionInfo(
779                **self,
780                dimension_index,
781                ptr.as_mut_ptr() as *mut *mut c_void,
782            )
783        })?;
784        let ptr = unsafe { ptr.assume_init() };
785        assert!(!ptr.is_null());
786        Ok(unsafe { CStr::from_ptr(ptr) }
787            .to_string_lossy()
788            .into_owned())
789    }
790
791    /// Release the specified CZI-document-info object.
792    ///
793    /// \\param  czi_document_info The CZI-document-info object.
794    ///
795    /// \\returns    An error-code indicating success or failure of the operation.
796    pub fn release(&self) -> Result<(), Error> {
797        lib_czi_error(unsafe { libCZI_ReleaseCziDocumentInfo(**self) })?;
798        Ok(())
799    }
800}
801
802impl Drop for CziDocumentInfo {
803    fn drop(&mut self) {
804        self.release().ok();
805    }
806}
807
808impl OutputStream {
809    /// Create an output stream object for a file identified by its filename, which is given as a wide string. Note that wchar_t on
810    /// Windows is 16-bit wide, and on Unix-like systems it is 32-bit wide.
811    ///
812    /// \\param          filename                Filename of the file which is to be opened (zero terminated wide string). Note that on Windows, this
813    ///                                         is a string with 16-bit code units, and on Unix-like systems it is typically a string with 32-bit code units.
814    /// \\param          overwrite               Indicates whether the file should be overwritten.
815    /// \\param \[out\]    output_stream_object    The output stream object that will hold the created stream.
816    ///
817    /// \\return         An error-code that indicates whether the operation is successful or not. Non-positive values indicates successful, positive values
818    ///                 indicates unsuccessful operation.
819    pub fn create_for_file_wide(file_name: Vec<u32>, overwrite: bool) -> Result<Self, Error> {
820        let mut output_stream = MaybeUninit::uninit();
821        let ptr = output_stream.as_mut_ptr();
822        lib_czi_error(unsafe {
823            libCZI_CreateOutputStreamForFileWide(file_name.as_ptr(), overwrite, ptr)
824        })?;
825        Ok(unsafe { Self::assume_init(output_stream) })
826    }
827
828    /// Create an input stream object for a file identified by its filename, which is given as an UTF8 - encoded string.
829    ///
830    /// \\param          filename                Filename of the file which is to be opened (in UTF8 encoding).
831    /// \\param          overwrite               Indicates whether the file should be overwritten.
832    /// \\param \[out\]    output_stream_object    The output stream object that will hold the created stream.
833    ///
834    /// \\return         An error-code that indicates whether the operation is successful or not. Non-positive values indicates successful, positive values
835    ///                 indicates unsuccessful operation.
836    pub fn create_for_file_utf8<S: AsRef<str>>(
837        file_name: S,
838        overwrite: bool,
839    ) -> Result<Self, Error> {
840        let mut output_stream = MaybeUninit::uninit();
841        let ptr = output_stream.as_mut_ptr();
842        let file_name = ManuallyDrop::new(CString::new(file_name.as_ref())?);
843        lib_czi_error(unsafe {
844            libCZI_CreateOutputStreamForFileUTF8(file_name.as_ptr(), overwrite, ptr)
845        })?;
846        Ok(unsafe { Self::assume_init(output_stream) })
847    }
848
849    /// Release the specified output stream object. After this function is called, the handle is no
850    /// longer valid. Note that calling this function will only decrement the usage count of the
851    /// underlying object; whereas the object itself (and the resources it holds) will only be
852    /// released when the usage count reaches zero.
853    ///
854    /// \\param  output_stream_object   The output stream object.
855    ///
856    /// \\returns    An error-code indicating success or failure of the operation.
857    pub fn release(&self) -> Result<(), Error> {
858        lib_czi_error(unsafe { libCZI_ReleaseOutputStream(**self) })?;
859        Ok(())
860    }
861
862    /// Create an output stream object which is using externally provided functions for operation
863    /// and writing the data. Please refer to the documentation of
864    /// 'ExternalOutputStreamStructInterop' for more information.
865    ///
866    /// \\param          external_output_stream_struct    Structure containing the information about the externally provided functions.
867    /// \\param \[out\]    output_stream_object             If successful, the handle to the newly created output stream object is put here.
868    ///
869    /// \\returns    An error-code indicating success or failure of the operation.
870    pub fn create_from_external(
871        external_input_stream: ExternalOutputStreamStruct,
872    ) -> Result<Self, Error> {
873        let mut stream = MaybeUninit::uninit();
874        let ptr = stream.as_mut_ptr();
875        lib_czi_error(unsafe {
876            libCZI_CreateOutputStreamFromExternal(external_input_stream.as_ptr(), ptr)
877        })?;
878        Ok(unsafe { Self::assume_init(stream) })
879    }
880}
881
882impl Drop for OutputStream {
883    fn drop(&mut self) {
884        self.release().ok();
885    }
886}
887
888impl CziWriter {
889    /// Create a writer object for authoring a document in CZI-format. The options string is a JSON-formatted string, here
890    /// is an example:
891    /// \\code
892    /// {
893    /// \"allow_duplicate_subblocks\" : true
894    /// }
895    /// \\endcode
896    ///
897    /// \\param \[out\] writer_object If the operation is successful, a handle to the newly created writer object is put here.
898    /// \\param       options       A JSON-formatted zero-terminated string (in UTF8-encoding) containing options for the writer creation.
899    ///
900    /// \\returns An error-code indicating success or failure of the operation.
901    pub fn create<S: AsRef<str>>(options: S) -> Result<Self, Error> {
902        let mut writer = MaybeUninit::uninit();
903        let ptr = writer.as_mut_ptr();
904        let options = ManuallyDrop::new(CString::new(options.as_ref())?);
905        lib_czi_error(unsafe { libCZI_CreateWriter(ptr, options.as_ptr()) })?;
906        Ok(unsafe { Self::assume_init(writer) })
907    }
908
909    /// Initializes the writer object with the specified output stream object. The options string is a JSON-formatted string, here
910    /// is an example:
911    /// \\code
912    /// {
913    /// \"file_guid\" : \"123e4567-e89b-12d3-a456-426614174000\",
914    /// \"reserved_size_attachments_directory\" : 4096,
915    /// \"reserved_size_metadata_segment\" : 50000,
916    /// \"minimum_m_index\" : 0,
917    /// \"maximum_m_index\" : 100
918    /// }
919    /// \\endcode
920    ///
921    /// \\param \[out\] writer_object If the operation is successful, a handle to the newly created writer object is put here.
922    /// \\param       output_stream_object The output stream object to be used for writing the CZI data.
923    /// \\param       parameters       A JSON-formatted zero-terminated string (in UTF8-encoding) containing options for the writer initialization.
924    ///
925    /// \\returns An error-code indicating success or failure of the operation.
926    pub fn init<S: AsRef<str>>(
927        &self,
928        output_stream: &OutputStream,
929        parameters: S,
930    ) -> Result<(), Error> {
931        let parameters = ManuallyDrop::new(CString::new(parameters.as_ref())?);
932        lib_czi_error(unsafe {
933            libCZI_WriterCreate(**self, **output_stream, parameters.as_ptr())
934        })?;
935        Ok(())
936    }
937
938    /// Add the specified sub-block to the writer object. The sub-block information is provided in the 'add_sub_block_info_interop' structure.
939    ///
940    /// \\param  writer_object               The writer object.
941    /// \\param  add_sub_block_info_interop  Information describing the sub-block to be added.
942    ///
943    /// \\returns    An error-code indicating success or failure of the operation.
944    pub fn add_sub_block(&self, add_sub_block_info: AddSubBlockInfo) -> Result<(), Error> {
945        lib_czi_error(unsafe { libCZI_WriterAddSubBlock(**self, add_sub_block_info.as_ptr()) })?;
946        Ok(())
947    }
948
949    /// Add the specified attachment to the writer object. The attachment is provided in the 'add_attachment_info_interop' structure.
950    ///
951    /// \\param  writer_object               The writer object.
952    /// \\param  add_attachment_info_interop Information describing the attachment to be added.
953    ///
954    /// \\returns    An error-code indicating success or failure of the operation.
955    pub fn add_attachement(&self, add_attachment_info: AddAttachmentInfo) -> Result<(), Error> {
956        lib_czi_error(unsafe { libCZI_WriterAddAttachment(**self, add_attachment_info.as_ptr()) })?;
957        Ok(())
958    }
959
960    /// Add the specified metadata to the writer object. The metadata is provided in the 'write_metadata_info_interop' structure.
961    ///
962    /// \\param  writer_object               Handle to the writer object to which the metadata will be added.
963    /// \\param  write_metadata_info_interop Information describing the metadata to be added.
964    ///
965    /// \\returns    An error-code indicating success or failure of the operation.
966    pub fn write_metadata(&self, write_metadata_info: WriteMetadataInfo) -> Result<(), Error> {
967        lib_czi_error(unsafe { libCZI_WriterWriteMetadata(**self, write_metadata_info.as_ptr()) })?;
968        Ok(())
969    }
970
971    /// inalizes the CZI (i.e. writes out the final directory-segments) and closes the file.
972    /// Note that this method must be called explicitly in order to get a valid CZI - calling 'libCZI_ReleaseWriter' without
973    /// a prior call to this method will close the file immediately without finalization.
974    ///
975    /// \\param  writer_object   Handle to the writer object that is to be closed.
976    ///
977    /// \\returns    An error-code indicating success or failure of the operation.
978    pub fn close(&self) -> Result<(), Error> {
979        lib_czi_error(unsafe { libCZI_WriterClose(**self) })?;
980        Ok(())
981    }
982
983    /// Release the specified writer object.
984    ///
985    /// \\param  writer_object Handle to the writer object that is to be released.
986    ///
987    /// \\returns    An error-code indicating success or failure of the operation.
988    pub fn release(&self) -> Result<(), Error> {
989        lib_czi_error(unsafe { libCZI_ReleaseWriter(**self) })?;
990        Ok(())
991    }
992}
993
994impl Drop for CziWriter {
995    fn drop(&mut self) {
996        self.close().ok();
997        self.release().ok();
998    }
999}
1000
1001impl SingleChannelScalingTileAccessor {
1002    /// Gets the size information of the specified tile accessor based on the region of interest and zoom factor.
1003    ///
1004    /// \\param  accessor_object     Handle to the tile accessor object for which the size is to be calculated. This object is responsible for managing the access to the tiles within the specified plane.
1005    /// \\param  roi                 The region of interest that defines the region of interest within the plane for which the size is to be calculated.
1006    /// \\param  zoom                A floating-point value representing the zoom factor.
1007    /// \\param  size \[out\]          The size of the tile accessor. It contains width and height information.
1008    ///
1009    /// \\returns    An error-code indicating success or failure of the operation.
1010    pub fn calc_size(&self, roi: IntRect, zoom: f32) -> Result<IntSize, Error> {
1011        let mut size = MaybeUninit::uninit();
1012        let ptr = size.as_mut_ptr();
1013        lib_czi_error(unsafe {
1014            libCZI_SingleChannelTileAccessorCalcSize(**self, roi.as_ptr(), zoom, ptr)
1015        })?;
1016        Ok(unsafe { IntSize::assume_init(size) })
1017    }
1018
1019    /// Gets the tile bitmap of the specified plane and the specified roi with the specified zoom factor.
1020    ///
1021    /// \\param  accessor_object         Handle to the tile accessor object. This object is responsible for managing the access to the tiles within the specified plane.
1022    /// \\param  coordinate              Pointer to a `CoordinateInterop` structure that specifies the coordinates within the plane from which the tile bitmap is to be retrieved.
1023    /// \\param  roi                     The region of interest that defines within the plane for which the tile bitmap is requested.
1024    /// \\param  zoom                    A floating-point value representing the zoom factor.
1025    /// \\param  options                 A pointer to an AccessorOptionsInterop structure that may contain additional options for accessing the tile bitmap.
1026    /// \\param  bitmap_object \[out\]     If the operation is successful, the created bitmap object will be put here.
1027    ///
1028    /// \\returns    An error-code indicating success or failure of the operation.
1029    pub fn get(
1030        &self,
1031        coordinate: Coordinate,
1032        roi: IntRect,
1033        zoom: f32,
1034        options: AccessorOptions,
1035    ) -> Result<Bitmap, Error> {
1036        let mut bitmap = MaybeUninit::uninit();
1037        let ptr = bitmap.as_mut_ptr();
1038        lib_czi_error(unsafe {
1039            libCZI_SingleChannelTileAccessorGet(
1040                **self,
1041                coordinate.as_ptr(),
1042                roi.as_ptr(),
1043                zoom,
1044                options.as_ptr(),
1045                ptr,
1046            )
1047        })?;
1048        Ok(unsafe { Bitmap::assume_init(bitmap) })
1049    }
1050
1051    /// Release the specified accessor object.
1052    ///
1053    /// \\param  accessor_object      The accessor object.
1054    ///
1055    /// \\returns    An error-code indicating success or failure of the operation.
1056    pub fn release(&self) -> Result<(), Error> {
1057        lib_czi_error(unsafe { libCZI_ReleaseCreateSingleChannelTileAccessor(**self) })?;
1058        Ok(())
1059    }
1060}
1061
1062impl Drop for SingleChannelScalingTileAccessor {
1063    fn drop(&mut self) {
1064        self.release().ok();
1065    }
1066}
1067
1068impl DisplaySettings {
1069    /// Given a display-settings object and the channel-number, this function fills out the
1070    /// composition-channel-information which is needed for the multi-channel-composition.
1071    /// Note that in the returned 'CompositionChannelInfoInterop' structure, the 'lut' field is a pointer to the LUT-data,
1072    /// which must be freed with 'libCZI_Free' by the caller.
1073    ///
1074    /// \\param          display_settings_handle             The display settings handle.
1075    /// \\param          channel_index                       The channel-index (referring to the display settings object) we are concerned with.
1076    /// \\param          sixteen_or_eight_bits_lut           True for generating a 16-bit LUT; if false, then an 8-bit LUT is generated.
1077    /// \\param \[out\]    composition_channel_info_interop    The composition channel information is put here.
1078    ///
1079    /// \\returns    An error-code indicating success or failure of the operation.
1080    pub fn compositor_fill_out_composition_channel_info_interop(
1081        &self,
1082        channel_index: i32,
1083        sixteen_or_eight_bits_lut: bool,
1084    ) -> Result<CompositionChannelInfo, Error> {
1085        let mut composition_channel_info = MaybeUninit::uninit();
1086        let ptr = composition_channel_info.as_mut_ptr();
1087        lib_czi_error(unsafe {
1088            libCZI_CompositorFillOutCompositionChannelInfoInterop(
1089                **self,
1090                channel_index,
1091                sixteen_or_eight_bits_lut,
1092                ptr,
1093            )
1094        })?;
1095        Ok(unsafe { CompositionChannelInfo::assume_init(composition_channel_info) })
1096    }
1097
1098    pub fn get_channel_display_settings(
1099        &self,
1100        channel_id: i32,
1101    ) -> Result<ChannelDisplaySettings, Error> {
1102        let mut channel_display_setting = MaybeUninit::uninit();
1103        let ptr = channel_display_setting.as_mut_ptr();
1104        lib_czi_error(unsafe {
1105            libCZI_DisplaySettingsGetChannelDisplaySettings(**self, channel_id, ptr)
1106        })?;
1107        Ok(unsafe { ChannelDisplaySettings::assume_init(channel_display_setting) })
1108    }
1109
1110    /// Release the specified display settings object.
1111    ///
1112    /// \\param  display_settings_handle      The display settings object.
1113    ///
1114    /// \\returns    An error-code indicating success or failure of the operation.
1115    pub fn release(&self) -> Result<(), Error> {
1116        lib_czi_error(unsafe { libCZI_ReleaseDisplaySettings(**self) })?;
1117        Ok(())
1118    }
1119}
1120
1121impl Drop for DisplaySettings {
1122    fn drop(&mut self) {
1123        self.release().ok();
1124    }
1125}
1126
1127/// Perform a multi-channel-composition operation. The source bitmaps are provided in the 'source_bitmaps' array, and the
1128/// array of 'CompositionChannelInfoInterop' structures provide the information needed for the composition. The resulting bitmap
1129/// is then put into the 'bitmap_object' handle.
1130///
1131/// \\param       channelCount       The number of channels - this defines the size of the 'source_bitmaps' and 'channel_info' arrays.
1132/// \\param       source_bitmaps     The array of source bitmaps.
1133/// \\param       channel_info       The array of channel information.
1134/// \\param \[out\] bitmap_object      The resulting bitmap is put here.
1135///
1136/// \\return     An error-code indicating success or failure of the operation.
1137pub fn compositor_do_multi_channel_composition(
1138    channel_count: i32,
1139    source_bitmaps: Vec<Bitmap>,
1140    channel_info: CompositionChannelInfo,
1141) -> Result<Bitmap, Error> {
1142    let mut bitmap = MaybeUninit::uninit();
1143    let ptr = bitmap.as_mut_ptr();
1144    lib_czi_error(unsafe {
1145        libCZI_CompositorDoMultiChannelComposition(
1146            channel_count,
1147            source_bitmaps.as_ptr() as *const BitmapObjectHandle,
1148            channel_info.as_ptr(),
1149            ptr,
1150        )
1151    })?;
1152    Ok(unsafe { Bitmap::assume_init(bitmap) })
1153}
1154
1155impl ChannelDisplaySettings {
1156    /// Release the specified channel-display settings object.
1157    ///
1158    /// \\param  channel_display_settings_handle      The channel-display settings object.
1159    ///
1160    /// \\returns    An error-code indicating success or failure of the operation.
1161    pub fn release(&self) -> Result<(), Error> {
1162        lib_czi_error(unsafe { libCZI_ReleaseDisplaySettings(**self) })?;
1163        Ok(())
1164    }
1165}
1166
1167impl Drop for ChannelDisplaySettings {
1168    fn drop(&mut self) {
1169        self.release().ok();
1170    }
1171}