Avoid allocation when not reducing

This commit is contained in:
Kornel Lesiński 2018-07-16 14:35:18 +01:00
parent eb75989333
commit 96889d6917

View file

@ -1,24 +1,35 @@
use png::PngData; use png::PngData;
pub fn reduce_alpha_channel(png: &mut PngData, bpp_factor: usize) -> Option<Vec<u8>> { pub fn reduce_alpha_channel(png: &mut PngData, channels: usize) -> Option<Vec<u8>> {
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: u8 = png.ihdr_data.bit_depth.as_u8() >> 3;
let bpp: usize = bpp_factor * byte_depth as usize; let bpp: usize = channels * byte_depth as usize;
let colored_bytes = bpp - byte_depth as usize; let colored_bytes = bpp - byte_depth as usize;
for line in png.scan_lines() { for line in png.scan_lines() {
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 % bpp >= colored_bytes {
if *byte != 255 { if byte != 255 {
return None; return None;
} }
} else {
reduced.push(*byte);
} }
} }
} }
let mut reduced = Vec::with_capacity(png.raw_data.len());
for line in png.scan_lines() {
reduced.push(line.filter);
for (i, &byte) in line.data.iter().enumerate() {
if i % bpp >= colored_bytes {
continue;
} else {
reduced.push(byte);
}
}
}
// sBIT contains information about alpha channel's original depth,
// 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(), bpp_factor); assert_eq!(sbit_header.len(), channels);
sbit_header.pop(); sbit_header.pop();
} }