Skip to content

Commit

Permalink
Merge pull request #2385 from awxkee/yuv-stride-fix
Browse files Browse the repository at this point in the history
Fix YUV 4:2:0, 4:2:2 large strides
  • Loading branch information
HeroicKatora authored Nov 27, 2024
2 parents 2c986d3 + 45767ee commit 5080752
Showing 1 changed file with 17 additions and 7 deletions.
24 changes: 17 additions & 7 deletions src/codecs/avif/yuv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,13 +521,23 @@ fn process_halved_chroma_row<

let max_value = (1 << BIT_DEPTH) - 1;

// If the stride is larger than the plane size,
// it might contain junk data beyond the actual valid region.
// To avoid processing artifacts when working with odd-sized images,
// the buffer is reshaped to its actual size,
// preventing accidental use of invalid values from the trailing region.

let y_plane = &image.y_plane[0..image.width];
let chroma_size = image.width.div_ceil(2);
let u_plane = &image.u_plane[0..chroma_size];
let v_plane = &image.v_plane[0..chroma_size];
let rgba = &mut rgba[0..image.width * CHANNELS];

let bias_y = range.bias_y as i32;
let bias_uv = range.bias_uv as i32;
let y_iter = image.y_plane.chunks_exact(2);
let y_iter = y_plane.chunks_exact(2);
let rgb_chunks = rgba.chunks_exact_mut(CHANNELS * 2);
for (((y_src, &u_src), &v_src), rgb_dst) in
y_iter.zip(image.u_plane).zip(image.v_plane).zip(rgb_chunks)
{
for (((y_src, &u_src), &v_src), rgb_dst) in y_iter.zip(u_plane).zip(v_plane).zip(rgb_chunks) {
let y_value: i32 = (y_src[0].as_() - bias_y) * y_coef;
let cb_value: i32 = u_src.as_() - bias_uv;
let cr_value: i32 = v_src.as_() - bias_uv;
Expand Down Expand Up @@ -571,13 +581,13 @@ fn process_halved_chroma_row<

// Process remainder if width is odd.
if image.width & 1 != 0 {
let y_left = image.y_plane.chunks_exact(2).remainder();
let y_left = y_plane.chunks_exact(2).remainder();
let rgb_chunks = rgba
.chunks_exact_mut(CHANNELS * 2)
.into_remainder()
.chunks_exact_mut(CHANNELS);
let u_iter = image.u_plane.iter().rev();
let v_iter = image.v_plane.iter().rev();
let u_iter = u_plane.iter().rev();
let v_iter = v_plane.iter().rev();

for (((y_src, u_src), v_src), rgb_dst) in
y_left.iter().zip(u_iter).zip(v_iter).zip(rgb_chunks)
Expand Down

0 comments on commit 5080752

Please sign in to comment.