From bb2aa4ce9b0fc18af8070efa55aca5e80fd18734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kornel=20Lesi=C5=84ski?= Date: Mon, 16 Jul 2018 15:26:30 +0100 Subject: [PATCH] Avoid slow modulo --- src/reduction/alpha.rs | 16 +++++++++------- src/reduction/color.rs | 12 +++++++----- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/reduction/alpha.rs b/src/reduction/alpha.rs index de1499cd..18248271 100644 --- a/src/reduction/alpha.rs +++ b/src/reduction/alpha.rs @@ -1,12 +1,14 @@ use png::PngData; -pub fn reduce_alpha_channel(png: &mut PngData, channels: usize) -> Option> { - let byte_depth: u8 = png.ihdr_data.bit_depth.as_u8() >> 3; - let bpp: usize = channels * byte_depth as usize; - let colored_bytes = bpp - byte_depth as usize; +pub fn reduce_alpha_channel(png: &mut PngData, channels: u8) -> Option> { + let byte_depth = png.ihdr_data.bit_depth.as_u8() >> 3; + let bpp = channels * byte_depth; + let bpp_mask = bpp - 1; + assert_eq!(0, bpp & bpp_mask); + let colored_bytes = bpp - byte_depth; for line in png.scan_lines() { for (i, &byte) in line.data.iter().enumerate() { - if i % bpp >= colored_bytes { + if i as u8 & bpp_mask >= colored_bytes { if byte != 255 { return None; } @@ -18,7 +20,7 @@ pub fn reduce_alpha_channel(png: &mut PngData, channels: usize) -> Option= colored_bytes { + if i as u8 & bpp_mask >= colored_bytes { continue; } else { reduced.push(byte); @@ -29,7 +31,7 @@ pub fn reduce_alpha_channel(png: &mut PngData, channels: usize) -> Option bool { pub fn reduce_rgba_to_grayscale_alpha(png: &mut PngData) -> bool { let mut reduced = Vec::with_capacity(png.raw_data.len()); - let byte_depth: u8 = png.ihdr_data.bit_depth.as_u8() >> 3; - let bpp: usize = 4 * byte_depth as usize; - let colored_bytes = bpp - byte_depth as usize; + let byte_depth = png.ihdr_data.bit_depth.as_u8() >> 3; + let bpp = 4 * byte_depth; + let bpp_mask = bpp - 1; + assert_eq!(0, bpp & bpp_mask); + let colored_bytes = bpp - byte_depth; for line in png.scan_lines() { reduced.push(line.filter); let mut low_bytes = Vec::with_capacity(4); let mut high_bytes = Vec::with_capacity(4); let mut trans_bytes = Vec::with_capacity(byte_depth as usize); for (i, byte) in line.data.iter().enumerate() { - if i % bpp < colored_bytes { + if i as u8 & bpp_mask < colored_bytes { if byte_depth == 1 || i % 2 == 1 { low_bytes.push(*byte); } else { @@ -35,7 +37,7 @@ pub fn reduce_rgba_to_grayscale_alpha(png: &mut PngData) -> bool { trans_bytes.push(*byte); } - if i % bpp == bpp - 1 { + if (i as u8 & bpp_mask) == bpp - 1 { if low_bytes.iter().unique().count() > 1 { return false; }