apple_vision/registration/
mod.rs1#![allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]
2#![allow(clippy::too_long_first_doc_paragraph)]
3use std::ffi::{CStr, CString};
8use std::path::Path;
9use std::ptr;
10
11use crate::error::VisionError;
12use crate::ffi;
13
14#[derive(Debug, Clone, Copy, PartialEq)]
17pub struct TranslationalAlignment {
18 pub tx: f64,
19 pub ty: f64,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq)]
25pub struct HomographicAlignment {
26 pub matrix: [[f32; 3]; 3],
27}
28
29pub fn register_translational(
36 target: impl AsRef<Path>,
37 floating: impl AsRef<Path>,
38) -> Result<TranslationalAlignment, VisionError> {
39 let target_str = target.as_ref().to_str().ok_or_else(|| VisionError::InvalidArgument("non-UTF-8 target path".into()))?;
40 let tp = CString::new(target_str).map_err(|e| VisionError::InvalidArgument(format!("target path NUL byte: {e}")))?;
41 let floating_str = floating.as_ref().to_str().ok_or_else(|| VisionError::InvalidArgument("non-UTF-8 floating path".into()))?;
42 let fp = CString::new(floating_str).map_err(|e| VisionError::InvalidArgument(format!("floating path NUL byte: {e}")))?;
43 let mut out = ffi::TranslationalAlignmentRaw { tx: 0.0, ty: 0.0 };
44 let mut err: *mut std::ffi::c_char = ptr::null_mut();
45 let status = unsafe {
46 ffi::vn_register_translational_in_paths(tp.as_ptr(), fp.as_ptr(), &mut out, &mut err)
47 };
48 if status != ffi::status::OK {
49 let msg = unsafe { take_err(err) };
50 return Err(VisionError::RequestFailed(msg));
51 }
52 Ok(TranslationalAlignment {
53 tx: out.tx,
54 ty: out.ty,
55 })
56}
57
58pub fn register_homographic(
66 target: impl AsRef<Path>,
67 floating: impl AsRef<Path>,
68) -> Result<HomographicAlignment, VisionError> {
69 let target_str = target.as_ref().to_str().ok_or_else(|| VisionError::InvalidArgument("non-UTF-8 target path".into()))?;
70 let tp = CString::new(target_str).map_err(|e| VisionError::InvalidArgument(format!("target path NUL byte: {e}")))?;
71 let floating_str = floating.as_ref().to_str().ok_or_else(|| VisionError::InvalidArgument("non-UTF-8 floating path".into()))?;
72 let fp = CString::new(floating_str).map_err(|e| VisionError::InvalidArgument(format!("floating path NUL byte: {e}")))?;
73 let mut out = ffi::HomographicAlignmentRaw {
74 m00: 0.0,
75 m01: 0.0,
76 m02: 0.0,
77 m10: 0.0,
78 m11: 0.0,
79 m12: 0.0,
80 m20: 0.0,
81 m21: 0.0,
82 m22: 0.0,
83 _pad: 0.0,
84 };
85 let mut err: *mut std::ffi::c_char = ptr::null_mut();
86 let status = unsafe {
87 ffi::vn_register_homographic_in_paths(tp.as_ptr(), fp.as_ptr(), &mut out, &mut err)
88 };
89 if status != ffi::status::OK {
90 let msg = unsafe { take_err(err) };
91 return Err(VisionError::RequestFailed(msg));
92 }
93 Ok(HomographicAlignment {
94 matrix: [
95 [out.m00, out.m01, out.m02],
96 [out.m10, out.m11, out.m12],
97 [out.m20, out.m21, out.m22],
98 ],
99 })
100}
101
102unsafe fn take_err(p: *mut std::ffi::c_char) -> String {
103 if p.is_null() {
104 return String::new();
105 }
106 let s = unsafe { CStr::from_ptr(p) }.to_string_lossy().into_owned();
107 unsafe { libc::free(p.cast()) };
108 s
109}