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