#[derive(Debug, Clone, Copy)] pub struct Image<'a> { pub width: u32, pub height: u32, pub data: &'a [u8], } #[derive(Debug)] pub struct ImageMut<'a> { pub width: u32, pub height: u32, pub data: &'a mut [u8], } impl ImageMut<'_> { pub fn composite_alpha(&mut self, src: &Image<'_>) { assert_eq!(self.width, src.width); assert_eq!(self.height, src.height); fn fixp_mul(a: u8, b: u8) -> u8 { ((a as u16 * b as u16 + 255) >> 8) as u8 } fn alpha_blend(dst: u8, src: u8, alpha: u8) -> u8 { fixp_mul(src, alpha) + fixp_mul(dst, 255 - alpha) } for (dst_rgba, src_rgba) in self.data.chunks_exact_mut(4).zip(src.data.chunks_exact(4)) { let src_alpha = src_rgba[3]; dst_rgba[0] = alpha_blend(dst_rgba[0], src_rgba[0], src_alpha); dst_rgba[1] = alpha_blend(dst_rgba[1], src_rgba[1], src_alpha); dst_rgba[2] = alpha_blend(dst_rgba[2], src_rgba[2], src_alpha); dst_rgba[3] = alpha_blend(dst_rgba[3], src_rgba[3], src_alpha); } } }