use std::sync::Arc;
use cudarc::driver::{CudaContext, CudaSlice, CudaStream, DevicePtrMut, DriverError};
use nvtiff_sys::{
nvtiffDecodeCheckSupported, nvtiffDecodeImage, nvtiffDecodeParams, nvtiffDecodeParamsCreate,
nvtiffDecoder, nvtiffDecoderCreateSimple, nvtiffStatus, nvtiffStream, nvtiffStreamCreate,
nvtiffStreamParseFromFile,
};
#[test]
fn decode_image() -> Result<(), DriverError> {
let mut host_stream = std::mem::MaybeUninit::uninit();
let mut tiff_stream: *mut nvtiffStream = host_stream.as_mut_ptr();
let status_cpustream: nvtiffStatus::Type = unsafe { nvtiffStreamCreate(&raw mut tiff_stream) };
assert_eq!(status_cpustream, nvtiffStatus::NVTIFF_STATUS_SUCCESS);
let ctx: Arc<CudaContext> = cudarc::driver::CudaContext::new(0)?; let stream: Arc<CudaStream> = ctx.default_stream();
let cuda_stream: *mut nvtiff_sys::CUstream_st = stream.cu_stream().cast::<_>();
let mut decoder_handle = std::mem::MaybeUninit::uninit();
let mut nvtiff_decoder: *mut nvtiffDecoder = decoder_handle.as_mut_ptr();
let status_decoder: u32 =
unsafe { nvtiffDecoderCreateSimple(&raw mut nvtiff_decoder, cuda_stream) };
dbg!(status_decoder);
assert_eq!(status_decoder, nvtiffStatus::NVTIFF_STATUS_SUCCESS);
let tiff_cstr = std::ffi::CString::new("images/float32.tif").expect("CString::new failed");
let tiff_path: *const std::os::raw::c_char = tiff_cstr.as_ptr();
let status_parse: u32 = unsafe { nvtiffStreamParseFromFile(tiff_path, tiff_stream) };
dbg!(status_parse);
assert_eq!(status_parse, nvtiffStatus::NVTIFF_STATUS_SUCCESS);
let mut params = std::mem::MaybeUninit::uninit();
let mut decode_params: *mut nvtiffDecodeParams = params.as_mut_ptr();
let status_param: u32 = unsafe { nvtiffDecodeParamsCreate(&raw mut decode_params) };
dbg!(status_param);
assert_eq!(status_param, nvtiffStatus::NVTIFF_STATUS_SUCCESS);
let status_check: u32 = unsafe {
nvtiffDecodeCheckSupported(
tiff_stream,
nvtiff_decoder,
decode_params,
0, )
};
dbg!(status_check);
assert_eq!(status_check, nvtiffStatus::NVTIFF_STATUS_SUCCESS);
let image_size: usize = 3 * 2 * 4; let mut image_stream: CudaSlice<u8> = stream.alloc_zeros::<u8>(image_size)?;
let image_ptr: u64 = image_stream.device_ptr_mut(&stream).0;
let image_out_d = image_ptr as *mut std::ffi::c_void;
let status_decode: u32 = unsafe {
nvtiffDecodeImage(
tiff_stream,
nvtiff_decoder,
decode_params,
0, image_out_d,
cuda_stream,
)
};
dbg!(status_decode); assert_eq!(status_decode, nvtiffStatus::NVTIFF_STATUS_SUCCESS);
let mut image_out_h: Vec<u8> = vec![0; image_size];
stream.memcpy_dtoh(&image_stream, &mut image_out_h)?;
dbg!(image_out_h.clone());
let float_array: Vec<f32> = image_out_h
.chunks_exact(4)
.map(TryInto::try_into)
.map(Result::unwrap)
.map(f32::from_le_bytes)
.collect();
assert_eq!(float_array, vec![1.41, 1.23, 0.78, 0.32, -0.23, -1.88]);
Ok(())
}