Avoid slow modulo
This commit is contained in:
parent
96889d6917
commit
bb2aa4ce9b
2 changed files with 16 additions and 12 deletions
|
|
@ -1,12 +1,14 @@
|
||||||
use png::PngData;
|
use png::PngData;
|
||||||
|
|
||||||
pub fn reduce_alpha_channel(png: &mut PngData, channels: usize) -> Option<Vec<u8>> {
|
pub fn reduce_alpha_channel(png: &mut PngData, channels: u8) -> Option<Vec<u8>> {
|
||||||
let byte_depth: u8 = png.ihdr_data.bit_depth.as_u8() >> 3;
|
let byte_depth = png.ihdr_data.bit_depth.as_u8() >> 3;
|
||||||
let bpp: usize = channels * byte_depth as usize;
|
let bpp = channels * byte_depth;
|
||||||
let colored_bytes = bpp - byte_depth as usize;
|
let bpp_mask = bpp - 1;
|
||||||
|
assert_eq!(0, bpp & bpp_mask);
|
||||||
|
let colored_bytes = bpp - byte_depth;
|
||||||
for line in png.scan_lines() {
|
for line in png.scan_lines() {
|
||||||
for (i, &byte) in line.data.iter().enumerate() {
|
for (i, &byte) in line.data.iter().enumerate() {
|
||||||
if i % bpp >= colored_bytes {
|
if i as u8 & bpp_mask >= colored_bytes {
|
||||||
if byte != 255 {
|
if byte != 255 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
@ -18,7 +20,7 @@ pub fn reduce_alpha_channel(png: &mut PngData, channels: usize) -> Option<Vec<u8
|
||||||
for line in png.scan_lines() {
|
for line in png.scan_lines() {
|
||||||
reduced.push(line.filter);
|
reduced.push(line.filter);
|
||||||
for (i, &byte) in line.data.iter().enumerate() {
|
for (i, &byte) in line.data.iter().enumerate() {
|
||||||
if i % bpp >= colored_bytes {
|
if i as u8 & bpp_mask >= colored_bytes {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
reduced.push(byte);
|
reduced.push(byte);
|
||||||
|
|
@ -29,7 +31,7 @@ pub fn reduce_alpha_channel(png: &mut PngData, channels: usize) -> Option<Vec<u8
|
||||||
// sBIT contains information about alpha channel's original depth,
|
// sBIT contains information about alpha channel's original depth,
|
||||||
// and alpha has just been removed
|
// and alpha has just been removed
|
||||||
if let Some(sbit_header) = png.aux_headers.get_mut(&"sBIT".to_string()) {
|
if let Some(sbit_header) = png.aux_headers.get_mut(&"sBIT".to_string()) {
|
||||||
assert_eq!(sbit_header.len(), channels);
|
assert_eq!(sbit_header.len(), channels as usize);
|
||||||
sbit_header.pop();
|
sbit_header.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,18 @@ pub fn reduce_rgba_to_rgb(png: &mut PngData) -> bool {
|
||||||
|
|
||||||
pub fn reduce_rgba_to_grayscale_alpha(png: &mut PngData) -> bool {
|
pub fn reduce_rgba_to_grayscale_alpha(png: &mut PngData) -> bool {
|
||||||
let mut reduced = Vec::with_capacity(png.raw_data.len());
|
let mut reduced = Vec::with_capacity(png.raw_data.len());
|
||||||
let byte_depth: u8 = png.ihdr_data.bit_depth.as_u8() >> 3;
|
let byte_depth = png.ihdr_data.bit_depth.as_u8() >> 3;
|
||||||
let bpp: usize = 4 * byte_depth as usize;
|
let bpp = 4 * byte_depth;
|
||||||
let colored_bytes = bpp - byte_depth as usize;
|
let bpp_mask = bpp - 1;
|
||||||
|
assert_eq!(0, bpp & bpp_mask);
|
||||||
|
let colored_bytes = bpp - byte_depth;
|
||||||
for line in png.scan_lines() {
|
for line in png.scan_lines() {
|
||||||
reduced.push(line.filter);
|
reduced.push(line.filter);
|
||||||
let mut low_bytes = Vec::with_capacity(4);
|
let mut low_bytes = Vec::with_capacity(4);
|
||||||
let mut high_bytes = Vec::with_capacity(4);
|
let mut high_bytes = Vec::with_capacity(4);
|
||||||
let mut trans_bytes = Vec::with_capacity(byte_depth as usize);
|
let mut trans_bytes = Vec::with_capacity(byte_depth as usize);
|
||||||
for (i, byte) in line.data.iter().enumerate() {
|
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 {
|
if byte_depth == 1 || i % 2 == 1 {
|
||||||
low_bytes.push(*byte);
|
low_bytes.push(*byte);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -35,7 +37,7 @@ pub fn reduce_rgba_to_grayscale_alpha(png: &mut PngData) -> bool {
|
||||||
trans_bytes.push(*byte);
|
trans_bytes.push(*byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
if i % bpp == bpp - 1 {
|
if (i as u8 & bpp_mask) == bpp - 1 {
|
||||||
if low_bytes.iter().unique().count() > 1 {
|
if low_bytes.iter().unique().count() > 1 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue