diff options
Diffstat (limited to 'components/pixels/lib.rs')
-rw-r--r-- | components/pixels/lib.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/components/pixels/lib.rs b/components/pixels/lib.rs index 7cba060ec74..24386ff830a 100644 --- a/components/pixels/lib.rs +++ b/components/pixels/lib.rs @@ -84,6 +84,7 @@ pub fn rgba8_premultiply_inplace(pixels: &mut [u8]) -> bool { is_opaque } +#[inline(always)] pub fn multiply_u8_color(a: u8, b: u8) -> u8 { (a as u32 * b as u32 / 255) as u8 } @@ -254,6 +255,69 @@ pub fn unmultiply_inplace<const SWAP_RB: bool>(pixels: &mut [u8]) { } } +#[repr(u8)] +pub enum Multiply { + None = 0, + PreMultiply = 1, + UnMultiply = 2, +} + +pub fn transform_inplace(pixels: &mut [u8], multiply: Multiply, swap_rb: bool, clear_alpha: bool) { + match (multiply, swap_rb, clear_alpha) { + (Multiply::None, true, true) => generic_transform_inplace::<0, true, true>(pixels), + (Multiply::None, true, false) => generic_transform_inplace::<0, true, false>(pixels), + (Multiply::None, false, true) => generic_transform_inplace::<0, false, true>(pixels), + (Multiply::None, false, false) => generic_transform_inplace::<0, false, false>(pixels), + (Multiply::PreMultiply, true, true) => generic_transform_inplace::<1, true, true>(pixels), + (Multiply::PreMultiply, true, false) => generic_transform_inplace::<1, true, false>(pixels), + (Multiply::PreMultiply, false, true) => generic_transform_inplace::<1, false, true>(pixels), + (Multiply::PreMultiply, false, false) => { + generic_transform_inplace::<1, false, false>(pixels) + }, + (Multiply::UnMultiply, true, true) => generic_transform_inplace::<2, true, true>(pixels), + (Multiply::UnMultiply, true, false) => generic_transform_inplace::<2, true, false>(pixels), + (Multiply::UnMultiply, false, true) => generic_transform_inplace::<2, false, true>(pixels), + (Multiply::UnMultiply, false, false) => { + generic_transform_inplace::<2, false, false>(pixels) + }, + } +} + +pub fn generic_transform_inplace< + const MULTIPLY: u8, // 1 premultiply, 2 unmultiply + const SWAP_RB: bool, + const CLEAR_ALPHA: bool, +>( + pixels: &mut [u8], +) { + for rgba in pixels.chunks_mut(4) { + match MULTIPLY { + 1 => { + let a = rgba[3]; + multiply_u8_color(rgba[0], a); + multiply_u8_color(rgba[1], a); + multiply_u8_color(rgba[2], a); + }, + 2 => { + let a = rgba[3] as u32; + + if a > 0 { + rgba[0] = (rgba[0] as u32 * 255 / a) as u8; + rgba[1] = (rgba[1] as u32 * 255 / a) as u8; + rgba[2] = (rgba[2] as u32 * 255 / a) as u8; + } + }, + _ => {}, + } + if SWAP_RB { + rgba.swap(0, 2); + } + if CLEAR_ALPHA { + rgba[3] = u8::MAX; + } + } +} + fn is_gif(buffer: &[u8]) -> bool { buffer.starts_with(b"GIF87a") || buffer.starts_with(b"GIF89a") } |