summaryrefslogtreecommitdiffstats
path: root/gfx/wr/wrench/src/premultiply.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gfx/wr/wrench/src/premultiply.rs56
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
+ );
+}