1use crate::definitions::Clamp;
4use crate::math::cast;
5use conv::ValueInto;
6use image::Pixel;
7
8pub fn weighted_sum<P: Pixel>(left: P, right: P, left_weight: f32, right_weight: f32) -> P
26where
27 P::Subpixel: ValueInto<f32> + Clamp<f32>,
28{
29 left.map2(&right, |p, q| {
30 weighted_channel_sum(p, q, left_weight, right_weight)
31 })
32}
33
34pub fn interpolate<P: Pixel>(left: P, right: P, left_weight: f32) -> P
52where
53 P::Subpixel: ValueInto<f32> + Clamp<f32>,
54{
55 weighted_sum(left, right, left_weight, 1.0 - left_weight)
56}
57
58#[inline(always)]
59fn weighted_channel_sum<C>(left: C, right: C, left_weight: f32, right_weight: f32) -> C
60where
61 C: ValueInto<f32> + Clamp<f32>,
62{
63 Clamp::clamp(cast(left) * left_weight + cast(right) * right_weight)
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use image::{Luma, Rgb};
70 use test::{black_box, Bencher};
71
72 #[test]
73 fn test_weighted_channel_sum() {
74 assert_eq!(weighted_channel_sum(10u8, 20u8, 0.5, 0.5), 15u8);
76 assert_eq!(weighted_channel_sum(10u8, 20u8, 0.9, 0.1), 11u8);
78 assert_eq!(weighted_channel_sum(150u8, 150u8, 1.8, 0.8), 255u8);
80 }
81
82 #[bench]
83 fn bench_weighted_sum_rgb(b: &mut Bencher) {
84 b.iter(|| {
85 let left = black_box(Rgb([10u8, 20u8, 33u8]));
86 let right = black_box(Rgb([80u8, 70u8, 60u8]));
87 let left_weight = black_box(0.3);
88 let right_weight = black_box(0.7);
89 black_box(weighted_sum(left, right, left_weight, right_weight));
90 })
91 }
92
93 #[bench]
94 fn bench_weighted_sum_gray(b: &mut Bencher) {
95 b.iter(|| {
96 let left = black_box(Luma([10u8]));
97 let right = black_box(Luma([80u8]));
98 let left_weight = black_box(0.3);
99 let right_weight = black_box(0.7);
100 black_box(weighted_sum(left, right, left_weight, right_weight));
101 })
102 }
103
104 #[bench]
105 fn bench_interpolate_rgb(b: &mut Bencher) {
106 b.iter(|| {
107 let left = black_box(Rgb([10u8, 20u8, 33u8]));
108 let right = black_box(Rgb([80u8, 70u8, 60u8]));
109 let left_weight = black_box(0.3);
110 black_box(interpolate(left, right, left_weight));
111 })
112 }
113
114 #[bench]
115 fn bench_interpolate_gray(b: &mut Bencher) {
116 b.iter(|| {
117 let left = black_box(Luma([10u8]));
118 let right = black_box(Luma([80u8]));
119 let left_weight = black_box(0.3);
120 black_box(interpolate(left, right, left_weight));
121 })
122 }
123}