Work on implementing interlacing [ci skip]

This commit is contained in:
Joshua Holmer 2016-03-28 00:33:36 -04:00
parent 489964add2
commit 5740867be5
87 changed files with 1609 additions and 5 deletions

View file

@ -187,9 +187,6 @@ pub fn optimize(filepath: &Path, opts: &Options) -> Result<(), String> {
if let Some(interlacing) = opts.interlace {
if png.change_interlacing(interlacing) {
something_changed = true;
if opts.verbosity == Some(1) {
report_reduction(&png);
}
}
}

View file

@ -123,6 +123,8 @@ pub struct ScanLines<'a> {
pub png: &'a PngData,
start: usize,
end: usize,
/// Current pass number, and 0-indexed row within the pass
pass: Option<(u8, u32)>,
}
impl<'a> Iterator for ScanLines<'a> {
@ -130,7 +132,99 @@ impl<'a> Iterator for ScanLines<'a> {
fn next(&mut self) -> Option<Self::Item> {
if self.end == self.png.raw_data.len() {
None
} else if self.png.ihdr_data.interlaced == 1 {
// Scanlines for interlaced PNG files
if self.pass.is_none() {
self.pass = Some((1, 0));
}
// Handle edge cases for images smaller than 5 pixels in either direction
if self.png.ihdr_data.width < 5 && self.pass.unwrap().0 == 2 {
if let Some(pass) = self.pass.as_mut() {
pass.0 = 3;
pass.1 = 4;
}
}
// Intentionally keep these separate so that they can be applied one after another
if self.png.ihdr_data.height < 5 && self.pass.unwrap().0 == 3 {
if let Some(pass) = self.pass.as_mut() {
pass.0 = 4;
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 y_steps;
match self.pass {
Some((1, _)) => {
bits_per_line >>= 3;
y_steps = 8;
}
Some((2, _)) => {
bits_per_line >>= 3;
y_steps = 8;
}
Some((3, _)) => {
bits_per_line >>= 2;
y_steps = 8;
}
Some((4, _)) => {
bits_per_line >>= 2;
y_steps = 4;
}
Some((5, _)) => {
bits_per_line >>= 1;
y_steps = 4;
}
Some((6, _)) => {
bits_per_line >>= 1;
y_steps = 2;
}
Some((7, _)) => {
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,
};
if gap >= x_start {
bits_per_line += bits_per_pixel - gap;
} else {
bits_per_line -= gap;
}
}
// Round up without converting to float
let bytes_per_line = (bits_per_line + bits_per_line % 8) >> 3;
self.start = self.end;
self.end = self.start + bytes_per_line + 1;
// TODO: Handle 4x4 pixel images
if let Some(pass) = self.pass.as_mut() {
if pass.1 + y_steps >= self.png.ihdr_data.height {
pass.0 += 1;
pass.1 = match pass.0 {
3 => 4,
5 => 2,
7 => 1,
_ => 0,
};
} else {
pass.1 += y_steps;
}
}
Some(ScanLine {
filter: self.png.raw_data[self.start],
data: self.png.raw_data[(self.start + 1)..self.end].to_owned(),
})
} else {
// Standard, non-interlaced PNG scanlines
let bits_per_line = self.png.ihdr_data.width as usize *
self.png.ihdr_data.bit_depth.as_u8() as usize *
self.png.channels_per_pixel() as usize;
@ -338,6 +432,7 @@ impl PngData {
png: &self,
start: 0,
end: 0,
pass: None,
}
}
/// Reverse all filters applied on the image, returning an unfiltered IDAT bytestream
@ -543,11 +638,15 @@ impl PngData {
/// Convert the image to the specified interlacing type
/// Returns true if the interlacing was changed, false otherwise
pub fn change_interlacing(&mut self, interlace: u8) -> bool {
// TODO: Implement
if interlace != self.ihdr_data.interlaced {
if interlace == self.ihdr_data.interlaced {
return false;
}
if interlace == 1 {
// TODO: Interlace
} else {
// TODO: Deinterlace
}
false
}
}

157
tests/files/generate.sh Executable file
View file

@ -0,0 +1,157 @@
#/bin/bash
cp rgba_16_should_be_rgba_16.png interlaced_rgba_16_should_be_rgba_16.png
cp rgba_16_should_be_rgba_8.png interlaced_rgba_16_should_be_rgba_8.png
cp rgba_8_should_be_rgba_8.png interlaced_rgba_8_should_be_rgba_8.png
cp rgba_16_should_be_rgb_16.png interlaced_rgba_16_should_be_rgb_16.png
cp rgba_16_should_be_rgb_8.png interlaced_rgba_16_should_be_rgb_8.png
cp rgba_8_should_be_rgb_8.png interlaced_rgba_8_should_be_rgb_8.png
cp rgba_16_should_be_palette_8.png interlaced_rgba_16_should_be_palette_8.png
cp rgba_8_should_be_palette_8.png interlaced_rgba_8_should_be_palette_8.png
cp rgba_16_should_be_palette_4.png interlaced_rgba_16_should_be_palette_4.png
cp rgba_8_should_be_palette_4.png interlaced_rgba_8_should_be_palette_4.png
cp rgba_16_should_be_palette_2.png interlaced_rgba_16_should_be_palette_2.png
cp rgba_8_should_be_palette_2.png interlaced_rgba_8_should_be_palette_2.png
cp rgba_16_should_be_palette_1.png interlaced_rgba_16_should_be_palette_1.png
cp rgba_8_should_be_palette_1.png interlaced_rgba_8_should_be_palette_1.png
cp rgba_16_should_be_grayscale_alpha_16.png interlaced_rgba_16_should_be_grayscale_alpha_16.png
cp rgba_16_should_be_grayscale_alpha_8.png interlaced_rgba_16_should_be_grayscale_alpha_8.png
cp rgba_8_should_be_grayscale_alpha_8.png interlaced_rgba_8_should_be_grayscale_alpha_8.png
cp rgba_16_should_be_grayscale_16.png interlaced_rgba_16_should_be_grayscale_16.png
cp rgba_16_should_be_grayscale_8.png interlaced_rgba_16_should_be_grayscale_8.png
cp rgba_8_should_be_grayscale_8.png interlaced_rgba_8_should_be_grayscale_8.png
cp rgba_16_should_be_palette_4_grayscale.png interlaced_rgba_16_should_be_palette_4_grayscale.png
cp rgba_8_should_be_palette_4_grayscale.png interlaced_rgba_8_should_be_palette_4_grayscale.png
cp rgba_16_should_be_palette_2_grayscale.png interlaced_rgba_16_should_be_palette_2_grayscale.png
cp rgba_8_should_be_palette_2_grayscale.png interlaced_rgba_8_should_be_palette_2_grayscale.png
cp rgba_16_should_be_palette_1_grayscale.png interlaced_rgba_16_should_be_palette_1_grayscale.png
cp rgba_8_should_be_palette_1_grayscale.png interlaced_rgba_8_should_be_palette_1_grayscale.png
cp rgb_16_should_be_rgb_16.png interlaced_rgb_16_should_be_rgb_16.png
cp rgb_16_should_be_rgb_8.png interlaced_rgb_16_should_be_rgb_8.png
cp rgb_8_should_be_rgb_8.png interlaced_rgb_8_should_be_rgb_8.png
cp rgb_16_should_be_palette_8.png interlaced_rgb_16_should_be_palette_8.png
cp rgb_8_should_be_palette_8.png interlaced_rgb_8_should_be_palette_8.png
cp rgb_16_should_be_palette_4.png interlaced_rgb_16_should_be_palette_4.png
cp rgb_8_should_be_palette_4.png interlaced_rgb_8_should_be_palette_4.png
cp rgb_16_should_be_palette_2.png interlaced_rgb_16_should_be_palette_2.png
cp rgb_8_should_be_palette_2.png interlaced_rgb_8_should_be_palette_2.png
cp rgb_16_should_be_palette_1.png interlaced_rgb_16_should_be_palette_1.png
cp rgb_8_should_be_palette_1.png interlaced_rgb_8_should_be_palette_1.png
cp rgb_16_should_be_grayscale_16.png interlaced_rgb_16_should_be_grayscale_16.png
cp rgb_16_should_be_grayscale_8.png interlaced_rgb_16_should_be_grayscale_8.png
cp rgb_8_should_be_grayscale_8.png interlaced_rgb_8_should_be_grayscale_8.png
cp rgb_16_should_be_palette_4_grayscale.png interlaced_rgb_16_should_be_palette_4_grayscale.png
cp rgb_8_should_be_palette_4_grayscale.png interlaced_rgb_8_should_be_palette_4_grayscale.png
cp rgb_16_should_be_palette_2_grayscale.png interlaced_rgb_16_should_be_palette_2_grayscale.png
cp rgb_8_should_be_palette_2_grayscale.png interlaced_rgb_8_should_be_palette_2_grayscale.png
cp rgb_16_should_be_palette_1_grayscale.png interlaced_rgb_16_should_be_palette_1_grayscale.png
cp rgb_8_should_be_palette_1_grayscale.png interlaced_rgb_8_should_be_palette_1_grayscale.png
cp palette_8_should_be_grayscale_8.png interlaced_palette_8_should_be_grayscale_8.png
cp palette_8_should_be_palette_8.png interlaced_palette_8_should_be_palette_8.png
cp palette_8_should_be_palette_4.png interlaced_palette_8_should_be_palette_4.png
cp palette_4_should_be_palette_4.png interlaced_palette_4_should_be_palette_4.png
cp palette_8_should_be_palette_2.png interlaced_palette_8_should_be_palette_2.png
cp palette_4_should_be_palette_2.png interlaced_palette_4_should_be_palette_2.png
cp palette_2_should_be_palette_2.png interlaced_palette_2_should_be_palette_2.png
cp palette_8_should_be_palette_1.png interlaced_palette_8_should_be_palette_1.png
cp palette_4_should_be_palette_1.png interlaced_palette_4_should_be_palette_1.png
cp palette_2_should_be_palette_1.png interlaced_palette_2_should_be_palette_1.png
cp palette_1_should_be_palette_1.png interlaced_palette_1_should_be_palette_1.png
cp grayscale_alpha_16_should_be_grayscale_alpha_16.png interlaced_grayscale_alpha_16_should_be_grayscale_alpha_16.png
cp grayscale_alpha_16_should_be_grayscale_alpha_8.png interlaced_grayscale_alpha_16_should_be_grayscale_alpha_8.png
cp grayscale_alpha_8_should_be_grayscale_alpha_8.png interlaced_grayscale_alpha_8_should_be_grayscale_alpha_8.png
cp grayscale_alpha_16_should_be_grayscale_16.png interlaced_grayscale_alpha_16_should_be_grayscale_16.png
cp grayscale_alpha_16_should_be_grayscale_8.png interlaced_grayscale_alpha_16_should_be_grayscale_8.png
cp grayscale_alpha_8_should_be_grayscale_8.png interlaced_grayscale_alpha_8_should_be_grayscale_8.png
cp grayscale_alpha_16_should_be_palette_4.png interlaced_grayscale_alpha_16_should_be_palette_4.png
cp grayscale_alpha_8_should_be_palette_4.png interlaced_grayscale_alpha_8_should_be_palette_4.png
cp grayscale_alpha_16_should_be_palette_2.png interlaced_grayscale_alpha_16_should_be_palette_2.png
cp grayscale_alpha_8_should_be_palette_2.png interlaced_grayscale_alpha_8_should_be_palette_2.png
cp grayscale_alpha_16_should_be_palette_1.png interlaced_grayscale_alpha_16_should_be_palette_1.png
cp grayscale_alpha_8_should_be_palette_1.png interlaced_grayscale_alpha_8_should_be_palette_1.png
cp grayscale_16_should_be_grayscale_16.png interlaced_grayscale_16_should_be_grayscale_16.png
cp grayscale_16_should_be_grayscale_8.png interlaced_grayscale_16_should_be_grayscale_8.png
cp grayscale_16_should_be_palette_4.png interlaced_grayscale_16_should_be_palette_4.png
cp grayscale_16_should_be_palette_2.png interlaced_grayscale_16_should_be_palette_2.png
cp grayscale_16_should_be_palette_1.png interlaced_grayscale_16_should_be_palette_1.png
cp grayscale_8_should_be_grayscale_8.png interlaced_grayscale_8_should_be_grayscale_8.png
cp grayscale_8_should_be_palette_4.png interlaced_grayscale_8_should_be_palette_4.png
cp grayscale_8_should_be_palette_2.png interlaced_grayscale_8_should_be_palette_2.png
cp grayscale_8_should_be_palette_1.png interlaced_grayscale_8_should_be_palette_1.png
optipng -nx -i 1 interlaced_rgba_16_should_be_rgba_16.png
optipng -nx -i 1 interlaced_rgba_16_should_be_rgba_8.png
optipng -nx -i 1 interlaced_rgba_8_should_be_rgba_8.png
optipng -nx -i 1 interlaced_rgba_16_should_be_rgb_16.png
optipng -nx -i 1 interlaced_rgba_16_should_be_rgb_8.png
optipng -nx -i 1 interlaced_rgba_8_should_be_rgb_8.png
optipng -nx -i 1 interlaced_rgba_16_should_be_palette_8.png
optipng -nx -i 1 interlaced_rgba_8_should_be_palette_8.png
optipng -nx -i 1 interlaced_rgba_16_should_be_palette_4.png
optipng -nx -i 1 interlaced_rgba_8_should_be_palette_4.png
optipng -nx -i 1 interlaced_rgba_16_should_be_palette_2.png
optipng -nx -i 1 interlaced_rgba_8_should_be_palette_2.png
optipng -nx -i 1 interlaced_rgba_16_should_be_palette_1.png
optipng -nx -i 1 interlaced_rgba_8_should_be_palette_1.png
optipng -nx -i 1 interlaced_rgba_16_should_be_grayscale_alpha_16.png
optipng -nx -i 1 interlaced_rgba_16_should_be_grayscale_alpha_8.png
optipng -nx -i 1 interlaced_rgba_8_should_be_grayscale_alpha_8.png
optipng -nx -i 1 interlaced_rgba_16_should_be_grayscale_16.png
optipng -nx -i 1 interlaced_rgba_16_should_be_grayscale_8.png
optipng -nx -i 1 interlaced_rgba_8_should_be_grayscale_8.png
optipng -nx -i 1 interlaced_rgba_16_should_be_palette_4_grayscale.png
optipng -nx -i 1 interlaced_rgba_8_should_be_palette_4_grayscale.png
optipng -nx -i 1 interlaced_rgba_16_should_be_palette_2_grayscale.png
optipng -nx -i 1 interlaced_rgba_8_should_be_palette_2_grayscale.png
optipng -nx -i 1 interlaced_rgba_16_should_be_palette_1_grayscale.png
optipng -nx -i 1 interlaced_rgba_8_should_be_palette_1_grayscale.png
optipng -nx -i 1 interlaced_rgb_16_should_be_rgb_16.png
optipng -nx -i 1 interlaced_rgb_16_should_be_rgb_8.png
optipng -nx -i 1 interlaced_rgb_8_should_be_rgb_8.png
optipng -nx -i 1 interlaced_rgb_16_should_be_palette_8.png
optipng -nx -i 1 interlaced_rgb_8_should_be_palette_8.png
optipng -nx -i 1 interlaced_rgb_16_should_be_palette_4.png
optipng -nx -i 1 interlaced_rgb_8_should_be_palette_4.png
optipng -nx -i 1 interlaced_rgb_16_should_be_palette_2.png
optipng -nx -i 1 interlaced_rgb_8_should_be_palette_2.png
optipng -nx -i 1 interlaced_rgb_16_should_be_palette_1.png
optipng -nx -i 1 interlaced_rgb_8_should_be_palette_1.png
optipng -nx -i 1 interlaced_rgb_16_should_be_grayscale_16.png
optipng -nx -i 1 interlaced_rgb_16_should_be_grayscale_8.png
optipng -nx -i 1 interlaced_rgb_8_should_be_grayscale_8.png
optipng -nx -i 1 interlaced_rgb_16_should_be_palette_4_grayscale.png
optipng -nx -i 1 interlaced_rgb_8_should_be_palette_4_grayscale.png
optipng -nx -i 1 interlaced_rgb_16_should_be_palette_2_grayscale.png
optipng -nx -i 1 interlaced_rgb_8_should_be_palette_2_grayscale.png
optipng -nx -i 1 interlaced_rgb_16_should_be_palette_1_grayscale.png
optipng -nx -i 1 interlaced_rgb_8_should_be_palette_1_grayscale.png
optipng -nx -i 1 interlaced_palette_8_should_be_grayscale_8.png
optipng -nx -i 1 interlaced_palette_8_should_be_palette_8.png
optipng -nx -i 1 interlaced_palette_8_should_be_palette_4.png
optipng -nx -i 1 interlaced_palette_4_should_be_palette_4.png
optipng -nx -i 1 interlaced_palette_8_should_be_palette_2.png
optipng -nx -i 1 interlaced_palette_4_should_be_palette_2.png
optipng -nx -i 1 interlaced_palette_2_should_be_palette_2.png
optipng -nx -i 1 interlaced_palette_8_should_be_palette_1.png
optipng -nx -i 1 interlaced_palette_4_should_be_palette_1.png
optipng -nx -i 1 interlaced_palette_2_should_be_palette_1.png
optipng -nx -i 1 interlaced_palette_1_should_be_palette_1.png
optipng -nx -i 1 interlaced_grayscale_alpha_16_should_be_grayscale_alpha_16.png
optipng -nx -i 1 interlaced_grayscale_alpha_16_should_be_grayscale_alpha_8.png
optipng -nx -i 1 interlaced_grayscale_alpha_8_should_be_grayscale_alpha_8.png
optipng -nx -i 1 interlaced_grayscale_alpha_16_should_be_grayscale_16.png
optipng -nx -i 1 interlaced_grayscale_alpha_16_should_be_grayscale_8.png
optipng -nx -i 1 interlaced_grayscale_alpha_8_should_be_grayscale_8.png
optipng -nx -i 1 interlaced_grayscale_alpha_16_should_be_palette_4.png
optipng -nx -i 1 interlaced_grayscale_alpha_8_should_be_palette_4.png
optipng -nx -i 1 interlaced_grayscale_alpha_16_should_be_palette_2.png
optipng -nx -i 1 interlaced_grayscale_alpha_8_should_be_palette_2.png
optipng -nx -i 1 interlaced_grayscale_alpha_16_should_be_palette_1.png
optipng -nx -i 1 interlaced_grayscale_alpha_8_should_be_palette_1.png
optipng -nx -i 1 interlaced_grayscale_16_should_be_grayscale_16.png
optipng -nx -i 1 interlaced_grayscale_16_should_be_grayscale_8.png
optipng -nx -i 1 interlaced_grayscale_16_should_be_palette_4.png
optipng -nx -i 1 interlaced_grayscale_16_should_be_palette_2.png
optipng -nx -i 1 interlaced_grayscale_16_should_be_palette_1.png
optipng -nx -i 1 interlaced_grayscale_8_should_be_grayscale_8.png
optipng -nx -i 1 interlaced_grayscale_8_should_be_palette_4.png
optipng -nx -i 1 interlaced_grayscale_8_should_be_palette_2.png
optipng -nx -i 1 interlaced_grayscale_8_should_be_palette_1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

View file

@ -267,3 +267,77 @@ fn strip_headers_none() {
remove_file(output).ok();
}
#[test]
fn interlacing_0_to_1() {
let input = PathBuf::from("tests/files/interlacing_0_to_1.png");
let mut opts = get_opts(&input);
opts.interlace = Some(1);
let output = opts.out_file.clone();
let png = png::PngData::new(&input).unwrap();
assert!(png.ihdr_data.interlaced == 0);
match oxipng::optimize(&input, &opts) {
Ok(_) => (),
Err(x) => panic!(x.to_owned()),
};
assert!(output.exists());
let png = match png::PngData::new(&output) {
Ok(x) => x,
Err(x) => {
remove_file(output).ok();
panic!(x.to_owned())
}
};
assert!(png.ihdr_data.interlaced == 1);
let old_png = image::open(&input).unwrap();
let new_png = image::open(&output).unwrap();
// Conversion should be lossless
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
remove_file(output).ok();
}
#[test]
fn interlacing_1_to_0() {
let input = PathBuf::from("tests/files/interlacing_1_to_0.png");
let mut opts = get_opts(&input);
opts.interlace = Some(0);
let output = opts.out_file.clone();
let png = png::PngData::new(&input).unwrap();
assert!(png.ihdr_data.interlaced == 1);
match oxipng::optimize(&input, &opts) {
Ok(_) => (),
Err(x) => panic!(x.to_owned()),
};
assert!(output.exists());
let png = match png::PngData::new(&output) {
Ok(x) => x,
Err(x) => {
remove_file(output).ok();
panic!(x.to_owned())
}
};
assert!(png.ihdr_data.interlaced == 0);
let old_png = image::open(&input).unwrap();
let new_png = image::open(&output).unwrap();
// Conversion should be lossless
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
remove_file(output).ok();
}

1276
tests/interlaced.rs Normal file

File diff suppressed because it is too large Load diff

View file

@ -60,6 +60,7 @@ fn test_it_converts(input: &Path,
assert!(png.ihdr_data.color_type == color_type_in);
assert!(png.ihdr_data.bit_depth == bit_depth_in);
assert!(png.ihdr_data.interlaced == 0);
match oxipng::optimize(input, opts) {
Ok(_) => (),