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	// MSRV: change to `unsafe extern "C"` when MSRV is 1.82
43	extern "C" {
44		fn cv_InputArray_input_array(instance: *const c_void, ocvrs_return: *mut sys::Result<*mut c_void>);
45	}
46	return_send!(via ocvrs_return);
47	unsafe { cv_InputArray_input_array(input_array.as_raw__InputArray(), ocvrs_return.as_mut_ptr()) }
48	return_receive!(ocvrs_return => ret);
49	ret.into_result().map(|ptr| unsafe { _InputArray::from_raw(ptr) }.into())
50}
51
52#[inline]
53fn call_output_array(output_array: &mut impl _OutputArrayTrait) -> Result<BoxedRefMut<_OutputArray>> {
54	extern "C" {
55		fn cv_OutputArray_output_array(instance: *mut c_void, ocvrs_return: *mut sys::Result<*mut c_void>);
56	}
57	return_send!(via ocvrs_return);
58	unsafe { cv_OutputArray_output_array(output_array.as_raw_mut__OutputArray(), ocvrs_return.as_mut_ptr()) }
59	return_receive!(ocvrs_return => ret);
60	ret.into_result().map(|ptr| unsafe { _OutputArray::from_raw(ptr) }.into())
61}
62
63impl ToInputArray for _InputArray {
64	#[inline]
65	fn input_array(&self) -> Result<BoxedRef<_InputArray>> {
66		call_input_array(self)
67	}
68}
69
70impl ToInputArray for _OutputArray {
71	#[inline]
72	fn input_array(&self) -> Result<BoxedRef<_InputArray>> {
73		call_input_array(self)
74	}
75}
76
77impl ToInputArray for _InputOutputArray {
78	#[inline]
79	fn input_array(&self) -> Result<BoxedRef<_InputArray>> {
80		call_input_array(self)
81	}
82}
83
84impl ToOutputArray for _OutputArray {
85	#[inline]
86	fn output_array(&mut self) -> Result<BoxedRefMut<_OutputArray>> {
87		call_output_array(self)
88	}
89}
90
91impl ToOutputArray for _InputOutputArray {
92	#[inline]
93	fn output_array(&mut self) -> Result<BoxedRefMut<_OutputArray>> {
94		call_output_array(self)
95	}
96}
97
98impl ToInputOutputArray for _InputOutputArray {
99	#[inline]
100	fn input_output_array(&mut self) -> Result<BoxedRefMut<_InputOutputArray>> {
101		extern "C" {
102			fn cv_InputOutputArray_input_output_array(instance: *mut c_void, ocvrs_return: *mut sys::Result<*mut c_void>);
103		}
104		return_send!(via ocvrs_return);
105		unsafe { cv_InputOutputArray_input_output_array(self.as_raw_mut__InputOutputArray(), ocvrs_return.as_mut_ptr()) }
106		return_receive!(ocvrs_return => ret);
107		ret.into_result()
108			.map(|ptr| unsafe { _InputOutputArray::from_raw(ptr) }.into())
109	}
110}
111
112#[doc(hidden)]
113#[macro_export]
114macro_rules! input_output_array {
115	($type: ty, $const_cons: ident) => {
116		impl $crate::core::ToInputArray for $type {
117			#[inline]
118			fn input_array(&self) -> $crate::Result<$crate::boxed_ref::BoxedRef<$crate::core::_InputArray>> {
119				$crate::core::_InputArray::$const_cons(self)
120			}
121		}
122
123		$crate::input_array_ref_forward! { $type }
124	};
125
126	($type: ty, $const_cons: ident, $mut_cons: ident) => {
127		$crate::input_output_array! { $type, $const_cons }
128
129		impl $crate::core::ToOutputArray for $type {
130			#[inline]
131			fn output_array(&mut self) -> $crate::Result<$crate::boxed_ref::BoxedRefMut<$crate::core::_OutputArray>> {
132				$crate::core::_OutputArray::$mut_cons(self)
133			}
134		}
135
136		impl $crate::core::ToInputOutputArray for $type {
137			#[inline]
138			fn input_output_array(&mut self) -> $crate::Result<$crate::boxed_ref::BoxedRefMut<$crate::core::_InputOutputArray>> {
139				$crate::core::_InputOutputArray::$mut_cons(self)
140			}
141		}
142
143		$crate::output_array_ref_forward! { $type }
144	};
145}
146
147#[doc(hidden)]
148#[macro_export]
149macro_rules! input_output_array_vector {
150	($type: ty, $const_cons: ident) => {
151		impl $crate::core::ToInputArray for $crate::core::Vector<$crate::boxed_ref::BoxedRef<'_, $type>> {
152			#[inline]
153			fn input_array(&self) -> $crate::Result<$crate::boxed_ref::BoxedRef<$crate::core::_InputArray>> {
154				$crate::core::_InputArray::$const_cons(self.as_non_ref_vec())
155			}
156		}
157
158		$crate::input_array_ref_forward! { $crate::core::Vector<$crate::boxed_ref::BoxedRef<'_, $type>> }
159
160		$crate::input_output_array! { $crate::core::Vector<$type>, $const_cons }
161	};
162
163	($type: ty, $const_cons: ident, $mut_cons: ident) => {
164		impl $crate::core::ToInputArray for $crate::core::Vector<$crate::boxed_ref::BoxedRef<'_, $type>> {
165			#[inline]
166			fn input_array(&self) -> $crate::Result<$crate::boxed_ref::BoxedRef<$crate::core::_InputArray>> {
167				$crate::core::_InputArray::$const_cons(self.as_non_ref_vec())
168			}
169		}
170
171		$crate::input_array_ref_forward! { $crate::core::Vector<$crate::boxed_ref::BoxedRef<'_, $type>> }
172
173		$crate::input_output_array! { $crate::core::Vector<$type>, $const_cons, $mut_cons }
174	};
175}
176
177/// Adds automatic implementation for [ToInputArray] for the reference to the supplied type
178#[doc(hidden)]
179#[macro_export]
180macro_rules! input_array_ref_forward {
181	($type: ty) => {
182		impl $crate::core::ToInputArray for &$type {
183			#[inline]
184			fn input_array(&self) -> $crate::Result<$crate::boxed_ref::BoxedRef<$crate::core::_InputArray>> {
185				(*self).input_array()
186			}
187		}
188	};
189}
190
191/// Adds automatic implementations for [ToOutputArray] and [ToInputOutputArray] for the mutable references to the supplied type
192#[doc(hidden)]
193#[macro_export]
194macro_rules! output_array_ref_forward {
195	($type: ty) => {
196		impl $crate::core::ToOutputArray for &mut $type {
197			#[inline]
198			fn output_array(&mut self) -> $crate::Result<$crate::boxed_ref::BoxedRefMut<$crate::core::_OutputArray>> {
199				(*self).output_array()
200			}
201		}
202
203		impl $crate::core::ToInputOutputArray for &mut $type {
204			#[inline]
205			fn input_output_array(&mut self) -> $crate::Result<$crate::boxed_ref::BoxedRefMut<$crate::core::_InputOutputArray>> {
206				(*self).input_output_array()
207			}
208		}
209	};
210}
211
212input_output_array! { f64, from_f64 }
213
214impl ToInputArray for &[u8] {
215	#[inline]
216	fn input_array(&self) -> Result<BoxedRef<_InputArray>> {
217		_InputArray::from_byte_slice(self)
218	}
219}
220
221impl<const N: usize> ToInputArray for [u8; N] {
222	#[inline]
223	fn input_array(&self) -> Result<BoxedRef<_InputArray>> {
224		_InputArray::from_byte_slice(self)
225	}
226}
227
228impl<T: Boxed + ToInputArray> ToInputArray for BoxedRef<'_, T> {
229	#[inline]
230	fn input_array(&self) -> Result<BoxedRef<_InputArray>> {
231		self.reference.input_array()
232	}
233}
234
235impl<T: Boxed + ToInputArray> ToInputArray for &BoxedRef<'_, T> {
236	#[inline]
237	fn input_array(&self) -> Result<BoxedRef<_InputArray>> {
238		(*self).input_array()
239	}
240}
241
242impl<T: Boxed + ToInputArray> ToInputArray for BoxedRefMut<'_, T> {
243	#[inline]
244	fn input_array(&self) -> Result<BoxedRef<_InputArray>> {
245		self.reference.input_array()
246	}
247}
248
249impl<T: Boxed + ToInputArray> ToInputArray for &BoxedRefMut<'_, T> {
250	#[inline]
251	fn input_array(&self) -> Result<BoxedRef<_InputArray>> {
252		(*self).input_array()
253	}
254}
255
256impl<T: Boxed + ToOutputArray> ToOutputArray for BoxedRefMut<'_, T> {
257	#[inline]
258	fn output_array(&mut self) -> Result<BoxedRefMut<_OutputArray>> {
259		self.reference.output_array()
260	}
261}
262
263impl<T: Boxed + ToOutputArray> ToOutputArray for &mut BoxedRefMut<'_, T> {
264	#[inline]
265	fn output_array(&mut self) -> Result<BoxedRefMut<_OutputArray>> {
266		(*self).output_array()
267	}
268}
269
270impl<T: Boxed + ToInputOutputArray> ToInputOutputArray for BoxedRefMut<'_, T> {
271	#[inline]
272	fn input_output_array(&mut self) -> Result<BoxedRefMut<_InputOutputArray>> {
273		self.reference.input_output_array()
274	}
275}
276
277impl<T: Boxed + ToInputOutputArray> ToInputOutputArray for &mut BoxedRefMut<'_, T> {
278	#[inline]
279	fn input_output_array(&mut self) -> Result<BoxedRefMut<_InputOutputArray>> {
280		(*self).input_output_array()
281	}
282}