YaLTeR / vapoursynth-rs

A safe Rust wrapper for VapourSynth.
Apache License 2.0
31 stars 8 forks source link

Better support for non-mod32 frame widths #18

Closed quietvoid closed 2 years ago

quietvoid commented 2 years ago

Currently, it's impossible to request a frame that has a non mod32 width. For example, 1410x1080 fails with NonZeroPadding(30) but 1408x1080 and 1440x1080 both work fine.

YaLTeR commented 2 years ago

Do you mean Frame::plane()? It checks for non-zero padding because I made the safe assumption that padding bytes might be uninitialized, and accessing uninitialized data is undefined behavior. You can always get individual rows with Frame::plane_row().

quietvoid commented 2 years ago

Ah yes, I do mean Frame::plane(). I'm currently iterating over every pixel, perhaps I can make myself a helper using plane_row.

Will try and if it works I'll close this.

YaLTeR commented 2 years ago

I think the documentation for plane() should mention plane_row() as a way to access pixel data regardless of padding.

quietvoid commented 2 years ago

It wasn't too complicated using rows, and now I can request any mod2 resolution plane. Thanks for the tip.

For my usecase, converting a FrameRef into a image::ImageBuffer:

let mut buf = ImageBuffer::new(w as u32, h as u32);

buf.enumerate_rows_mut().for_each(|(i, pixels)| {
    let row = i as usize;
    let r: &[u8] = frame.plane_row(0, row);
    let g: &[u8] = frame.plane_row(1, row);
    let b: &[u8] = frame.plane_row(2, row);

    pixels.for_each(|(x, _, p)| {
        let x = x as usize;
        *p = image::Rgb([r[x], g[x], b[x]])
    });
});