libczirw_sys/
functions.rs

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