resvg/filter/
displacement_map.rs1use super::{ImageRef, ImageRefMut};
5use usvg::filter::{ColorChannel, DisplacementMap};
6
7pub fn apply(
18 fe: &DisplacementMap,
19 sx: f32,
20 sy: f32,
21 src: ImageRef,
22 map: ImageRef,
23 dest: ImageRefMut,
24) {
25 assert!(src.width == map.width && src.width == dest.width);
26 assert!(src.height == map.height && src.height == dest.height);
27
28 let w = src.width as i32;
29 let h = src.height as i32;
30
31 let mut x: u32 = 0;
32 let mut y: u32 = 0;
33 for pixel in map.data.iter() {
34 let calc_offset = |channel| {
35 let c = match channel {
36 ColorChannel::B => pixel.b,
37 ColorChannel::G => pixel.g,
38 ColorChannel::R => pixel.r,
39 ColorChannel::A => pixel.a,
40 };
41
42 c as f32 / 255.0 - 0.5
43 };
44
45 let dx = calc_offset(fe.x_channel_selector());
46 let dy = calc_offset(fe.y_channel_selector());
47 let ox = (x as f32 + dx * sx * fe.scale()).round() as i32;
48 let oy = (y as f32 + dy * sy * fe.scale()).round() as i32;
49
50 if x < w as u32 && y < h as u32 && ox >= 0 && ox < w && oy >= 0 && oy < h {
53 let idx = (oy * w + ox) as usize;
54 let idx1 = (y * w as u32 + x) as usize;
55 dest.data[idx1] = src.data[idx];
56 }
57
58 x += 1;
59 if x == src.width {
60 x = 0;
61 y += 1;
62 }
63 }
64}