FFI - converting raw pointers to different types of slices

I'm trying to wrap a C library that runs a camera. When I try to get the image buffer I get a *const u8 back from the C library. I want to convert this to some kind of reference to a slice (usually &[16]) and save it to a TIFF. I've tried a couple things, but none of them give me the right results.

I've tried std::slice::from_raw_parts although I know I shouldn't do this because because buf wasn't allocated by Rust:

let s = std::slice::from_raw_parts(buf as *mut u16, size/2);

I tried bytemuck:

let v = std::slice::from_raw_parts(buf as *mut u8, size);
let b: &[u16]= bytemuck::try_cast_slice(v).unwrap();

In both cases I looked at the histogram of the image and it looks like the values are clipped and the images are too dark.

What's the right way to do this?

If you just make a slice, it doesn't need to be allocated by rust. Who allocated it only matters when you go to deallocate it, and slices don't do that. from_raw_parts is the way to go.

2 Likes

What format is the data you're getting from the library? Are you encoding it to TIFF or just writing the data directly to a file?

1 Like

This makes me wonder if you have a byte order or other encoding mismatch.

4 Likes

You might be running into endianness issues— Depending on the specifics of how the external library and TIFF writer work, the high and low bytes might be getting swapped.

1 Like

I was thinking the same thing, but I carefully made sure everything was LE. I actually figured it out by using an example program from the vendor and learning that most of the data is indeed in the lower bits and that it needs to be normalized.