Skip to main content

apple_vision/ffi/
mod.rs

1//! Raw FFI declarations matching the Swift bridge in
2//! `swift-bridge/Sources/VisionBridge/*.swift`.
3
4#![allow(missing_docs, non_camel_case_types, clippy::pub_underscore_fields)]
5
6use core::ffi::{c_char, c_void};
7
8/// Mirrors `VNRecognizedTextRaw` in the Swift bridge. 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 `VNRequestObservationRaw` in the Swift bridge. Layout-compatible.
20#[repr(C)]
21pub struct RequestObservationRaw {
22    pub uuid: *mut c_char,
23    pub text: *mut c_char,
24    pub confidence: f32,
25    pub has_time_range: bool,
26    pub time_range_start_seconds: f64,
27    pub time_range_duration_seconds: f64,
28    pub bbox_x: f64,
29    pub bbox_y: f64,
30    pub bbox_w: f64,
31    pub bbox_h: f64,
32}
33
34/// Mirrors `VNDetectedFaceRaw` in the Swift bridge. Layout-compatible.
35#[repr(C)]
36pub struct DetectedFaceRaw {
37    pub bbox_x: f64,
38    pub bbox_y: f64,
39    pub bbox_w: f64,
40    pub bbox_h: f64,
41    pub confidence: f32,
42    pub roll: f32,
43    pub yaw: f32,
44    pub pitch: f32,
45}
46
47/// Mirrors `VNDetectedBarcodeRaw` in the Swift bridge. Layout-compatible.
48#[repr(C)]
49pub struct DetectedBarcodeRaw {
50    pub payload: *mut c_char,
51    pub symbology: *mut c_char,
52    pub confidence: f32,
53    pub bbox_x: f64,
54    pub bbox_y: f64,
55    pub bbox_w: f64,
56    pub bbox_h: f64,
57}
58
59/// Mirrors `VNSaliencyRegionRaw` in the Swift bridge. Layout-compatible.
60#[repr(C)]
61pub struct SaliencyRegionRaw {
62    pub confidence: f32,
63    pub bbox_x: f64,
64    pub bbox_y: f64,
65    pub bbox_w: f64,
66    pub bbox_h: f64,
67}
68
69/// Mirrors `VNFaceLandmarksRaw` in the Swift bridge. Layout-compatible.
70///
71/// All `*_count` fields are NUMBER OF POINTS; each point buffer is an
72/// interleaved `[x0, y0, x1, y1, …]` array of doubles, length
73/// `count * 2`. A NULL pointer + 0 count means the region wasn't
74/// produced for this face.
75#[repr(C)]
76pub struct FaceLandmarksRaw {
77    pub bbox_x: f64,
78    pub bbox_y: f64,
79    pub bbox_w: f64,
80    pub bbox_h: f64,
81    pub confidence: f32,
82    pub roll: f32,
83    pub yaw: f32,
84    pub pitch: f32,
85
86    pub face_contour: *mut f64,
87    pub face_contour_count: usize,
88    pub left_eye: *mut f64,
89    pub left_eye_count: usize,
90    pub right_eye: *mut f64,
91    pub right_eye_count: usize,
92    pub left_eyebrow: *mut f64,
93    pub left_eyebrow_count: usize,
94    pub right_eyebrow: *mut f64,
95    pub right_eyebrow_count: usize,
96    pub nose: *mut f64,
97    pub nose_count: usize,
98    pub nose_crest: *mut f64,
99    pub nose_crest_count: usize,
100    pub median_line: *mut f64,
101    pub median_line_count: usize,
102    pub outer_lips: *mut f64,
103    pub outer_lips_count: usize,
104    pub inner_lips: *mut f64,
105    pub inner_lips_count: usize,
106    pub left_pupil: *mut f64,
107    pub left_pupil_count: usize,
108    pub right_pupil: *mut f64,
109    pub right_pupil_count: usize,
110}
111
112/// Mirrors `VNPoseObservationRaw` in the Swift bridge. Layout-compatible.
113#[repr(C)]
114pub struct PoseObservationRaw {
115    pub bbox_x: f64,
116    pub bbox_y: f64,
117    pub bbox_w: f64,
118    pub bbox_h: f64,
119    pub confidence: f32,
120    pub joint_names: *mut *mut c_char,
121    pub joint_xs: *mut f64,
122    pub joint_ys: *mut f64,
123    pub joint_confidences: *mut f32,
124    pub joint_count: usize,
125}
126
127/// Mirrors `VNContourRaw` in the Swift bridge. Layout-compatible.
128#[repr(C)]
129pub struct ContourRaw {
130    pub point_xs: *mut f64,
131    pub point_ys: *mut f64,
132    pub point_count: usize,
133    pub child_count: isize,
134    pub aspect_ratio: f32,
135}
136
137/// Mirrors `VNRecognizedAnimalRaw` in the Swift bridge. Layout-compatible.
138#[repr(C)]
139pub struct RecognizedAnimalRaw {
140    pub identifier: *mut c_char,
141    pub confidence: f32,
142    pub bbox_x: f64,
143    pub bbox_y: f64,
144    pub bbox_w: f64,
145    pub bbox_h: f64,
146}
147
148/// Mirrors `VNClassificationRaw` in the Swift bridge. Layout-compatible.
149#[repr(C)]
150pub struct ClassificationRaw {
151    pub identifier: *mut c_char,
152    pub confidence: f32,
153}
154
155/// Mirrors `VNRectangleObservationRaw` in the Swift bridge. Layout-compatible.
156#[repr(C)]
157pub struct RectangleObservationRaw {
158    pub bbox_x: f64,
159    pub bbox_y: f64,
160    pub bbox_w: f64,
161    pub bbox_h: f64,
162    pub confidence: f32,
163    pub tl_x: f64,
164    pub tl_y: f64,
165    pub tr_x: f64,
166    pub tr_y: f64,
167    pub bl_x: f64,
168    pub bl_y: f64,
169    pub br_x: f64,
170    pub br_y: f64,
171}
172
173/// Mirrors `VNFeaturePrintRaw` in the Swift bridge. Layout-compatible.
174#[repr(C)]
175pub struct FeaturePrintRaw {
176    pub element_type: i32,
177    pub element_count: usize,
178    pub bytes: *mut c_void,
179}
180
181/// Mirrors `VNHumanObservationRaw` in the Swift bridge. Layout-compatible.
182#[repr(C)]
183pub struct HumanObservationRaw {
184    pub bbox_x: f64,
185    pub bbox_y: f64,
186    pub bbox_w: f64,
187    pub bbox_h: f64,
188    pub confidence: f32,
189    pub upper_body_only: bool,
190}
191
192/// Mirrors `VNAestheticsScoresRaw` in the Swift bridge. Layout-compatible.
193#[repr(C)]
194pub struct AestheticsScoresRaw {
195    pub overall_score: f32,
196    pub is_utility: bool,
197}
198
199/// Mirrors `VNFaceQualityRaw` in the Swift bridge. Layout-compatible.
200#[repr(C)]
201pub struct FaceQualityRaw {
202    pub bbox_x: f64,
203    pub bbox_y: f64,
204    pub bbox_w: f64,
205    pub bbox_h: f64,
206    pub confidence: f32,
207    pub capture_quality: f32,
208    pub has_quality: bool,
209}
210
211/// Mirrors `VNSegmentationMaskRaw` in the Swift bridge. Layout-compatible.
212#[repr(C)]
213pub struct SegmentationMaskRaw {
214    pub width: usize,
215    pub height: usize,
216    pub bytes_per_row: usize,
217    pub bytes: *mut c_void,
218}
219
220extern "C" {
221    pub fn vn_string_free(s: *mut c_char);
222
223    pub fn vn_recognize_text_in_path(
224        path: *const c_char,
225        recognition_level: i32,
226        uses_language_correction: bool,
227        out_array: *mut *mut c_void,
228        out_count: *mut usize,
229        out_error_message: *mut *mut c_char,
230    ) -> i32;
231
232    pub fn vn_recognize_text_in_pixel_buffer(
233        pixel_buffer: *mut c_void,
234        recognition_level: i32,
235        uses_language_correction: bool,
236        out_array: *mut *mut c_void,
237        out_count: *mut usize,
238        out_error_message: *mut *mut c_char,
239    ) -> i32;
240
241    pub fn vn_recognized_text_free(array: *mut c_void, count: usize);
242
243    pub fn vn_image_request_handler_perform_text_request(
244        image_path: *const c_char,
245        recognition_level: i32,
246        uses_language_correction: bool,
247        prefer_background_processing: bool,
248        uses_cpu_only: bool,
249        revision: usize,
250        has_revision: bool,
251        out_array: *mut *mut c_void,
252        out_count: *mut usize,
253        out_error_message: *mut *mut c_char,
254    ) -> i32;
255
256    pub fn vn_sequence_request_handler_create(
257        out_handle: *mut *mut c_void,
258        out_error_message: *mut *mut c_char,
259    ) -> i32;
260
261    pub fn vn_sequence_request_handler_perform_text_request(
262        handle: *mut c_void,
263        image_path: *const c_char,
264        recognition_level: i32,
265        uses_language_correction: bool,
266        prefer_background_processing: bool,
267        uses_cpu_only: bool,
268        revision: usize,
269        has_revision: bool,
270        out_array: *mut *mut c_void,
271        out_count: *mut usize,
272        out_error_message: *mut *mut c_char,
273    ) -> i32;
274
275    pub fn vn_sequence_request_handler_free(handle: *mut c_void);
276
277    pub fn vn_video_processor_analyze_text_request(
278        video_path: *const c_char,
279        recognition_level: i32,
280        uses_language_correction: bool,
281        prefer_background_processing: bool,
282        uses_cpu_only: bool,
283        revision: usize,
284        has_revision: bool,
285        cadence_kind: i32,
286        cadence_value: f64,
287        out_array: *mut *mut c_void,
288        out_count: *mut usize,
289        out_error_message: *mut *mut c_char,
290    ) -> i32;
291
292    pub fn vn_request_observations_free(array: *mut c_void, count: usize);
293
294    pub fn vn_detect_faces_in_path(
295        path: *const c_char,
296        out_array: *mut *mut c_void,
297        out_count: *mut usize,
298        out_error_message: *mut *mut c_char,
299    ) -> i32;
300
301    pub fn vn_detect_faces_in_pixel_buffer(
302        pixel_buffer: *mut c_void,
303        out_array: *mut *mut c_void,
304        out_count: *mut usize,
305        out_error_message: *mut *mut c_char,
306    ) -> i32;
307
308    pub fn vn_detected_faces_free(array: *mut c_void, count: usize);
309
310    pub fn vn_detect_barcodes_in_path(
311        path: *const c_char,
312        out_array: *mut *mut c_void,
313        out_count: *mut usize,
314        out_error_message: *mut *mut c_char,
315    ) -> i32;
316
317    pub fn vn_detected_barcodes_free(array: *mut c_void, count: usize);
318
319    pub fn vn_attention_saliency_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_saliency_regions_free(array: *mut c_void, count: usize);
327
328    pub fn vn_detect_face_landmarks_in_path(
329        path: *const c_char,
330        out_array: *mut *mut c_void,
331        out_count: *mut usize,
332        out_error_message: *mut *mut c_char,
333    ) -> i32;
334
335    pub fn vn_face_landmarks_free(array: *mut c_void, count: usize);
336
337    pub fn vn_detect_human_body_pose_in_path(
338        path: *const c_char,
339        out_array: *mut *mut c_void,
340        out_count: *mut usize,
341        out_error_message: *mut *mut c_char,
342    ) -> i32;
343
344    pub fn vn_detect_human_hand_pose_in_path(
345        path: *const c_char,
346        max_hands: usize,
347        out_array: *mut *mut c_void,
348        out_count: *mut usize,
349        out_error_message: *mut *mut c_char,
350    ) -> i32;
351
352    pub fn vn_pose_observations_free(array: *mut c_void, count: usize);
353
354    pub fn vn_detect_contours_in_path(
355        path: *const c_char,
356        contrast_adjustment: f32,
357        detects_dark_on_light: bool,
358        out_array: *mut *mut c_void,
359        out_count: *mut usize,
360        out_error_message: *mut *mut c_char,
361    ) -> i32;
362
363    pub fn vn_contours_free(array: *mut c_void, count: usize);
364
365    pub fn vn_recognize_animals_in_path(
366        path: *const c_char,
367        out_array: *mut *mut c_void,
368        out_count: *mut usize,
369        out_error_message: *mut *mut c_char,
370    ) -> i32;
371
372    pub fn vn_recognized_animals_free(array: *mut c_void, count: usize);
373
374    pub fn vn_classify_image_in_path(
375        path: *const c_char,
376        out_array: *mut *mut c_void,
377        out_count: *mut usize,
378        out_error_message: *mut *mut c_char,
379    ) -> i32;
380    pub fn vn_classifications_free(array: *mut c_void, count: usize);
381
382    pub fn vn_detect_rectangles_in_path(
383        path: *const c_char,
384        max_observations: usize,
385        minimum_aspect_ratio: f32,
386        maximum_aspect_ratio: f32,
387        minimum_size: f32,
388        minimum_confidence: f32,
389        out_array: *mut *mut c_void,
390        out_count: *mut usize,
391        out_error_message: *mut *mut c_char,
392    ) -> i32;
393
394    pub fn vn_detect_document_segmentation_in_path(
395        path: *const c_char,
396        out_array: *mut *mut c_void,
397        out_count: *mut usize,
398        out_error_message: *mut *mut c_char,
399    ) -> i32;
400
401    pub fn vn_rectangle_observations_free(array: *mut c_void, count: usize);
402
403    pub fn vn_detect_horizon_in_path(
404        path: *const c_char,
405        out_angle: *mut f64,
406        out_has_value: *mut bool,
407        out_error_message: *mut *mut c_char,
408    ) -> i32;
409
410    pub fn vn_generate_image_feature_print_in_path(
411        path: *const c_char,
412        out_feature: *mut FeaturePrintRaw,
413        out_error_message: *mut *mut c_char,
414    ) -> i32;
415    pub fn vn_feature_print_free(feature: *mut FeaturePrintRaw);
416
417    pub fn vn_detect_human_rectangles_in_path(
418        path: *const c_char,
419        upper_body_only: bool,
420        out_array: *mut *mut c_void,
421        out_count: *mut usize,
422        out_error_message: *mut *mut c_char,
423    ) -> i32;
424    pub fn vn_human_observations_free(array: *mut c_void, count: usize);
425
426    pub fn vn_calculate_aesthetics_scores_in_path(
427        path: *const c_char,
428        out_scores: *mut AestheticsScoresRaw,
429        out_has_value: *mut bool,
430        out_error_message: *mut *mut c_char,
431    ) -> i32;
432
433    pub fn vn_detect_face_capture_quality_in_path(
434        path: *const c_char,
435        out_array: *mut *mut c_void,
436        out_count: *mut usize,
437        out_error_message: *mut *mut c_char,
438    ) -> i32;
439
440    pub fn vn_face_quality_observations_free(array: *mut c_void, count: usize);
441
442    pub fn vn_generate_person_segmentation_in_path(
443        path: *const c_char,
444        quality_level: i32,
445        out_mask: *mut SegmentationMaskRaw,
446        out_has_value: *mut bool,
447        out_error_message: *mut *mut c_char,
448    ) -> i32;
449
450    pub fn vn_generate_foreground_instance_mask_in_path(
451        path: *const c_char,
452        out_mask: *mut SegmentationMaskRaw,
453        out_instance_count: *mut usize,
454        out_has_value: *mut bool,
455        out_error_message: *mut *mut c_char,
456    ) -> i32;
457
458    pub fn vn_segmentation_mask_free(mask: *mut SegmentationMaskRaw);
459
460    pub fn vn_generate_optical_flow_in_paths(
461        path_a: *const c_char,
462        path_b: *const c_char,
463        computation_accuracy: i32,
464        out_mask: *mut SegmentationMaskRaw,
465        out_has_value: *mut bool,
466        out_error_message: *mut *mut c_char,
467    ) -> i32;
468
469    pub fn vn_coreml_classify_in_path(
470        path: *const c_char,
471        model_path: *const c_char,
472        out_array: *mut *mut c_void,
473        out_count: *mut usize,
474        out_error_message: *mut *mut c_char,
475    ) -> i32;
476
477    pub fn vn_test_helper_render_text_png(
478        text: *const c_char,
479        width: i32,
480        height: i32,
481        output_path: *const c_char,
482    ) -> i32;
483
484    pub fn vn_test_helper_render_text_video(
485        first_text: *const c_char,
486        second_text: *const c_char,
487        width: i32,
488        height: i32,
489        fps: i32,
490        frames_per_text: i32,
491        output_path: *const c_char,
492    ) -> i32;
493}
494
495// ===== v0.13 missing requests =====
496
497/// Mirrors `VNAnimalJointRaw` in the Swift bridge.
498#[repr(C)]
499pub struct AnimalJointRaw {
500    pub name: *mut c_char,
501    pub x: f64,
502    pub y: f64,
503    pub confidence: f32,
504    pub _pad: f32,
505}
506
507/// Mirrors `VNHumanJoint3DRaw`.
508#[repr(C)]
509pub struct HumanJoint3DRaw {
510    pub name: *mut c_char,
511    pub x: f32,
512    pub y: f32,
513    pub z: f32,
514    pub confidence: f32,
515}
516
517/// Mirrors `VNSimpleRectRaw`.
518#[repr(C)]
519pub struct SimpleRectRaw {
520    pub x: f64,
521    pub y: f64,
522    pub w: f64,
523    pub h: f64,
524    pub confidence: f32,
525    pub _pad: f32,
526}
527
528/// Mirrors `VNTrajectoryRaw`.
529#[repr(C)]
530pub struct TrajectoryRaw {
531    pub detected_x: f64,
532    pub detected_y: f64,
533    pub projected_x: f64,
534    pub projected_y: f64,
535    pub equation_a: f64,
536    pub equation_b: f64,
537    pub equation_c: f64,
538    pub confidence: f32,
539    pub _pad: f32,
540}
541
542/// Mirrors `VNTranslationalAlignmentRaw`.
543#[repr(C)]
544pub struct TranslationalAlignmentRaw {
545    pub tx: f64,
546    pub ty: f64,
547}
548
549/// Mirrors `VNHomographicAlignmentRaw` (3×3 row-major matrix).
550#[repr(C)]
551pub struct HomographicAlignmentRaw {
552    pub m00: f32,
553    pub m01: f32,
554    pub m02: f32,
555    pub m10: f32,
556    pub m11: f32,
557    pub m12: f32,
558    pub m20: f32,
559    pub m21: f32,
560    pub m22: f32,
561    pub _pad: f32,
562}
563
564extern "C" {
565    pub fn vn_detect_animal_body_pose_in_path(
566        path: *const c_char,
567        out_joints: *mut *mut AnimalJointRaw,
568        out_count: *mut isize,
569        out_err: *mut *mut c_char,
570    ) -> i32;
571    pub fn vn_animal_joints_free(ptr: *mut AnimalJointRaw, count: isize);
572
573    pub fn vn_detect_human_body_pose_3d_in_path(
574        path: *const c_char,
575        out_joints: *mut *mut HumanJoint3DRaw,
576        out_count: *mut isize,
577        out_err: *mut *mut c_char,
578    ) -> i32;
579    pub fn vn_human_joints_3d_free(ptr: *mut HumanJoint3DRaw, count: isize);
580
581    pub fn vn_detect_text_rectangles_in_path(
582        path: *const c_char,
583        reports_character_boxes: bool,
584        out_rects: *mut *mut SimpleRectRaw,
585        out_count: *mut isize,
586        out_err: *mut *mut c_char,
587    ) -> i32;
588    pub fn vn_objectness_saliency_in_path(
589        path: *const c_char,
590        out_rects: *mut *mut SimpleRectRaw,
591        out_count: *mut isize,
592        out_err: *mut *mut c_char,
593    ) -> i32;
594    pub fn vn_simple_rects_free(ptr: *mut SimpleRectRaw, count: isize);
595
596    pub fn vn_person_instance_mask_in_path(
597        path: *const c_char,
598        out_width: *mut isize,
599        out_height: *mut isize,
600        out_bytes_per_row: *mut isize,
601        out_data: *mut *mut u8,
602        out_err: *mut *mut c_char,
603    ) -> i32;
604    pub fn vn_mask_buffer_free(ptr: *mut u8, size: isize);
605
606    pub fn vn_detect_trajectories_in_path(
607        path: *const c_char,
608        trajectory_length: isize,
609        out_trajectories: *mut *mut TrajectoryRaw,
610        out_count: *mut isize,
611        out_err: *mut *mut c_char,
612    ) -> i32;
613    pub fn vn_trajectories_free(ptr: *mut TrajectoryRaw, count: isize);
614
615    pub fn vn_register_translational_in_paths(
616        target_path: *const c_char,
617        floating_path: *const c_char,
618        out: *mut TranslationalAlignmentRaw,
619        out_err: *mut *mut c_char,
620    ) -> i32;
621    pub fn vn_register_homographic_in_paths(
622        target_path: *const c_char,
623        floating_path: *const c_char,
624        out: *mut HomographicAlignmentRaw,
625        out_err: *mut *mut c_char,
626    ) -> i32;
627}
628
629// ===== tracking requests =====
630
631extern "C" {
632    pub fn vn_object_tracker_create(
633        initial_path: *const c_char,
634        initial_bbox: *mut c_void,
635        out_handle: *mut *mut c_void,
636        out_err: *mut *mut c_char,
637    ) -> i32;
638    pub fn vn_object_tracker_track(
639        handle: *mut c_void,
640        next_path: *const c_char,
641        out_bbox: *mut c_void,
642        out_err: *mut *mut c_char,
643    ) -> i32;
644    pub fn vn_object_tracker_release(handle: *mut c_void);
645
646    pub fn vn_rectangle_tracker_create(
647        initial_path: *const c_char,
648        initial_observation: *mut c_void,
649        out_handle: *mut *mut c_void,
650        out_err: *mut *mut c_char,
651    ) -> i32;
652    pub fn vn_rectangle_tracker_track(
653        handle: *mut c_void,
654        next_path: *const c_char,
655        out_observation: *mut c_void,
656        out_err: *mut *mut c_char,
657    ) -> i32;
658    pub fn vn_rectangle_tracker_release(handle: *mut c_void);
659
660    pub fn vn_optical_flow_tracker_create(
661        reference_path: *const c_char,
662        out_handle: *mut *mut c_void,
663        out_err: *mut *mut c_char,
664    ) -> i32;
665    pub fn vn_optical_flow_tracker_track(
666        handle: *mut c_void,
667        next_path: *const c_char,
668        out_mask: *mut c_void,
669        out_err: *mut *mut c_char,
670    ) -> i32;
671    pub fn vn_optical_flow_tracker_release(handle: *mut c_void);
672
673    pub fn vn_translational_image_tracker_create(
674        reference_path: *const c_char,
675        out_handle: *mut *mut c_void,
676        out_err: *mut *mut c_char,
677    ) -> i32;
678    pub fn vn_translational_image_tracker_track(
679        handle: *mut c_void,
680        next_path: *const c_char,
681        out_alignment: *mut c_void,
682        out_err: *mut *mut c_char,
683    ) -> i32;
684    pub fn vn_translational_image_tracker_release(handle: *mut c_void);
685
686    pub fn vn_homographic_image_tracker_create(
687        reference_path: *const c_char,
688        out_handle: *mut *mut c_void,
689        out_err: *mut *mut c_char,
690    ) -> i32;
691    pub fn vn_homographic_image_tracker_track(
692        handle: *mut c_void,
693        next_path: *const c_char,
694        out_alignment: *mut c_void,
695        out_err: *mut *mut c_char,
696    ) -> i32;
697    pub fn vn_homographic_image_tracker_release(handle: *mut c_void);
698}
699
700pub mod status {
701    pub const OK: i32 = 0;
702    pub const INVALID_ARGUMENT: i32 = -1;
703    pub const IMAGE_LOAD_FAILED: i32 = -2;
704    pub const REQUEST_FAILED: i32 = -3;
705    pub const UNKNOWN: i32 = -99;
706}
707
708// silence unused
709const _: () = {
710    let _ = core::mem::size_of::<*mut c_void>();
711};