nvtiff_sys/
result.rs

1//! A thin wrapper around [`nvtiffStatus_t`] providing [Result]s with [`NvTiffError`].
2#![warn(missing_docs)]
3use crate::nvtiffStatus_t;
4
5/// Result of an nvTIFF API call
6pub type NvTiffResult<T> = Result<T, NvTiffError>;
7
8/// Errors from an nvTIFF API call
9#[derive(Debug)]
10#[non_exhaustive]
11pub enum NvTiffError {
12    /// An error occured while decoding the TIFF image.
13    StatusError(NvTiffStatusError),
14}
15
16/// nvTIFF Decode API non-zero return status codes
17///
18/// Based on
19/// <https://docs.nvidia.com/cuda/nvtiff/userguide.html#decode-api-return-status-codes>
20#[derive(Debug, Eq, PartialEq)]
21#[non_exhaustive]
22pub enum NvTiffStatusError {
23    /// The library handle was not initialized.
24    NotInitialized, // 1
25    /// Wrong parameter was passed. For example, a null pointer as input data, or an
26    /// invalid enum value.
27    InvalidParameter, // 2
28    /// Cannot parse the TIFF stream. Likely due to a corruption that cannot be handled.
29    BadTiff, // 3
30    /// Attempting to decode a TIFF stream that is not supported by the nvTIFF library.
31    TiffNotSupported, // 4
32    /// The user-provided allocator functions, for either memory allocation or for
33    /// releasing the memory, returned a non-zero code.
34    AllocatorFailure, // 5
35    /// Error during the execution of the device tasks.
36    ExecutionFailed, // 6
37    /// The device capabilities are not enough for the set of input parameters provided.
38    ArchMismatch, // 7
39    /// Unknown error occured in the library.
40    InternalError, // 8
41    /// nvTiff is unable to load the nvcomp library.
42    NvcompNotFound, // 9
43    /// nvTiff is unable to load the nvjpeg library.
44    NvjpegNotFound, // 10
45    /// nvTiff is unable to find information about the provided tag.
46    TagNotFound, // 11
47    /// Provided parameter is outside the range of possible values.
48    ParameterOutOfBounds, // 12
49    /// nvTiff is unable to load the nvJPEG2000 library.
50    Nvjpeg2kNotFound, // 13
51
52    /// A custom (or unimplemented) error that does not fall under any other nvTIFF
53    /// status error kind.
54    Other(u32),
55}
56
57/// Trait for checking nvTIFF API return status codes
58pub trait NvTiffResultCheck {
59    /// Check if the nvTIFF API call has finished successfully.
60    ///
61    /// # Errors
62    /// Will return [`NvTiffError`] if the status code is non-zero.
63    fn result(self) -> NvTiffResult<()>;
64}
65
66impl NvTiffResultCheck for nvtiffStatus_t::Type {
67    /// Check if the nvTIFF Decode API call has finished successfully. Note that many of
68    /// the calls are asynchronous and some of the errors may be seen only after
69    /// synchronization.
70    ///
71    /// # Errors
72    /// Will return [`NvTiffError::StatusError`] if the status code is non-zero.
73    fn result(self) -> NvTiffResult<()> {
74        match self {
75            nvtiffStatus_t::NVTIFF_STATUS_SUCCESS => Ok(()),
76            nvtiffStatus_t::NVTIFF_STATUS_NOT_INITIALIZED => {
77                Err(NvTiffError::StatusError(NvTiffStatusError::NotInitialized))
78            }
79            nvtiffStatus_t::NVTIFF_STATUS_INVALID_PARAMETER => Err(NvTiffError::StatusError(
80                NvTiffStatusError::InvalidParameter,
81            )),
82            nvtiffStatus_t::NVTIFF_STATUS_BAD_TIFF => {
83                Err(NvTiffError::StatusError(NvTiffStatusError::BadTiff))
84            }
85            nvtiffStatus_t::NVTIFF_STATUS_TIFF_NOT_SUPPORTED => Err(NvTiffError::StatusError(
86                NvTiffStatusError::TiffNotSupported,
87            )),
88            nvtiffStatus_t::NVTIFF_STATUS_ALLOCATOR_FAILURE => Err(NvTiffError::StatusError(
89                NvTiffStatusError::AllocatorFailure,
90            )),
91            nvtiffStatus_t::NVTIFF_STATUS_EXECUTION_FAILED => {
92                Err(NvTiffError::StatusError(NvTiffStatusError::ExecutionFailed))
93            }
94            nvtiffStatus_t::NVTIFF_STATUS_ARCH_MISMATCH => {
95                Err(NvTiffError::StatusError(NvTiffStatusError::ArchMismatch))
96            }
97            nvtiffStatus_t::NVTIFF_STATUS_INTERNAL_ERROR => {
98                Err(NvTiffError::StatusError(NvTiffStatusError::InternalError))
99            }
100            nvtiffStatus_t::NVTIFF_STATUS_NVCOMP_NOT_FOUND => {
101                Err(NvTiffError::StatusError(NvTiffStatusError::NvcompNotFound))
102            }
103            nvtiffStatus_t::NVTIFF_STATUS_NVJPEG_NOT_FOUND => {
104                Err(NvTiffError::StatusError(NvTiffStatusError::NvjpegNotFound))
105            }
106            nvtiffStatus_t::NVTIFF_STATUS_TAG_NOT_FOUND => {
107                Err(NvTiffError::StatusError(NvTiffStatusError::TagNotFound))
108            }
109            nvtiffStatus_t::NVTIFF_STATUS_PARAMETER_OUT_OF_BOUNDS => Err(NvTiffError::StatusError(
110                NvTiffStatusError::ParameterOutOfBounds,
111            )),
112            nvtiffStatus_t::NVTIFF_STATUS_NVJPEG2K_NOT_FOUND => Err(NvTiffError::StatusError(
113                NvTiffStatusError::Nvjpeg2kNotFound,
114            )),
115            // Unknown nvTIFF decode API status code
116            status_code => Err(NvTiffError::StatusError(NvTiffStatusError::Other(
117                status_code,
118            ))),
119        }
120    }
121}
122
123#[cfg(test)]
124mod tests {
125    use std::ffi::CString;
126
127    use crate::{
128        NvTiffResultCheck, nvtiffStatus_t, nvtiffStream, nvtiffStreamCreate,
129        nvtiffStreamParseFromFile,
130    };
131
132    #[test]
133    fn test_nvtiff_status_result() {
134        let mut stream = std::mem::MaybeUninit::uninit();
135        let tiff_stream: *mut *mut nvtiffStream = stream.as_mut_ptr();
136
137        // Check return code = 0 success
138        let status_create: nvtiffStatus_t::Type = unsafe { nvtiffStreamCreate(tiff_stream) };
139        dbg!(status_create); // should be 0=SUCCESS
140        assert!(status_create.result().is_ok());
141
142        let tiff_cstr = CString::new("images/invalid.tif").unwrap();
143        let tiff_path: *const std::os::raw::c_char = tiff_cstr.as_ptr();
144
145        // Check return code >= 1 failure
146        let status_parse: nvtiffStatus_t::Type =
147            unsafe { nvtiffStreamParseFromFile(tiff_path, *tiff_stream) };
148        dbg!(status_parse); // should be 2=NVTIFF_STATUS_INVALID_PARAMETER
149        assert!(status_parse.result().is_err());
150    }
151
152    #[test]
153    fn test_nvtiff_other_error() {
154        let status_unknown: nvtiffStatus_t::Type = 42; // mock unimplemented status code
155        dbg!(status_unknown); // should be 42=?
156        assert!(status_unknown.result().is_err());
157    }
158}