use criterion::{Criterion, criterion_group, criterion_main}; use dither::kernel; use image::ImageReader; const LIST_OF_SAMPLES: [&str; 7] = [ "samples/david.png", "samples/david2.jpg", "samples/us.png", "samples/diderot_111.png", "samples/jane.jpg", "samples/jane2.webp", "samples/karel_käos.jpg", ]; pub fn bench_integer_variation(c: &mut Criterion) { let img = ImageReader::open(LIST_OF_SAMPLES[0]) .unwrap() .decode() .unwrap() .into_rgb8(); c.bench_function("dither atkinson integer only", |b| { b.iter(|| { let mut img = img.clone(); dither::dither_shift( &mut img, kernel::KernelShift { kernel: dither::kernel::ATKINSON_KERNEL_INTEGER.to_vec(), bit_shift: kernel::ATKINSON_KERNEL_BIT_SHIFT, }, ) }) }); c.bench_function("dither atkinson", |b| { b.iter(|| { let mut img = img.clone(); dither::dither(&mut img, dither::kernel::ATKINSON_KERNEL.to_vec()) }) }); /* * This bench verify that the image loading isn't the only thing we benchmark. * Indeed it isn't. * * Check it with: * $ cargo bench --features check-bench */ #[cfg(feature = "check-bench")] c.bench_function("image loading", |b| { b.iter(|| { let mut img = img.clone(); std::hint::black_box(&mut img); }) }); #[cfg(feature = "check-bench")] c.bench_function("image loading no black box", |b| { b.iter(|| { let _ = img.clone(); }) }); #[cfg(feature = "check-bench")] c.bench_function("image loading only black box", |b| { b.iter(|| { std::hint::black_box(11); }) }); } pub fn bench_dithers_on_david(c: &mut Criterion) { let sample_img = ImageReader::open(LIST_OF_SAMPLES[0]) .unwrap() .decode() .unwrap() .into_rgb8(); let algos: [(&str, dither::DitherFn); 14] = [ ("kernel_atkinson", |img| { dither::dither(img, kernel::ATKINSON_KERNEL.to_vec()) }), ("kernel_atkinson_integer", |img| { dither::dither_shift( img, dither::kernel::KernelShift { kernel: kernel::ATKINSON_KERNEL_INTEGER.to_vec(), bit_shift: kernel::ATKINSON_KERNEL_BIT_SHIFT, }, ) }), ("kernel_floyd_steinberg", |img| { dither::dither(img, dither::kernel::FLOYD_STEINBERG_KERNEL.to_vec()) }), ("kernel_fedoseev", |img| { dither::dither(img, dither::kernel::FEDOSEEV_KERNEL.to_vec()) }), ("kernel_fedoseev2", |img| { dither::dither(img, dither::kernel::FEDOSEEV2_KERNEL.to_vec()) }), ("kernel_fedoseev3", |img| { dither::dither(img, dither::kernel::FEDOSEEV3_KERNEL.to_vec()) }), ("kernel_fedoseev4", |img| { dither::dither(img, dither::kernel::FEDOSEEV4_KERNEL.to_vec()) }), ("kernel_wong_allebach", |img| { dither::dither(img, dither::kernel::WONG_ALLEBACH_KERNEL.to_vec()) }), ("kernel_jarvis_judice_ninke", |img| { dither::dither(img, dither::kernel::JARVIS_JUDICE_NINKE_KERNEL.to_vec()) }), ("kernel_stucki", |img| { dither::dither(img, dither::kernel::STUCKI_KERNEL.to_vec()) }), ("kernel_burkes", |img| { dither::dither(img, dither::kernel::BURKES_KERNEL.to_vec()) }), ("kernel_sierra3", |img| { dither::dither(img, dither::kernel::SIERRA3_KERNEL.to_vec()) }), ("kernel_sierra2", |img| { dither::dither(img, dither::kernel::SIERRA2_KERNEL.to_vec()) }), ("kernel_sierra-lite", |img| { dither::dither(img, dither::kernel::SIERRA_LITE_KERNEL.to_vec()) }), /* ("kernel_hallucination_prewitt", |img| { dither::dither(img, dither::kernel::PREWITT_KERNEL.to_vec()) }), ("kernel_hallucination_roberts", |img| { dither::dither(img, dither::kernel::ROBERTS_KERNEL.to_vec()) }), ("kernel_hallucination_sobel", |img| { dither::dither(img, dither::kernel::SOBEL_KERNEL.to_vec()) }), */ ]; let mut group = c.benchmark_group("every dithering algorithm on david"); for algo in &algos { group.bench_function(&format!("{} on david", algo.0), |b| { b.iter(|| { let mut img = sample_img.clone(); algo.1(&mut img) }) }); } } pub fn bench_stucki_all_samples(c: &mut Criterion) { let mut group = c.benchmark_group("stucki on all samples"); for sample in LIST_OF_SAMPLES { let sample_img = ImageReader::open(sample) .unwrap() .decode() .unwrap() .into_rgb8(); group.bench_function(&format!("Stucki on {}", sample), |b| { b.iter(|| { let mut img = sample_img.clone(); dither::dither(&mut img, kernel::STUCKI_KERNEL.to_vec()) }) }); } group.finish(); } criterion_group!(benche_int, bench_integer_variation); criterion_group!(benche_all_samples, bench_stucki_all_samples); criterion_group!(benche_all_kernels, bench_dithers_on_david); criterion_main!(benche_int, benche_all_samples, benche_all_kernels);