Run latest rustfmt
This commit is contained in:
parent
bb6a2513eb
commit
32e3d245f9
5 changed files with 65 additions and 78 deletions
|
|
@ -24,23 +24,21 @@ pub fn filter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> Vec
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
3 => {
|
3 => for (i, byte) in data.iter().enumerate() {
|
||||||
for (i, byte) in data.iter().enumerate() {
|
if last_line.is_empty() {
|
||||||
if last_line.is_empty() {
|
filtered.push(match i.checked_sub(bpp) {
|
||||||
filtered.push(match i.checked_sub(bpp) {
|
Some(x) => byte.wrapping_sub(data[x] >> 1),
|
||||||
Some(x) => byte.wrapping_sub(data[x] >> 1),
|
None => *byte,
|
||||||
None => *byte,
|
});
|
||||||
});
|
} else {
|
||||||
} else {
|
filtered.push(match i.checked_sub(bpp) {
|
||||||
filtered.push(match i.checked_sub(bpp) {
|
Some(x) => byte.wrapping_sub(
|
||||||
Some(x) => byte.wrapping_sub(
|
((u16::from(data[x]) + u16::from(last_line[i])) >> 1) as u8,
|
||||||
((u16::from(data[x]) + u16::from(last_line[i])) >> 1) as u8,
|
),
|
||||||
),
|
None => byte.wrapping_sub(last_line[i] >> 1),
|
||||||
None => byte.wrapping_sub(last_line[i] >> 1),
|
});
|
||||||
});
|
};
|
||||||
};
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
4 => for (i, byte) in data.iter().enumerate() {
|
4 => for (i, byte) in data.iter().enumerate() {
|
||||||
if last_line.is_empty() {
|
if last_line.is_empty() {
|
||||||
filtered.push(match i.checked_sub(bpp) {
|
filtered.push(match i.checked_sub(bpp) {
|
||||||
|
|
@ -104,12 +102,9 @@ pub fn unfilter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> V
|
||||||
match i.checked_sub(bpp) {
|
match i.checked_sub(bpp) {
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
let b = unfiltered[x];
|
let b = unfiltered[x];
|
||||||
unfiltered
|
unfiltered.push(byte.wrapping_add(
|
||||||
.push(
|
((u16::from(b) + u16::from(last_line[i])) >> 1) as u8,
|
||||||
byte.wrapping_add(
|
));
|
||||||
((u16::from(b) + u16::from(last_line[i])) >> 1) as u8,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
unfiltered.push(byte.wrapping_add(last_line[i] >> 1));
|
unfiltered.push(byte.wrapping_add(last_line[i] >> 1));
|
||||||
|
|
@ -132,9 +127,11 @@ pub fn unfilter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> V
|
||||||
match i.checked_sub(bpp) {
|
match i.checked_sub(bpp) {
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
let b = unfiltered[x];
|
let b = unfiltered[x];
|
||||||
unfiltered.push(
|
unfiltered.push(byte.wrapping_add(paeth_predictor(
|
||||||
byte.wrapping_add(paeth_predictor(b, last_line[i], last_line[x])),
|
b,
|
||||||
);
|
last_line[i],
|
||||||
|
last_line[x],
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
unfiltered.push(byte.wrapping_add(last_line[i]));
|
unfiltered.push(byte.wrapping_add(last_line[i]));
|
||||||
|
|
|
||||||
|
|
@ -93,16 +93,16 @@ pub fn deinterlace_image(png: &mut PngData) {
|
||||||
let mut current_y: usize = pass_constants.y_shift as usize;
|
let mut current_y: usize = pass_constants.y_shift as usize;
|
||||||
for line in png.scan_lines() {
|
for line in png.scan_lines() {
|
||||||
let bit_vec = BitVec::from_bytes(&line.data);
|
let bit_vec = BitVec::from_bytes(&line.data);
|
||||||
let bits_in_line = ((png.ihdr_data.width - u32::from(pass_constants.x_shift)) as f32 /
|
let bits_in_line = ((png.ihdr_data.width - u32::from(pass_constants.x_shift)) as f32
|
||||||
f32::from(pass_constants.x_step))
|
/ f32::from(pass_constants.x_step))
|
||||||
.ceil() as usize * bits_per_pixel as usize;
|
.ceil() as usize * bits_per_pixel as usize;
|
||||||
for (i, bit) in bit_vec.iter().enumerate() {
|
for (i, bit) in bit_vec.iter().enumerate() {
|
||||||
// Avoid moving padded 0's into new image
|
// Avoid moving padded 0's into new image
|
||||||
if i >= bits_in_line {
|
if i >= bits_in_line {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let current_x: usize = pass_constants.x_shift as usize +
|
let current_x: usize = pass_constants.x_shift as usize
|
||||||
(i / bits_per_pixel as usize) * pass_constants.x_step as usize;
|
+ (i / bits_per_pixel as usize) * pass_constants.x_step as usize;
|
||||||
// Copy this bit into the output line, offset by 8 because of filter byte
|
// Copy this bit into the output line, offset by 8 because of filter byte
|
||||||
let index = 8 + (i % bits_per_pixel as usize) + current_x * bits_per_pixel as usize;
|
let index = 8 + (i % bits_per_pixel as usize) + current_x * bits_per_pixel as usize;
|
||||||
lines[current_y].set(index, bit);
|
lines[current_y].set(index, bit);
|
||||||
|
|
|
||||||
21
src/lib.rs
21
src/lib.rs
|
|
@ -435,8 +435,7 @@ fn optimize_png(
|
||||||
if opts.verbosity.is_some() {
|
if opts.verbosity.is_some() {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
" {}x{} pixels, PNG format",
|
" {}x{} pixels, PNG format",
|
||||||
png.ihdr_data.width,
|
png.ihdr_data.width, png.ihdr_data.height
|
||||||
png.ihdr_data.height
|
|
||||||
);
|
);
|
||||||
if let Some(ref palette) = png.palette {
|
if let Some(ref palette) = png.palette {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
|
@ -463,8 +462,8 @@ fn optimize_png(
|
||||||
|
|
||||||
if opts.use_heuristics {
|
if opts.use_heuristics {
|
||||||
// Heuristically determine which set of options to use
|
// Heuristically determine which set of options to use
|
||||||
if png.ihdr_data.bit_depth.as_u8() >= 8 &&
|
if png.ihdr_data.bit_depth.as_u8() >= 8
|
||||||
png.ihdr_data.color_type != colors::ColorType::Indexed
|
&& png.ihdr_data.color_type != colors::ColorType::Indexed
|
||||||
{
|
{
|
||||||
if filter.is_empty() {
|
if filter.is_empty() {
|
||||||
filter.push(5);
|
filter.push(5);
|
||||||
|
|
@ -632,8 +631,8 @@ fn optimize_png(
|
||||||
.pixels()
|
.pixels()
|
||||||
.map(|x| x.2.channels().to_owned())
|
.map(|x| x.2.channels().to_owned())
|
||||||
.filter(|p| !(p.len() == 4 && p[3] == 0))
|
.filter(|p| !(p.len() == 4 && p[3] == 0))
|
||||||
.collect::<Vec<Vec<u8>>>() ==
|
.collect::<Vec<Vec<u8>>>()
|
||||||
new_png
|
== new_png
|
||||||
.pixels()
|
.pixels()
|
||||||
.map(|x| x.2.channels().to_owned())
|
.map(|x| x.2.channels().to_owned())
|
||||||
.filter(|p| !(p.len() == 4 && p[3] == 0))
|
.filter(|p| !(p.len() == 4 && p[3] == 0))
|
||||||
|
|
@ -726,15 +725,7 @@ fn perform_strip(png: &mut png::PngData, opts: &Options) {
|
||||||
},
|
},
|
||||||
Headers::Safe => {
|
Headers::Safe => {
|
||||||
const PRESERVED_HEADERS: [&str; 9] = [
|
const PRESERVED_HEADERS: [&str; 9] = [
|
||||||
"cHRM",
|
"cHRM", "gAMA", "iCCP", "sBIT", "sRGB", "bKGD", "hIST", "pHYs", "sPLT"
|
||||||
"gAMA",
|
|
||||||
"iCCP",
|
|
||||||
"sBIT",
|
|
||||||
"sRGB",
|
|
||||||
"bKGD",
|
|
||||||
"hIST",
|
|
||||||
"pHYs",
|
|
||||||
"sPLT",
|
|
||||||
];
|
];
|
||||||
let hdrs = png.aux_headers.keys().cloned().collect::<Vec<String>>();
|
let hdrs = png.aux_headers.keys().cloned().collect::<Vec<String>>();
|
||||||
for hdr in hdrs {
|
for hdr in hdrs {
|
||||||
|
|
|
||||||
|
|
@ -465,10 +465,7 @@ fn parse_numeric_range_opts(
|
||||||
let multiple_items = Regex::new(
|
let multiple_items = Regex::new(
|
||||||
format!(
|
format!(
|
||||||
r"^([{}-{}])(,|-)([{}-{}])$",
|
r"^([{}-{}])(,|-)([{}-{}])$",
|
||||||
min_value,
|
min_value, max_value, min_value, max_value
|
||||||
max_value,
|
|
||||||
min_value,
|
|
||||||
max_value
|
|
||||||
).as_ref(),
|
).as_ref(),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
let mut items = HashSet::new();
|
let mut items = HashSet::new();
|
||||||
|
|
|
||||||
60
src/png.rs
60
src/png.rs
|
|
@ -56,8 +56,8 @@ impl<'a> Iterator for ScanLines<'a> {
|
||||||
pass.1 = 0;
|
pass.1 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let bits_per_pixel = u32::from(self.png.ihdr_data.bit_depth.as_u8()) *
|
let bits_per_pixel = u32::from(self.png.ihdr_data.bit_depth.as_u8())
|
||||||
u32::from(self.png.channels_per_pixel());
|
* u32::from(self.png.channels_per_pixel());
|
||||||
let y_steps;
|
let y_steps;
|
||||||
let pixels_factor;
|
let pixels_factor;
|
||||||
match self.pass {
|
match self.pass {
|
||||||
|
|
@ -135,9 +135,9 @@ impl<'a> Iterator for ScanLines<'a> {
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Standard, non-interlaced PNG scanlines
|
// Standard, non-interlaced PNG scanlines
|
||||||
let bits_per_line = self.png.ihdr_data.width as usize *
|
let bits_per_line = self.png.ihdr_data.width as usize
|
||||||
self.png.ihdr_data.bit_depth.as_u8() as usize *
|
* self.png.ihdr_data.bit_depth.as_u8() as usize
|
||||||
self.png.channels_per_pixel() as usize;
|
* self.png.channels_per_pixel() as usize;
|
||||||
let bytes_per_line = (bits_per_line + 7) / 8 as usize;
|
let bytes_per_line = (bits_per_line + 7) / 8 as usize;
|
||||||
self.start = self.end;
|
self.start = self.end;
|
||||||
self.end = self.start + bytes_per_line + 1;
|
self.end = self.start + bytes_per_line + 1;
|
||||||
|
|
@ -196,7 +196,7 @@ impl PngData {
|
||||||
Err(_) => return Err(PngError::new("Failed to open file for reading")),
|
Err(_) => return Err(PngError::new("Failed to open file for reading")),
|
||||||
};
|
};
|
||||||
// Check file for PNG header
|
// Check file for PNG header
|
||||||
let mut header = [0; 8];
|
let mut header = [0; 8];
|
||||||
if file.read_exact(&mut header).is_err() {
|
if file.read_exact(&mut header).is_err() {
|
||||||
return Err(PngError::new("Not a PNG file: too small"));
|
return Err(PngError::new("Not a PNG file: too small"));
|
||||||
}
|
}
|
||||||
|
|
@ -329,9 +329,10 @@ impl PngData {
|
||||||
let _ = ihdr_data.write_u8(self.ihdr_data.interlaced);
|
let _ = ihdr_data.write_u8(self.ihdr_data.interlaced);
|
||||||
write_png_block(b"IHDR", &ihdr_data, &mut output);
|
write_png_block(b"IHDR", &ihdr_data, &mut output);
|
||||||
// Ancillary headers
|
// Ancillary headers
|
||||||
for (key, header) in self.aux_headers.iter().filter(|&(key, _)| {
|
for (key, header) in self.aux_headers
|
||||||
!(*key == "bKGD" || *key == "hIST" || *key == "tRNS")
|
.iter()
|
||||||
}) {
|
.filter(|&(key, _)| !(*key == "bKGD" || *key == "hIST" || *key == "tRNS"))
|
||||||
|
{
|
||||||
write_png_block(key.as_bytes(), header, &mut output);
|
write_png_block(key.as_bytes(), header, &mut output);
|
||||||
}
|
}
|
||||||
// Palette
|
// Palette
|
||||||
|
|
@ -346,9 +347,10 @@ impl PngData {
|
||||||
write_png_block(b"tRNS", transparency_pixel, &mut output);
|
write_png_block(b"tRNS", transparency_pixel, &mut output);
|
||||||
}
|
}
|
||||||
// Special ancillary headers that need to come after PLTE but before IDAT
|
// Special ancillary headers that need to come after PLTE but before IDAT
|
||||||
for (key, header) in self.aux_headers.iter().filter(
|
for (key, header) in self.aux_headers
|
||||||
|&(key, _)| *key == "bKGD" || *key == "hIST" || *key == "tRNS",
|
.iter()
|
||||||
) {
|
.filter(|&(key, _)| *key == "bKGD" || *key == "hIST" || *key == "tRNS")
|
||||||
|
{
|
||||||
write_png_block(key.as_bytes(), header, &mut output);
|
write_png_block(key.as_bytes(), header, &mut output);
|
||||||
}
|
}
|
||||||
// IDAT data
|
// IDAT data
|
||||||
|
|
@ -373,8 +375,7 @@ impl PngData {
|
||||||
/// Reverse all filters applied on the image, returning an unfiltered IDAT bytestream
|
/// Reverse all filters applied on the image, returning an unfiltered IDAT bytestream
|
||||||
pub fn unfilter_image(&self) -> Vec<u8> {
|
pub fn unfilter_image(&self) -> Vec<u8> {
|
||||||
let mut unfiltered = Vec::with_capacity(self.raw_data.len());
|
let mut unfiltered = Vec::with_capacity(self.raw_data.len());
|
||||||
let bpp = ((f32::from(self.ihdr_data.bit_depth.as_u8() * self.channels_per_pixel())) /
|
let bpp = ((f32::from(self.ihdr_data.bit_depth.as_u8() * self.channels_per_pixel())) / 8f32)
|
||||||
8f32)
|
|
||||||
.ceil() as usize;
|
.ceil() as usize;
|
||||||
let mut last_line: Vec<u8> = Vec::new();
|
let mut last_line: Vec<u8> = Vec::new();
|
||||||
let mut last_pass = 1;
|
let mut last_pass = 1;
|
||||||
|
|
@ -402,8 +403,7 @@ impl PngData {
|
||||||
/// 5: All (heuristically pick the best filter for each line)
|
/// 5: All (heuristically pick the best filter for each line)
|
||||||
pub fn filter_image(&self, filter: u8) -> Vec<u8> {
|
pub fn filter_image(&self, filter: u8) -> Vec<u8> {
|
||||||
let mut filtered = Vec::with_capacity(self.raw_data.len());
|
let mut filtered = Vec::with_capacity(self.raw_data.len());
|
||||||
let bpp = ((f32::from(self.ihdr_data.bit_depth.as_u8() * self.channels_per_pixel())) /
|
let bpp = ((f32::from(self.ihdr_data.bit_depth.as_u8() * self.channels_per_pixel())) / 8f32)
|
||||||
8f32)
|
|
||||||
.ceil() as usize;
|
.ceil() as usize;
|
||||||
let mut last_line: Vec<u8> = Vec::new();
|
let mut last_line: Vec<u8> = Vec::new();
|
||||||
let mut last_pass: Option<u8> = None;
|
let mut last_pass: Option<u8> = None;
|
||||||
|
|
@ -412,8 +412,12 @@ impl PngData {
|
||||||
0 | 1 | 2 | 3 | 4 => {
|
0 | 1 | 2 | 3 | 4 => {
|
||||||
if last_pass == line.pass || filter <= 1 {
|
if last_pass == line.pass || filter <= 1 {
|
||||||
filtered.push(filter);
|
filtered.push(filter);
|
||||||
filtered
|
filtered.extend_from_slice(&filter_line(
|
||||||
.extend_from_slice(&filter_line(filter, bpp, &line.data, &last_line));
|
filter,
|
||||||
|
bpp,
|
||||||
|
&line.data,
|
||||||
|
&last_line,
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
// Avoid vertical filtering on first line of each interlacing pass
|
// Avoid vertical filtering on first line of each interlacing pass
|
||||||
filtered.push(0);
|
filtered.push(0);
|
||||||
|
|
@ -453,8 +457,8 @@ impl PngData {
|
||||||
/// Returns true if the bit depth was reduced, false otherwise
|
/// Returns true if the bit depth was reduced, false otherwise
|
||||||
pub fn reduce_bit_depth(&mut self) -> bool {
|
pub fn reduce_bit_depth(&mut self) -> bool {
|
||||||
if self.ihdr_data.bit_depth != BitDepth::Sixteen {
|
if self.ihdr_data.bit_depth != BitDepth::Sixteen {
|
||||||
if self.ihdr_data.color_type == ColorType::Indexed ||
|
if self.ihdr_data.color_type == ColorType::Indexed
|
||||||
self.ihdr_data.color_type == ColorType::Grayscale
|
|| self.ihdr_data.color_type == ColorType::Grayscale
|
||||||
{
|
{
|
||||||
return reduce_bit_depth_8_or_less(self);
|
return reduce_bit_depth_8_or_less(self);
|
||||||
}
|
}
|
||||||
|
|
@ -463,8 +467,8 @@ impl PngData {
|
||||||
|
|
||||||
// Reduce from 16 to 8 bits per channel per pixel
|
// Reduce from 16 to 8 bits per channel per pixel
|
||||||
let mut reduced = Vec::with_capacity(
|
let mut reduced = Vec::with_capacity(
|
||||||
(self.ihdr_data.width * self.ihdr_data.height * u32::from(self.channels_per_pixel()) +
|
(self.ihdr_data.width * self.ihdr_data.height * u32::from(self.channels_per_pixel())
|
||||||
self.ihdr_data.height) as usize,
|
+ self.ihdr_data.height) as usize,
|
||||||
);
|
);
|
||||||
let mut high_byte = 0;
|
let mut high_byte = 0;
|
||||||
|
|
||||||
|
|
@ -698,9 +702,7 @@ impl PngData {
|
||||||
.cloned()
|
.cloned()
|
||||||
.flatten()
|
.flatten()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(i, _)| {
|
.filter(|&(i, _)| !(self.transparency_palette.is_some() && i % 4 == 3))
|
||||||
!(self.transparency_palette.is_some() && i % 4 == 3)
|
|
||||||
})
|
|
||||||
.map(|(_, x)| *x)
|
.map(|(_, x)| *x)
|
||||||
.collect::<Vec<u8>>();
|
.collect::<Vec<u8>>();
|
||||||
self.palette = Some(new_palette);
|
self.palette = Some(new_palette);
|
||||||
|
|
@ -723,15 +725,15 @@ impl PngData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.ihdr_data.color_type == ColorType::GrayscaleAlpha &&
|
if self.ihdr_data.color_type == ColorType::GrayscaleAlpha
|
||||||
reduce_grayscale_alpha_to_grayscale(self)
|
&& reduce_grayscale_alpha_to_grayscale(self)
|
||||||
{
|
{
|
||||||
changed = true;
|
changed = true;
|
||||||
should_reduce_bit_depth = true;
|
should_reduce_bit_depth = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.ihdr_data.color_type == ColorType::RGB &&
|
if self.ihdr_data.color_type == ColorType::RGB
|
||||||
(reduce_rgb_to_grayscale(self) || reduce_rgb_to_palette(self))
|
&& (reduce_rgb_to_grayscale(self) || reduce_rgb_to_palette(self))
|
||||||
{
|
{
|
||||||
changed = true;
|
changed = true;
|
||||||
should_reduce_bit_depth = true;
|
should_reduce_bit_depth = true;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue