premultiply.rs (1664B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 // These are slow. Gecko's gfx/2d/Swizzle.cpp has better versions 6 pub fn premultiply(data: &mut [u8]) { 7 for pixel in data.chunks_mut(4) { 8 let a = pixel[3] as u32; 9 let b = pixel[2] as u32; 10 let g = pixel[1] as u32; 11 let r = pixel[0] as u32; 12 13 pixel[3] = a as u8; 14 pixel[2] = ((r * a + 128) / 255) as u8; 15 pixel[1] = ((g * a + 128) / 255) as u8; 16 pixel[0] = ((b * a + 128) / 255) as u8; 17 } 18 } 19 20 #[allow(unused)] 21 pub fn unpremultiply(data: &mut [u8]) { 22 for pixel in data.chunks_mut(4) { 23 let a = pixel[3] as u32; 24 let mut b = pixel[2] as u32; 25 let mut g = pixel[1] as u32; 26 let mut r = pixel[0] as u32; 27 28 if a > 0 { 29 r = r * 255 / a; 30 g = g * 255 / a; 31 b = b * 255 / a; 32 } 33 34 pixel[3] = a as u8; 35 pixel[2] = r as u8; 36 pixel[1] = g as u8; 37 pixel[0] = b as u8; 38 } 39 } 40 41 #[test] 42 fn it_works() { 43 let mut f = [0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0x00, 0x80]; 44 premultiply(&mut f); 45 println!("{:?}", f); 46 assert!( 47 f[0] == 0x80 && f[1] == 0x80 && f[2] == 0x80 && f[3] == 0x80 && f[4] == 0x00 && 48 f[5] == 0x80 && f[6] == 0x00 && f[7] == 0x80 49 ); 50 unpremultiply(&mut f); 51 println!("{:?}", f); 52 assert!( 53 f[0] == 0xff && f[1] == 0xff && f[2] == 0xff && f[3] == 0x80 && f[4] == 0x00 && 54 f[5] == 0xff && f[6] == 0x00 && f[7] == 0x80 55 ); 56 }