Make sure that all useful specializations of Vec can be used as Input/OutputArray
MODIFY
src/manual/core/scalar.rs
src/manual/core/scalar.rs
-use std::ffi::c_void;
-
-use crate::{
- core::{_InputArray, ToInputArray},
- input_array_ref_forward,
- Result,
- sys,
- traits::Boxed,
-};
-
use super::VecN;
valid_types!(ValidScalarType: i32, f64);
@@ -48,15 +38,3 @@ impl<T: ValidScalarType> From<(T, T, T, T)> for Scalar_<T> {
Self::from([v.0, v.1, v.2, v.3])
}
}
-
-impl ToInputArray for Scalar_<f64> {
- #[inline]
- fn input_array(&self) -> Result<_InputArray> {
- extern "C" { fn cv_Scalar_input_array(instance: *const Scalar_<f64>) -> sys::Result<*mut c_void>; }
- unsafe { cv_Scalar_input_array(self) }
- .into_result()
- .map(|ptr| unsafe { _InputArray::from_raw(ptr) })
- }
-}
-
-input_array_ref_forward! { Scalar_<f64> }

MODIFY
src/manual/core/vec.rs
src/manual/core/vec.rs
use std::{
array,
+ ffi::c_void,
ops::{Deref, DerefMut, Mul},
};
-use crate::traits::{OpenCVType, OpenCVTypeArg, OpenCVTypeExternContainer};
+use crate::{
+ core::{_InputArray, _InputOutputArray, _OutputArray, ToInputArray, ToInputOutputArray, ToOutputArray},
+ Result,
+ sys,
+ traits::{Boxed, OpenCVType, OpenCVTypeArg, OpenCVTypeExternContainer},
+};
mod operations;
@@ -135,3 +141,102 @@ impl<T: ValidVecType, const N: usize> OpenCVTypeExternContainer for VecN<T, N> {
#[inline]
fn opencv_into_extern(self) -> Self::ExternSendMut { &mut *std::mem::ManuallyDrop::new(self) as _ }
}
+
+impl<T: ValidVecType, const N: usize> ToInputArray for VecN<T, N> where Self: VecExtern<T, N> {
+ fn input_array(&self) -> Result<_InputArray> {
+ unsafe { self.extern_input_array() }
+ .into_result()
+ .map(|ptr| unsafe { _InputArray::from_raw(ptr) })
+ }
+}
+
+impl<T: ValidVecType, const N: usize> ToInputArray for &VecN<T, N> where VecN<T, N>: VecExtern<T, N> {
+ fn input_array(&self) -> Result<_InputArray> {
+ (*self).input_array()
+ }
+}
+
+impl<T: ValidVecType, const N: usize> ToOutputArray for VecN<T, N> where Self: VecExtern<T, N> {
+ fn output_array(&mut self) -> Result<_OutputArray> {
+ unsafe { self.extern_output_array() }
+ .into_result()
+ .map(|ptr| unsafe { _OutputArray::from_raw(ptr) })
+ }
+}
+
+impl<T: ValidVecType, const N: usize> ToOutputArray for &mut VecN<T, N> where VecN<T, N>: VecExtern<T, N> {
+ fn output_array(&mut self) -> Result<_OutputArray> {
+ (*self).output_array()
+ }
+}
+
+impl<T: ValidVecType, const N: usize> ToInputOutputArray for VecN<T, N> where Self: VecExtern<T, N> {
+ fn input_output_array(&mut self) -> Result<_InputOutputArray> {
+ unsafe { self.extern_input_output_array() }
+ .into_result()
+ .map(|ptr| unsafe { _InputOutputArray::from_raw(ptr) })
+ }
+}
+
+impl<T: ValidVecType, const N: usize> ToInputOutputArray for &mut VecN<T, N> where VecN<T, N>: VecExtern<T, N> {
+ fn input_output_array(&mut self) -> Result<_InputOutputArray> {
+ (*self).input_output_array()
+ }
+}
+
+#[doc(hidden)]
+pub trait VecExtern<T: ValidVecType, const N: usize> {
+ #[doc(hidden)] unsafe fn extern_input_array(&self) -> sys::Result<*mut c_void>;
+ #[doc(hidden)] unsafe fn extern_output_array(&mut self) -> sys::Result<*mut c_void>;
+ #[doc(hidden)] unsafe fn extern_input_output_array(&mut self) -> sys::Result<*mut c_void>;
+}
+
+macro_rules! vecn_extern {
+ ($type: ty, $len: expr, $extern_input_array: ident, $extern_ouput_array: ident, $extern_input_array_output: ident) => {
+ impl $crate::manual::core::VecExtern<$type, $len> for $crate::manual::core::VecN<$type, $len> {
+ unsafe fn extern_input_array(&self) -> $crate::sys::Result<*mut ::std::ffi::c_void> {
+ extern "C" { fn $extern_input_array(instance: *const $crate::manual::core::VecN<$type, $len>) -> $crate::sys::Result<*mut ::std::ffi::c_void>; }
+ $extern_input_array(self)
+ }
+
+ unsafe fn extern_output_array(&mut self) -> $crate::sys::Result<*mut ::std::ffi::c_void> {
+ extern "C" { fn $extern_ouput_array(instance: *mut $crate::manual::core::VecN<$type, $len>) -> $crate::sys::Result<*mut ::std::ffi::c_void>; }
+ $extern_ouput_array(self)
+ }
+
+ unsafe fn extern_input_output_array(&mut self) -> $crate::sys::Result<*mut ::std::ffi::c_void> {
+ extern "C" { fn $extern_input_array_output(instance: *mut $crate::manual::core::VecN<$type, $len>) -> $crate::sys::Result<*mut ::std::ffi::c_void>; }
+ $extern_input_array_output(self)
+ }
+ }
+ }
+}
+
+vecn_extern!(u8, 2, cv_Vec2b_input_array, cv_Vec2b_output_array, cv_Vec2b_input_output_array);
+vecn_extern!(f64, 2, cv_Vec2d_input_array, cv_Vec2d_output_array, cv_Vec2d_input_output_array);
+vecn_extern!(f32, 2, cv_Vec2f_input_array, cv_Vec2f_output_array, cv_Vec2f_input_output_array);
+vecn_extern!(i32, 2, cv_Vec2i_input_array, cv_Vec2i_output_array, cv_Vec2i_input_output_array);
+vecn_extern!(i16, 2, cv_Vec2s_input_array, cv_Vec2s_output_array, cv_Vec2s_input_output_array);
+vecn_extern!(u16, 2, cv_Vec2w_input_array, cv_Vec2w_output_array, cv_Vec2w_input_output_array);
+
+vecn_extern!(u8, 3, cv_Vec3b_input_array, cv_Vec3b_output_array, cv_Vec3b_input_output_array);
+vecn_extern!(f64, 3, cv_Vec3d_input_array, cv_Vec3d_output_array, cv_Vec3d_input_output_array);
+vecn_extern!(f32, 3, cv_Vec3f_input_array, cv_Vec3f_output_array, cv_Vec3f_input_output_array);
+vecn_extern!(i32, 3, cv_Vec3i_input_array, cv_Vec3i_output_array, cv_Vec3i_input_output_array);
+vecn_extern!(i16, 3, cv_Vec3s_input_array, cv_Vec3s_output_array, cv_Vec3s_input_output_array);
+vecn_extern!(u16, 3, cv_Vec3w_input_array, cv_Vec3w_output_array, cv_Vec3w_input_output_array);
+
+vecn_extern!(u8, 4, cv_Vec4b_input_array, cv_Vec4b_output_array, cv_Vec4b_input_output_array);
+vecn_extern!(f64, 4, cv_Vec4d_input_array, cv_Vec4d_output_array, cv_Vec4d_input_output_array);
+vecn_extern!(f32, 4, cv_Vec4f_input_array, cv_Vec4f_output_array, cv_Vec4f_input_output_array);
+vecn_extern!(i32, 4, cv_Vec4i_input_array, cv_Vec4i_output_array, cv_Vec4i_input_output_array);
+vecn_extern!(i16, 4, cv_Vec4s_input_array, cv_Vec4s_output_array, cv_Vec4s_input_output_array);
+vecn_extern!(u16, 4, cv_Vec4w_input_array, cv_Vec4w_output_array, cv_Vec4w_input_output_array);
+
+vecn_extern!(f64, 6, cv_Vec6d_input_array, cv_Vec6d_output_array, cv_Vec6d_input_output_array);
+vecn_extern!(f32, 6, cv_Vec6f_input_array, cv_Vec6f_output_array, cv_Vec6f_input_output_array);
+vecn_extern!(i32, 6, cv_Vec6i_input_array, cv_Vec6i_output_array, cv_Vec6i_input_output_array);
+
+vecn_extern!(i32, 8, cv_Vec8i_input_array, cv_Vec8i_output_array, cv_Vec8i_input_output_array);
+
+vecn_extern!(f64, 18, cv_Vec18d_input_array, cv_Vec18d_output_array, cv_Vec18d_input_output_array);

MODIFY
src_cpp/manual-core.cpp
src_cpp/manual-core.cpp
@@ -22,13 +22,22 @@ template<typename T> inline Result<void*> ocvrs_input_output_array(T* instance)
} OCVRS_CATCH(Result<void*>)
}
-#define ocvrs_matx(base) \
- Result<void*> cv_##base##f_input_array(const cv::base##f* instance) { return ocvrs_input_array(instance); } \
- Result<void*> cv_##base##f_output_array(cv::base##f* instance) { return ocvrs_output_array(instance); } \
- Result<void*> cv_##base##f_input_output_array(cv::base##f* instance) { return ocvrs_input_output_array(instance); } \
- Result<void*> cv_##base##d_input_array(const cv::base##d* instance) { return ocvrs_input_array(instance); } \
- Result<void*> cv_##base##d_output_array(cv::base##d* instance) { return ocvrs_output_array(instance); } \
- Result<void*> cv_##base##d_input_output_array(cv::base##d* instance) { return ocvrs_input_output_array(instance); }
+#define ocvrs_ioa(base) \
+ Result<void*> cv_##base##_input_array(const cv::base* instance) { return ocvrs_input_array(instance); } \
+ Result<void*> cv_##base##_output_array(cv::base* instance) { return ocvrs_output_array(instance); } \
+ Result<void*> cv_##base##_input_output_array(cv::base* instance) { return ocvrs_input_output_array(instance); }
+
+#define ocvrs_ioa_df(base) \
+ ocvrs_ioa(base##d) \
+ ocvrs_ioa(base##f)
+
+#define ocvrs_ioa_bdfisw(base) \
+ ocvrs_ioa(base##b) \
+ ocvrs_ioa(base##d) \
+ ocvrs_ioa(base##f) \
+ ocvrs_ioa(base##i) \
+ ocvrs_ioa(base##s) \
+ ocvrs_ioa(base##w)
extern "C" {
Result<cv::Size> cv_manual_Mat_size(const cv::Mat* instance) {
@@ -74,27 +83,38 @@ extern "C" {
Result<void*> cv_OutputArray_output_array(cv::_OutputArray* instance) { return ocvrs_output_array(instance); }
Result<void*> cv_InputOutputArray_input_output_array(cv::_InputOutputArray* instance) { return ocvrs_input_output_array(instance); }
- Result<void*> cv_Scalar_input_array(cv::Scalar* instance) { return ocvrs_input_array(instance); }
+ ocvrs_ioa_df(Matx12)
+ ocvrs_ioa_df(Matx13)
+ ocvrs_ioa_df(Matx14)
+ ocvrs_ioa_df(Matx16)
- ocvrs_matx(Matx12)
- ocvrs_matx(Matx13)
- ocvrs_matx(Matx14)
- ocvrs_matx(Matx16)
+ ocvrs_ioa_df(Matx21)
+ ocvrs_ioa_df(Matx31)
+ ocvrs_ioa_df(Matx41)
+ ocvrs_ioa_df(Matx61)
- ocvrs_matx(Matx21)
- ocvrs_matx(Matx31)
- ocvrs_matx(Matx41)
- ocvrs_matx(Matx61)
+ ocvrs_ioa_df(Matx22)
+ ocvrs_ioa_df(Matx23)
+ ocvrs_ioa_df(Matx32)
- ocvrs_matx(Matx22)
- ocvrs_matx(Matx23)
- ocvrs_matx(Matx32)
+ ocvrs_ioa_df(Matx33)
- ocvrs_matx(Matx33)
+ ocvrs_ioa_df(Matx34)
+ ocvrs_ioa_df(Matx43)
- ocvrs_matx(Matx34)
- ocvrs_matx(Matx43)
+ ocvrs_ioa_df(Matx44)
+ ocvrs_ioa_df(Matx66)
- ocvrs_matx(Matx44)
- ocvrs_matx(Matx66)
+ ocvrs_ioa_bdfisw(Vec2)
+ ocvrs_ioa_bdfisw(Vec3)
+ ocvrs_ioa_bdfisw(Vec4)
+
+ ocvrs_ioa_df(Vec6)
+ ocvrs_ioa(Vec6i)
+
+ ocvrs_ioa(Vec8i)
+
+ Result<void*> cv_Vec18d_input_array(cv::Vec<double, 18>* instance) { return ocvrs_input_array(instance); }
+ Result<void*> cv_Vec18d_output_array(cv::Vec<double, 18>* instance) { return ocvrs_output_array(instance); }
+ Result<void*> cv_Vec18d_input_output_array(cv::Vec<double, 18>* instance) { return ocvrs_input_output_array(instance); }
}

MODIFY
tests/input_output_array.rs
tests/input_output_array.rs
use matches::assert_matches;
use opencv::{
- core::{self, Matx12d, Scalar, ToInputArray, UMat, UMatUsageFlags},
+ core::{self, Matx12d, Scalar, ToInputArray, ToInputOutputArray, ToOutputArray, UMat, UMatUsageFlags, Vec2b, VecN},
prelude::*,
Result,
types::{VectorOff64, VectorOfu8},
@@ -22,9 +22,32 @@ fn input_array() -> Result<()> {
#[test]
fn input_output_array_types() -> Result<()> {
assert!(Mat::default().input_array()?.is_mat()?);
+ assert!(Mat::default().output_array()?.is_mat()?);
+ assert!(Mat::default().input_output_array()?.is_mat()?);
+
assert!(VectorOfu8::new().input_array()?.is_vector()?);
+ assert!(VectorOfu8::new().output_array()?.is_vector()?);
+ assert!(VectorOfu8::new().input_output_array()?.is_vector()?);
+
assert!(Matx12d::default().input_array()?.is_matx()?);
+ assert!(Matx12d::default().output_array()?.is_matx()?);
+ assert!(Matx12d::default().input_output_array()?.is_matx()?);
+
assert!(UMat::new_rows_cols_with_default(1, 1, u8::typ(), Scalar::from(8.), UMatUsageFlags::USAGE_DEFAULT)?.input_array()?.is_umat()?);
+ assert!(UMat::new_rows_cols_with_default(1, 1, u8::typ(), Scalar::from(8.), UMatUsageFlags::USAGE_DEFAULT)?.output_array()?.is_umat()?);
+ assert!(UMat::new_rows_cols_with_default(1, 1, u8::typ(), Scalar::from(8.), UMatUsageFlags::USAGE_DEFAULT)?.input_output_array()?.is_umat()?);
+
+ assert!(Scalar::default().input_array()?.is_matx()?);
+ assert!(Scalar::default().output_array()?.is_matx()?);
+ assert!(Scalar::default().input_output_array()?.is_matx()?);
+
+ assert!(Vec2b::default().input_array()?.is_matx()?);
+ assert!(Vec2b::default().output_array()?.is_matx()?);
+ assert!(Vec2b::default().input_output_array()?.is_matx()?);
+
+ assert!(VecN::<f64, 18>::default().input_array()?.is_matx()?);
+ assert!(VecN::<f64, 18>::default().output_array()?.is_matx()?);
+ assert!(VecN::<f64, 18>::default().input_output_array()?.is_matx()?);
Ok(())
}

Make sure that all useful specializations of Vec can be used as Input/OutputArray