Skip to main content

apple_vision/ffi/
mod.rs

1//! Raw FFI declarations matching the Swift bridge in
2//! `swift-bridge/Sources/VisionBridge/Vision.swift`.
3
4#![allow(missing_docs, non_camel_case_types)]
5
6use core::ffi::{c_char, c_void};
7
8/// Mirrors `VNRecognizedTextRaw` in Vision.swift. Layout-compatible.
9#[repr(C)]
10pub struct RecognizedTextRaw {
11    pub text: *mut c_char,
12    pub confidence: f32,
13    pub bbox_x: f64,
14    pub bbox_y: f64,
15    pub bbox_w: f64,
16    pub bbox_h: f64,
17}
18
19/// Mirrors `VNDetectedFaceRaw` in Vision.swift. Layout-compatible.
20#[repr(C)]
21pub struct DetectedFaceRaw {
22    pub bbox_x: f64,
23    pub bbox_y: f64,
24    pub bbox_w: f64,
25    pub bbox_h: f64,
26    pub confidence: f32,
27    pub roll: f32,
28    pub yaw: f32,
29    pub pitch: f32,
30}
31
32/// Mirrors `VNDetectedBarcodeRaw` in Vision.swift. Layout-compatible.
33#[repr(C)]
34pub struct DetectedBarcodeRaw {
35    pub payload: *mut c_char,
36    pub symbology: *mut c_char,
37    pub confidence: f32,
38    pub bbox_x: f64,
39    pub bbox_y: f64,
40    pub bbox_w: f64,
41    pub bbox_h: f64,
42}
43
44/// Mirrors `VNSaliencyRegionRaw` in Vision.swift. Layout-compatible.
45#[repr(C)]
46pub struct SaliencyRegionRaw {
47    pub confidence: f32,
48    pub bbox_x: f64,
49    pub bbox_y: f64,
50    pub bbox_w: f64,
51    pub bbox_h: f64,
52}
53
54/// Mirrors `VNFaceLandmarksRaw` in Vision.swift. Layout-compatible.
55///
56/// All `*_count` fields are NUMBER OF POINTS; each point buffer is an
57/// interleaved `[x0, y0, x1, y1, …]` array of doubles, length
58/// `count * 2`. A NULL pointer + 0 count means the region wasn't
59/// produced for this face.
60#[repr(C)]
61pub struct FaceLandmarksRaw {
62    pub bbox_x: f64,
63    pub bbox_y: f64,
64    pub bbox_w: f64,
65    pub bbox_h: f64,
66    pub confidence: f32,
67    pub roll: f32,
68    pub yaw: f32,
69    pub pitch: f32,
70
71    pub face_contour: *mut f64,
72    pub face_contour_count: usize,
73    pub left_eye: *mut f64,
74    pub left_eye_count: usize,
75    pub right_eye: *mut f64,
76    pub right_eye_count: usize,
77    pub left_eyebrow: *mut f64,
78    pub left_eyebrow_count: usize,
79    pub right_eyebrow: *mut f64,
80    pub right_eyebrow_count: usize,
81    pub nose: *mut f64,
82    pub nose_count: usize,
83    pub nose_crest: *mut f64,
84    pub nose_crest_count: usize,
85    pub median_line: *mut f64,
86    pub median_line_count: usize,
87    pub outer_lips: *mut f64,
88    pub outer_lips_count: usize,
89    pub inner_lips: *mut f64,
90    pub inner_lips_count: usize,
91    pub left_pupil: *mut f64,
92    pub left_pupil_count: usize,
93    pub right_pupil: *mut f64,
94    pub right_pupil_count: usize,
95}
96
97/// Mirrors `VNPoseObservationRaw` in Vision.swift. Layout-compatible.
98#[repr(C)]
99pub struct PoseObservationRaw {
100    pub bbox_x: f64,
101    pub bbox_y: f64,
102    pub bbox_w: f64,
103    pub bbox_h: f64,
104    pub confidence: f32,
105    pub joint_names: *mut *mut c_char,
106    pub joint_xs: *mut f64,
107    pub joint_ys: *mut f64,
108    pub joint_confidences: *mut f32,
109    pub joint_count: usize,
110}
111
112/// Mirrors `VNContourRaw` in Vision.swift. Layout-compatible.
113#[repr(C)]
114pub struct ContourRaw {
115    pub point_xs: *mut f64,
116    pub point_ys: *mut f64,
117    pub point_count: usize,
118    pub child_count: isize,
119    pub aspect_ratio: f32,
120}
121
122/// Mirrors `VNRecognizedAnimalRaw` in Vision.swift. Layout-compatible.
123#[repr(C)]
124pub struct RecognizedAnimalRaw {
125    pub identifier: *mut c_char,
126    pub confidence: f32,
127    pub bbox_x: f64,
128    pub bbox_y: f64,
129    pub bbox_w: f64,
130    pub bbox_h: f64,
131}
132
133/// Mirrors `VNClassificationRaw` in Vision.swift. Layout-compatible.
134#[repr(C)]
135pub struct ClassificationRaw {
136    pub identifier: *mut c_char,
137    pub confidence: f32,
138}
139
140/// Mirrors `VNRectangleObservationRaw` in Vision.swift. Layout-compatible.
141#[repr(C)]
142pub struct RectangleObservationRaw {
143    pub bbox_x: f64,
144    pub bbox_y: f64,
145    pub bbox_w: f64,
146    pub bbox_h: f64,
147    pub confidence: f32,
148    pub tl_x: f64,
149    pub tl_y: f64,
150    pub tr_x: f64,
151    pub tr_y: f64,
152    pub bl_x: f64,
153    pub bl_y: f64,
154    pub br_x: f64,
155    pub br_y: f64,
156}
157
158/// Mirrors `VNFeaturePrintRaw` in Vision.swift. Layout-compatible.
159#[repr(C)]
160pub struct FeaturePrintRaw {
161    pub element_type: i32,
162    pub element_count: usize,
163    pub bytes: *mut c_void,
164}
165
166/// Mirrors `VNHumanObservationRaw` in Vision.swift. Layout-compatible.
167#[repr(C)]
168pub struct HumanObservationRaw {
169    pub bbox_x: f64,
170    pub bbox_y: f64,
171    pub bbox_w: f64,
172    pub bbox_h: f64,
173    pub confidence: f32,
174    pub upper_body_only: bool,
175}
176
177/// Mirrors `VNAestheticsScoresRaw` in Vision.swift. Layout-compatible.
178#[repr(C)]
179pub struct AestheticsScoresRaw {
180    pub overall_score: f32,
181    pub is_utility: bool,
182}
183
184/// Mirrors `VNFaceQualityRaw` in Vision.swift. Layout-compatible.
185#[repr(C)]
186pub struct FaceQualityRaw {
187    pub bbox_x: f64,
188    pub bbox_y: f64,
189    pub bbox_w: f64,
190    pub bbox_h: f64,
191    pub confidence: f32,
192    pub capture_quality: f32,
193    pub has_quality: bool,
194}
195
196extern "C" {
197    pub fn vn_string_free(s: *mut c_char);
198
199    pub fn vn_recognize_text_in_path(
200        path: *const c_char,
201        recognition_level: i32,
202        uses_language_correction: bool,
203        out_array: *mut *mut c_void,
204        out_count: *mut usize,
205        out_error_message: *mut *mut c_char,
206    ) -> i32;
207
208    pub fn vn_recognize_text_in_pixel_buffer(
209        pixel_buffer: *mut c_void,
210        recognition_level: i32,
211        uses_language_correction: bool,
212        out_array: *mut *mut c_void,
213        out_count: *mut usize,
214        out_error_message: *mut *mut c_char,
215    ) -> i32;
216
217    pub fn vn_recognized_text_free(array: *mut c_void, count: usize);
218
219    pub fn vn_detect_faces_in_path(
220        path: *const c_char,
221        out_array: *mut *mut c_void,
222        out_count: *mut usize,
223        out_error_message: *mut *mut c_char,
224    ) -> i32;
225
226    pub fn vn_detect_faces_in_pixel_buffer(
227        pixel_buffer: *mut c_void,
228        out_array: *mut *mut c_void,
229        out_count: *mut usize,
230        out_error_message: *mut *mut c_char,
231    ) -> i32;
232
233    pub fn vn_detected_faces_free(array: *mut c_void, count: usize);
234
235    pub fn vn_detect_barcodes_in_path(
236        path: *const c_char,
237        out_array: *mut *mut c_void,
238        out_count: *mut usize,
239        out_error_message: *mut *mut c_char,
240    ) -> i32;
241
242    pub fn vn_detected_barcodes_free(array: *mut c_void, count: usize);
243
244    pub fn vn_attention_saliency_in_path(
245        path: *const c_char,
246        out_array: *mut *mut c_void,
247        out_count: *mut usize,
248        out_error_message: *mut *mut c_char,
249    ) -> i32;
250
251    pub fn vn_saliency_regions_free(array: *mut c_void, count: usize);
252
253    pub fn vn_detect_face_landmarks_in_path(
254        path: *const c_char,
255        out_array: *mut *mut c_void,
256        out_count: *mut usize,
257        out_error_message: *mut *mut c_char,
258    ) -> i32;
259
260    pub fn vn_face_landmarks_free(array: *mut c_void, count: usize);
261
262    pub fn vn_detect_human_body_pose_in_path(
263        path: *const c_char,
264        out_array: *mut *mut c_void,
265        out_count: *mut usize,
266        out_error_message: *mut *mut c_char,
267    ) -> i32;
268
269    pub fn vn_detect_human_hand_pose_in_path(
270        path: *const c_char,
271        max_hands: usize,
272        out_array: *mut *mut c_void,
273        out_count: *mut usize,
274        out_error_message: *mut *mut c_char,
275    ) -> i32;
276
277    pub fn vn_pose_observations_free(array: *mut c_void, count: usize);
278
279    pub fn vn_detect_contours_in_path(
280        path: *const c_char,
281        contrast_adjustment: f32,
282        detects_dark_on_light: bool,
283        out_array: *mut *mut c_void,
284        out_count: *mut usize,
285        out_error_message: *mut *mut c_char,
286    ) -> i32;
287
288    pub fn vn_contours_free(array: *mut c_void, count: usize);
289
290    pub fn vn_recognize_animals_in_path(
291        path: *const c_char,
292        out_array: *mut *mut c_void,
293        out_count: *mut usize,
294        out_error_message: *mut *mut c_char,
295    ) -> i32;
296
297    pub fn vn_recognized_animals_free(array: *mut c_void, count: usize);
298
299    pub fn vn_classify_image_in_path(
300        path: *const c_char,
301        out_array: *mut *mut c_void,
302        out_count: *mut usize,
303        out_error_message: *mut *mut c_char,
304    ) -> i32;
305    pub fn vn_classifications_free(array: *mut c_void, count: usize);
306
307    pub fn vn_detect_rectangles_in_path(
308        path: *const c_char,
309        max_observations: usize,
310        minimum_aspect_ratio: f32,
311        maximum_aspect_ratio: f32,
312        minimum_size: f32,
313        minimum_confidence: f32,
314        out_array: *mut *mut c_void,
315        out_count: *mut usize,
316        out_error_message: *mut *mut c_char,
317    ) -> i32;
318
319    pub fn vn_detect_document_segmentation_in_path(
320        path: *const c_char,
321        out_array: *mut *mut c_void,
322        out_count: *mut usize,
323        out_error_message: *mut *mut c_char,
324    ) -> i32;
325
326    pub fn vn_rectangle_observations_free(array: *mut c_void, count: usize);
327
328    pub fn vn_detect_horizon_in_path(
329        path: *const c_char,
330        out_angle: *mut f64,
331        out_has_value: *mut bool,
332        out_error_message: *mut *mut c_char,
333    ) -> i32;
334
335    pub fn vn_generate_image_feature_print_in_path(
336        path: *const c_char,
337        out_feature: *mut FeaturePrintRaw,
338        out_error_message: *mut *mut c_char,
339    ) -> i32;
340    pub fn vn_feature_print_free(feature: *mut FeaturePrintRaw);
341
342    pub fn vn_detect_human_rectangles_in_path(
343        path: *const c_char,
344        upper_body_only: bool,
345        out_array: *mut *mut c_void,
346        out_count: *mut usize,
347        out_error_message: *mut *mut c_char,
348    ) -> i32;
349    pub fn vn_human_observations_free(array: *mut c_void, count: usize);
350
351    pub fn vn_calculate_aesthetics_scores_in_path(
352        path: *const c_char,
353        out_scores: *mut AestheticsScoresRaw,
354        out_has_value: *mut bool,
355        out_error_message: *mut *mut c_char,
356    ) -> i32;
357
358    pub fn vn_detect_face_capture_quality_in_path(
359        path: *const c_char,
360        out_array: *mut *mut c_void,
361        out_count: *mut usize,
362        out_error_message: *mut *mut c_char,
363    ) -> i32;
364
365    pub fn vn_face_quality_observations_free(array: *mut c_void, count: usize);
366
367    pub fn vn_test_helper_render_text_png(
368        text: *const c_char,
369        width: i32,
370        height: i32,
371        output_path: *const c_char,
372    ) -> i32;
373}
374
375pub mod status {
376    pub const OK: i32 = 0;
377    pub const INVALID_ARGUMENT: i32 = -1;
378    pub const IMAGE_LOAD_FAILED: i32 = -2;
379    pub const REQUEST_FAILED: i32 = -3;
380    pub const UNKNOWN: i32 = -99;
381}
382
383// silence unused
384const _: () = {
385    let _ = core::mem::size_of::<*mut c_void>();
386};