@@ -8,6 +8,7 @@ pub use mat_::*;
8
8
9
9
use crate :: boxed_ref:: { BoxedRef , BoxedRefMut } ;
10
10
use crate :: core:: { MatConstIterator , MatExpr , MatSize , Point , Rect , Scalar , Size , UMat } ;
11
+ use crate :: manual:: core:: DataType ;
11
12
use crate :: prelude:: * ;
12
13
use crate :: { core, input_output_array, input_output_array_vector, Error , Result } ;
13
14
@@ -42,30 +43,28 @@ fn match_format<T: DataType>(mat_type: i32) -> Result<()> {
42
43
}
43
44
}
44
45
45
- #[ inline]
46
- fn match_dims ( mat : & ( impl MatTraitConst + ?Sized ) , dims : usize ) -> Result < ( ) > {
47
- // safe because `Mat::dims()` returns value >= 2
48
- let mat_dims = mat. dims ( ) as usize ;
49
- if mat_dims == dims {
50
- Ok ( ( ) )
51
- } else {
52
- Err ( Error :: new (
46
+ fn match_indices ( mat : & ( impl MatTraitConst + ?Sized ) , idx : & [ i32 ] ) -> Result < ( ) > {
47
+ let mat_size = mat. mat_size ( ) ;
48
+ let size = & * mat_size;
49
+ if size. len ( ) != idx. len ( ) {
50
+ return Err ( Error :: new (
53
51
core:: StsUnmatchedSizes ,
54
- format ! ( "Mat dims is: {mat_dims}, but requested dims is: {dims}" ) ,
55
- ) )
52
+ format ! (
53
+ "Amount of Mat dimensions: {} doesn't match the amount of requested indices: {}" ,
54
+ size. len( ) ,
55
+ idx. len( )
56
+ ) ,
57
+ ) ) ;
56
58
}
57
- }
58
-
59
- fn match_indices ( mat : & ( impl MatTraitConst + ? Sized ) , idx : & [ i32 ] ) -> Result < ( ) > {
60
- let size = mat . mat_size ( ) ;
61
- match_dims ( mat , idx . len ( ) ) ? ;
62
- if let Some ( ( out_dim , out_size ) ) = size . iter ( ) . enumerate ( ) . find ( | & ( i , & x ) | idx [ i ] < 0 || idx [ i ] >= x ) {
59
+ if let Some ( ( out_idx , ( out_idx_val , out_size ) ) ) = idx
60
+ . iter ( )
61
+ . zip ( size )
62
+ . enumerate ( )
63
+ . find ( | ( _ , ( idx_val , & size ) ) | ! ( 0 ..size ) . contains ( idx_val ) )
64
+ {
63
65
Err ( Error :: new (
64
66
core:: StsOutOfRange ,
65
- format ! (
66
- "Index: {} along dimension: {} out of bounds 0..{}" ,
67
- idx[ out_dim] , out_dim, out_size
68
- ) ,
67
+ format ! ( "Index: {out_idx_val} along dimension: {out_idx} out of bounds 0..{out_size}" ) ,
69
68
) )
70
69
} else {
71
70
Ok ( ( ) )
@@ -98,21 +97,23 @@ fn match_is_continuous(mat: &(impl MatTraitConst + ?Sized)) -> Result<()> {
98
97
}
99
98
}
100
99
101
- #[ inline]
102
100
fn match_length ( sizes : & [ i32 ] , len : usize ) -> Result < ( ) > {
103
101
if sizes. is_empty ( ) {
104
102
return Err ( Error :: new ( core:: StsUnmatchedSizes , "Dimensions must not be empty" ) ) ;
105
103
}
106
- let data_len = i32:: try_from ( len) ?;
107
- if sizes. iter ( ) . product :: < i32 > ( ) != data_len {
108
- let msg = if sizes. len ( ) == 2 {
109
- format ! (
110
- "The length of the slice: {data_len} must match the passed row: {rows} and column: {cols} counts exactly" ,
111
- rows = sizes[ 0 ] ,
112
- cols = sizes[ 1 ] ,
113
- )
114
- } else {
115
- format ! ( "The length of the slice: {data_len} must match the passed dimensions: {sizes:?} exactly" )
104
+ let mut volume: u64 = 1 ;
105
+ for ( i, size) in sizes. iter ( ) . enumerate ( ) {
106
+ let size =
107
+ u64:: try_from ( * size) . map_err ( |_| Error :: new ( core:: StsOutOfRange , format ! ( "Dimension {i} must not be negative" ) ) ) ?;
108
+ volume = volume. saturating_mul ( size) ;
109
+ }
110
+ let data_len = u64:: try_from ( len) . map_err ( |_| Error :: new ( core:: StsOutOfRange , "Length must fit in u64" ) ) ?;
111
+ if volume != data_len {
112
+ let msg = match sizes {
113
+ [ rows, cols] => {
114
+ format ! ( "The length of the slice: {data_len} must match the passed row: {rows} and column: {cols} counts exactly" )
115
+ }
116
+ _ => format ! ( "The length of the slice: {data_len} must match the passed dimensions: {sizes:?} exactly" ) ,
116
117
} ;
117
118
return Err ( Error :: new ( core:: StsUnmatchedSizes , msg) ) ;
118
119
}
@@ -344,16 +345,13 @@ pub(crate) mod mat_forward {
344
345
#[ inline]
345
346
pub fn at < T : DataType > ( mat : & ( impl MatTraitConst + ?Sized ) , i0 : i32 ) -> Result < & T > {
346
347
match_format :: < T > ( mat. typ ( ) )
347
- . and_then ( |_| match_dims ( mat, 2 ) )
348
348
. and_then ( |_| match_total ( mat, i0) )
349
349
. and_then ( |_| unsafe { mat. at_unchecked ( i0) } )
350
350
}
351
351
352
352
#[ inline]
353
353
pub fn at_mut < T : DataType > ( mat : & mut ( impl MatTrait + ?Sized ) , i0 : i32 ) -> Result < & mut T > {
354
- match_format :: < T > ( mat. typ ( ) )
355
- . and_then ( |_| match_dims ( mat, 2 ) )
356
- . and_then ( |_| match_total ( mat, i0) ) ?;
354
+ match_format :: < T > ( mat. typ ( ) ) . and_then ( |_| match_total ( mat, i0) ) ?;
357
355
unsafe { mat. at_unchecked_mut ( i0) }
358
356
}
359
357
@@ -520,8 +518,19 @@ pub trait MatTraitConstManual: MatTraitConst {
520
518
}
521
519
522
520
fn to_vec_2d < T : DataType > ( & self ) -> Result < Vec < Vec < T > > > {
523
- match_format :: < T > ( self . typ ( ) ) . and_then ( |_| match_dims ( self , 2 ) ) . and_then ( |_| {
524
- let size = self . size ( ) ?;
521
+ match_format :: < T > ( self . typ ( ) ) . and_then ( |_| {
522
+ let size = match * self . mat_size ( ) {
523
+ [ rows, cols] => Size :: new ( cols, rows) ,
524
+ ref mat_size => {
525
+ return Err ( Error :: new (
526
+ core:: StsUnmatchedSizes ,
527
+ format ! (
528
+ "Mat must have 2 dimensions for this operation, but it has: {}" ,
529
+ mat_size. len( )
530
+ ) ,
531
+ ) )
532
+ }
533
+ } ;
525
534
// safe because Mat size can't be negative
526
535
let width = size. width as usize ;
527
536
if self . is_continuous ( ) {
0 commit comments