Fix bug where interlaced images with certain widths would fail to optimize
This commit is contained in:
parent
1d39714b0f
commit
ecc19ad5cd
4 changed files with 50 additions and 23 deletions
|
|
@ -1,5 +1,6 @@
|
|||
**Version 0.8.1 (unreleased)**
|
||||
- Minor optimizations
|
||||
- Fix issue where interlaced images with certain widths would fail to optimize
|
||||
|
||||
**Version 0.8.0**
|
||||
- [SEMVER_MINOR] Add support for optimizing PNGs already loaded into memory via library function
|
||||
|
|
|
|||
57
src/png.rs
57
src/png.rs
|
|
@ -151,58 +151,69 @@ impl<'a> Iterator for ScanLines<'a> {
|
|||
pass.1 = 0;
|
||||
}
|
||||
}
|
||||
let bits_per_pixel = self.png.ihdr_data.bit_depth.as_u8() as usize *
|
||||
self.png.channels_per_pixel() as usize;
|
||||
let mut bits_per_line = self.png.ihdr_data.width as usize * bits_per_pixel;
|
||||
let bits_per_pixel = self.png.ihdr_data.bit_depth.as_u8() as u32 *
|
||||
self.png.channels_per_pixel() as u32;
|
||||
let y_steps;
|
||||
let pixels_factor;
|
||||
match self.pass {
|
||||
Some((1, _)) | Some((2, _)) => {
|
||||
bits_per_line = (bits_per_line as f32 / 8f32).ceil() as usize;
|
||||
pixels_factor = 8;
|
||||
y_steps = 8;
|
||||
}
|
||||
Some((3, _)) => {
|
||||
bits_per_line = (bits_per_line as f32 / 4f32).ceil() as usize;
|
||||
pixels_factor = 4;
|
||||
y_steps = 8;
|
||||
}
|
||||
Some((4, _)) => {
|
||||
bits_per_line = (bits_per_line as f32 / 4f32).ceil() as usize;
|
||||
pixels_factor = 4;
|
||||
y_steps = 4;
|
||||
}
|
||||
Some((5, _)) => {
|
||||
bits_per_line = (bits_per_line as f32 / 2f32).ceil() as usize;
|
||||
pixels_factor = 2;
|
||||
y_steps = 4;
|
||||
}
|
||||
Some((6, _)) => {
|
||||
bits_per_line = (bits_per_line as f32 / 2f32).ceil() as usize;
|
||||
pixels_factor = 2;
|
||||
y_steps = 2;
|
||||
}
|
||||
Some((7, _)) => {
|
||||
pixels_factor = 1;
|
||||
y_steps = 2;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
// Determine whether to trim the last (overflow) pixel for rows on this pass
|
||||
let gap = bits_per_line % bits_per_pixel;
|
||||
if gap != 0 {
|
||||
let x_start = bits_per_pixel *
|
||||
match self.pass.unwrap().0 {
|
||||
2 => 4,
|
||||
4 => 2,
|
||||
6 => 1,
|
||||
_ => 0,
|
||||
let mut pixels_per_line = self.png.ihdr_data.width / pixels_factor as u32;
|
||||
// Determine whether to add pixels if there is a final, incomplete 8x8 block
|
||||
let gap = self.png.ihdr_data.width % pixels_factor;
|
||||
if gap > 0 {
|
||||
match self.pass.unwrap().0 {
|
||||
1 | 3 | 5 => {
|
||||
pixels_per_line += 1;
|
||||
}
|
||||
2 => {
|
||||
if gap >= 5 {
|
||||
pixels_per_line += 1;
|
||||
}
|
||||
}
|
||||
4 => {
|
||||
if gap >= 3 {
|
||||
pixels_per_line += 1;
|
||||
}
|
||||
}
|
||||
6 => {
|
||||
if gap >= 2 {
|
||||
pixels_per_line += 1;
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
if gap >= x_start {
|
||||
bits_per_line += bits_per_pixel - gap;
|
||||
} else {
|
||||
bits_per_line -= gap;
|
||||
}
|
||||
}
|
||||
let current_pass = if let Some(pass) = self.pass {
|
||||
Some(pass.0)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let bytes_per_line = (bits_per_line as f32 / 8f32).ceil() as usize;
|
||||
let bytes_per_line = ((pixels_per_line * bits_per_pixel) as f32 / 8f32).ceil() as usize;
|
||||
self.start = self.end;
|
||||
self.end = self.start + bytes_per_line + 1;
|
||||
if let Some(pass) = self.pass.as_mut() {
|
||||
|
|
|
|||
BIN
tests/files/interlaced_odd_width.png
Normal file
BIN
tests/files/interlaced_odd_width.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 670 KiB |
|
|
@ -1246,3 +1246,18 @@ fn interlaced_small_files() {
|
|||
png::ColorType::Indexed,
|
||||
png::BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_odd_width() {
|
||||
let input = PathBuf::from("tests/files/interlaced_odd_width.png");
|
||||
let opts = get_opts(&input);
|
||||
let output = opts.out_file.clone();
|
||||
|
||||
test_it_converts(&input,
|
||||
&output,
|
||||
&opts,
|
||||
png::ColorType::RGB,
|
||||
png::BitDepth::Eight,
|
||||
png::ColorType::RGB,
|
||||
png::BitDepth::Eight);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue