From 1bca930ddb3338af6f8be5aa9c2b1d5c5a93997b Mon Sep 17 00:00:00 2001 From: Topi Kainulainen Date: Sat, 10 Feb 2024 23:04:56 +0200 Subject: [PATCH 1/2] Fix avif odd width/height handling --- src/codecs/avif/decoder.rs | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/codecs/avif/decoder.rs b/src/codecs/avif/decoder.rs index f8ff0c4410..b599b3e6ad 100644 --- a/src/codecs/avif/decoder.rs +++ b/src/codecs/avif/decoder.rs @@ -113,7 +113,7 @@ impl<'a, R: 'a + Read> ImageDecoder<'a> for AvifDecoder { let pixel_format = match self.picture.pixel_layout() { PixelLayout::I400 => todo!(), PixelLayout::I420 => dcp::PixelFormat::I420, - PixelLayout::I422 => dcp::PixelFormat::I422, + PixelLayout::I422 => todo!(), PixelLayout::I444 => dcp::PixelFormat::I444, }; let src_format = dcp::ImageFormat { @@ -127,29 +127,53 @@ impl<'a, R: 'a + Read> ImageDecoder<'a> for AvifDecoder { num_planes: 1, }; let (width, height) = self.dimensions(); + + // Round up to the nearest multiple of 2 + let (rounded_width, rounded_height) = + (((width + 2 - 1) / 2) * 2, ((height + 2 - 1) / 2) * 2); + let planes = &[ self.picture.plane(PlanarImageComponent::Y), self.picture.plane(PlanarImageComponent::U), self.picture.plane(PlanarImageComponent::V), ]; - let src_buffers = planes.iter().map(AsRef::as_ref).collect::>(); + let mut src_buffers = planes.iter().map(|p| p.to_vec()).collect::>(); let strides = &[ self.picture.stride(PlanarImageComponent::Y) as usize, self.picture.stride(PlanarImageComponent::U) as usize, self.picture.stride(PlanarImageComponent::V) as usize, ]; - let dst_buffers = &mut [&mut buf[..]]; + + if rounded_height != height { + let len = src_buffers[0].len(); + src_buffers[0].resize(len + strides[0], 0u8); + } + + let mut tmp_buf: Vec = Vec::new(); + tmp_buf.resize(rounded_width as usize * rounded_height as usize * 4, 0u8); + let mut tmp_buf_wrapper = [tmp_buf.as_mut_slice()]; + + let src_buffers = src_buffers.iter().map(AsRef::as_ref).collect::>(); + dcp::convert_image( - width, - height, + rounded_width, + rounded_height, &src_format, Some(strides), &src_buffers, &dst_format, None, - dst_buffers, + &mut tmp_buf_wrapper, ) .map_err(error_map)?; + + for l in 0..height as usize { + let src = l * rounded_width as usize * 4 + ..l * rounded_width as usize * 4 + width as usize * 4; + let dst = l * width as usize * 4..l * width as usize * 4 + width as usize * 4; + + buf[dst].clone_from_slice(&tmp_buf[src]); + } } else { let plane = self.picture.plane(PlanarImageComponent::Y); buf.copy_from_slice(plane.as_ref()); From 9daf113553277750ccf453ff908264f43043b01b Mon Sep 17 00:00:00 2001 From: Topi Kainulainen Date: Sat, 10 Feb 2024 23:42:27 +0200 Subject: [PATCH 2/2] Fixed clippy error --- src/codecs/avif/decoder.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/codecs/avif/decoder.rs b/src/codecs/avif/decoder.rs index b599b3e6ad..986a0e934f 100644 --- a/src/codecs/avif/decoder.rs +++ b/src/codecs/avif/decoder.rs @@ -149,8 +149,7 @@ impl<'a, R: 'a + Read> ImageDecoder<'a> for AvifDecoder { src_buffers[0].resize(len + strides[0], 0u8); } - let mut tmp_buf: Vec = Vec::new(); - tmp_buf.resize(rounded_width as usize * rounded_height as usize * 4, 0u8); + let mut tmp_buf = vec![0u8; rounded_width as usize * rounded_height as usize * 4]; let mut tmp_buf_wrapper = [tmp_buf.as_mut_slice()]; let src_buffers = src_buffers.iter().map(AsRef::as_ref).collect::>();