diff --git a/.cargo/config b/.cargo/config.toml similarity index 100% rename from .cargo/config rename to .cargo/config.toml diff --git a/.github/workflows/safety.yml b/.github/workflows/safety.yml index f4bf8218..3d9455ac 100644 --- a/.github/workflows/safety.yml +++ b/.github/workflows/safety.yml @@ -54,3 +54,26 @@ jobs: env: LSAN_OPTIONS: "suppressions=lsan-suppressions.txt" RUSTFLAGS: "-Z sanitizer=leak" + miri: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - run: | + echo "NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)" >> $GITHUB_ENV + - name: Install ${{ env.NIGHTLY }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.NIGHTLY }} + components: miri + - name: Install cargo-nextest + uses: baptiste0928/cargo-install@v1 + with: + crate: cargo-nextest + locked: true + - name: cargo miri test + timeout-minutes: 120 + run: cargo miri nextest run --no-default-features --features=image/default + env: + MIRIFLAGS: "" diff --git a/src/binary_descriptors/brief.rs b/src/binary_descriptors/brief.rs index 377dc4db..1ebafdaa 100644 --- a/src/binary_descriptors/brief.rs +++ b/src/binary_descriptors/brief.rs @@ -269,13 +269,11 @@ pub fn brief( #[cfg(test)] mod tests { + use super::*; + use crate::utils::gray_bench_image; use rand::Rng; use test::{black_box, Bencher}; - use crate::utils::gray_bench_image; - - use super::*; - #[test] fn test_compute_hamming_distance() { let d1 = BriefDescriptor { @@ -326,6 +324,15 @@ mod tests { let integral_image: ImageBuffer, Vec> = integral_image(&image); assert_eq!(local_pixel_average(&integral_image, 3, 3, 2), 117); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::utils::gray_bench_image; + use rand::Rng; + use test::{black_box, Bencher}; #[bench] #[ignore] diff --git a/src/binary_descriptors/mod.rs b/src/binary_descriptors/mod.rs index fabb9566..f695bc14 100644 --- a/src/binary_descriptors/mod.rs +++ b/src/binary_descriptors/mod.rs @@ -133,8 +133,9 @@ pub fn match_binary_descriptors<'a, T: BinaryDescriptor>( matches } +#[cfg(not(miri))] #[cfg(test)] -mod tests { +mod benches { use super::*; use crate::{binary_descriptors::brief::brief, utils::gray_bench_image}; use test::{black_box, Bencher}; diff --git a/src/contrast.rs b/src/contrast.rs index 8d3aa57d..6a511479 100644 --- a/src/contrast.rs +++ b/src/contrast.rs @@ -380,14 +380,10 @@ pub fn stretch_contrast_mut(image: &mut GrayImage, lower: u8, upper: u8) { #[cfg(test)] mod tests { - use test::{black_box, Bencher}; - - use image::{GrayImage, Luma}; - + use super::*; use crate::definitions::{HasBlack, HasWhite}; use crate::utils::gray_bench_image; - - use super::*; + use image::{GrayImage, Luma}; #[test] fn adaptive_threshold_constant() { @@ -443,35 +439,6 @@ mod tests { } } - #[bench] - fn bench_adaptive_threshold(b: &mut Bencher) { - let image = gray_bench_image(200, 200); - let block_radius = 10; - b.iter(|| { - let thresholded = adaptive_threshold(&image, block_radius); - black_box(thresholded); - }); - } - - #[bench] - fn bench_match_histogram(b: &mut Bencher) { - let target = GrayImage::from_pixel(200, 200, Luma([150])); - let image = gray_bench_image(200, 200); - b.iter(|| { - let matched = match_histogram(&image, &target); - black_box(matched); - }); - } - - #[bench] - fn bench_match_histogram_mut(b: &mut Bencher) { - let target = GrayImage::from_pixel(200, 200, Luma([150])); - let mut image = gray_bench_image(200, 200); - b.iter(|| { - match_histogram_mut(&mut image, &target); - }); - } - #[test] fn test_histogram_lut_source_and_target_equal() { let mut histc = [0u32; 256]; @@ -544,15 +511,6 @@ mod tests { assert_eq!(level, 120); } - #[bench] - fn bench_otsu_level(b: &mut Bencher) { - let image = gray_bench_image(200, 200); - b.iter(|| { - let level = otsu_level(&image); - black_box(level); - }); - } - #[test] fn test_threshold_0_image_0() { let expected = 0u8; @@ -586,6 +544,45 @@ mod tests { let actual = threshold(&original, 125u8, ThresholdType::Binary); assert_pixels_eq!(expected, actual); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::definitions::{HasBlack, HasWhite}; + use crate::utils::gray_bench_image; + use image::{GrayImage, Luma}; + use test::{black_box, Bencher}; + + #[bench] + fn bench_adaptive_threshold(b: &mut Bencher) { + let image = gray_bench_image(200, 200); + let block_radius = 10; + b.iter(|| { + let thresholded = adaptive_threshold(&image, block_radius); + black_box(thresholded); + }); + } + + #[bench] + fn bench_match_histogram(b: &mut Bencher) { + let target = GrayImage::from_pixel(200, 200, Luma([150])); + let image = gray_bench_image(200, 200); + b.iter(|| { + let matched = match_histogram(&image, &target); + black_box(matched); + }); + } + + #[bench] + fn bench_match_histogram_mut(b: &mut Bencher) { + let target = GrayImage::from_pixel(200, 200, Luma([150])); + let mut image = gray_bench_image(200, 200); + b.iter(|| { + match_histogram_mut(&mut image, &target); + }); + } #[bench] fn bench_equalize_histogram(b: &mut Bencher) { @@ -640,4 +637,13 @@ mod tests { black_box(()); }); } + + #[bench] + fn bench_otsu_level(b: &mut Bencher) { + let image = gray_bench_image(200, 200); + b.iter(|| { + let level = otsu_level(&image); + black_box(level); + }); + } } diff --git a/src/corners.rs b/src/corners.rs index 59706977..ba51daed 100644 --- a/src/corners.rs +++ b/src/corners.rs @@ -495,7 +495,6 @@ where #[cfg(test)] mod tests { use super::*; - use test::{black_box, Bencher}; #[test] fn test_is_corner_fast12_12_contiguous_darker_pixels() { @@ -553,20 +552,6 @@ mod tests { assert!(!is_corner_fast12(&image, 8, 3, 3)); } - #[bench] - fn bench_is_corner_fast12_12_noncontiguous(b: &mut Bencher) { - let image = black_box(gray_image!( - 10, 10, 00, 00, 00, 10, 10; - 10, 00, 10, 10, 10, 00, 10; - 00, 10, 10, 10, 10, 10, 10; - 00, 10, 10, 10, 10, 10, 10; - 10, 10, 10, 10, 10, 10, 00; - 10, 00, 10, 10, 10, 10, 10; - 10, 10, 00, 00, 00, 10, 10)); - - b.iter(|| black_box(is_corner_fast12(&image, 8, 3, 3))); - } - #[test] fn test_is_corner_fast12_near_image_boundary() { let image = gray_image!( @@ -644,6 +629,60 @@ mod tests { ); } + #[test] + fn test_is_corner_fast9_12_noncontiguous() { + let image = gray_image!( + 10, 10, 00, 00, 00, 10, 10; + 10, 00, 10, 10, 10, 00, 10; + 00, 10, 10, 10, 10, 10, 10; + 00, 10, 10, 10, 10, 10, 10; + 10, 10, 10, 10, 10, 10, 00; + 10, 00, 10, 10, 10, 10, 10; + 10, 10, 00, 00, 00, 10, 10); + + assert!(!is_corner_fast9(&image, 8, 3, 3)); + } + + #[test] + fn test_corner_score_fast9() { + // 8 pixels with an intensity diff of 20, then 1 with a diff of 10 + let image = gray_image!( + 10, 10, 00, 00, 00, 10, 10; + 10, 00, 10, 10, 10, 00, 10; + 00, 10, 10, 10, 10, 10, 10; + 00, 10, 10, 20, 10, 10, 10; + 00, 10, 10, 10, 10, 10, 10; + 10, 10, 10, 10, 10, 10, 10; + 10, 10, 10, 10, 10, 10, 10); + + let score = fast_corner_score(&image, 5, 3, 3, Fast::Nine); + assert_eq!(score, 9); + + let score = fast_corner_score(&image, 9, 3, 3, Fast::Nine); + assert_eq!(score, 9); + } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use test::{black_box, Bencher}; + + #[bench] + fn bench_is_corner_fast12_12_noncontiguous(b: &mut Bencher) { + let image = black_box(gray_image!( + 10, 10, 00, 00, 00, 10, 10; + 10, 00, 10, 10, 10, 00, 10; + 00, 10, 10, 10, 10, 10, 10; + 00, 10, 10, 10, 10, 10, 10; + 10, 10, 10, 10, 10, 10, 00; + 10, 00, 10, 10, 10, 10, 10; + 10, 10, 00, 00, 00, 10, 10)); + + b.iter(|| black_box(is_corner_fast12(&image, 8, 3, 3))); + } + #[bench] fn bench_intensity_centroid(b: &mut Bencher) { let image = gray_image!( @@ -699,37 +738,4 @@ mod tests { b.iter(|| black_box(is_corner_fast9(&image, 8, 3, 3))); } - - #[test] - fn test_is_corner_fast9_12_noncontiguous() { - let image = gray_image!( - 10, 10, 00, 00, 00, 10, 10; - 10, 00, 10, 10, 10, 00, 10; - 00, 10, 10, 10, 10, 10, 10; - 00, 10, 10, 10, 10, 10, 10; - 10, 10, 10, 10, 10, 10, 00; - 10, 00, 10, 10, 10, 10, 10; - 10, 10, 00, 00, 00, 10, 10); - - assert!(!is_corner_fast9(&image, 8, 3, 3)); - } - - #[test] - fn test_corner_score_fast9() { - // 8 pixels with an intensity diff of 20, then 1 with a diff of 10 - let image = gray_image!( - 10, 10, 00, 00, 00, 10, 10; - 10, 00, 10, 10, 10, 00, 10; - 00, 10, 10, 10, 10, 10, 10; - 00, 10, 10, 20, 10, 10, 10; - 00, 10, 10, 10, 10, 10, 10; - 10, 10, 10, 10, 10, 10, 10; - 10, 10, 10, 10, 10, 10, 10); - - let score = fast_corner_score(&image, 5, 3, 3, Fast::Nine); - assert_eq!(score, 9); - - let score = fast_corner_score(&image, 9, 3, 3, Fast::Nine); - assert_eq!(score, 9); - } } diff --git a/src/distance_transform.rs b/src/distance_transform.rs index fdfce395..3ceec38b 100644 --- a/src/distance_transform.rs +++ b/src/distance_transform.rs @@ -454,12 +454,11 @@ mod tests { use super::*; use crate::definitions::Image; use crate::property_testing::GrayTestImage; - use crate::utils::{gray_bench_image, pixel_diff_summary}; + use crate::utils::pixel_diff_summary; use image::{GrayImage, Luma}; use quickcheck::{quickcheck, Arbitrary, Gen, TestResult}; use std::cmp::max; use std::f64; - use test::{black_box, Bencher}; /// Avoid generating garbage floats during certain calculations below. #[derive(Debug, Clone)] @@ -630,6 +629,14 @@ mod tests { let dist = euclidean_squared_distance_transform(&image); assert_pixels_eq_within!(dist, expected, 1e-6); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::utils::gray_bench_image; + use test::{black_box, Bencher}; macro_rules! bench_euclidean_squared_distance_transform { ($name:ident, side: $s:expr) => { diff --git a/src/drawing/bezier.rs b/src/drawing/bezier.rs index 14a898bd..ea4ee1f9 100644 --- a/src/drawing/bezier.rs +++ b/src/drawing/bezier.rs @@ -81,8 +81,9 @@ pub fn draw_cubic_bezier_curve_mut( } } +#[cfg(not(miri))] #[cfg(test)] -mod tests { +mod benches { use image::{GrayImage, Luma}; macro_rules! bench_cubic_bezier_curve { diff --git a/src/drawing/conics.rs b/src/drawing/conics.rs index ec649bcd..11b07ea2 100644 --- a/src/drawing/conics.rs +++ b/src/drawing/conics.rs @@ -356,6 +356,7 @@ mod tests { } } + #[cfg_attr(miri, ignore = "slow [>1480s]")] #[test] fn test_draw_filled_ellipse() { let ellipse = Ellipse { @@ -376,6 +377,13 @@ mod tests { const EPS: f32 = 0.0019; check_filled_ellipse(&img, ellipse, inner_color, outer_color, EPS); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use image::{GrayImage, Luma}; macro_rules! bench_hollow_ellipse { ($name:ident, $center:expr, $width_radius:expr, $height_radius:expr) => { diff --git a/src/drawing/line.rs b/src/drawing/line.rs index dd924bf5..26bef92e 100644 --- a/src/drawing/line.rs +++ b/src/drawing/line.rs @@ -561,6 +561,44 @@ mod tests { assert_pixels_eq!(oct3, expected); } + #[test] + fn test_draw_line_segment_horizontal_using_bresenham_line_pixel_iter_mut() { + let image = GrayImage::from_pixel(5, 5, Luma([1u8])); + + let expected = gray_image!( + 1, 1, 1, 1, 1; + 4, 4, 4, 4, 4; + 1, 1, 1, 1, 1; + 1, 1, 1, 1, 1; + 1, 1, 1, 1, 1); + + let mut right = image.clone(); + { + let right_iter = + BresenhamLinePixelIterMut::new(&mut right, (-3f32, 1f32), (6f32, 1f32)); + for p in right_iter { + *p = Luma([4u8]); + } + } + assert_pixels_eq!(right, expected); + + let mut left = image.clone(); + { + let left_iter = BresenhamLinePixelIterMut::new(&mut left, (6f32, 1f32), (-3f32, 1f32)); + for p in left_iter { + *p = Luma([4u8]); + } + } + assert_pixels_eq!(left, expected); + } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use image::{GrayImage, Luma}; + macro_rules! bench_antialiased_lines { ($name:ident, $start:expr, $end:expr) => { #[bench] @@ -601,35 +639,4 @@ mod tests { (10, 10), (450, 80) ); - - #[test] - fn test_draw_line_segment_horizontal_using_bresenham_line_pixel_iter_mut() { - let image = GrayImage::from_pixel(5, 5, Luma([1u8])); - - let expected = gray_image!( - 1, 1, 1, 1, 1; - 4, 4, 4, 4, 4; - 1, 1, 1, 1, 1; - 1, 1, 1, 1, 1; - 1, 1, 1, 1, 1); - - let mut right = image.clone(); - { - let right_iter = - BresenhamLinePixelIterMut::new(&mut right, (-3f32, 1f32), (6f32, 1f32)); - for p in right_iter { - *p = Luma([4u8]); - } - } - assert_pixels_eq!(right, expected); - - let mut left = image.clone(); - { - let left_iter = BresenhamLinePixelIterMut::new(&mut left, (6f32, 1f32), (-3f32, 1f32)); - for p in left_iter { - *p = Luma([4u8]); - } - } - assert_pixels_eq!(left, expected); - } } diff --git a/src/drawing/rect.rs b/src/drawing/rect.rs index dc163848..d6f38ab7 100644 --- a/src/drawing/rect.rs +++ b/src/drawing/rect.rs @@ -76,18 +76,6 @@ mod tests { use crate::drawing::Blend; use crate::rect::Rect; use image::{GrayImage, Luma, Pixel, Rgb, RgbImage, Rgba, RgbaImage}; - use test::{black_box, Bencher}; - - #[bench] - fn bench_draw_filled_rect_mut_rgb(b: &mut Bencher) { - let mut image = RgbImage::new(200, 200); - let color = Rgb([120u8, 60u8, 47u8]); - let rect = Rect::at(50, 50).of_size(80, 90); - b.iter(|| { - draw_filled_rect_mut(&mut image, rect, color); - black_box(&image); - }); - } #[test] fn test_draw_hollow_rect() { @@ -156,3 +144,24 @@ mod tests { assert_eq!(*image.0.get_pixel(2, 2), blue); } } + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::drawing::Blend; + use crate::rect::Rect; + use image::{GrayImage, Luma, Pixel, Rgb, RgbImage, Rgba, RgbaImage}; + use test::{black_box, Bencher}; + + #[bench] + fn bench_draw_filled_rect_mut_rgb(b: &mut Bencher) { + let mut image = RgbImage::new(200, 200); + let color = Rgb([120u8, 60u8, 47u8]); + let rect = Rect::at(50, 50).of_size(80, 90); + b.iter(|| { + draw_filled_rect_mut(&mut image, rect, color); + black_box(&image); + }); + } +} diff --git a/src/edges.rs b/src/edges.rs index c6991e0b..34172942 100644 --- a/src/edges.rs +++ b/src/edges.rs @@ -186,8 +186,9 @@ pub fn laplacian_edge_detector(image: &GrayImage) -> ImageBuffer, Vec GrayImage { @@ -800,17 +770,6 @@ mod tests { let kernel = vec![1f32 / 10f32; 10]; black_box(horizontal_filter(&image, &kernel)); } - - #[bench] - fn bench_horizontal_filter(b: &mut Bencher) { - let image = gray_bench_image(500, 500); - let kernel = vec![1f32 / 5f32; 5]; - b.iter(|| { - let filtered = horizontal_filter(&image, &kernel); - black_box(filtered); - }); - } - #[test] fn test_vertical_filter() { let image = gray_image!( @@ -839,17 +798,6 @@ mod tests { let kernel = vec![1f32 / 10f32; 10]; black_box(vertical_filter(&image, &kernel)); } - - #[bench] - fn bench_vertical_filter(b: &mut Bencher) { - let image = gray_bench_image(500, 500); - let kernel = vec![1f32 / 5f32; 5]; - b.iter(|| { - let filtered = vertical_filter(&image, &kernel); - black_box(filtered); - }); - } - #[test] fn test_filter3x3_with_results_outside_input_channel_range() { #[rustfmt::skip] @@ -932,6 +880,102 @@ mod tests { assert_pixels_eq!(filtered, expected); } + #[test] + #[should_panic] + fn test_gaussian_blur_f32_rejects_zero_sigma() { + let image = gray_image!( + 1, 2, 3; + 4, 5, 6; + 7, 8, 9 + ); + let _ = gaussian_blur_f32(&image, 0.0); + } + + #[test] + #[should_panic] + fn test_gaussian_blur_f32_rejects_negative_sigma() { + let image = gray_image!( + 1, 2, 3; + 4, 5, 6; + 7, 8, 9 + ); + let _ = gaussian_blur_f32(&image, -0.5); + } + + #[test] + fn test_gaussian_on_u8_white_idempotent() { + let image = ImageBuffer::, Vec>::from_pixel(64, 64, Luma([255])); + let image2 = gaussian_blur_f32(&image, 10f32); + assert_pixels_eq_within!(image2, image, 0); + } + + #[test] + fn test_gaussian_on_f32_white_idempotent() { + let image = ImageBuffer::, Vec>::from_pixel(64, 64, Luma([1.0])); + let image2 = gaussian_blur_f32(&image, 10f32); + assert_pixels_eq_within!(image2, image, 1e-6); + } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::definitions::{Clamp, Image}; + use crate::utils::{gray_bench_image, rgb_bench_image}; + use image::imageops::blur; + use image::{GenericImage, GrayImage, ImageBuffer, Luma, Rgb}; + use std::cmp::{max, min}; + use test::{black_box, Bencher}; + + #[bench] + fn bench_bilateral_filter(b: &mut Bencher) { + let image = gray_bench_image(500, 500); + b.iter(|| { + let filtered = bilateral_filter(&image, 10, 10., 3.); + black_box(filtered); + }); + } + + #[bench] + fn bench_box_filter(b: &mut Bencher) { + let image = gray_bench_image(500, 500); + b.iter(|| { + let filtered = box_filter(&image, 7, 7); + black_box(filtered); + }); + } + + #[bench] + fn bench_separable_filter(b: &mut Bencher) { + let image = gray_bench_image(300, 300); + let h_kernel = vec![1f32 / 5f32; 5]; + let v_kernel = vec![0.1f32, 0.4f32, 0.3f32, 0.1f32, 0.1f32]; + b.iter(|| { + let filtered = separable_filter(&image, &h_kernel, &v_kernel); + black_box(filtered); + }); + } + + #[bench] + fn bench_horizontal_filter(b: &mut Bencher) { + let image = gray_bench_image(500, 500); + let kernel = vec![1f32 / 5f32; 5]; + b.iter(|| { + let filtered = horizontal_filter(&image, &kernel); + black_box(filtered); + }); + } + + #[bench] + fn bench_vertical_filter(b: &mut Bencher) { + let image = gray_bench_image(500, 500); + let kernel = vec![1f32 / 5f32; 5]; + b.iter(|| { + let filtered = vertical_filter(&image, &kernel); + black_box(filtered); + }); + } #[bench] fn bench_filter3x3_i32_filter(b: &mut Bencher) { @@ -1015,40 +1059,4 @@ mod tests { black_box(blurred); }); } - - #[test] - #[should_panic] - fn test_gaussian_blur_f32_rejects_zero_sigma() { - let image = gray_image!( - 1, 2, 3; - 4, 5, 6; - 7, 8, 9 - ); - let _ = gaussian_blur_f32(&image, 0.0); - } - - #[test] - #[should_panic] - fn test_gaussian_blur_f32_rejects_negative_sigma() { - let image = gray_image!( - 1, 2, 3; - 4, 5, 6; - 7, 8, 9 - ); - let _ = gaussian_blur_f32(&image, -0.5); - } - - #[test] - fn test_gaussian_on_u8_white_idempotent() { - let image = ImageBuffer::, Vec>::from_pixel(64, 64, Luma([255])); - let image2 = gaussian_blur_f32(&image, 10f32); - assert_pixels_eq_within!(image2, image, 0); - } - - #[test] - fn test_gaussian_on_f32_white_idempotent() { - let image = ImageBuffer::, Vec>::from_pixel(64, 64, Luma([1.0])); - let image2 = gaussian_blur_f32(&image, 10f32); - assert_pixels_eq_within!(image2, image, 1e-6); - } } diff --git a/src/geometric_transformations.rs b/src/geometric_transformations.rs index e8d5128d..667290ff 100644 --- a/src/geometric_transformations.rs +++ b/src/geometric_transformations.rs @@ -744,7 +744,6 @@ mod tests { use super::*; use crate::utils::gray_bench_image; use image::{GrayImage, Luma}; - use test::{black_box, Bencher}; #[test] fn test_rotate_nearest_zero_radians() { @@ -795,39 +794,6 @@ mod tests { assert_pixels_eq!(rotated, expected); } - #[bench] - fn bench_rotate_nearest(b: &mut Bencher) { - let image = GrayImage::from_pixel(200, 200, Luma([15u8])); - let c = Projection::translate(3.0, 3.0); - let rot = c * Projection::rotate(1f32.to_degrees()) * c.invert(); - b.iter(|| { - let rotated = warp(&image, &rot, Interpolation::Nearest, Luma([98u8])); - black_box(rotated); - }); - } - - #[bench] - fn bench_rotate_bilinear(b: &mut Bencher) { - let image = GrayImage::from_pixel(200, 200, Luma([15u8])); - let c = Projection::translate(3.0, 3.0); - let rot = c * Projection::rotate(1f32.to_degrees()) * c.invert(); - b.iter(|| { - let rotated = warp(&image, &rot, Interpolation::Bilinear, Luma([98u8])); - black_box(rotated); - }); - } - - #[bench] - fn bench_rotate_bicubic(b: &mut Bencher) { - let image = GrayImage::from_pixel(200, 200, Luma([15u8])); - let c = Projection::translate(3.0, 3.0); - let rot = c * Projection::rotate(1f32.to_degrees()) * c.invert(); - b.iter(|| { - let rotated = warp(&image, &rot, Interpolation::Bicubic, Luma([98u8])); - black_box(rotated); - }); - } - #[test] fn test_translate_positive_x_positive_y() { let image = gray_image!( @@ -893,15 +859,6 @@ mod tests { assert_pixels_eq!(translated, expected); } - #[bench] - fn bench_translate(b: &mut Bencher) { - let image = gray_bench_image(500, 500); - b.iter(|| { - let translated = translate(&image, (30, 30)); - black_box(translated); - }); - } - #[test] fn test_translate_positive_x_positive_y_projection() { let image = gray_image!( @@ -966,35 +923,6 @@ mod tests { assert_pixels_eq!(translated, expected); } - #[bench] - fn bench_translate_projection(b: &mut Bencher) { - let image = gray_bench_image(500, 500); - let t = Projection::translate(-30.0, -30.0); - - b.iter(|| { - let translated = warp(&image, &t, Interpolation::Nearest, Luma([0u8])); - black_box(translated); - }); - } - - #[bench] - fn bench_translate_with(b: &mut Bencher) { - let image = gray_bench_image(500, 500); - - b.iter(|| { - let (width, height) = image.dimensions(); - let mut out = ImageBuffer::new(width, height); - warp_into_with( - &image, - |x, y| (x - 30.0, y - 30.0), - Interpolation::Nearest, - Luma([0u8]), - &mut out, - ); - black_box(out); - }); - } - #[test] fn test_affine() { let image = gray_image!( @@ -1048,57 +976,7 @@ mod tests { assert_pixels_eq!(translated_bicubic, expected); } - #[bench] - fn bench_affine_nearest(b: &mut Bencher) { - let image = GrayImage::from_pixel(200, 200, Luma([15u8])); - - #[rustfmt::skip] - let aff = Projection::from_matrix([ - 1.0, 0.0, -1.0, - 0.0, 1.0, -1.0, - 0.0, 0.0, 1.0 - ]).unwrap(); - - b.iter(|| { - let transformed = warp(&image, &aff, Interpolation::Nearest, Luma([0u8])); - black_box(transformed); - }); - } - - #[bench] - fn bench_affine_bilinear(b: &mut Bencher) { - let image = GrayImage::from_pixel(200, 200, Luma([15u8])); - - #[rustfmt::skip] - let aff = Projection::from_matrix([ - 1.8, -0.2, 5.0, - 0.2, 1.9, 6.0, - 0.0002, 0.0003, 1.0 - ]).unwrap(); - - b.iter(|| { - let transformed = warp(&image, &aff, Interpolation::Bilinear, Luma([0u8])); - black_box(transformed); - }); - } - - #[bench] - fn bench_affine_bicubic(b: &mut test::Bencher) { - let image = GrayImage::from_pixel(200, 200, Luma([15u8])); - - #[rustfmt::skip] - let aff = Projection::from_matrix([ - 1.8, -0.2, 5.0, - 0.2, 1.9, 6.0, - 0.0002, 0.0003, 1.0 - ]).unwrap(); - - b.iter(|| { - let transformed = warp(&image, &aff, Interpolation::Bicubic, Luma([0u8])); - black_box(transformed); - }); - } - + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_translate() { let from = [(0f32, 0.0), (50.0, 50.0), (50.0, 0.0), (0.0, 50.0)]; @@ -1113,6 +991,7 @@ mod tests { assert_approx_eq!(out.1, 5.0, 1e-10); } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points() { let from = [(0f32, 0.0), (50.0, 50.0), (50.0, 0.0), (0.0, 50.0)]; @@ -1127,6 +1006,7 @@ mod tests { assert_approx_eq!(out.1, 20.0, 1e-10); } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_2() { let from = [ @@ -1141,6 +1021,7 @@ mod tests { assert!(p.is_some()); } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] /// Test case from https://github.com/image-rs/imageproc/issues/412 fn test_from_control_points_nofreeze() { @@ -1155,6 +1036,7 @@ mod tests { Projection::from_control_points(from, to); } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_known_transform() { let t = Projection::translate(10f32, 10f32); @@ -1176,6 +1058,7 @@ mod tests { } } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_colinear() { let from = [(0f32, 0.0), (50.0, 50.0), (50.0, 0.0), (0.0, 50.0)]; @@ -1186,6 +1069,7 @@ mod tests { assert!(p.is_none()); } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_translation() { let p = Projection::translate(10f32, 15f32); @@ -1204,6 +1088,7 @@ mod tests { } } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_underdetermined() { let from = [ @@ -1217,6 +1102,137 @@ mod tests { let p = Projection::from_control_points(from, to); p.unwrap(); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::utils::gray_bench_image; + use image::{GrayImage, Luma}; + use test::{black_box, Bencher}; + + #[bench] + fn bench_rotate_nearest(b: &mut Bencher) { + let image = GrayImage::from_pixel(200, 200, Luma([15u8])); + let c = Projection::translate(3.0, 3.0); + let rot = c * Projection::rotate(1f32.to_degrees()) * c.invert(); + b.iter(|| { + let rotated = warp(&image, &rot, Interpolation::Nearest, Luma([98u8])); + black_box(rotated); + }); + } + + #[bench] + fn bench_rotate_bilinear(b: &mut Bencher) { + let image = GrayImage::from_pixel(200, 200, Luma([15u8])); + let c = Projection::translate(3.0, 3.0); + let rot = c * Projection::rotate(1f32.to_degrees()) * c.invert(); + b.iter(|| { + let rotated = warp(&image, &rot, Interpolation::Bilinear, Luma([98u8])); + black_box(rotated); + }); + } + + #[bench] + fn bench_rotate_bicubic(b: &mut Bencher) { + let image = GrayImage::from_pixel(200, 200, Luma([15u8])); + let c = Projection::translate(3.0, 3.0); + let rot = c * Projection::rotate(1f32.to_degrees()) * c.invert(); + b.iter(|| { + let rotated = warp(&image, &rot, Interpolation::Bicubic, Luma([98u8])); + black_box(rotated); + }); + } + + #[bench] + fn bench_translate(b: &mut Bencher) { + let image = gray_bench_image(500, 500); + b.iter(|| { + let translated = translate(&image, (30, 30)); + black_box(translated); + }); + } + + #[bench] + fn bench_translate_projection(b: &mut Bencher) { + let image = gray_bench_image(500, 500); + let t = Projection::translate(-30.0, -30.0); + + b.iter(|| { + let translated = warp(&image, &t, Interpolation::Nearest, Luma([0u8])); + black_box(translated); + }); + } + + #[bench] + fn bench_translate_with(b: &mut Bencher) { + let image = gray_bench_image(500, 500); + + b.iter(|| { + let (width, height) = image.dimensions(); + let mut out = ImageBuffer::new(width, height); + warp_into_with( + &image, + |x, y| (x - 30.0, y - 30.0), + Interpolation::Nearest, + Luma([0u8]), + &mut out, + ); + black_box(out); + }); + } + + #[bench] + fn bench_affine_nearest(b: &mut Bencher) { + let image = GrayImage::from_pixel(200, 200, Luma([15u8])); + + #[rustfmt::skip] + let aff = Projection::from_matrix([ + 1.0, 0.0, -1.0, + 0.0, 1.0, -1.0, + 0.0, 0.0, 1.0 + ]).unwrap(); + + b.iter(|| { + let transformed = warp(&image, &aff, Interpolation::Nearest, Luma([0u8])); + black_box(transformed); + }); + } + + #[bench] + fn bench_affine_bilinear(b: &mut Bencher) { + let image = GrayImage::from_pixel(200, 200, Luma([15u8])); + + #[rustfmt::skip] + let aff = Projection::from_matrix([ + 1.8, -0.2, 5.0, + 0.2, 1.9, 6.0, + 0.0002, 0.0003, 1.0 + ]).unwrap(); + + b.iter(|| { + let transformed = warp(&image, &aff, Interpolation::Bilinear, Luma([0u8])); + black_box(transformed); + }); + } + + #[bench] + fn bench_affine_bicubic(b: &mut test::Bencher) { + let image = GrayImage::from_pixel(200, 200, Luma([15u8])); + + #[rustfmt::skip] + let aff = Projection::from_matrix([ + 1.8, -0.2, 5.0, + 0.2, 1.9, 6.0, + 0.0002, 0.0003, 1.0 + ]).unwrap(); + + b.iter(|| { + let transformed = warp(&image, &aff, Interpolation::Bicubic, Luma([0u8])); + black_box(transformed); + }); + } #[bench] fn bench_from_control_points(b: &mut Bencher) { diff --git a/src/gradients.rs b/src/gradients.rs index 3f2e0947..f1e7fbb2 100644 --- a/src/gradients.rs +++ b/src/gradients.rs @@ -253,7 +253,6 @@ mod tests { use super::*; use crate::utils::gray_bench_image; use image::{ImageBuffer, Luma}; - use test::{black_box, Bencher}; #[rustfmt::skip::macros(gray_image)] #[test] @@ -363,6 +362,14 @@ mod tests { let filtered = vertical_prewitt(&image); assert_pixels_eq!(filtered, expected); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::utils::gray_bench_image; + use test::{black_box, Bencher}; #[bench] fn bench_sobel_gradients(b: &mut Bencher) { diff --git a/src/haar.rs b/src/haar.rs index 1b7543ad..be8efce5 100644 --- a/src/haar.rs +++ b/src/haar.rs @@ -734,6 +734,14 @@ mod tests { assert_pixels_eq!(actual, expected); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::{integral_image::integral_image, utils::gray_bench_image}; + use test::Bencher; #[bench] fn bench_evaluate_all_features_10x10(b: &mut test::Bencher) { diff --git a/src/hog.rs b/src/hog.rs index 55a42721..24cf773d 100644 --- a/src/hog.rs +++ b/src/hog.rs @@ -684,6 +684,14 @@ mod tests { let desc_unsigned = hog(&image, opts_unsigned); test::black_box(desc_unsigned.unwrap()); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::utils::gray_bench_image; + use ::test; #[bench] fn bench_hog(b: &mut test::Bencher) { diff --git a/src/hough.rs b/src/hough.rs index ce1a663d..812b44ef 100644 --- a/src/hough.rs +++ b/src/hough.rs @@ -206,7 +206,6 @@ fn intersection_points( mod tests { use super::*; use image::{GrayImage, ImageBuffer, Luma}; - use test::{black_box, Bencher}; fn assert_points_eq( actual: Option<((f32, f32), (f32, f32))>, @@ -538,6 +537,14 @@ mod tests { test_detect_line!(detect_line_eps_135, 0.001, 135); // https://github.com/image-rs/imageproc/issues/280 test_detect_line!(detect_line_neg10_120, -10.0, 120); +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use image::{GrayImage, ImageBuffer, Luma}; + use test::{black_box, Bencher}; macro_rules! bench_detect_lines { ($name:ident, $r:expr, $angle:expr) => { diff --git a/src/integral_image.rs b/src/integral_image.rs index b441a48f..e1d8c45d 100644 --- a/src/integral_image.rs +++ b/src/integral_image.rs @@ -467,7 +467,6 @@ mod tests { use crate::definitions::Image; use crate::property_testing::GrayTestImage; use crate::utils::{gray_bench_image, pixel_diff_summary, rgb_bench_image}; - use ::test; use image::{GenericImage, ImageBuffer, Luma}; use quickcheck::{quickcheck, TestResult}; @@ -555,24 +554,6 @@ mod tests { assert_eq!(sum_image_pixels(&integral, 1, 1, 1, 1), [10, 11, 12]); } - #[bench] - fn bench_integral_image_gray(b: &mut test::Bencher) { - let image = gray_bench_image(500, 500); - b.iter(|| { - let integral = integral_image::<_, u32>(&image); - test::black_box(integral); - }); - } - - #[bench] - fn bench_integral_image_rgb(b: &mut test::Bencher) { - let image = rgb_bench_image(500, 500); - b.iter(|| { - let integral = integral_image::<_, u32>(&image); - test::black_box(integral); - }); - } - /// Simple implementation of integral_image to validate faster versions against. fn integral_image_ref(image: &I) -> Image> where @@ -611,7 +592,32 @@ mod tests { } quickcheck(prop as fn(GrayTestImage) -> TestResult); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::utils::{gray_bench_image, pixel_diff_summary, rgb_bench_image}; + use ::test; + + #[bench] + fn bench_integral_image_gray(b: &mut test::Bencher) { + let image = gray_bench_image(500, 500); + b.iter(|| { + let integral = integral_image::<_, u32>(&image); + test::black_box(integral); + }); + } + #[bench] + fn bench_integral_image_rgb(b: &mut test::Bencher) { + let image = rgb_bench_image(500, 500); + b.iter(|| { + let integral = integral_image::<_, u32>(&image); + test::black_box(integral); + }); + } #[bench] fn bench_row_running_sum(b: &mut test::Bencher) { let image = gray_bench_image(1000, 1); diff --git a/src/local_binary_patterns.rs b/src/local_binary_patterns.rs index ea198f23..e93d6fbd 100644 --- a/src/local_binary_patterns.rs +++ b/src/local_binary_patterns.rs @@ -651,7 +651,6 @@ pub static MIN_SHIFT: [u8; 256] = [ mod tests { use super::*; use image::{GrayImage, Luma}; - use test::{black_box, Bencher}; #[test] fn test_uniform_representative_2() { @@ -662,6 +661,14 @@ mod tests { let c = 0b10011001; assert_eq!(UNIFORM_REPRESENTATIVE_2[c], 0b10101010); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use image::{GrayImage, Luma}; + use test::{black_box, Bencher}; #[bench] fn bench_local_binary_pattern(b: &mut Bencher) { diff --git a/src/morphology.rs b/src/morphology.rs index 5ce344b4..b42522a0 100644 --- a/src/morphology.rs +++ b/src/morphology.rs @@ -355,7 +355,6 @@ pub fn close_mut(image: &mut GrayImage, norm: Norm, k: u8) { #[cfg(test)] mod tests { use super::*; - use ::test::*; use image::{GrayImage, Luma}; use std::cmp::{max, min}; @@ -771,6 +770,15 @@ mod tests { ); assert_pixels_eq!(eroded, expected); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use ::test::*; + use image::{GrayImage, Luma}; + use std::cmp::{max, min}; #[test] fn test_erode_dented_wall_linf_4() { diff --git a/src/noise.rs b/src/noise.rs index 685caa27..b691d88c 100644 --- a/src/noise.rs +++ b/src/noise.rs @@ -64,8 +64,9 @@ where } } +#[cfg(not(miri))] #[cfg(test)] -mod tests { +mod benches { use super::*; use image::GrayImage; use test::{black_box, Bencher}; diff --git a/src/pixelops.rs b/src/pixelops.rs index 69a14d68..ef7542c7 100644 --- a/src/pixelops.rs +++ b/src/pixelops.rs @@ -64,8 +64,6 @@ where #[cfg(test)] mod tests { use super::*; - use image::{Luma, Rgb}; - use test::{black_box, Bencher}; #[test] fn test_weighted_channel_sum() { @@ -76,6 +74,14 @@ mod tests { // Clamped assert_eq!(weighted_channel_sum(150u8, 150u8, 1.8, 0.8), 255u8); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use image::{Luma, Rgb}; + use test::{black_box, Bencher}; #[bench] fn bench_weighted_sum_rgb(b: &mut Bencher) { diff --git a/src/region_labelling.rs b/src/region_labelling.rs index 22af7302..4853408b 100644 --- a/src/region_labelling.rs +++ b/src/region_labelling.rs @@ -279,7 +279,7 @@ mod tests { // One huge component with eight-way connectivity, loads of // isolated components with four-way connectivity. - fn chessboard(width: u32, height: u32) -> GrayImage { + pub(super) fn chessboard(width: u32, height: u32) -> GrayImage { ImageBuffer::from_fn(width, height, |x, y| { if (x + y) % 2 == 0 { Luma([255u8]) @@ -306,6 +306,17 @@ mod tests { let max_component = components.pixels().map(|p| p[0]).max(); assert_eq!(max_component, Some(450u32)); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::connected_components; + use super::tests::chessboard; + use super::Connectivity::{Eight, Four}; + use crate::definitions::{HasBlack, HasWhite}; + use ::test; + use image::{GrayImage, ImageBuffer, Luma}; #[bench] fn bench_connected_components_eight_chessboard(b: &mut test::Bencher) { diff --git a/src/seam_carving.rs b/src/seam_carving.rs index a12bbdb3..f2a39446 100644 --- a/src/seam_carving.rs +++ b/src/seam_carving.rs @@ -181,8 +181,9 @@ pub fn draw_vertical_seams(image: &GrayImage, seams: &[VerticalSeam]) -> Image RgbImage { RgbImage::from_fn(width, height, |x, y| Rgb([x as u8, y as u8, (x + y) as u8])) diff --git a/src/suppress.rs b/src/suppress.rs index fe61dfae..5397b283 100644 --- a/src/suppress.rs +++ b/src/suppress.rs @@ -180,17 +180,16 @@ mod tests { use image::{GenericImage, GrayImage, ImageBuffer, Luma, Primitive}; use quickcheck::{quickcheck, TestResult}; use std::cmp; - use test::Bencher; #[derive(PartialEq, Debug, Copy, Clone)] - struct T { + pub(super) struct T { x: u32, y: u32, score: f32, } impl T { - fn new(x: u32, y: u32, score: f32) -> T { + pub(super) fn new(x: u32, y: u32, score: f32) -> T { T { x, y, score } } } @@ -236,29 +235,6 @@ mod tests { assert_eq!(max, expected); } - #[bench] - fn bench_local_maxima_dense(b: &mut Bencher) { - let mut ts = vec![]; - for x in 0..20 { - for y in 0..20 { - let score = (x * y) % 15; - ts.push(T::new(x, y, score as f32)); - } - } - b.iter(|| local_maxima(&ts, 15)); - } - - #[bench] - fn bench_local_maxima_sparse(b: &mut Bencher) { - let mut ts = vec![]; - for x in 0..20 { - for y in 0..20 { - ts.push(T::new(50 * x, 50 * y, 50f32)); - } - } - b.iter(|| local_maxima(&ts, 15)); - } - #[test] fn test_suppress_non_maximum() { let mut image = GrayImage::new(25, 25); @@ -296,45 +272,6 @@ mod tests { assert!(s.width() == 3); } - #[bench] - fn bench_suppress_non_maximum_increasing_gradient(b: &mut Bencher) { - // Increasing gradient in both directions. This can be a worst-case for - // early-abort strategies. - let img = ImageBuffer::from_fn(40, 20, |x, y| Luma([(x + y) as u8])); - b.iter(|| suppress_non_maximum(&img, 7)); - } - - #[bench] - fn bench_suppress_non_maximum_decreasing_gradient(b: &mut Bencher) { - let width = 40u32; - let height = 20u32; - let img = ImageBuffer::from_fn(width, height, |x, y| { - Luma([((width - x) + (height - y)) as u8]) - }); - b.iter(|| suppress_non_maximum(&img, 7)); - } - - #[bench] - fn bench_suppress_non_maximum_noise_7(b: &mut Bencher) { - let mut img: GrayImage = ImageBuffer::new(40, 20); - gaussian_noise_mut(&mut img, 128f64, 30f64, 1); - b.iter(|| suppress_non_maximum(&img, 7)); - } - - #[bench] - fn bench_suppress_non_maximum_noise_3(b: &mut Bencher) { - let mut img: GrayImage = ImageBuffer::new(40, 20); - gaussian_noise_mut(&mut img, 128f64, 30f64, 1); - b.iter(|| suppress_non_maximum(&img, 3)); - } - - #[bench] - fn bench_suppress_non_maximum_noise_1(b: &mut Bencher) { - let mut img: GrayImage = ImageBuffer::new(40, 20); - gaussian_noise_mut(&mut img, 128f64, 30f64, 1); - b.iter(|| suppress_non_maximum(&img, 1)); - } - /// Reference implementation of suppress_non_maximum. Used to validate /// the (presumably faster) actual implementation. fn suppress_non_maximum_reference(image: &I, radius: u32) -> ImageBuffer, Vec> @@ -403,3 +340,74 @@ mod tests { assert_eq!((4u32..4).step_by(4).collect::>(), vec![]); } } + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::{local_maxima, suppress_non_maximum, tests::T}; + use crate::noise::gaussian_noise_mut; + use image::{GenericImage, GrayImage, ImageBuffer, Luma, Primitive}; + use test::Bencher; + + #[bench] + fn bench_local_maxima_dense(b: &mut Bencher) { + let mut ts = vec![]; + for x in 0..20 { + for y in 0..20 { + let score = (x * y) % 15; + ts.push(T::new(x, y, score as f32)); + } + } + b.iter(|| local_maxima(&ts, 15)); + } + + #[bench] + fn bench_local_maxima_sparse(b: &mut Bencher) { + let mut ts = vec![]; + for x in 0..20 { + for y in 0..20 { + ts.push(T::new(50 * x, 50 * y, 50f32)); + } + } + b.iter(|| local_maxima(&ts, 15)); + } + + #[bench] + fn bench_suppress_non_maximum_increasing_gradient(b: &mut Bencher) { + // Increasing gradient in both directions. This can be a worst-case for + // early-abort strategies. + let img = ImageBuffer::from_fn(40, 20, |x, y| Luma([(x + y) as u8])); + b.iter(|| suppress_non_maximum(&img, 7)); + } + + #[bench] + fn bench_suppress_non_maximum_decreasing_gradient(b: &mut Bencher) { + let width = 40u32; + let height = 20u32; + let img = ImageBuffer::from_fn(width, height, |x, y| { + Luma([((width - x) + (height - y)) as u8]) + }); + b.iter(|| suppress_non_maximum(&img, 7)); + } + + #[bench] + fn bench_suppress_non_maximum_noise_7(b: &mut Bencher) { + let mut img: GrayImage = ImageBuffer::new(40, 20); + gaussian_noise_mut(&mut img, 128f64, 30f64, 1); + b.iter(|| suppress_non_maximum(&img, 7)); + } + + #[bench] + fn bench_suppress_non_maximum_noise_3(b: &mut Bencher) { + let mut img: GrayImage = ImageBuffer::new(40, 20); + gaussian_noise_mut(&mut img, 128f64, 30f64, 1); + b.iter(|| suppress_non_maximum(&img, 3)); + } + + #[bench] + fn bench_suppress_non_maximum_noise_1(b: &mut Bencher) { + let mut img: GrayImage = ImageBuffer::new(40, 20); + gaussian_noise_mut(&mut img, 128f64, 30f64, 1); + b.iter(|| suppress_non_maximum(&img, 1)); + } +} diff --git a/src/template_matching.rs b/src/template_matching.rs index 0120efbf..84db112b 100644 --- a/src/template_matching.rs +++ b/src/template_matching.rs @@ -278,7 +278,6 @@ mod tests { use super::*; use crate::utils::gray_bench_image; use image::GrayImage; - use test::{black_box, Bencher}; #[test] #[should_panic] @@ -418,6 +417,32 @@ mod tests { assert_pixels_eq!(actual, expected); } + #[test] + fn test_find_extremes() { + let image = gray_image!( + 10, 7, 8, 1; + 9, 15, 4, 2 + ); + + let expected = Extremes { + max_value: 15, + min_value: 1, + max_value_location: (1, 1), + min_value_location: (3, 0), + }; + + assert_eq!(find_extremes(&image), expected); + } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::utils::gray_bench_image; + use image::GrayImage; + use test::{black_box, Bencher}; + macro_rules! bench_match_template { ($name:ident, image_size: $s:expr, template_size: $t:expr, method: $m:expr) => { #[bench] @@ -468,21 +493,4 @@ mod tests { image_size: 100, template_size: 16, method: MatchTemplateMethod::SumOfSquaredErrorsNormalized); - - #[test] - fn test_find_extremes() { - let image = gray_image!( - 10, 7, 8, 1; - 9, 15, 4, 2 - ); - - let expected = Extremes { - max_value: 15, - min_value: 1, - max_value_location: (1, 1), - min_value_location: (3, 0), - }; - - assert_eq!(find_extremes(&image), expected); - } } diff --git a/src/union_find.rs b/src/union_find.rs index 18362b48..76813e0a 100644 --- a/src/union_find.rs +++ b/src/union_find.rs @@ -177,6 +177,15 @@ mod tests { assert_eq!(forest.parent, vec![1, 1, 1, 1, 0, 5]); assert_eq!(forest.num_trees(), 2); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use rand::{rngs::StdRng, SeedableRng}; + use rand_distr::{Distribution, Uniform}; + use test::Bencher; #[bench] fn bench_disjoint_set_forest(b: &mut test::Bencher) { diff --git a/tests/regression.rs b/tests/regression.rs index 6081f5e1..1745680a 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -10,6 +10,8 @@ //! //! [caltech256 dataset]: https://authors.library.caltech.edu/7694/ +#![cfg(not(miri))] + #[macro_use] extern crate imageproc;