diff options
Diffstat (limited to 'gfx/wr/wrench/src/premultiply.rs')
-rw-r--r-- | gfx/wr/wrench/src/premultiply.rs | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/gfx/wr/wrench/src/premultiply.rs b/gfx/wr/wrench/src/premultiply.rs new file mode 100644 index 0000000000..04f43add56 --- /dev/null +++ b/gfx/wr/wrench/src/premultiply.rs @@ -0,0 +1,56 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// These are slow. Gecko's gfx/2d/Swizzle.cpp has better versions +pub fn premultiply(data: &mut [u8]) { + for pixel in data.chunks_mut(4) { + let a = pixel[3] as u32; + let b = pixel[2] as u32; + let g = pixel[1] as u32; + let r = pixel[0] as u32; + + pixel[3] = a as u8; + pixel[2] = ((r * a + 128) / 255) as u8; + pixel[1] = ((g * a + 128) / 255) as u8; + pixel[0] = ((b * a + 128) / 255) as u8; + } +} + +#[allow(unused)] +pub fn unpremultiply(data: &mut [u8]) { + for pixel in data.chunks_mut(4) { + let a = pixel[3] as u32; + let mut b = pixel[2] as u32; + let mut g = pixel[1] as u32; + let mut r = pixel[0] as u32; + + if a > 0 { + r = r * 255 / a; + g = g * 255 / a; + b = b * 255 / a; + } + + pixel[3] = a as u8; + pixel[2] = r as u8; + pixel[1] = g as u8; + pixel[0] = b as u8; + } +} + +#[test] +fn it_works() { + let mut f = [0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0x00, 0x80]; + premultiply(&mut f); + println!("{:?}", f); + assert!( + f[0] == 0x80 && f[1] == 0x80 && f[2] == 0x80 && f[3] == 0x80 && f[4] == 0x00 && + f[5] == 0x80 && f[6] == 0x00 && f[7] == 0x80 + ); + unpremultiply(&mut f); + println!("{:?}", f); + assert!( + f[0] == 0xff && f[1] == 0xff && f[2] == 0xff && f[3] == 0x80 && f[4] == 0x00 && + f[5] == 0xff && f[6] == 0x00 && f[7] == 0x80 + ); +} |