apple_vision/trajectories/
mod.rs1#![allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]
2#![allow(clippy::too_long_first_doc_paragraph)]
3use std::ffi::{CStr, CString};
6use std::path::Path;
7use std::ptr;
8
9use crate::error::VisionError;
10use crate::ffi;
11
12#[derive(Debug, Clone, Copy, PartialEq)]
14pub struct Trajectory {
15 pub detected_x: f64,
16 pub detected_y: f64,
17 pub projected_x: f64,
18 pub projected_y: f64,
19 pub equation_a: f64,
21 pub equation_b: f64,
22 pub equation_c: f64,
23 pub confidence: f32,
24}
25
26pub fn detect_trajectories(
36 path: impl AsRef<Path>,
37 trajectory_length: usize,
38) -> Result<Vec<Trajectory>, VisionError> {
39 let path_str = path.as_ref().to_str().ok_or_else(|| VisionError::InvalidArgument("non-UTF-8 path".into()))?;
40 let cpath = CString::new(path_str).map_err(|e| VisionError::InvalidArgument(format!("path NUL byte: {e}")))?;
41 let mut traj_ptr: *mut ffi::TrajectoryRaw = ptr::null_mut();
42 let mut count: isize = 0;
43 let mut err: *mut std::ffi::c_char = ptr::null_mut();
44 let status = unsafe {
45 ffi::vn_detect_trajectories_in_path(
46 cpath.as_ptr(),
47 trajectory_length as isize,
48 &mut traj_ptr,
49 &mut count,
50 &mut err,
51 )
52 };
53 if status != ffi::status::OK {
54 let msg = unsafe { take_err(err) };
55 return Err(VisionError::RequestFailed(msg));
56 }
57 let mut out = Vec::with_capacity(count.max(0) as usize);
58 for i in 0..count {
59 let t = unsafe { traj_ptr.offset(i).read() };
60 out.push(Trajectory {
61 detected_x: t.detected_x,
62 detected_y: t.detected_y,
63 projected_x: t.projected_x,
64 projected_y: t.projected_y,
65 equation_a: t.equation_a,
66 equation_b: t.equation_b,
67 equation_c: t.equation_c,
68 confidence: t.confidence,
69 });
70 }
71 if !traj_ptr.is_null() {
72 unsafe { ffi::vn_trajectories_free(traj_ptr, count) };
73 }
74 Ok(out)
75}
76
77unsafe fn take_err(p: *mut std::ffi::c_char) -> String {
78 if p.is_null() {
79 return String::new();
80 }
81 let s = unsafe { CStr::from_ptr(p) }.to_string_lossy().into_owned();
82 unsafe { libc::free(p.cast()) };
83 s
84}