Skip to main content

opencv/manual/core/
input_output_array.rs

1use std::ffi::c_void;
2
3use crate::boxed_ref::{BoxedRef, BoxedRefMut};
4use crate::core::{
5	_InputArray, _InputArrayTraitConst, _InputOutputArray, _InputOutputArrayTrait, _OutputArray, _OutputArrayTrait,
6};
7use crate::traits::Boxed;
8use crate::{sys, Result};
9
10/// Trait to serve as a replacement for `InputArray` in C++ OpenCV
11///
12/// You can pass references to the types implementing this trait everywhere where OpenCV API expects
13/// `InputArray` or `InputArrayOfArrays`.
14///
15/// More info in [OpenCV docs](https://docs.opencv.org/master/d4/d32/classcv_1_1__InputArray.html#details).
16pub trait ToInputArray {
17	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>>;
18}
19
20/// Trait to serve as a replacement for `OutputArray` in C++ OpenCV
21///
22/// You can pass reference to the type implementing this trait everywhere where OpenCV API expects
23/// `OutputArray` or `OutputArrayOfArrays`.
24///
25/// More info in [OpenCV docs](https://docs.opencv.org/master/d2/d9e/classcv_1_1__OutputArray.html#details).
26pub trait ToOutputArray {
27	fn output_array(&mut self) -> Result<BoxedRefMut<'_, _OutputArray>>;
28}
29
30/// Trait to serve as a replacement for `InputOutputArray` in C++ OpenCV
31///
32/// You can pass reference to the type implementing this trait everywhere where OpenCV API expects
33/// `InputOutputArray` or `InputOutputArrayOfArrays`.
34///
35/// For more info see comments for [ToInputArray] and [ToOutputArray].
36pub trait ToInputOutputArray {
37	fn input_output_array(&mut self) -> Result<BoxedRefMut<'_, _InputOutputArray>>;
38}
39
40#[inline]
41fn call_input_array(input_array: &impl _InputArrayTraitConst) -> Result<BoxedRef<'_, _InputArray>> {
42	unsafe extern "C" {
43		fn cv_InputArray_input_array(instance: *const c_void, ocvrs_return: *mut sys::Result<*mut c_void>);
44	}
45	return_send!(via ocvrs_return);
46	unsafe { cv_InputArray_input_array(input_array.as_raw__InputArray(), ocvrs_return.as_mut_ptr()) }
47	return_receive!(ocvrs_return => ret);
48	ret.into_result().map(|ptr| unsafe { _InputArray::from_raw(ptr) }.into())
49}
50
51#[inline]
52fn call_output_array(output_array: &mut impl _OutputArrayTrait) -> Result<BoxedRefMut<'_, _OutputArray>> {
53	unsafe extern "C" {
54		fn cv_OutputArray_output_array(instance: *mut c_void, ocvrs_return: *mut sys::Result<*mut c_void>);
55	}
56	return_send!(via ocvrs_return);
57	unsafe { cv_OutputArray_output_array(output_array.as_raw_mut__OutputArray(), ocvrs_return.as_mut_ptr()) }
58	return_receive!(ocvrs_return => ret);
59	ret.into_result().map(|ptr| unsafe { _OutputArray::from_raw(ptr) }.into())
60}
61
62impl ToInputArray for _InputArray {
63	#[inline]
64	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>> {
65		call_input_array(self)
66	}
67}
68
69impl ToInputArray for _OutputArray {
70	#[inline]
71	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>> {
72		call_input_array(self)
73	}
74}
75
76impl ToInputArray for _InputOutputArray {
77	#[inline]
78	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>> {
79		call_input_array(self)
80	}
81}
82
83impl ToOutputArray for _OutputArray {
84	#[inline]
85	fn output_array(&mut self) -> Result<BoxedRefMut<'_, _OutputArray>> {
86		call_output_array(self)
87	}
88}
89
90impl ToOutputArray for _InputOutputArray {
91	#[inline]
92	fn output_array(&mut self) -> Result<BoxedRefMut<'_, _OutputArray>> {
93		call_output_array(self)
94	}
95}
96
97impl ToInputOutputArray for _InputOutputArray {
98	#[inline]
99	fn input_output_array(&mut self) -> Result<BoxedRefMut<'_, _InputOutputArray>> {
100		unsafe extern "C" {
101			fn cv_InputOutputArray_input_output_array(instance: *mut c_void, ocvrs_return: *mut sys::Result<*mut c_void>);
102		}
103		return_send!(via ocvrs_return);
104		unsafe { cv_InputOutputArray_input_output_array(self.as_raw_mut__InputOutputArray(), ocvrs_return.as_mut_ptr()) }
105		return_receive!(ocvrs_return => ret);
106		ret.into_result()
107			.map(|ptr| unsafe { _InputOutputArray::from_raw(ptr) }.into())
108	}
109}
110
111#[doc(hidden)]
112#[macro_export]
113macro_rules! input_output_array {
114	($type: ty, $const_cons: ident) => {
115		impl $crate::core::ToInputArray for $type {
116			#[inline]
117			fn input_array(&self) -> $crate::Result<$crate::boxed_ref::BoxedRef<'_, $crate::core::_InputArray>> {
118				$crate::core::_InputArray::$const_cons(self)
119			}
120		}
121
122		$crate::input_array_ref_forward! { $type }
123	};
124
125	($type: ty, $const_cons: ident, $mut_cons: ident) => {
126		$crate::input_output_array! { $type, $const_cons }
127
128		impl $crate::core::ToOutputArray for $type {
129			#[inline]
130			fn output_array(&mut self) -> $crate::Result<$crate::boxed_ref::BoxedRefMut<'_, $crate::core::_OutputArray>> {
131				$crate::core::_OutputArray::$mut_cons(self)
132			}
133		}
134
135		impl $crate::core::ToInputOutputArray for $type {
136			#[inline]
137			fn input_output_array(&mut self) -> $crate::Result<$crate::boxed_ref::BoxedRefMut<'_, $crate::core::_InputOutputArray>> {
138				$crate::core::_InputOutputArray::$mut_cons(self)
139			}
140		}
141
142		$crate::output_array_ref_forward! { $type }
143	};
144}
145
146#[doc(hidden)]
147#[macro_export]
148macro_rules! input_output_array_vector {
149	($type: ty, $const_cons: ident) => {
150		impl $crate::core::ToInputArray for $crate::core::Vector<$crate::boxed_ref::BoxedRef<'_, $type>> {
151			#[inline]
152			fn input_array(&self) -> $crate::Result<$crate::boxed_ref::BoxedRef<'_, $crate::core::_InputArray>> {
153				$crate::core::_InputArray::$const_cons(self.as_non_ref_vec())
154			}
155		}
156
157		$crate::input_array_ref_forward! { $crate::core::Vector<$crate::boxed_ref::BoxedRef<'_, $type>> }
158
159		$crate::input_output_array! { $crate::core::Vector<$type>, $const_cons }
160	};
161
162	($type: ty, $const_cons: ident, $mut_cons: ident) => {
163		impl $crate::core::ToInputArray for $crate::core::Vector<$crate::boxed_ref::BoxedRef<'_, $type>> {
164			#[inline]
165			fn input_array(&self) -> $crate::Result<$crate::boxed_ref::BoxedRef<'_, $crate::core::_InputArray>> {
166				$crate::core::_InputArray::$const_cons(self.as_non_ref_vec())
167			}
168		}
169
170		$crate::input_array_ref_forward! { $crate::core::Vector<$crate::boxed_ref::BoxedRef<'_, $type>> }
171
172		$crate::input_output_array! { $crate::core::Vector<$type>, $const_cons, $mut_cons }
173	};
174}
175
176/// Adds automatic implementation for [ToInputArray] for the reference to the supplied type
177#[doc(hidden)]
178#[macro_export]
179macro_rules! input_array_ref_forward {
180	($type: ty) => {
181		impl $crate::core::ToInputArray for &$type {
182			#[inline]
183			fn input_array(&self) -> $crate::Result<$crate::boxed_ref::BoxedRef<'_, $crate::core::_InputArray>> {
184				(*self).input_array()
185			}
186		}
187	};
188}
189
190/// Adds automatic implementations for [ToOutputArray] and [ToInputOutputArray] for the mutable references to the supplied type
191#[doc(hidden)]
192#[macro_export]
193macro_rules! output_array_ref_forward {
194	($type: ty) => {
195		impl $crate::core::ToOutputArray for &mut $type {
196			#[inline]
197			fn output_array(&mut self) -> $crate::Result<$crate::boxed_ref::BoxedRefMut<'_, $crate::core::_OutputArray>> {
198				(*self).output_array()
199			}
200		}
201
202		impl $crate::core::ToInputOutputArray for &mut $type {
203			#[inline]
204			fn input_output_array(&mut self) -> $crate::Result<$crate::boxed_ref::BoxedRefMut<'_, $crate::core::_InputOutputArray>> {
205				(*self).input_output_array()
206			}
207		}
208	};
209}
210
211input_output_array! { f64, from_f64 }
212
213impl ToInputArray for &[u8] {
214	#[inline]
215	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>> {
216		_InputArray::from_byte_slice(self)
217	}
218}
219
220impl<const N: usize> ToInputArray for [u8; N] {
221	#[inline]
222	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>> {
223		_InputArray::from_byte_slice(self)
224	}
225}
226
227impl<T: Boxed + ToInputArray> ToInputArray for BoxedRef<'_, T> {
228	#[inline]
229	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>> {
230		self.reference.input_array()
231	}
232}
233
234impl<T: Boxed + ToInputArray> ToInputArray for &BoxedRef<'_, T> {
235	#[inline]
236	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>> {
237		(*self).input_array()
238	}
239}
240
241impl<T: Boxed + ToInputArray> ToInputArray for BoxedRefMut<'_, T> {
242	#[inline]
243	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>> {
244		self.reference.input_array()
245	}
246}
247
248impl<T: Boxed + ToInputArray> ToInputArray for &BoxedRefMut<'_, T> {
249	#[inline]
250	fn input_array(&self) -> Result<BoxedRef<'_, _InputArray>> {
251		(*self).input_array()
252	}
253}
254
255impl<T: Boxed + ToOutputArray> ToOutputArray for BoxedRefMut<'_, T> {
256	#[inline]
257	fn output_array(&mut self) -> Result<BoxedRefMut<'_, _OutputArray>> {
258		self.reference.output_array()
259	}
260}
261
262impl<T: Boxed + ToOutputArray> ToOutputArray for &mut BoxedRefMut<'_, T> {
263	#[inline]
264	fn output_array(&mut self) -> Result<BoxedRefMut<'_, _OutputArray>> {
265		(*self).output_array()
266	}
267}
268
269impl<T: Boxed + ToInputOutputArray> ToInputOutputArray for BoxedRefMut<'_, T> {
270	#[inline]
271	fn input_output_array(&mut self) -> Result<BoxedRefMut<'_, _InputOutputArray>> {
272		self.reference.input_output_array()
273	}
274}
275
276impl<T: Boxed + ToInputOutputArray> ToInputOutputArray for &mut BoxedRefMut<'_, T> {
277	#[inline]
278	fn input_output_array(&mut self) -> Result<BoxedRefMut<'_, _InputOutputArray>> {
279		(*self).input_output_array()
280	}
281}