kornelski / imgref

A trivial Rust struct for interchange of pixel buffers with width, height & stride
https://lib.rs/crates/imgref
Apache License 2.0
59 stars 6 forks source link

Limitation of pixel-sized instead of byte-sized `stride`. #23

Open axxel opened 5 months ago

axxel commented 5 months ago

I recently implemented a Rust wrapper for my zxing-cpp barcode scanning library. On the c++ side I have the ImageView class that I needed to wrap/replace in Rust. I thought about using ImgRef for that but came to the conclusion that the pixel-sized stride implementation is not general enough. You explicitly mention video frame buffers as a potential input but it seems to me your decision to define the stride as a factor for sizeof(Pixel) does prohibit that use case in general.

Say you have an RGB frame buffer (3 bytes per pixel) of size 2x2 but your video hardware insist to start each row on a 4-byte aligned address. So the first row starts at address p : *const u8, then the next starts at p + 8 but you can't specify that as an ImgRef.

I understand that this is a consequence of defining your underlying container as a series of pixels instead of u8 data. Do you know of an alternative to ImgRef that allows that? Is this use-case so niche that no-one needs it anyway? I believe the QImage class from qt also has this internal memory layout.

kornelski commented 5 months ago

Yes, I'm aware of this limitation. It's not possible to fix it in this crate. I don't know if there's a replacement, but you can roll your own.

If you're going to implement a generic one, be careful that &T in Rust is not allowed to be unaligned. You may also need &[MaybeUninit<u8>] type for the data if padding may be uninitialized.

gabm commented 4 months ago

I also came across this limitation. As most image processing libraries I came across use strides in bytes, they should not be in pixels imho...

kornelski commented 4 months ago

I've started work on v2 of imgref, with support for byte offsets, as well as custom container types, and different integer sizes for the dimensions.

Currently it's very incomplete, unsafe, and crashing:

https://github.com/kornelski/imgref/compare/v2-preview

but if you're interested you can take it as a starting point, or contribute to it.