@@ -545,7 +545,7 @@ class Mat extends CvStruct<cvg.Mat> {
545545 }
546546
547547 /// equivalent to Mat::at\<T\>(i0, i1, i2) = val;
548- /// where T might be basic value types like uchar, char, int .
548+ /// where T might be int, double .
549549 /// or cv::Vec<> like cv::Vec3b
550550 ///
551551 /// example
@@ -568,6 +568,154 @@ class Mat extends CvStruct<cvg.Mat> {
568568 // https://github.com/dart-lang/sdk/issues/43390#issuecomment-690993957
569569 bool isSubtype <S , T >() => < S > [] is List <T >;
570570
571+ /// equivalent to Mat::ptr\<T\>(i0, i1, i2)
572+ ///
573+ /// **DANGEROUS**
574+ ///
575+ /// returns a pointer to operate Mat directly and effectively, use with caution!
576+ ///
577+ /// Example:
578+ /// ```dart
579+ /// final mat = cv.Mat.ones(3, 3, cv.MatType.CV_8UC1);
580+ /// mat.set<int>(0, 0, 99);
581+ ///
582+ /// final ptr = mat.ptrAt<cv.U8>(0, 0);
583+ /// print(ptr[0]); // 99
584+ ///
585+ /// ptr[0] = 21;
586+ /// // Mat::ptr(i, j)
587+ /// print(mat.at<int>(0, 0)); // 21
588+ /// print(ptr[0]); // 21
589+ ///
590+ /// final ptr1 = mat.ptrAt<cv.U8>(0);
591+ /// print(ptr1[0]); // 21
592+ /// print(List.generate(mat.cols, (i)=>ptr1[i]); // [21, 1, 1]
593+ /// ```
594+ ///
595+ /// https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html#a8b2912f6a6f5d55a3c9a7aae9134d862
596+ ffi.Pointer <T > ptrAt< T extends ffi.NativeType > (int i0, [int ? i1, int ? i2]) {
597+ if (T == ffi.UnsignedChar ) return ptrU8 (i0, i1, i2) as ffi.Pointer <T >;
598+ if (T == ffi.Char ) return ptrI8 (i0, i1, i2) as ffi.Pointer <T >;
599+ if (T == ffi.UnsignedShort ) return ptrU16 (i0, i1, i2) as ffi.Pointer <T >;
600+ if (T == ffi.Short ) return ptrI16 (i0, i1, i2) as ffi.Pointer <T >;
601+ if (T == ffi.Int ) return ptrI32 (i0, i1, i2) as ffi.Pointer <T >;
602+ if (T == ffi.Float ) return ptrF32 (i0, i1, i2) as ffi.Pointer <T >;
603+ if (T == ffi.Double ) return ptrF64 (i0, i1, i2) as ffi.Pointer <T >;
604+ throw UnsupportedError ("ptr<$T >() is not supported!" );
605+ }
606+
607+ ffi.Pointer <ffi.UnsignedChar > ptrU8 (int i0, [int ? i1, int ? i2]) {
608+ final p = calloc< ffi.Pointer <ffi.UnsignedChar >> ();
609+ if (i1 == null && i2 == null ) {
610+ cvRun (() => CFFI .Mat_Ptr_u8_1 (ref, i0, p));
611+ } else if (i1 != null && i2 == null ) {
612+ cvRun (() => CFFI .Mat_Ptr_u8_2 (ref, i0, i1, p));
613+ } else if (i1 != null && i2 != null ) {
614+ cvRun (() => CFFI .Mat_Ptr_u8_3 (ref, i0, i1, i2, p));
615+ } else {
616+ throw UnsupportedError ("ptrU8($i0 , $i1 , $i2 ) is not supported!" );
617+ }
618+ final ret = p.value.cast< ffi.UnsignedChar > ();
619+ calloc.free (p);
620+ return ret;
621+ }
622+
623+ ffi.Pointer <ffi.Char > ptrI8 (int i0, [int ? i1, int ? i2]) {
624+ final p = calloc< ffi.Pointer <ffi.Char >> ();
625+ if (i1 == null && i2 == null ) {
626+ cvRun (() => CFFI .Mat_Ptr_i8_1 (ref, i0, p));
627+ } else if (i1 != null && i2 == null ) {
628+ cvRun (() => CFFI .Mat_Ptr_i8_2 (ref, i0, i1, p));
629+ } else if (i1 != null && i2 != null ) {
630+ cvRun (() => CFFI .Mat_Ptr_i8_3 (ref, i0, i1, i2, p));
631+ } else {
632+ throw UnsupportedError ("ptrI8($i0 , $i1 , $i2 ) is not supported!" );
633+ }
634+ final ret = p.value.cast< ffi.Char > ();
635+ calloc.free (p);
636+ return ret;
637+ }
638+
639+ ffi.Pointer <ffi.UnsignedShort > ptrU16 (int i0, [int ? i1, int ? i2]) {
640+ final p = calloc< ffi.Pointer <ffi.UnsignedShort >> ();
641+ if (i1 == null && i2 == null ) {
642+ cvRun (() => CFFI .Mat_Ptr_u16_1 (ref, i0, p));
643+ } else if (i1 != null && i2 == null ) {
644+ cvRun (() => CFFI .Mat_Ptr_u16_2 (ref, i0, i1, p));
645+ } else if (i1 != null && i2 != null ) {
646+ cvRun (() => CFFI .Mat_Ptr_u16_3 (ref, i0, i1, i2, p));
647+ } else {
648+ throw UnsupportedError ("ptrU16($i0 , $i1 , $i2 ) is not supported!" );
649+ }
650+ final ret = p.value.cast< ffi.UnsignedShort > ();
651+ calloc.free (p);
652+ return ret;
653+ }
654+
655+ ffi.Pointer <ffi.Short > ptrI16 (int i0, [int ? i1, int ? i2]) {
656+ final p = calloc< ffi.Pointer <ffi.Short >> ();
657+ if (i1 == null && i2 == null ) {
658+ cvRun (() => CFFI .Mat_Ptr_i16_1 (ref, i0, p));
659+ } else if (i1 != null && i2 == null ) {
660+ cvRun (() => CFFI .Mat_Ptr_i16_2 (ref, i0, i1, p));
661+ } else if (i1 != null && i2 != null ) {
662+ cvRun (() => CFFI .Mat_Ptr_i16_3 (ref, i0, i1, i2, p));
663+ } else {
664+ throw UnsupportedError ("ptrI16($i0 , $i1 , $i2 ) is not supported!" );
665+ }
666+ final ret = p.value.cast< ffi.Short > ();
667+ calloc.free (p);
668+ return ret;
669+ }
670+
671+ ffi.Pointer <ffi.Int > ptrI32 (int i0, [int ? i1, int ? i2]) {
672+ final p = calloc< ffi.Pointer <ffi.Int >> ();
673+ if (i1 == null && i2 == null ) {
674+ cvRun (() => CFFI .Mat_Ptr_i32_1 (ref, i0, p));
675+ } else if (i1 != null && i2 == null ) {
676+ cvRun (() => CFFI .Mat_Ptr_i32_2 (ref, i0, i1, p));
677+ } else if (i1 != null && i2 != null ) {
678+ cvRun (() => CFFI .Mat_Ptr_i32_3 (ref, i0, i1, i2, p));
679+ } else {
680+ throw UnsupportedError ("ptrI32($i0 , $i1 , $i2 ) is not supported!" );
681+ }
682+ final ret = p.value.cast< ffi.Int > ();
683+ calloc.free (p);
684+ return ret;
685+ }
686+
687+ ffi.Pointer <ffi.Float > ptrF32 (int i0, [int ? i1, int ? i2]) {
688+ final p = calloc< ffi.Pointer <ffi.Float >> ();
689+ if (i1 == null && i2 == null ) {
690+ cvRun (() => CFFI .Mat_Ptr_f32_1 (ref, i0, p));
691+ } else if (i1 != null && i2 == null ) {
692+ cvRun (() => CFFI .Mat_Ptr_f32_2 (ref, i0, i1, p));
693+ } else if (i1 != null && i2 != null ) {
694+ cvRun (() => CFFI .Mat_Ptr_f32_3 (ref, i0, i1, i2, p));
695+ } else {
696+ throw UnsupportedError ("ptrF32($i0 , $i1 , $i2 ) is not supported!" );
697+ }
698+ final ret = p.value.cast< ffi.Float > ();
699+ calloc.free (p);
700+ return ret;
701+ }
702+
703+ ffi.Pointer <ffi.Double > ptrF64 (int i0, [int ? i1, int ? i2]) {
704+ final p = calloc< ffi.Pointer <ffi.Double >> ();
705+ if (i1 == null && i2 == null ) {
706+ cvRun (() => CFFI .Mat_Ptr_f64_1 (ref, i0, p));
707+ } else if (i1 != null && i2 == null ) {
708+ cvRun (() => CFFI .Mat_Ptr_f64_2 (ref, i0, i1, p));
709+ } else if (i1 != null && i2 != null ) {
710+ cvRun (() => CFFI .Mat_Ptr_f64_3 (ref, i0, i1, i2, p));
711+ } else {
712+ throw UnsupportedError ("ptrF64($i0 , $i1 , $i2 ) is not supported!" );
713+ }
714+ final ret = p.value.cast< ffi.Double > ();
715+ calloc.free (p);
716+ return ret;
717+ }
718+
571719 // TODO: for now, dart do not support operator overloading
572720 // https://github.com/dart-lang/language/issues/2456
573721 // waiting for it's implementation and add more methods
0 commit comments