Skip to main content

apple_mps/generated/
image.rs

1use crate::ffi;
2use crate::image::Image;
3use apple_metal::CommandBuffer as MetalCommandBuffer;
4use core::ffi::c_void;
5use core::ptr;
6use std::collections::HashSet;
7
8macro_rules! opaque_generated_handle {
9    ($name:ident) => {
10        pub struct $name {
11            ptr: *mut c_void,
12        }
13
14        unsafe impl Send for $name {}
15        unsafe impl Sync for $name {}
16
17        impl Drop for $name {
18            fn drop(&mut self) {
19                if !self.ptr.is_null() {
20                    unsafe { ffi::mps_object_release(self.ptr) };
21                    self.ptr = ptr::null_mut();
22                }
23            }
24        }
25
26        impl $name {
27            #[must_use]
28            pub const fn as_ptr(&self) -> *mut c_void {
29                self.ptr
30            }
31
32            /// # Safety
33            ///
34            /// `ptr` must be a valid Objective-C object of the matching MPS type or protocol.
35            #[must_use]
36            pub unsafe fn retained_from_raw(ptr: *mut c_void) -> Option<Self> {
37                let retained = unsafe { ffi::mps_object_retain(ptr) };
38                if retained.is_null() {
39                    None
40                } else {
41                    Some(Self { ptr: retained })
42                }
43            }
44        }
45    };
46}
47
48macro_rules! raw_value_type {
49    ($name:ident, $raw:ty) => {
50        #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
51        #[repr(transparent)]
52        pub struct $name(pub $raw);
53
54        impl $name {
55            #[must_use]
56            pub const fn from_raw(raw: $raw) -> Self {
57                Self(raw)
58            }
59
60            #[must_use]
61            pub const fn as_raw(self) -> $raw {
62                self.0
63            }
64        }
65
66        impl From<$raw> for $name {
67            fn from(value: $raw) -> Self {
68                Self(value)
69            }
70        }
71
72        impl From<$name> for $raw {
73            fn from(value: $name) -> Self {
74                value.0
75            }
76        }
77    };
78}
79
80#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
81pub struct ImageCoordinate {
82    pub x: usize,
83    pub y: usize,
84    pub channel: usize,
85}
86
87#[must_use]
88pub fn get_image_type(image: &Image) -> ImageType {
89    ImageType::from_raw(unsafe { ffi::mps_get_image_type(image.as_ptr()) })
90}
91
92#[must_use]
93pub fn image_batch_increment_read_count(images: &[&Image], amount: isize) -> usize {
94    let handles: Vec<_> = images.iter().map(|image| image.as_ptr()).collect();
95    let handles_ptr = if handles.is_empty() {
96        ptr::null()
97    } else {
98        handles.as_ptr()
99    };
100    unsafe { ffi::mps_image_batch_increment_read_count(handles_ptr, handles.len(), amount) }
101}
102
103#[must_use]
104pub fn image_batch_resource_size(images: &[&Image]) -> usize {
105    let handles: Vec<_> = images.iter().map(|image| image.as_ptr()).collect();
106    let handles_ptr = if handles.is_empty() {
107        ptr::null()
108    } else {
109        handles.as_ptr()
110    };
111    unsafe { ffi::mps_image_batch_resource_size(handles_ptr, handles.len()) }
112}
113
114pub fn image_batch_synchronize(images: &[&Image], command_buffer: &MetalCommandBuffer) {
115    let handles: Vec<_> = images.iter().map(|image| image.as_ptr()).collect();
116    let handles_ptr = if handles.is_empty() {
117        ptr::null()
118    } else {
119        handles.as_ptr()
120    };
121    unsafe {
122        ffi::mps_image_batch_synchronize(handles_ptr, handles.len(), command_buffer.as_ptr());
123    }
124}
125
126#[must_use]
127pub fn image_batch_iterate<F>(images: &[&Image], mut iterator: F) -> isize
128where
129    F: FnMut(&Image, usize) -> isize,
130{
131    let mut seen = HashSet::new();
132    let mut last = isize::MIN;
133    for (index, image) in images.iter().enumerate() {
134        if seen.insert(image.as_ptr() as usize) {
135            last = iterator(image, index);
136            if last > isize::MIN {
137                return last;
138            }
139        }
140    }
141    last
142}
143
144raw_value_type!(AlphaType, usize);
145raw_value_type!(ImageType, u32);
146raw_value_type!(PurgeableState, usize);
147opaque_generated_handle!(BinaryImageKernel);
148opaque_generated_handle!(ImageAreaMax);
149opaque_generated_handle!(ImageAreaMin);
150opaque_generated_handle!(ImageArithmetic);
151opaque_generated_handle!(ImageCanny);
152opaque_generated_handle!(ImageConversion);
153opaque_generated_handle!(ImageCopyToMatrix);
154opaque_generated_handle!(ImageDilate);
155opaque_generated_handle!(ImageDivide);
156opaque_generated_handle!(ImageEDLines);
157opaque_generated_handle!(ImageErode);
158opaque_generated_handle!(ImageEuclideanDistanceTransform);
159opaque_generated_handle!(ImageFindKeypoints);
160opaque_generated_handle!(ImageGaussianPyramid);
161opaque_generated_handle!(ImageGuidedFilter);
162opaque_generated_handle!(ImageHistogramEqualization);
163opaque_generated_handle!(ImageHistogramSpecification);
164opaque_generated_handle!(ImageIntegral);
165opaque_generated_handle!(ImageIntegralOfSquares);
166opaque_generated_handle!(ImageLaplacian);
167opaque_generated_handle!(ImageLaplacianPyramid);
168opaque_generated_handle!(ImageLaplacianPyramidAdd);
169opaque_generated_handle!(ImageLaplacianPyramidSubtract);
170opaque_generated_handle!(ImageMultiply);
171opaque_generated_handle!(ImageNormalizedHistogram);
172opaque_generated_handle!(ImagePyramid);
173opaque_generated_handle!(ImageReduceColumnMax);
174opaque_generated_handle!(ImageReduceColumnMean);
175opaque_generated_handle!(ImageReduceColumnMin);
176opaque_generated_handle!(ImageReduceColumnSum);
177opaque_generated_handle!(ImageReduceUnary);
178opaque_generated_handle!(ImageScale);
179opaque_generated_handle!(ImageStatisticsMeanAndVariance);
180opaque_generated_handle!(ImageSubtract);
181opaque_generated_handle!(ImageTent);
182opaque_generated_handle!(ImageThresholdBinaryInverse);
183opaque_generated_handle!(ImageThresholdToZero);
184opaque_generated_handle!(ImageThresholdToZeroInverse);
185opaque_generated_handle!(ImageThresholdTruncate);
186opaque_generated_handle!(ImageTranspose);
187opaque_generated_handle!(TemporaryImage);
188opaque_generated_handle!(UnaryImageKernel);
189opaque_generated_handle!(ImageAllocator);
190opaque_generated_handle!(ImageSizeEncodingState);
191opaque_generated_handle!(ImageTransformProvider);