From 74ec806c643a581012090e76b729ab4b0237658e Mon Sep 17 00:00:00 2001 From: Andrew Date: Sun, 6 Nov 2022 15:56:31 +1300 Subject: [PATCH] Add tests and benches --- benches/strategies.rs | 58 ++++++++++++ tests/interlacing.rs | 202 ++++++++++++++++++++++++++++++++++++++++++ tests/strategies.rs | 124 ++++++++++++++++++++++++++ 3 files changed, 384 insertions(+) create mode 100644 benches/strategies.rs create mode 100644 tests/interlacing.rs create mode 100644 tests/strategies.rs diff --git a/benches/strategies.rs b/benches/strategies.rs new file mode 100644 index 00000000..a8b6c091 --- /dev/null +++ b/benches/strategies.rs @@ -0,0 +1,58 @@ +#![feature(test)] + +extern crate oxipng; +extern crate test; + +use oxipng::{internal_tests::*, RowFilter}; +use std::path::PathBuf; +use test::Bencher; + +#[bench] +fn filters_minsum(b: &mut Bencher) { + let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); + let png = PngData::new(&input, false).unwrap(); + + b.iter(|| { + png.raw.filter_image(RowFilter::MinSum); + }); +} + +#[bench] +fn filters_entropy(b: &mut Bencher) { + let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); + let png = PngData::new(&input, false).unwrap(); + + b.iter(|| { + png.raw.filter_image(RowFilter::Entropy); + }); +} + +#[bench] +fn filters_bigrams(b: &mut Bencher) { + let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); + let png = PngData::new(&input, false).unwrap(); + + b.iter(|| { + png.raw.filter_image(RowFilter::Bigrams); + }); +} + +#[bench] +fn filters_bigent(b: &mut Bencher) { + let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); + let png = PngData::new(&input, false).unwrap(); + + b.iter(|| { + png.raw.filter_image(RowFilter::BigEnt); + }); +} + +#[bench] +fn filters_brute(b: &mut Bencher) { + let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png")); + let png = PngData::new(&input, false).unwrap(); + + b.iter(|| { + png.raw.filter_image(RowFilter::Brute); + }); +} diff --git a/tests/interlacing.rs b/tests/interlacing.rs new file mode 100644 index 00000000..b80eabc2 --- /dev/null +++ b/tests/interlacing.rs @@ -0,0 +1,202 @@ +use indexmap::IndexSet; +use oxipng::{internal_tests::*, RowFilter}; +use oxipng::{InFile, OutFile}; +use std::fs::remove_file; +use std::path::Path; +use std::path::PathBuf; + +fn get_opts(input: &Path) -> (OutFile, oxipng::Options) { + let mut options = oxipng::Options { + force: true, + ..Default::default() + }; + let mut filter = IndexSet::new(); + filter.insert(RowFilter::None); + options.filter = filter; + + ( + OutFile::Path(Some(input.with_extension("out.png"))), + options, + ) +} + +fn test_it_converts( + input: &str, + interlace: u8, + color_type_in: ColorType, + bit_depth_in: BitDepth, + color_type_out: ColorType, + bit_depth_out: BitDepth, +) { + let input = PathBuf::from(input); + let (output, mut opts) = get_opts(&input); + let png = PngData::new(&input, opts.fix_errors).unwrap(); + opts.interlace = Some(interlace); + assert_eq!(png.raw.ihdr.color_type, color_type_in); + assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in); + assert_eq!(png.raw.ihdr.interlaced, if interlace == 1 { 0 } else { 1 }); + + match oxipng::optimize(&InFile::Path(input), &output, &opts) { + Ok(_) => (), + Err(x) => panic!("{}", x), + }; + let output = output.path().unwrap(); + assert!(output.exists()); + + let png = match PngData::new(output, opts.fix_errors) { + Ok(x) => x, + Err(x) => { + remove_file(output).ok(); + panic!("{}", x) + } + }; + + assert_eq!(png.raw.ihdr.color_type, color_type_out); + assert_eq!(png.raw.ihdr.bit_depth, bit_depth_out); + + remove_file(output).ok(); +} + +#[test] +fn deinterlace_rgb_16() { + test_it_converts( + "tests/files/interlaced_rgb_16_should_be_rgb_16.png", + 0, + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen, + ); +} + +#[test] +fn deinterlace_rgb_8() { + test_it_converts( + "tests/files/interlaced_rgb_8_should_be_rgb_8.png", + 0, + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight, + ); +} + +#[test] +fn deinterlace_palette_8() { + test_it_converts( + "tests/files/interlaced_palette_8_should_be_palette_8.png", + 0, + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Eight, + ); +} + +#[test] +fn deinterlace_palette_4() { + test_it_converts( + "tests/files/interlaced_palette_4_should_be_palette_4.png", + 0, + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Four, + ); +} + +#[test] +fn deinterlace_palette_2() { + test_it_converts( + "tests/files/interlaced_palette_2_should_be_palette_2.png", + 0, + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::Two, + ); +} + +#[test] +fn deinterlace_palette_1() { + test_it_converts( + "tests/files/interlaced_palette_1_should_be_palette_1.png", + 0, + ColorType::Indexed, + BitDepth::One, + ColorType::Indexed, + BitDepth::One, + ); +} + +#[test] +fn interlace_rgb_16() { + test_it_converts( + "tests/files/rgb_16_should_be_rgb_16.png", + 1, + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen, + ); +} + +#[test] +fn interlace_rgb_8() { + test_it_converts( + "tests/files/rgb_8_should_be_rgb_8.png", + 1, + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight, + ); +} + +#[test] +fn interlace_palette_8() { + test_it_converts( + "tests/files/palette_8_should_be_palette_8.png", + 1, + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Eight, + ); +} + +#[test] +fn interlace_palette_4() { + test_it_converts( + "tests/files/palette_4_should_be_palette_4.png", + 1, + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Four, + ); +} + +#[test] +fn interlace_palette_2() { + test_it_converts( + "tests/files/palette_2_should_be_palette_2.png", + 1, + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::Two, + ); +} + +#[test] +fn interlace_palette_1() { + test_it_converts( + "tests/files/palette_1_should_be_palette_1.png", + 1, + ColorType::Indexed, + BitDepth::One, + ColorType::Indexed, + BitDepth::One, + ); +} diff --git a/tests/strategies.rs b/tests/strategies.rs new file mode 100644 index 00000000..aa5d80f4 --- /dev/null +++ b/tests/strategies.rs @@ -0,0 +1,124 @@ +use indexmap::IndexSet; +use oxipng::{internal_tests::*, RowFilter}; +use oxipng::{InFile, OutFile}; +use std::fs::remove_file; +use std::path::Path; +use std::path::PathBuf; + +fn get_opts(input: &Path) -> (OutFile, oxipng::Options) { + let mut options = oxipng::Options { + force: true, + ..Default::default() + }; + let mut filter = IndexSet::new(); + filter.insert(RowFilter::None); + options.filter = filter; + + ( + OutFile::Path(Some(input.with_extension("out.png"))), + options, + ) +} + +fn test_it_converts( + input: &str, + filter: RowFilter, + color_type_in: ColorType, + bit_depth_in: BitDepth, + color_type_out: ColorType, + bit_depth_out: BitDepth, +) { + let input = PathBuf::from(input); + + let (output, mut opts) = get_opts(&input); + let png = PngData::new(&input, opts.fix_errors).unwrap(); + opts.filter = IndexSet::new(); + opts.filter.insert(filter); + assert_eq!(png.raw.ihdr.color_type, color_type_in); + assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in); + + match oxipng::optimize(&InFile::Path(input), &output, &opts) { + Ok(_) => (), + Err(x) => panic!("{}", x), + }; + let output = output.path().unwrap(); + assert!(output.exists()); + + let png = match PngData::new(output, opts.fix_errors) { + Ok(x) => x, + Err(x) => { + remove_file(output).ok(); + panic!("{}", x) + } + }; + + assert_eq!(png.raw.ihdr.color_type, color_type_out); + assert_eq!(png.raw.ihdr.bit_depth, bit_depth_out); + if let Some(palette) = png.raw.palette.as_ref() { + assert!(palette.len() <= 1 << (png.raw.ihdr.bit_depth.as_u8() as usize)); + } else { + assert_ne!(png.raw.ihdr.color_type, ColorType::Indexed); + } + + remove_file(output).ok(); +} + +#[test] +fn filter_minsum() { + test_it_converts( + "tests/files/rgb_16_should_be_rgb_16.png", + RowFilter::MinSum, + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen, + ); +} + +#[test] +fn filter_entropy() { + test_it_converts( + "tests/files/rgb_8_should_be_rgb_8.png", + RowFilter::Entropy, + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight, + ); +} + +#[test] +fn filter_bigrams() { + test_it_converts( + "tests/files/rgba_8_should_be_rgba_8.png", + RowFilter::Bigrams, + ColorType::RGBA, + BitDepth::Eight, + ColorType::RGBA, + BitDepth::Eight, + ); +} + +#[test] +fn filter_bigent() { + test_it_converts( + "tests/files/grayscale_8_should_be_grayscale_8.png", + RowFilter::BigEnt, + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight, + ); +} + +#[test] +fn filter_brute() { + test_it_converts( + "tests/files/palette_8_should_be_palette_8.png", + RowFilter::Brute, + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Eight, + ); +}