1use image::{GenericImageView, ImageBuffer, Rgb};
2
3use rvimage_domain::{pos_transform, BbF, Calc, PtF, ShapeI, TPtF};
4
5pub type ImageU8 = ImageBuffer<Rgb<u8>, Vec<u8>>;
6
7pub fn scale_coord<T>(x: T, size_from: T, size_to: T) -> T
9where
10 T: Calc,
11{
12 x * size_to / size_from
13}
14
15fn coord_view_2_orig(x: TPtF, n_transformed: TPtF, n_orig: TPtF, off: TPtF) -> TPtF {
16 off + scale_coord(x, n_transformed, n_orig)
17}
18
19pub fn pos_2_orig_pos(
21 view_pos: PtF,
22 shape_orig: ShapeI,
23 shape_win: ShapeI,
24 zoom_box: &Option<BbF>,
25) -> PtF {
26 pos_transform(view_pos, shape_orig, shape_win, zoom_box, coord_view_2_orig)
27}
28fn coord_orig_2_view(x: f64, n_transformed: f64, n_orig: f64, off: f64) -> f64 {
29 scale_coord(x - off, n_orig, n_transformed)
30}
31
32pub fn pos_from_orig_pos(
34 orig_pos: PtF,
35 shape_orig: ShapeI,
36 shape_win: ShapeI,
37 zoom_box: &Option<BbF>,
38) -> Option<PtF> {
39 if let Some(zb) = zoom_box {
40 if !zb.contains(orig_pos) {
41 return None;
42 }
43 }
44 Some(pos_transform(
45 orig_pos,
46 shape_orig,
47 shape_win,
48 zoom_box,
49 coord_orig_2_view,
50 ))
51}
52#[must_use]
53pub fn from_orig(im_orig: &ImageU8, zoom_box: Option<BbF>) -> ImageU8 {
54 if let Some(zoom_box) = zoom_box {
55 im_orig
56 .view(
57 zoom_box.x.round() as u32,
58 zoom_box.y.round() as u32,
59 zoom_box.w.round() as u32,
60 zoom_box.h.round() as u32,
61 )
62 .to_image()
63 } else {
64 im_orig.clone()
65 }
66}
67
68#[must_use]
69pub fn project_on_bb(p: PtF, bb: &BbF) -> PtF {
70 let x = p.x.max(bb.x).min(bb.x + bb.w - 1.0);
71 let y = p.y.max(bb.y).min(bb.y + bb.h - 1.0);
72 PtF { x, y }
73}
74
75#[test]
76fn test_project() {
77 let bb = BbF::from_arr(&[5.0, 5.0, 10.0, 10.0]);
78 assert_eq!(
79 PtF { x: 5.0, y: 5.0 },
80 project_on_bb((0.0, 0.0).into(), &bb)
81 );
82 assert_eq!(
83 PtF { x: 14.0, y: 14.0 },
84 project_on_bb((15.0, 20.0).into(), &bb)
85 );
86 assert_eq!(
87 PtF { x: 10.0, y: 14.0 },
88 project_on_bb((10.0, 15.0).into(), &bb)
89 );
90 assert_eq!(
91 PtF { x: 14.0, y: 14.0 },
92 project_on_bb((20.0, 15.0).into(), &bb)
93 );
94}