From c0d659728958775863c85a8e314705e04775db37 Mon Sep 17 00:00:00 2001 From: Paolo Barbolini Date: Sat, 30 Mar 2024 09:00:07 +0100 Subject: [PATCH] Drop conv dependency --- Cargo.toml | 1 - src/drawing/text.rs | 5 ++--- src/filter/mod.rs | 20 ++++++++--------- src/geometric_transformations.rs | 38 +++++++++++++++----------------- src/math.rs | 13 ----------- src/noise.rs | 8 +++---- src/pixelops.rs | 10 ++++----- src/stats.rs | 14 +++++------- 8 files changed, 42 insertions(+), 67 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 59153442..1fe9dbab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ display-window = ["sdl2"] [dependencies] ab_glyph = "0.2.23" approx = "0.5" -conv = "0.3.3" image = { version = "0.25.0", default-features = false } itertools = "0.12" nalgebra = { version = "0.32", default-features = false, features = ["std"] } diff --git a/src/drawing/text.rs b/src/drawing/text.rs index c22eca58..d98ced86 100644 --- a/src/drawing/text.rs +++ b/src/drawing/text.rs @@ -1,4 +1,3 @@ -use conv::ValueInto; use image::{GenericImage, ImageBuffer, Pixel}; use std::f32; @@ -59,7 +58,7 @@ pub fn draw_text_mut( text: &str, ) where C: Canvas, - ::Subpixel: ValueInto + Clamp, + ::Subpixel: Into + Clamp, { let image_width = canvas.width() as i32; let image_height = canvas.height() as i32; @@ -97,7 +96,7 @@ pub fn draw_text( ) -> Image where I: GenericImage, - ::Subpixel: ValueInto + Clamp, + ::Subpixel: Into + Clamp, { let mut out = ImageBuffer::new(image.width(), image.height()); out.copy_from(image, 0, 0).unwrap(); diff --git a/src/filter/mod.rs b/src/filter/mod.rs index 5a457405..810d51c8 100644 --- a/src/filter/mod.rs +++ b/src/filter/mod.rs @@ -13,8 +13,6 @@ use crate::integral_image::{column_running_sum, row_running_sum}; use crate::map::{ChannelMap, WithChannel}; use num::{abs, pow, Num}; -use crate::math::cast; -use conv::ValueInto; use std::cmp::{max, min}; use std::f32; @@ -237,7 +235,7 @@ impl<'a, K: Num + Copy + 'a> Kernel<'a, K> { pub fn filter(&self, image: &Image

, mut f: F) -> Image where P: Pixel, -

::Subpixel: ValueInto, +

::Subpixel: Into, Q: Pixel, F: FnMut(&mut Q::Subpixel, K), { @@ -304,7 +302,7 @@ fn gaussian_kernel_f32(sigma: f32) -> Vec { pub fn gaussian_blur_f32

(image: &Image

, sigma: f32) -> Image

where P: Pixel, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, { assert!(sigma > 0.0, "sigma must be > 0.0"); let kernel = gaussian_kernel_f32(sigma); @@ -317,7 +315,7 @@ where pub fn separable_filter(image: &Image

, h_kernel: &[K], v_kernel: &[K]) -> Image

where P: Pixel, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, K: Num + Copy, { let h = horizontal_filter(image, h_kernel); @@ -330,7 +328,7 @@ where pub fn separable_filter_equal(image: &Image

, kernel: &[K]) -> Image

where P: Pixel, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, K: Num + Copy, { separable_filter(image, kernel, kernel) @@ -341,7 +339,7 @@ where #[must_use = "the function does not modify the original image"] pub fn filter3x3(image: &Image

, kernel: &[K]) -> Image> where - P::Subpixel: ValueInto, + P::Subpixel: Into, S: Clamp + Primitive, P: WithChannel, K: Num + Copy, @@ -357,7 +355,7 @@ where pub fn horizontal_filter(image: &Image

, kernel: &[K]) -> Image

where P: Pixel, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, K: Num + Copy, { // Don't replace this with a call to Kernel::filter without @@ -453,7 +451,7 @@ where pub fn vertical_filter(image: &Image

, kernel: &[K]) -> Image

where P: Pixel, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, K: Num + Copy, { // Don't replace this with a call to Kernel::filter without @@ -550,11 +548,11 @@ where fn accumulate(acc: &mut [K], pixel: &P, weight: K) where P: Pixel, -

::Subpixel: ValueInto, +

::Subpixel: Into, K: Num + Copy, { for i in 0..(P::CHANNEL_COUNT as usize) { - acc[i] = acc[i] + cast(pixel.channels()[i]) * weight; + acc[i] = acc[i] + pixel.channels()[i].into() * weight; } } diff --git a/src/geometric_transformations.rs b/src/geometric_transformations.rs index 061f50a6..e8d5128d 100644 --- a/src/geometric_transformations.rs +++ b/src/geometric_transformations.rs @@ -2,8 +2,6 @@ //! projective transformations. use crate::definitions::{Clamp, Image}; -use crate::math::cast; -use conv::ValueInto; use image::{GenericImageView, ImageBuffer, Pixel}; #[cfg(feature = "rayon")] use rayon::prelude::*; @@ -286,7 +284,7 @@ pub fn rotate_about_center

( where P: Pixel + Send + Sync,

::Subpixel: Send + Sync, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, { let (w, h) = image.dimensions(); rotate( @@ -311,7 +309,7 @@ pub fn rotate

( where P: Pixel + Send + Sync,

::Subpixel: Send + Sync, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, { let (cx, cy) = center; let projection = @@ -384,7 +382,7 @@ pub fn warp

( where P: Pixel + Send + Sync,

::Subpixel: Send + Sync, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, { let (width, height) = image.dimensions(); let mut out = ImageBuffer::new(width, height); @@ -404,7 +402,7 @@ pub fn warp_into

( ) where P: Pixel + Send + Sync,

::Subpixel: Send + Sync, -

::Subpixel: ValueInto + Clamp + Sync, +

::Subpixel: Into + Clamp + Sync, { let projection = projection.invert(); let nn = |x, y| interpolate_nearest(image, x, y, default); @@ -456,7 +454,7 @@ where F: Fn(f32, f32) -> (f32, f32) + Sync + Send, P: Pixel + Send + Sync,

::Subpixel: Send + Sync, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, { let (width, height) = image.dimensions(); let mut out = ImageBuffer::new(width, height); @@ -478,7 +476,7 @@ pub fn warp_into_with( F: Fn(f32, f32) -> (f32, f32) + Send + Sync, P: Pixel + Send + Sync,

::Subpixel: Send + Sync, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, { let nn = |x, y| interpolate_nearest(image, x, y, default); let bl = |x, y| interpolate_bilinear(image, x, y, default); @@ -498,7 +496,7 @@ fn warp_inner(out: &mut Image

, mapping: Fc, get_pixel: Fi) where P: Pixel,

::Subpixel: Send + Sync, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, Fc: Fn(f32, f32) -> (f32, f32) + Send + Sync, Fi: Fn(f32, f32) -> P + Send + Sync, { @@ -600,15 +598,15 @@ fn mul3x3(a: [f32; 9], b: [f32; 9]) -> [f32; 9] { fn blend_cubic

(px0: &P, px1: &P, px2: &P, px3: &P, x: f32) -> P where P: Pixel, - P::Subpixel: ValueInto + Clamp, + P::Subpixel: Into + Clamp, { let mut outp = *px0; for i in 0..(P::CHANNEL_COUNT as usize) { - let p0 = cast(px0.channels()[i]); - let p1 = cast(px1.channels()[i]); - let p2 = cast(px2.channels()[i]); - let p3 = cast(px3.channels()[i]); + let p0 = px0.channels()[i].into(); + let p1 = px1.channels()[i].into(); + let p2 = px2.channels()[i].into(); + let p3 = px3.channels()[i].into(); #[rustfmt::skip] let pval = p1 + 0.5 * x * (p2 - p0 + x * (2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3 + x * (3.0 * (p1 - p2) + p3 - p0))); outp.channels_mut()[i] =

::Subpixel::clamp(pval); @@ -620,7 +618,7 @@ where fn interpolate_bicubic

(image: &Image

, x: f32, y: f32, default: P) -> P where P: Pixel, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, { let left = x.floor() - 1f32; let right = left + 4f32; @@ -664,25 +662,25 @@ fn blend_bilinear

( ) -> P where P: Pixel, - P::Subpixel: ValueInto + Clamp, + P::Subpixel: Into + Clamp, { let top = top_left.map2(&top_right, |u, v| { - P::Subpixel::clamp((1f32 - right_weight) * cast(u) + right_weight * cast(v)) + P::Subpixel::clamp((1f32 - right_weight) * u.into() + right_weight * v.into()) }); let bottom = bottom_left.map2(&bottom_right, |u, v| { - P::Subpixel::clamp((1f32 - right_weight) * cast(u) + right_weight * cast(v)) + P::Subpixel::clamp((1f32 - right_weight) * u.into() + right_weight * v.into()) }); top.map2(&bottom, |u, v| { - P::Subpixel::clamp((1f32 - bottom_weight) * cast(u) + bottom_weight * cast(v)) + P::Subpixel::clamp((1f32 - bottom_weight) * u.into() + bottom_weight * v.into()) }) } fn interpolate_bilinear

(image: &Image

, x: f32, y: f32, default: P) -> P where P: Pixel, -

::Subpixel: ValueInto + Clamp, +

::Subpixel: Into + Clamp, { let left = x.floor(); let right = left + 1f32; diff --git a/src/math.rs b/src/math.rs index 400fe320..d7200a7a 100644 --- a/src/math.rs +++ b/src/math.rs @@ -1,7 +1,5 @@ //! Assorted mathematical helper functions. -use conv::ValueInto; - /// L1 norm of a vector. pub fn l1_norm(xs: &[f32]) -> f32 { xs.iter().fold(0f32, |acc, x| acc + x.abs()) @@ -11,14 +9,3 @@ pub fn l1_norm(xs: &[f32]) -> f32 { pub fn l2_norm(xs: &[f32]) -> f32 { xs.iter().fold(0f32, |acc, x| acc + x * x).sqrt() } - -/// Helper for a conversion that we know can't fail. -pub fn cast(x: T) -> U -where - T: ValueInto, -{ - match x.value_into() { - Ok(y) => y, - Err(_) => panic!("Failed to convert"), - } -} diff --git a/src/noise.rs b/src/noise.rs index 21d3a4bd..685caa27 100644 --- a/src/noise.rs +++ b/src/noise.rs @@ -1,8 +1,6 @@ //! Functions for adding synthetic noise to images. use crate::definitions::{Clamp, HasBlack, HasWhite, Image}; -use crate::math::cast; -use conv::ValueInto; use image::Pixel; use rand::{rngs::StdRng, SeedableRng}; use rand_distr::{Distribution, Normal, Uniform}; @@ -12,7 +10,7 @@ use rand_distr::{Distribution, Normal, Uniform}; pub fn gaussian_noise

(image: &Image

, mean: f64, stddev: f64, seed: u64) -> Image

where P: Pixel, - P::Subpixel: ValueInto + Clamp, + P::Subpixel: Into + Clamp, { let mut out = image.clone(); gaussian_noise_mut(&mut out, mean, stddev, seed); @@ -24,7 +22,7 @@ where pub fn gaussian_noise_mut

(image: &mut Image

, mean: f64, stddev: f64, seed: u64) where P: Pixel, - P::Subpixel: ValueInto + Clamp, + P::Subpixel: Into + Clamp, { let mut rng: StdRng = SeedableRng::seed_from_u64(seed); let normal = Normal::new(mean, stddev).unwrap(); @@ -32,7 +30,7 @@ where for p in image.pixels_mut() { for c in p.channels_mut() { let noise = normal.sample(&mut rng); - *c = P::Subpixel::clamp(cast(*c) + noise); + *c = P::Subpixel::clamp((*c).into() + noise); } } } diff --git a/src/pixelops.rs b/src/pixelops.rs index 573d8f56..69a14d68 100644 --- a/src/pixelops.rs +++ b/src/pixelops.rs @@ -1,8 +1,6 @@ //! Pixel manipulations. use crate::definitions::Clamp; -use crate::math::cast; -use conv::ValueInto; use image::Pixel; /// Adds pixels with the given weights. Results are clamped to prevent arithmetical overflows. @@ -24,7 +22,7 @@ use image::Pixel; /// ``` pub fn weighted_sum(left: P, right: P, left_weight: f32, right_weight: f32) -> P where - P::Subpixel: ValueInto + Clamp, + P::Subpixel: Into + Clamp, { left.map2(&right, |p, q| { weighted_channel_sum(p, q, left_weight, right_weight) @@ -50,7 +48,7 @@ where /// ``` pub fn interpolate(left: P, right: P, left_weight: f32) -> P where - P::Subpixel: ValueInto + Clamp, + P::Subpixel: Into + Clamp, { weighted_sum(left, right, left_weight, 1.0 - left_weight) } @@ -58,9 +56,9 @@ where #[inline(always)] fn weighted_channel_sum(left: C, right: C, left_weight: f32, right_weight: f32) -> C where - C: ValueInto + Clamp, + C: Into + Clamp, { - Clamp::clamp(cast(left) * left_weight + cast(right) * right_weight) + Clamp::clamp(left.into() * left_weight + right.into() * right_weight) } #[cfg(test)] diff --git a/src/stats.rs b/src/stats.rs index 811fbefc..b1883b0c 100644 --- a/src/stats.rs +++ b/src/stats.rs @@ -1,8 +1,6 @@ //! Statistical properties of images. use crate::definitions::Image; -use crate::math::cast; -use conv::ValueInto; use image::{GenericImageView, GrayImage, Pixel, Primitive}; use num::Bounded; @@ -110,7 +108,7 @@ where I: GenericImageView, J: GenericImageView, P: Pixel, - P::Subpixel: ValueInto, + P::Subpixel: Into, { mean_squared_error(left, right).sqrt() } @@ -124,9 +122,9 @@ where I: GenericImageView, J: GenericImageView, P: Pixel, - P::Subpixel: ValueInto + Primitive, + P::Subpixel: Into + Primitive, { - let max: f64 = cast(::max_value()); + let max: f64 = ::max_value().into(); let mse = mean_squared_error(original, noisy); 20f64 * max.log(10f64) - 10f64 * mse.log(10f64) } @@ -136,14 +134,14 @@ where I: GenericImageView, J: GenericImageView, P: Pixel, - P::Subpixel: ValueInto, + P::Subpixel: Into, { assert_dimensions_match!(left, right); let mut sum_squared_diffs = 0f64; for (p, q) in left.pixels().zip(right.pixels()) { for (c, d) in p.2.channels().iter().zip(q.2.channels().iter()) { - let fc: f64 = cast(*c); - let fd: f64 = cast(*d); + let fc: f64 = (*c).into(); + let fd: f64 = (*d).into(); let diff = fc - fd; sum_squared_diffs += diff * diff; }