1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html
4 
5 #include "precomp.hpp"
6 #include "opencv2/core/mat.hpp"
7 
8 namespace cv {
9 
10 /*************************************************************************************************\
11                                         Input/Output Array
12 \*************************************************************************************************/
13 
getMat_(int i) const14 Mat _InputArray::getMat_(int i) const
15 {
16     _InputArray::KindFlag k = kind();
17     AccessFlag accessFlags = flags & ACCESS_MASK;
18 
19     if( k == MAT )
20     {
21         const Mat* m = (const Mat*)obj;
22         if( i < 0 )
23             return *m;
24         return m->row(i);
25     }
26 
27     if( k == UMAT )
28     {
29         const UMat* m = (const UMat*)obj;
30         if( i < 0 )
31             return m->getMat(accessFlags);
32         return m->getMat(accessFlags).row(i);
33     }
34 
35     if (k == MATX)
36     {
37         CV_Assert( i < 0 );
38         return Mat(sz, flags, obj);
39     }
40 
41     if( k == STD_VECTOR )
42     {
43         CV_Assert( i < 0 );
44         int t = CV_MAT_TYPE(flags);
45         const std::vector<uchar>& v = *(const std::vector<uchar>*)obj;
46 
47         return !v.empty() ? Mat(size(), t, (void*)&v[0]) : Mat();
48     }
49 
50     if( k == STD_BOOL_VECTOR )
51     {
52         CV_Assert( i < 0 );
53         int t = CV_8U;
54         const std::vector<bool>& v = *(const std::vector<bool>*)obj;
55         int j, n = (int)v.size();
56         if( n == 0 )
57             return Mat();
58         Mat m(1, n, t);
59         uchar* dst = m.data;
60         for( j = 0; j < n; j++ )
61             dst[j] = (uchar)v[j];
62         return m;
63     }
64 
65     if( k == NONE )
66         return Mat();
67 
68     if( k == STD_VECTOR_VECTOR )
69     {
70         int t = type(i);
71         const std::vector<std::vector<uchar> >& vv = *(const std::vector<std::vector<uchar> >*)obj;
72         CV_Assert( 0 <= i && i < (int)vv.size() );
73         const std::vector<uchar>& v = vv[i];
74 
75         return !v.empty() ? Mat(size(i), t, (void*)&v[0]) : Mat();
76     }
77 
78     if( k == STD_VECTOR_MAT )
79     {
80         const std::vector<Mat>& v = *(const std::vector<Mat>*)obj;
81         CV_Assert( 0 <= i && i < (int)v.size() );
82 
83         return v[i];
84     }
85 
86     if( k == STD_ARRAY_MAT )
87     {
88         const Mat* v = (const Mat*)obj;
89         CV_Assert( 0 <= i && i < sz.height );
90 
91         return v[i];
92     }
93 
94     if( k == STD_VECTOR_UMAT )
95     {
96         const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
97         CV_Assert( 0 <= i && i < (int)v.size() );
98 
99         return v[i].getMat(accessFlags);
100     }
101 
102     if( k == OPENGL_BUFFER )
103     {
104         CV_Assert( i < 0 );
105         CV_Error(cv::Error::StsNotImplemented, "You should explicitly call mapHost/unmapHost methods for ogl::Buffer object");
106     }
107 
108     if( k == CUDA_GPU_MAT )
109     {
110         CV_Assert( i < 0 );
111         CV_Error(cv::Error::StsNotImplemented, "You should explicitly call download method for cuda::GpuMat object");
112     }
113 
114     if( k == CUDA_HOST_MEM )
115     {
116         CV_Assert( i < 0 );
117 
118         const cuda::HostMem* cuda_mem = (const cuda::HostMem*)obj;
119 
120         return cuda_mem->createMatHeader();
121     }
122 
123     CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
124 }
125 
getUMat(int i) const126 UMat _InputArray::getUMat(int i) const
127 {
128     _InputArray::KindFlag k = kind();
129     AccessFlag accessFlags = flags & ACCESS_MASK;
130 
131     if( k == UMAT )
132     {
133         const UMat* m = (const UMat*)obj;
134         if( i < 0 )
135             return *m;
136         return m->row(i);
137     }
138 
139     if( k == STD_VECTOR_UMAT )
140     {
141         const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
142         CV_Assert( 0 <= i && i < (int)v.size() );
143 
144         return v[i];
145     }
146 
147     if( k == MAT )
148     {
149         const Mat* m = (const Mat*)obj;
150         if( i < 0 )
151             return m->getUMat(accessFlags);
152         return m->row(i).getUMat(accessFlags);
153     }
154 
155     return getMat(i).getUMat(accessFlags);
156 }
157 
getMatVector(std::vector<Mat> & mv) const158 void _InputArray::getMatVector(std::vector<Mat>& mv) const
159 {
160     _InputArray::KindFlag k = kind();
161     AccessFlag accessFlags = flags & ACCESS_MASK;
162 
163     if( k == MAT )
164     {
165         const Mat& m = *(const Mat*)obj;
166         int n = (int)m.size[0];
167         mv.resize(n);
168 
169         for( int i = 0; i < n; i++ )
170             mv[i] = m.dims == 2 ? Mat(1, m.cols, m.type(), (void*)m.ptr(i)) :
171                 Mat(m.dims-1, &m.size[1], m.type(), (void*)m.ptr(i), &m.step[1]);
172         return;
173     }
174 
175     if (k == MATX)
176     {
177         size_t n = sz.height, esz = CV_ELEM_SIZE(flags);
178         mv.resize(n);
179 
180         for( size_t i = 0; i < n; i++ )
181             mv[i] = Mat(1, sz.width, CV_MAT_TYPE(flags), (uchar*)obj + esz*sz.width*i);
182         return;
183     }
184 
185     if( k == STD_VECTOR )
186     {
187         const std::vector<uchar>& v = *(const std::vector<uchar>*)obj;
188 
189         size_t n = size().width, esz = CV_ELEM_SIZE(flags);
190         int t = CV_MAT_DEPTH(flags), cn = CV_MAT_CN(flags);
191         mv.resize(n);
192 
193         for( size_t i = 0; i < n; i++ )
194             mv[i] = Mat(1, cn, t, (void*)(&v[0] + esz*i));
195         return;
196     }
197 
198     if( k == NONE )
199     {
200         mv.clear();
201         return;
202     }
203 
204     if( k == STD_VECTOR_VECTOR )
205     {
206         const std::vector<std::vector<uchar> >& vv = *(const std::vector<std::vector<uchar> >*)obj;
207         int n = (int)vv.size();
208         int t = CV_MAT_TYPE(flags);
209         mv.resize(n);
210 
211         for( int i = 0; i < n; i++ )
212         {
213             const std::vector<uchar>& v = vv[i];
214             mv[i] = Mat(size(i), t, (void*)&v[0]);
215         }
216         return;
217     }
218 
219     if( k == STD_VECTOR_MAT )
220     {
221         const std::vector<Mat>& v = *(const std::vector<Mat>*)obj;
222         size_t n = v.size();
223         mv.resize(n);
224 
225         for( size_t i = 0; i < n; i++ )
226             mv[i] = v[i];
227         return;
228     }
229 
230     if( k == STD_ARRAY_MAT )
231     {
232         const Mat* v = (const Mat*)obj;
233         size_t n = sz.height;
234         mv.resize(n);
235 
236         for( size_t i = 0; i < n; i++ )
237             mv[i] = v[i];
238         return;
239     }
240 
241     if( k == STD_VECTOR_UMAT )
242     {
243         const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
244         size_t n = v.size();
245         mv.resize(n);
246 
247         for( size_t i = 0; i < n; i++ )
248             mv[i] = v[i].getMat(accessFlags);
249         return;
250     }
251 
252     CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
253 }
254 
getUMatVector(std::vector<UMat> & umv) const255 void _InputArray::getUMatVector(std::vector<UMat>& umv) const
256 {
257     _InputArray::KindFlag k = kind();
258     AccessFlag accessFlags = flags & ACCESS_MASK;
259 
260     if( k == NONE )
261     {
262         umv.clear();
263         return;
264     }
265 
266     if( k == STD_VECTOR_MAT )
267     {
268         const std::vector<Mat>& v = *(const std::vector<Mat>*)obj;
269         size_t n = v.size();
270         umv.resize(n);
271 
272         for( size_t i = 0; i < n; i++ )
273             umv[i] = v[i].getUMat(accessFlags);
274         return;
275     }
276 
277     if( k == STD_ARRAY_MAT )
278     {
279         const Mat* v = (const Mat*)obj;
280         size_t n = sz.height;
281         umv.resize(n);
282 
283         for( size_t i = 0; i < n; i++ )
284             umv[i] = v[i].getUMat(accessFlags);
285         return;
286     }
287 
288     if( k == STD_VECTOR_UMAT )
289     {
290         const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
291         size_t n = v.size();
292         umv.resize(n);
293 
294         for( size_t i = 0; i < n; i++ )
295             umv[i] = v[i];
296         return;
297     }
298 
299     if( k == UMAT )
300     {
301         UMat& v = *(UMat*)obj;
302         umv.resize(1);
303         umv[0] = v;
304         return;
305     }
306     if( k == MAT )
307     {
308         Mat& v = *(Mat*)obj;
309         umv.resize(1);
310         umv[0] = v.getUMat(accessFlags);
311         return;
312     }
313 
314     CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
315 }
316 
getGpuMat() const317 cuda::GpuMat _InputArray::getGpuMat() const
318 {
319 #ifdef HAVE_CUDA
320     _InputArray::KindFlag k = kind();
321 
322     if (k == CUDA_GPU_MAT)
323     {
324         const cuda::GpuMat* d_mat = (const cuda::GpuMat*)obj;
325         return *d_mat;
326     }
327 
328     if (k == CUDA_HOST_MEM)
329     {
330         const cuda::HostMem* cuda_mem = (const cuda::HostMem*)obj;
331         return cuda_mem->createGpuMatHeader();
332     }
333 
334     if (k == OPENGL_BUFFER)
335     {
336         CV_Error(cv::Error::StsNotImplemented, "You should explicitly call mapDevice/unmapDevice methods for ogl::Buffer object");
337     }
338 
339     if (k == NONE)
340         return cuda::GpuMat();
341 
342     CV_Error(cv::Error::StsNotImplemented, "getGpuMat is available only for cuda::GpuMat and cuda::HostMem");
343 #else
344     CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
345 #endif
346 }
getGpuMatVector(std::vector<cuda::GpuMat> & gpumv) const347 void _InputArray::getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const
348 {
349 #ifdef HAVE_CUDA
350     _InputArray::KindFlag k = kind();
351     if (k == STD_VECTOR_CUDA_GPU_MAT)
352     {
353         gpumv = *(std::vector<cuda::GpuMat>*)obj;
354     }
355 #else
356     CV_UNUSED(gpumv);
357     CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
358 #endif
359 }
getOGlBuffer() const360 ogl::Buffer _InputArray::getOGlBuffer() const
361 {
362     _InputArray::KindFlag k = kind();
363 
364     CV_Assert(k == OPENGL_BUFFER);
365 
366     const ogl::Buffer* gl_buf = (const ogl::Buffer*)obj;
367     return *gl_buf;
368 }
369 
kind() const370 _InputArray::KindFlag _InputArray::kind() const
371 {
372     KindFlag k = flags & KIND_MASK;
373 #if CV_VERSION_MAJOR < 5
374     CV_DbgAssert(k != EXPR);
375     CV_DbgAssert(k != STD_ARRAY);
376 #endif
377     return k;
378 }
379 
rows(int i) const380 int _InputArray::rows(int i) const
381 {
382     return size(i).height;
383 }
384 
cols(int i) const385 int _InputArray::cols(int i) const
386 {
387     return size(i).width;
388 }
389 
size(int i) const390 Size _InputArray::size(int i) const
391 {
392     _InputArray::KindFlag k = kind();
393 
394     if( k == MAT )
395     {
396         CV_Assert( i < 0 );
397         return ((const Mat*)obj)->size();
398     }
399 
400     if( k == UMAT )
401     {
402         CV_Assert( i < 0 );
403         return ((const UMat*)obj)->size();
404     }
405 
406     if (k == MATX)
407     {
408         CV_Assert( i < 0 );
409         return sz;
410     }
411 
412     if( k == STD_VECTOR )
413     {
414         CV_Assert( i < 0 );
415         const std::vector<uchar>& v = *(const std::vector<uchar>*)obj;
416         const std::vector<int>& iv = *(const std::vector<int>*)obj;
417         size_t szb = v.size(), szi = iv.size();
418         return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1);
419     }
420 
421     if( k == STD_BOOL_VECTOR )
422     {
423         CV_Assert( i < 0 );
424         const std::vector<bool>& v = *(const std::vector<bool>*)obj;
425         return Size((int)v.size(), 1);
426     }
427 
428     if( k == NONE )
429         return Size();
430 
431     if( k == STD_VECTOR_VECTOR )
432     {
433         const std::vector<std::vector<uchar> >& vv = *(const std::vector<std::vector<uchar> >*)obj;
434         if( i < 0 )
435             return vv.empty() ? Size() : Size((int)vv.size(), 1);
436         CV_Assert( i < (int)vv.size() );
437         const std::vector<std::vector<int> >& ivv = *(const std::vector<std::vector<int> >*)obj;
438 
439         size_t szb = vv[i].size(), szi = ivv[i].size();
440         return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1);
441     }
442 
443     if( k == STD_VECTOR_MAT )
444     {
445         const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
446         if( i < 0 )
447             return vv.empty() ? Size() : Size((int)vv.size(), 1);
448         CV_Assert( i < (int)vv.size() );
449 
450         return vv[i].size();
451     }
452 
453     if( k == STD_ARRAY_MAT )
454     {
455         const Mat* vv = (const Mat*)obj;
456         if( i < 0 )
457             return sz.height==0 ? Size() : Size(sz.height, 1);
458         CV_Assert( i < sz.height );
459 
460         return vv[i].size();
461     }
462 
463     if (k == STD_VECTOR_CUDA_GPU_MAT)
464     {
465 #ifdef HAVE_CUDA
466         const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
467         if (i < 0)
468             return vv.empty() ? Size() : Size((int)vv.size(), 1);
469         CV_Assert(i < (int)vv.size());
470         return vv[i].size();
471 #else
472         CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
473 #endif
474     }
475 
476     if( k == STD_VECTOR_UMAT )
477     {
478         const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
479         if( i < 0 )
480             return vv.empty() ? Size() : Size((int)vv.size(), 1);
481         CV_Assert( i < (int)vv.size() );
482 
483         return vv[i].size();
484     }
485 
486     if( k == OPENGL_BUFFER )
487     {
488         CV_Assert( i < 0 );
489         const ogl::Buffer* buf = (const ogl::Buffer*)obj;
490         return buf->size();
491     }
492 
493     if( k == CUDA_GPU_MAT )
494     {
495         CV_Assert( i < 0 );
496         const cuda::GpuMat* d_mat = (const cuda::GpuMat*)obj;
497         return d_mat->size();
498     }
499 
500     if( k == CUDA_HOST_MEM )
501     {
502         CV_Assert( i < 0 );
503         const cuda::HostMem* cuda_mem = (const cuda::HostMem*)obj;
504         return cuda_mem->size();
505     }
506 
507     CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
508 }
509 
sizend(int * arrsz,int i) const510 int _InputArray::sizend(int* arrsz, int i) const
511 {
512     int j, d = 0;
513     _InputArray::KindFlag k = kind();
514 
515     if( k == NONE )
516         ;
517     else if( k == MAT )
518     {
519         CV_Assert( i < 0 );
520         const Mat& m = *(const Mat*)obj;
521         d = m.dims;
522         if(arrsz)
523             for(j = 0; j < d; j++)
524                 arrsz[j] = m.size.p[j];
525     }
526     else if( k == UMAT )
527     {
528         CV_Assert( i < 0 );
529         const UMat& m = *(const UMat*)obj;
530         d = m.dims;
531         if(arrsz)
532             for(j = 0; j < d; j++)
533                 arrsz[j] = m.size.p[j];
534     }
535     else if( k == STD_VECTOR_MAT && i >= 0 )
536     {
537         const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
538         CV_Assert( i < (int)vv.size() );
539         const Mat& m = vv[i];
540         d = m.dims;
541         if(arrsz)
542             for(j = 0; j < d; j++)
543                 arrsz[j] = m.size.p[j];
544     }
545     else if( k == STD_ARRAY_MAT && i >= 0 )
546     {
547         const Mat* vv = (const Mat*)obj;
548         CV_Assert( i < sz.height );
549         const Mat& m = vv[i];
550         d = m.dims;
551         if(arrsz)
552             for(j = 0; j < d; j++)
553                 arrsz[j] = m.size.p[j];
554     }
555     else if( k == STD_VECTOR_UMAT && i >= 0 )
556     {
557         const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
558         CV_Assert( i < (int)vv.size() );
559         const UMat& m = vv[i];
560         d = m.dims;
561         if(arrsz)
562             for(j = 0; j < d; j++)
563                 arrsz[j] = m.size.p[j];
564     }
565     else
566     {
567         CV_CheckLE(dims(i), 2, "Not supported");
568         Size sz2d = size(i);
569         d = 2;
570         if(arrsz)
571         {
572             arrsz[0] = sz2d.height;
573             arrsz[1] = sz2d.width;
574         }
575     }
576 
577     return d;
578 }
579 
sameSize(const _InputArray & arr) const580 bool _InputArray::sameSize(const _InputArray& arr) const
581 {
582     _InputArray::KindFlag k1 = kind(), k2 = arr.kind();
583     Size sz1;
584 
585     if( k1 == MAT )
586     {
587         const Mat* m = ((const Mat*)obj);
588         if( k2 == MAT )
589             return m->size == ((const Mat*)arr.obj)->size;
590         if( k2 == UMAT )
591             return m->size == ((const UMat*)arr.obj)->size;
592         if( m->dims > 2 )
593             return false;
594         sz1 = m->size();
595     }
596     else if( k1 == UMAT )
597     {
598         const UMat* m = ((const UMat*)obj);
599         if( k2 == MAT )
600             return m->size == ((const Mat*)arr.obj)->size;
601         if( k2 == UMAT )
602             return m->size == ((const UMat*)arr.obj)->size;
603         if( m->dims > 2 )
604             return false;
605         sz1 = m->size();
606     }
607     else
608         sz1 = size();
609     if( arr.dims() > 2 )
610         return false;
611     return sz1 == arr.size();
612 }
613 
dims(int i) const614 int _InputArray::dims(int i) const
615 {
616     _InputArray::KindFlag k = kind();
617 
618     if( k == MAT )
619     {
620         CV_Assert( i < 0 );
621         return ((const Mat*)obj)->dims;
622     }
623 
624     if( k == UMAT )
625     {
626         CV_Assert( i < 0 );
627         return ((const UMat*)obj)->dims;
628     }
629 
630     if (k == MATX)
631     {
632         CV_Assert( i < 0 );
633         return 2;
634     }
635 
636     if( k == STD_VECTOR || k == STD_BOOL_VECTOR )
637     {
638         CV_Assert( i < 0 );
639         return 2;
640     }
641 
642     if( k == NONE )
643         return 0;
644 
645     if( k == STD_VECTOR_VECTOR )
646     {
647         const std::vector<std::vector<uchar> >& vv = *(const std::vector<std::vector<uchar> >*)obj;
648         if( i < 0 )
649             return 1;
650         CV_Assert( i < (int)vv.size() );
651         return 2;
652     }
653 
654     if( k == STD_VECTOR_MAT )
655     {
656         const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
657         if( i < 0 )
658             return 1;
659         CV_Assert( i < (int)vv.size() );
660 
661         return vv[i].dims;
662     }
663 
664     if( k == STD_ARRAY_MAT )
665     {
666         const Mat* vv = (const Mat*)obj;
667         if( i < 0 )
668             return 1;
669         CV_Assert( i < sz.height );
670 
671         return vv[i].dims;
672     }
673 
674     if( k == STD_VECTOR_UMAT )
675     {
676         const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
677         if( i < 0 )
678             return 1;
679         CV_Assert( i < (int)vv.size() );
680 
681         return vv[i].dims;
682     }
683 
684     if( k == OPENGL_BUFFER )
685     {
686         CV_Assert( i < 0 );
687         return 2;
688     }
689 
690     if( k == CUDA_GPU_MAT )
691     {
692         CV_Assert( i < 0 );
693         return 2;
694     }
695 
696     if( k == CUDA_HOST_MEM )
697     {
698         CV_Assert( i < 0 );
699         return 2;
700     }
701 
702     CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
703 }
704 
total(int i) const705 size_t _InputArray::total(int i) const
706 {
707     _InputArray::KindFlag k = kind();
708 
709     if( k == MAT )
710     {
711         CV_Assert( i < 0 );
712         return ((const Mat*)obj)->total();
713     }
714 
715     if( k == UMAT )
716     {
717         CV_Assert( i < 0 );
718         return ((const UMat*)obj)->total();
719     }
720 
721     if( k == STD_VECTOR_MAT )
722     {
723         const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
724         if( i < 0 )
725             return vv.size();
726 
727         CV_Assert( i < (int)vv.size() );
728         return vv[i].total();
729     }
730 
731     if( k == STD_ARRAY_MAT )
732     {
733         const Mat* vv = (const Mat*)obj;
734         if( i < 0 )
735             return sz.height;
736 
737         CV_Assert( i < sz.height );
738         return vv[i].total();
739     }
740 
741     if( k == STD_VECTOR_UMAT )
742     {
743         const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
744         if( i < 0 )
745             return vv.size();
746 
747         CV_Assert( i < (int)vv.size() );
748         return vv[i].total();
749     }
750 
751     return size(i).area();
752 }
753 
type(int i) const754 int _InputArray::type(int i) const
755 {
756     _InputArray::KindFlag k = kind();
757 
758     if( k == MAT )
759         return ((const Mat*)obj)->type();
760 
761     if( k == UMAT )
762         return ((const UMat*)obj)->type();
763 
764     if( k == MATX || k == STD_VECTOR || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
765         return CV_MAT_TYPE(flags);
766 
767     if( k == NONE )
768         return -1;
769 
770     if( k == STD_VECTOR_UMAT )
771     {
772         const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
773         if( vv.empty() )
774         {
775             CV_Assert((flags & FIXED_TYPE) != 0);
776             return CV_MAT_TYPE(flags);
777         }
778         CV_Assert( i < (int)vv.size() );
779         return vv[i >= 0 ? i : 0].type();
780     }
781 
782     if( k == STD_VECTOR_MAT )
783     {
784         const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
785         if( vv.empty() )
786         {
787             CV_Assert((flags & FIXED_TYPE) != 0);
788             return CV_MAT_TYPE(flags);
789         }
790         CV_Assert( i < (int)vv.size() );
791         return vv[i >= 0 ? i : 0].type();
792     }
793 
794     if( k == STD_ARRAY_MAT )
795     {
796         const Mat* vv = (const Mat*)obj;
797         if( sz.height == 0 )
798         {
799             CV_Assert((flags & FIXED_TYPE) != 0);
800             return CV_MAT_TYPE(flags);
801         }
802         CV_Assert( i < sz.height );
803         return vv[i >= 0 ? i : 0].type();
804     }
805 
806     if (k == STD_VECTOR_CUDA_GPU_MAT)
807     {
808 #ifdef HAVE_CUDA
809         const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
810         if (vv.empty())
811         {
812             CV_Assert((flags & FIXED_TYPE) != 0);
813             return CV_MAT_TYPE(flags);
814         }
815         CV_Assert(i < (int)vv.size());
816         return vv[i >= 0 ? i : 0].type();
817 #else
818         CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
819 #endif
820     }
821 
822     if( k == OPENGL_BUFFER )
823         return ((const ogl::Buffer*)obj)->type();
824 
825     if( k == CUDA_GPU_MAT )
826         return ((const cuda::GpuMat*)obj)->type();
827 
828     if( k == CUDA_HOST_MEM )
829         return ((const cuda::HostMem*)obj)->type();
830 
831     CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
832 }
833 
depth(int i) const834 int _InputArray::depth(int i) const
835 {
836     return CV_MAT_DEPTH(type(i));
837 }
838 
channels(int i) const839 int _InputArray::channels(int i) const
840 {
841     return CV_MAT_CN(type(i));
842 }
843 
empty() const844 bool _InputArray::empty() const
845 {
846     _InputArray::KindFlag k = kind();
847 
848     if( k == MAT )
849         return ((const Mat*)obj)->empty();
850 
851     if( k == UMAT )
852         return ((const UMat*)obj)->empty();
853 
854     if (k == MATX)
855         return false;
856 
857     if( k == STD_VECTOR )
858     {
859         const std::vector<uchar>& v = *(const std::vector<uchar>*)obj;
860         return v.empty();
861     }
862 
863     if( k == STD_BOOL_VECTOR )
864     {
865         const std::vector<bool>& v = *(const std::vector<bool>*)obj;
866         return v.empty();
867     }
868 
869     if( k == NONE )
870         return true;
871 
872     if( k == STD_VECTOR_VECTOR )
873     {
874         const std::vector<std::vector<uchar> >& vv = *(const std::vector<std::vector<uchar> >*)obj;
875         return vv.empty();
876     }
877 
878     if( k == STD_VECTOR_MAT )
879     {
880         const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
881         return vv.empty();
882     }
883 
884     if( k == STD_ARRAY_MAT )
885     {
886         return sz.height == 0;
887     }
888 
889     if( k == STD_VECTOR_UMAT )
890     {
891         const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
892         return vv.empty();
893     }
894 
895     if( k == OPENGL_BUFFER )
896         return ((const ogl::Buffer*)obj)->empty();
897 
898     if( k == CUDA_GPU_MAT )
899         return ((const cuda::GpuMat*)obj)->empty();
900 
901     if (k == STD_VECTOR_CUDA_GPU_MAT)
902     {
903         const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
904         return vv.empty();
905     }
906 
907     if( k == CUDA_HOST_MEM )
908         return ((const cuda::HostMem*)obj)->empty();
909 
910     CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
911 }
912 
isContinuous(int i) const913 bool _InputArray::isContinuous(int i) const
914 {
915     _InputArray::KindFlag k = kind();
916 
917     if( k == MAT )
918         return i < 0 ? ((const Mat*)obj)->isContinuous() : true;
919 
920     if( k == UMAT )
921         return i < 0 ? ((const UMat*)obj)->isContinuous() : true;
922 
923     if( k == MATX || k == STD_VECTOR ||
924         k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
925         return true;
926 
927     if( k == STD_VECTOR_MAT )
928     {
929         const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
930         CV_Assert(i >= 0 && (size_t)i < vv.size());
931         return vv[i].isContinuous();
932     }
933 
934     if( k == STD_ARRAY_MAT )
935     {
936         const Mat* vv = (const Mat*)obj;
937         CV_Assert(i >= 0 && i < sz.height);
938         return vv[i].isContinuous();
939     }
940 
941     if( k == STD_VECTOR_UMAT )
942     {
943         const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
944         CV_Assert(i >= 0 && (size_t)i < vv.size());
945         return vv[i].isContinuous();
946     }
947 
948     if( k == CUDA_GPU_MAT )
949       return i < 0 ? ((const cuda::GpuMat*)obj)->isContinuous() : true;
950 
951     CV_Error(CV_StsNotImplemented, "Unknown/unsupported array type");
952 }
953 
isSubmatrix(int i) const954 bool _InputArray::isSubmatrix(int i) const
955 {
956     _InputArray::KindFlag k = kind();
957 
958     if( k == MAT )
959         return i < 0 ? ((const Mat*)obj)->isSubmatrix() : false;
960 
961     if( k == UMAT )
962         return i < 0 ? ((const UMat*)obj)->isSubmatrix() : false;
963 
964     if( k == MATX || k == STD_VECTOR ||
965         k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
966         return false;
967 
968     if( k == STD_VECTOR_MAT )
969     {
970         const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
971         CV_Assert(i >= 0 && (size_t)i < vv.size());
972         return vv[i].isSubmatrix();
973     }
974 
975     if( k == STD_ARRAY_MAT )
976     {
977         const Mat* vv = (const Mat*)obj;
978         CV_Assert(i >= 0 && i < sz.height);
979         return vv[i].isSubmatrix();
980     }
981 
982     if( k == STD_VECTOR_UMAT )
983     {
984         const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
985         CV_Assert(i >= 0 && (size_t)i < vv.size());
986         return vv[i].isSubmatrix();
987     }
988 
989     CV_Error(CV_StsNotImplemented, "");
990 }
991 
offset(int i) const992 size_t _InputArray::offset(int i) const
993 {
994     _InputArray::KindFlag k = kind();
995 
996     if( k == MAT )
997     {
998         CV_Assert( i < 0 );
999         const Mat * const m = ((const Mat*)obj);
1000         return (size_t)(m->ptr() - m->datastart);
1001     }
1002 
1003     if( k == UMAT )
1004     {
1005         CV_Assert( i < 0 );
1006         return ((const UMat*)obj)->offset;
1007     }
1008 
1009     if( k == MATX || k == STD_VECTOR ||
1010         k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
1011         return 0;
1012 
1013     if( k == STD_VECTOR_MAT )
1014     {
1015         const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
1016         CV_Assert( i >= 0 && i < (int)vv.size() );
1017 
1018         return (size_t)(vv[i].ptr() - vv[i].datastart);
1019     }
1020 
1021     if( k == STD_ARRAY_MAT )
1022     {
1023         const Mat* vv = (const Mat*)obj;
1024         CV_Assert( i >= 0 && i < sz.height );
1025         return (size_t)(vv[i].ptr() - vv[i].datastart);
1026     }
1027 
1028     if( k == STD_VECTOR_UMAT )
1029     {
1030         const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
1031         CV_Assert(i >= 0 && (size_t)i < vv.size());
1032         return vv[i].offset;
1033     }
1034 
1035     if( k == CUDA_GPU_MAT )
1036     {
1037         CV_Assert( i < 0 );
1038         const cuda::GpuMat * const m = ((const cuda::GpuMat*)obj);
1039         return (size_t)(m->data - m->datastart);
1040     }
1041 
1042     if (k == STD_VECTOR_CUDA_GPU_MAT)
1043     {
1044         const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
1045         CV_Assert(i >= 0 && (size_t)i < vv.size());
1046         return (size_t)(vv[i].data - vv[i].datastart);
1047     }
1048 
1049     CV_Error(Error::StsNotImplemented, "");
1050 }
1051 
step(int i) const1052 size_t _InputArray::step(int i) const
1053 {
1054     _InputArray::KindFlag k = kind();
1055 
1056     if( k == MAT )
1057     {
1058         CV_Assert( i < 0 );
1059         return ((const Mat*)obj)->step;
1060     }
1061 
1062     if( k == UMAT )
1063     {
1064         CV_Assert( i < 0 );
1065         return ((const UMat*)obj)->step;
1066     }
1067 
1068     if( k == MATX || k == STD_VECTOR ||
1069         k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
1070         return 0;
1071 
1072     if( k == STD_VECTOR_MAT )
1073     {
1074         const std::vector<Mat>& vv = *(const std::vector<Mat>*)obj;
1075         CV_Assert( i >= 0 && i < (int)vv.size() );
1076         return vv[i].step;
1077     }
1078 
1079     if( k == STD_ARRAY_MAT )
1080     {
1081         const Mat* vv = (const Mat*)obj;
1082         CV_Assert( i >= 0 && i < sz.height );
1083         return vv[i].step;
1084     }
1085 
1086     if( k == STD_VECTOR_UMAT )
1087     {
1088         const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
1089         CV_Assert(i >= 0 && (size_t)i < vv.size());
1090         return vv[i].step;
1091     }
1092 
1093     if( k == CUDA_GPU_MAT )
1094     {
1095         CV_Assert( i < 0 );
1096         return ((const cuda::GpuMat*)obj)->step;
1097     }
1098     if (k == STD_VECTOR_CUDA_GPU_MAT)
1099     {
1100         const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
1101         CV_Assert(i >= 0 && (size_t)i < vv.size());
1102         return vv[i].step;
1103     }
1104 
1105     CV_Error(Error::StsNotImplemented, "");
1106 }
1107 
copyTo(const _OutputArray & arr) const1108 void _InputArray::copyTo(const _OutputArray& arr) const
1109 {
1110     _InputArray::KindFlag k = kind();
1111 
1112     if( k == NONE )
1113         arr.release();
1114     else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_BOOL_VECTOR )
1115     {
1116         Mat m = getMat();
1117         m.copyTo(arr);
1118     }
1119     else if( k == UMAT )
1120         ((UMat*)obj)->copyTo(arr);
1121 #ifdef HAVE_CUDA
1122     else if (k == CUDA_GPU_MAT)
1123         ((cuda::GpuMat*)obj)->copyTo(arr);
1124 #endif
1125     else
1126         CV_Error(Error::StsNotImplemented, "");
1127 }
1128 
copyTo(const _OutputArray & arr,const _InputArray & mask) const1129 void _InputArray::copyTo(const _OutputArray& arr, const _InputArray & mask) const
1130 {
1131     _InputArray::KindFlag k = kind();
1132 
1133     if( k == NONE )
1134         arr.release();
1135     else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_BOOL_VECTOR )
1136     {
1137         Mat m = getMat();
1138         m.copyTo(arr, mask);
1139     }
1140     else if( k == UMAT )
1141         ((UMat*)obj)->copyTo(arr, mask);
1142 #ifdef HAVE_CUDA
1143     else if (k == CUDA_GPU_MAT)
1144         ((cuda::GpuMat*)obj)->copyTo(arr, mask);
1145 #endif
1146     else
1147         CV_Error(Error::StsNotImplemented, "");
1148 }
1149 
fixedSize() const1150 bool _OutputArray::fixedSize() const
1151 {
1152     return (flags & FIXED_SIZE) == FIXED_SIZE;
1153 }
1154 
fixedType() const1155 bool _OutputArray::fixedType() const
1156 {
1157     return (flags & FIXED_TYPE) == FIXED_TYPE;
1158 }
1159 
create(Size _sz,int mtype,int i,bool allowTransposed,_OutputArray::DepthMask fixedDepthMask) const1160 void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
1161 {
1162     _InputArray::KindFlag k = kind();
1163     if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1164     {
1165         CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == _sz);
1166         CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype);
1167         ((Mat*)obj)->create(_sz, mtype);
1168         return;
1169     }
1170     if( k == UMAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1171     {
1172         CV_Assert(!fixedSize() || ((UMat*)obj)->size.operator()() == _sz);
1173         CV_Assert(!fixedType() || ((UMat*)obj)->type() == mtype);
1174         ((UMat*)obj)->create(_sz, mtype);
1175         return;
1176     }
1177     if( k == CUDA_GPU_MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1178     {
1179         CV_Assert(!fixedSize() || ((cuda::GpuMat*)obj)->size() == _sz);
1180         CV_Assert(!fixedType() || ((cuda::GpuMat*)obj)->type() == mtype);
1181 #ifdef HAVE_CUDA
1182         ((cuda::GpuMat*)obj)->create(_sz, mtype);
1183         return;
1184 #else
1185         CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1186 #endif
1187     }
1188     if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1189     {
1190         CV_Assert(!fixedSize() || ((ogl::Buffer*)obj)->size() == _sz);
1191         CV_Assert(!fixedType() || ((ogl::Buffer*)obj)->type() == mtype);
1192 #ifdef HAVE_OPENGL
1193         ((ogl::Buffer*)obj)->create(_sz, mtype);
1194         return;
1195 #else
1196         CV_Error(Error::StsNotImplemented, "OpenGL support is not enabled in this OpenCV build (missing HAVE_OPENGL)");
1197 #endif
1198     }
1199     if( k == CUDA_HOST_MEM && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1200     {
1201         CV_Assert(!fixedSize() || ((cuda::HostMem*)obj)->size() == _sz);
1202         CV_Assert(!fixedType() || ((cuda::HostMem*)obj)->type() == mtype);
1203 #ifdef HAVE_CUDA
1204         ((cuda::HostMem*)obj)->create(_sz, mtype);
1205         return;
1206 #else
1207         CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1208 #endif
1209     }
1210     int sizes[] = {_sz.height, _sz.width};
1211     create(2, sizes, mtype, i, allowTransposed, fixedDepthMask);
1212 }
1213 
create(int _rows,int _cols,int mtype,int i,bool allowTransposed,_OutputArray::DepthMask fixedDepthMask) const1214 void _OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
1215 {
1216     _InputArray::KindFlag k = kind();
1217     if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1218     {
1219         CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == Size(_cols, _rows));
1220         CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype);
1221         ((Mat*)obj)->create(_rows, _cols, mtype);
1222         return;
1223     }
1224     if( k == UMAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1225     {
1226         CV_Assert(!fixedSize() || ((UMat*)obj)->size.operator()() == Size(_cols, _rows));
1227         CV_Assert(!fixedType() || ((UMat*)obj)->type() == mtype);
1228         ((UMat*)obj)->create(_rows, _cols, mtype);
1229         return;
1230     }
1231     if( k == CUDA_GPU_MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1232     {
1233         CV_Assert(!fixedSize() || ((cuda::GpuMat*)obj)->size() == Size(_cols, _rows));
1234         CV_Assert(!fixedType() || ((cuda::GpuMat*)obj)->type() == mtype);
1235 #ifdef HAVE_CUDA
1236         ((cuda::GpuMat*)obj)->create(_rows, _cols, mtype);
1237         return;
1238 #else
1239         CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1240 #endif
1241     }
1242     if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1243     {
1244         CV_Assert(!fixedSize() || ((ogl::Buffer*)obj)->size() == Size(_cols, _rows));
1245         CV_Assert(!fixedType() || ((ogl::Buffer*)obj)->type() == mtype);
1246 #ifdef HAVE_OPENGL
1247         ((ogl::Buffer*)obj)->create(_rows, _cols, mtype);
1248         return;
1249 #else
1250         CV_Error(Error::StsNotImplemented, "OpenGL support is not enabled in this OpenCV build (missing HAVE_OPENGL)");
1251 #endif
1252     }
1253     if( k == CUDA_HOST_MEM && i < 0 && !allowTransposed && fixedDepthMask == 0 )
1254     {
1255         CV_Assert(!fixedSize() || ((cuda::HostMem*)obj)->size() == Size(_cols, _rows));
1256         CV_Assert(!fixedType() || ((cuda::HostMem*)obj)->type() == mtype);
1257 #ifdef HAVE_CUDA
1258         ((cuda::HostMem*)obj)->create(_rows, _cols, mtype);
1259         return;
1260 #else
1261         CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1262 #endif
1263     }
1264     int sizes[] = {_rows, _cols};
1265     create(2, sizes, mtype, i, allowTransposed, fixedDepthMask);
1266 }
1267 
create(int d,const int * sizes,int mtype,int i,bool allowTransposed,_OutputArray::DepthMask fixedDepthMask) const1268 void _OutputArray::create(int d, const int* sizes, int mtype, int i,
1269                           bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
1270 {
1271     int sizebuf[2];
1272     if(d == 1)
1273     {
1274         d = 2;
1275         sizebuf[0] = sizes[0];
1276         sizebuf[1] = 1;
1277         sizes = sizebuf;
1278     }
1279     _InputArray::KindFlag k = kind();
1280     mtype = CV_MAT_TYPE(mtype);
1281 
1282     if( k == MAT )
1283     {
1284         CV_Assert( i < 0 );
1285         Mat& m = *(Mat*)obj;
1286         CV_Assert(!(m.empty() && fixedType() && fixedSize()) && "Can't reallocate empty Mat with locked layout (probably due to misused 'const' modifier)");
1287         if (allowTransposed && !m.empty() &&
1288             d == 2 && m.dims == 2 &&
1289             m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] &&
1290             m.isContinuous())
1291         {
1292             return;
1293         }
1294 
1295         if(fixedType())
1296         {
1297             if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
1298                 mtype = m.type();
1299             else
1300                 CV_CheckTypeEQ(m.type(), CV_MAT_TYPE(mtype), "Can't reallocate Mat with locked type (probably due to misused 'const' modifier)");
1301         }
1302         if(fixedSize())
1303         {
1304             CV_CheckEQ(m.dims, d, "Can't reallocate Mat with locked size (probably due to misused 'const' modifier)");
1305             for(int j = 0; j < d; ++j)
1306                 CV_CheckEQ(m.size[j], sizes[j], "Can't reallocate Mat with locked size (probably due to misused 'const' modifier)");
1307         }
1308         m.create(d, sizes, mtype);
1309         return;
1310     }
1311 
1312     if( k == UMAT )
1313     {
1314         CV_Assert( i < 0 );
1315         UMat& m = *(UMat*)obj;
1316         CV_Assert(!(m.empty() && fixedType() && fixedSize()) && "Can't reallocate empty UMat with locked layout (probably due to misused 'const' modifier)");
1317         if (allowTransposed && !m.empty() &&
1318             d == 2 && m.dims == 2 &&
1319             m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] &&
1320             m.isContinuous())
1321         {
1322             return;
1323         }
1324 
1325         if(fixedType())
1326         {
1327             if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
1328                 mtype = m.type();
1329             else
1330                 CV_CheckTypeEQ(m.type(), CV_MAT_TYPE(mtype), "Can't reallocate UMat with locked type (probably due to misused 'const' modifier)");
1331         }
1332         if(fixedSize())
1333         {
1334             CV_CheckEQ(m.dims, d, "Can't reallocate UMat with locked size (probably due to misused 'const' modifier)");
1335             for(int j = 0; j < d; ++j)
1336                 CV_CheckEQ(m.size[j], sizes[j], "Can't reallocate UMat with locked size (probably due to misused 'const' modifier)");
1337         }
1338         m.create(d, sizes, mtype);
1339         return;
1340     }
1341 
1342     if( k == MATX )
1343     {
1344         CV_Assert( i < 0 );
1345         int type0 = CV_MAT_TYPE(flags);
1346         CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == 1 && ((1 << type0) & fixedDepthMask) != 0) );
1347         CV_CheckLE(d, 2, "");
1348         Size requested_size(d == 2 ? sizes[1] : 1, d >= 1 ? sizes[0] : 1);
1349         if (sz.width == 1 || sz.height == 1)
1350         {
1351             // NB: 1D arrays assume allowTransposed=true (see #4159)
1352             int total_1d = std::max(sz.width, sz.height);
1353             CV_Check(requested_size, std::max(requested_size.width, requested_size.height) == total_1d, "");
1354         }
1355         else
1356         {
1357             if (!allowTransposed)
1358             {
1359                 CV_CheckEQ(requested_size, sz, "");
1360             }
1361             else
1362             {
1363                 CV_Check(requested_size,
1364                         (requested_size == sz || (requested_size.height == sz.width && requested_size.width == sz.height)),
1365                         "");
1366             }
1367         }
1368         return;
1369     }
1370 
1371     if( k == STD_VECTOR || k == STD_VECTOR_VECTOR )
1372     {
1373         CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
1374         size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0;
1375         std::vector<uchar>* v = (std::vector<uchar>*)obj;
1376 
1377         if( k == STD_VECTOR_VECTOR )
1378         {
1379             std::vector<std::vector<uchar> >& vv = *(std::vector<std::vector<uchar> >*)obj;
1380             if( i < 0 )
1381             {
1382                 CV_Assert(!fixedSize() || len == vv.size());
1383                 vv.resize(len);
1384                 return;
1385             }
1386             CV_Assert( i < (int)vv.size() );
1387             v = &vv[i];
1388         }
1389         else
1390             CV_Assert( i < 0 );
1391 
1392         int type0 = CV_MAT_TYPE(flags);
1393         CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0) );
1394 
1395         int esz = CV_ELEM_SIZE(type0);
1396         CV_Assert(!fixedSize() || len == ((std::vector<uchar>*)v)->size() / esz);
1397         switch( esz )
1398         {
1399         case 1:
1400             ((std::vector<uchar>*)v)->resize(len);
1401             break;
1402         case 2:
1403             ((std::vector<Vec2b>*)v)->resize(len);
1404             break;
1405         case 3:
1406             ((std::vector<Vec3b>*)v)->resize(len);
1407             break;
1408         case 4:
1409             ((std::vector<int>*)v)->resize(len);
1410             break;
1411         case 6:
1412             ((std::vector<Vec3s>*)v)->resize(len);
1413             break;
1414         case 8:
1415             ((std::vector<Vec2i>*)v)->resize(len);
1416             break;
1417         case 12:
1418             ((std::vector<Vec3i>*)v)->resize(len);
1419             break;
1420         case 16:
1421             ((std::vector<Vec4i>*)v)->resize(len);
1422             break;
1423         case 20:
1424             ((std::vector<Vec<int, 5> >*)v)->resize(len);
1425             break;
1426         case 24:
1427             ((std::vector<Vec6i>*)v)->resize(len);
1428             break;
1429         case 28:
1430             ((std::vector<Vec<int, 7> >*)v)->resize(len);
1431             break;
1432         case 32:
1433             ((std::vector<Vec8i>*)v)->resize(len);
1434             break;
1435         case 36:
1436             ((std::vector<Vec<int, 9> >*)v)->resize(len);
1437             break;
1438         case 40:
1439             ((std::vector<Vec<int, 10> >*)v)->resize(len);
1440             break;
1441         case 44:
1442             ((std::vector<Vec<int, 11> >*)v)->resize(len);
1443             break;
1444         case 48:
1445             ((std::vector<Vec<int, 12> >*)v)->resize(len);
1446             break;
1447         case 52:
1448             ((std::vector<Vec<int, 13> >*)v)->resize(len);
1449             break;
1450         case 56:
1451             ((std::vector<Vec<int, 14> >*)v)->resize(len);
1452             break;
1453         case 60:
1454             ((std::vector<Vec<int, 15> >*)v)->resize(len);
1455             break;
1456         case 64:
1457             ((std::vector<Vec<int, 16> >*)v)->resize(len);
1458             break;
1459         case 128:
1460             ((std::vector<Vec<int, 32> >*)v)->resize(len);
1461             break;
1462         case 256:
1463             ((std::vector<Vec<int, 64> >*)v)->resize(len);
1464             break;
1465         case 512:
1466             ((std::vector<Vec<int, 128> >*)v)->resize(len);
1467             break;
1468         default:
1469             CV_Error_(CV_StsBadArg, ("Vectors with element size %d are not supported. Please, modify OutputArray::create()\n", esz));
1470         }
1471         return;
1472     }
1473 
1474     if( k == NONE )
1475     {
1476         CV_Error(CV_StsNullPtr, "create() called for the missing output array" );
1477     }
1478 
1479     if( k == STD_VECTOR_MAT )
1480     {
1481         std::vector<Mat>& v = *(std::vector<Mat>*)obj;
1482 
1483         if( i < 0 )
1484         {
1485             CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
1486             size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0, len0 = v.size();
1487 
1488             CV_Assert(!fixedSize() || len == len0);
1489             v.resize(len);
1490             if( fixedType() )
1491             {
1492                 int _type = CV_MAT_TYPE(flags);
1493                 for( size_t j = len0; j < len; j++ )
1494                 {
1495                     if( v[j].type() == _type )
1496                         continue;
1497                     CV_Assert( v[j].empty() );
1498                     v[j].flags = (v[j].flags & ~CV_MAT_TYPE_MASK) | _type;
1499                 }
1500             }
1501             return;
1502         }
1503 
1504         CV_Assert( i < (int)v.size() );
1505         Mat& m = v[i];
1506 
1507         if( allowTransposed )
1508         {
1509             if( !m.isContinuous() )
1510             {
1511                 CV_Assert(!fixedType() && !fixedSize());
1512                 m.release();
1513             }
1514 
1515             if( d == 2 && m.dims == 2 && m.data &&
1516                 m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] )
1517                 return;
1518         }
1519 
1520         if(fixedType())
1521         {
1522             if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
1523                 mtype = m.type();
1524             else
1525                 CV_Assert(CV_MAT_TYPE(mtype) == m.type());
1526         }
1527         if(fixedSize())
1528         {
1529             CV_Assert(m.dims == d);
1530             for(int j = 0; j < d; ++j)
1531                 CV_Assert(m.size[j] == sizes[j]);
1532         }
1533 
1534         m.create(d, sizes, mtype);
1535         return;
1536     }
1537 
1538     if( k == STD_ARRAY_MAT )
1539     {
1540         Mat* v = (Mat*)obj;
1541 
1542         if( i < 0 )
1543         {
1544             CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
1545             size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0, len0 = sz.height;
1546 
1547             CV_Assert(len == len0);
1548             if( fixedType() )
1549             {
1550                 int _type = CV_MAT_TYPE(flags);
1551                 for( size_t j = len0; j < len; j++ )
1552                 {
1553                     if( v[j].type() == _type )
1554                         continue;
1555                     CV_Assert( v[j].empty() );
1556                     v[j].flags = (v[j].flags & ~CV_MAT_TYPE_MASK) | _type;
1557                 }
1558             }
1559             return;
1560         }
1561 
1562         CV_Assert( i < sz.height );
1563         Mat& m = v[i];
1564 
1565         if( allowTransposed )
1566         {
1567             if( !m.isContinuous() )
1568             {
1569                 CV_Assert(!fixedType() && !fixedSize());
1570                 m.release();
1571             }
1572 
1573             if( d == 2 && m.dims == 2 && m.data &&
1574                 m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] )
1575                 return;
1576         }
1577 
1578         if(fixedType())
1579         {
1580             if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
1581                 mtype = m.type();
1582             else
1583                 CV_Assert(CV_MAT_TYPE(mtype) == m.type());
1584         }
1585 
1586         if(fixedSize())
1587         {
1588             CV_Assert(m.dims == d);
1589             for(int j = 0; j < d; ++j)
1590                 CV_Assert(m.size[j] == sizes[j]);
1591         }
1592 
1593         m.create(d, sizes, mtype);
1594         return;
1595     }
1596 
1597     if( k == STD_VECTOR_UMAT )
1598     {
1599         std::vector<UMat>& v = *(std::vector<UMat>*)obj;
1600 
1601         if( i < 0 )
1602         {
1603             CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
1604             size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0, len0 = v.size();
1605 
1606             CV_Assert(!fixedSize() || len == len0);
1607             v.resize(len);
1608             if( fixedType() )
1609             {
1610                 int _type = CV_MAT_TYPE(flags);
1611                 for( size_t j = len0; j < len; j++ )
1612                 {
1613                     if( v[j].type() == _type )
1614                         continue;
1615                     CV_Assert( v[j].empty() );
1616                     v[j].flags = (v[j].flags & ~CV_MAT_TYPE_MASK) | _type;
1617                 }
1618             }
1619             return;
1620         }
1621 
1622         CV_Assert( i < (int)v.size() );
1623         UMat& m = v[i];
1624 
1625         if( allowTransposed )
1626         {
1627             if( !m.isContinuous() )
1628             {
1629                 CV_Assert(!fixedType() && !fixedSize());
1630                 m.release();
1631             }
1632 
1633             if( d == 2 && m.dims == 2 && m.u &&
1634                 m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] )
1635                 return;
1636         }
1637 
1638         if(fixedType())
1639         {
1640             if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
1641                 mtype = m.type();
1642             else
1643                 CV_Assert(CV_MAT_TYPE(mtype) == m.type());
1644         }
1645         if(fixedSize())
1646         {
1647             CV_Assert(m.dims == d);
1648             for(int j = 0; j < d; ++j)
1649                 CV_Assert(m.size[j] == sizes[j]);
1650         }
1651 
1652         m.create(d, sizes, mtype);
1653         return;
1654     }
1655 
1656     CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
1657 }
1658 
createSameSize(const _InputArray & arr,int mtype) const1659 void _OutputArray::createSameSize(const _InputArray& arr, int mtype) const
1660 {
1661     int arrsz[CV_MAX_DIM], d = arr.sizend(arrsz);
1662     create(d, arrsz, mtype);
1663 }
1664 
release() const1665 void _OutputArray::release() const
1666 {
1667     CV_Assert(!fixedSize());
1668 
1669     _InputArray::KindFlag k = kind();
1670 
1671     if( k == MAT )
1672     {
1673         ((Mat*)obj)->release();
1674         return;
1675     }
1676 
1677     if( k == UMAT )
1678     {
1679         ((UMat*)obj)->release();
1680         return;
1681     }
1682 
1683     if( k == CUDA_GPU_MAT )
1684     {
1685 #ifdef HAVE_CUDA
1686         ((cuda::GpuMat*)obj)->release();
1687         return;
1688 #else
1689         CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1690 #endif
1691     }
1692 
1693     if( k == CUDA_HOST_MEM )
1694     {
1695 #ifdef HAVE_CUDA
1696         ((cuda::HostMem*)obj)->release();
1697         return;
1698 #else
1699         CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1700 #endif
1701     }
1702 
1703     if( k == OPENGL_BUFFER )
1704     {
1705 #ifdef HAVE_OPENGL
1706         ((ogl::Buffer*)obj)->release();
1707         return;
1708 #else
1709         CV_Error(Error::StsNotImplemented, "OpenGL support is not enabled in this OpenCV build (missing HAVE_OPENGL)");
1710 #endif
1711     }
1712 
1713     if( k == NONE )
1714         return;
1715 
1716     if( k == STD_VECTOR )
1717     {
1718         create(Size(), CV_MAT_TYPE(flags));
1719         return;
1720     }
1721 
1722     if( k == STD_VECTOR_VECTOR )
1723     {
1724         ((std::vector<std::vector<uchar> >*)obj)->clear();
1725         return;
1726     }
1727 
1728     if( k == STD_VECTOR_MAT )
1729     {
1730         ((std::vector<Mat>*)obj)->clear();
1731         return;
1732     }
1733 
1734     if( k == STD_VECTOR_UMAT )
1735     {
1736         ((std::vector<UMat>*)obj)->clear();
1737         return;
1738     }
1739     if (k == STD_VECTOR_CUDA_GPU_MAT)
1740     {
1741 #ifdef HAVE_CUDA
1742         ((std::vector<cuda::GpuMat>*)obj)->clear();
1743         return;
1744 #else
1745         CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1746 #endif
1747     }
1748     CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
1749 }
1750 
clear() const1751 void _OutputArray::clear() const
1752 {
1753     _InputArray::KindFlag k = kind();
1754 
1755     if( k == MAT )
1756     {
1757         CV_Assert(!fixedSize());
1758         ((Mat*)obj)->resize(0);
1759         return;
1760     }
1761 
1762     release();
1763 }
1764 
needed() const1765 bool _OutputArray::needed() const
1766 {
1767     return kind() != NONE;
1768 }
1769 
getMatRef(int i) const1770 Mat& _OutputArray::getMatRef(int i) const
1771 {
1772     _InputArray::KindFlag k = kind();
1773     if( i < 0 )
1774     {
1775         CV_Assert( k == MAT );
1776         return *(Mat*)obj;
1777     }
1778 
1779     CV_Assert( k == STD_VECTOR_MAT || k == STD_ARRAY_MAT );
1780 
1781     if( k == STD_VECTOR_MAT )
1782     {
1783         std::vector<Mat>& v = *(std::vector<Mat>*)obj;
1784         CV_Assert( i < (int)v.size() );
1785         return v[i];
1786     }
1787     else
1788     {
1789         Mat* v = (Mat*)obj;
1790         CV_Assert( 0 <= i && i < sz.height );
1791         return v[i];
1792     }
1793 }
1794 
getUMatRef(int i) const1795 UMat& _OutputArray::getUMatRef(int i) const
1796 {
1797     _InputArray::KindFlag k = kind();
1798     if( i < 0 )
1799     {
1800         CV_Assert( k == UMAT );
1801         return *(UMat*)obj;
1802     }
1803     else
1804     {
1805         CV_Assert( k == STD_VECTOR_UMAT );
1806         std::vector<UMat>& v = *(std::vector<UMat>*)obj;
1807         CV_Assert( i < (int)v.size() );
1808         return v[i];
1809     }
1810 }
1811 
getGpuMatRef() const1812 cuda::GpuMat& _OutputArray::getGpuMatRef() const
1813 {
1814     _InputArray::KindFlag k = kind();
1815     CV_Assert( k == CUDA_GPU_MAT );
1816     return *(cuda::GpuMat*)obj;
1817 }
getGpuMatVecRef() const1818 std::vector<cuda::GpuMat>& _OutputArray::getGpuMatVecRef() const
1819 {
1820     _InputArray::KindFlag k = kind();
1821     CV_Assert(k == STD_VECTOR_CUDA_GPU_MAT);
1822     return *(std::vector<cuda::GpuMat>*)obj;
1823 }
1824 
getOGlBufferRef() const1825 ogl::Buffer& _OutputArray::getOGlBufferRef() const
1826 {
1827     _InputArray::KindFlag k = kind();
1828     CV_Assert( k == OPENGL_BUFFER );
1829     return *(ogl::Buffer*)obj;
1830 }
1831 
getHostMemRef() const1832 cuda::HostMem& _OutputArray::getHostMemRef() const
1833 {
1834     _InputArray::KindFlag k = kind();
1835     CV_Assert( k == CUDA_HOST_MEM );
1836     return *(cuda::HostMem*)obj;
1837 }
1838 
setTo(const _InputArray & arr,const _InputArray & mask) const1839 void _OutputArray::setTo(const _InputArray& arr, const _InputArray & mask) const
1840 {
1841     _InputArray::KindFlag k = kind();
1842 
1843     if( k == NONE )
1844         ;
1845     else if (k == MAT || k == MATX || k == STD_VECTOR)
1846     {
1847         Mat m = getMat();
1848         m.setTo(arr, mask);
1849     }
1850     else if( k == UMAT )
1851         ((UMat*)obj)->setTo(arr, mask);
1852     else if( k == CUDA_GPU_MAT )
1853     {
1854 #ifdef HAVE_CUDA
1855         Mat value = arr.getMat();
1856         CV_Assert( checkScalar(value, type(), arr.kind(), _InputArray::CUDA_GPU_MAT) );
1857         ((cuda::GpuMat*)obj)->setTo(Scalar(Vec<double, 4>(value.ptr<double>())), mask);
1858 #else
1859         CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
1860 #endif
1861     }
1862     else
1863         CV_Error(Error::StsNotImplemented, "");
1864 }
1865 
1866 
assign(const UMat & u) const1867 void _OutputArray::assign(const UMat& u) const
1868 {
1869     _InputArray::KindFlag k = kind();
1870     if (k == UMAT)
1871     {
1872         *(UMat*)obj = u;
1873     }
1874     else if (k == MAT)
1875     {
1876         u.copyTo(*(Mat*)obj); // TODO check u.getMat()
1877     }
1878     else if (k == MATX)
1879     {
1880         u.copyTo(getMat()); // TODO check u.getMat()
1881     }
1882     else
1883     {
1884         CV_Error(Error::StsNotImplemented, "");
1885     }
1886 }
1887 
1888 
assign(const Mat & m) const1889 void _OutputArray::assign(const Mat& m) const
1890 {
1891     _InputArray::KindFlag k = kind();
1892     if (k == UMAT)
1893     {
1894         m.copyTo(*(UMat*)obj); // TODO check m.getUMat()
1895     }
1896     else if (k == MAT)
1897     {
1898         *(Mat*)obj = m;
1899     }
1900     else if (k == MATX)
1901     {
1902         m.copyTo(getMat());
1903     }
1904     else
1905     {
1906         CV_Error(Error::StsNotImplemented, "");
1907     }
1908 }
1909 
1910 
move(UMat & u) const1911 void _OutputArray::move(UMat& u) const
1912 {
1913     if (fixedSize())
1914     {
1915         // TODO Performance warning
1916         assign(u);
1917         return;
1918     }
1919     int k = kind();
1920     if (k == UMAT)
1921     {
1922 #ifdef CV_CXX11
1923         *(UMat*)obj = std::move(u);
1924 #else
1925         *(UMat*)obj = u;
1926         u.release();
1927 #endif
1928     }
1929     else if (k == MAT)
1930     {
1931         u.copyTo(*(Mat*)obj); // TODO check u.getMat()
1932         u.release();
1933     }
1934     else if (k == MATX)
1935     {
1936         u.copyTo(getMat()); // TODO check u.getMat()
1937         u.release();
1938     }
1939     else
1940     {
1941         CV_Error(Error::StsNotImplemented, "");
1942     }
1943 }
1944 
1945 
move(Mat & m) const1946 void _OutputArray::move(Mat& m) const
1947 {
1948     if (fixedSize())
1949     {
1950         // TODO Performance warning
1951         assign(m);
1952         return;
1953     }
1954     int k = kind();
1955     if (k == UMAT)
1956     {
1957         m.copyTo(*(UMat*)obj); // TODO check m.getUMat()
1958         m.release();
1959     }
1960     else if (k == MAT)
1961     {
1962 #ifdef CV_CXX11
1963         *(Mat*)obj = std::move(m);
1964 #else
1965         *(Mat*)obj = m;
1966         m.release();
1967 #endif
1968     }
1969     else if (k == MATX)
1970     {
1971         m.copyTo(getMat());
1972         m.release();
1973     }
1974     else
1975     {
1976         CV_Error(Error::StsNotImplemented, "");
1977     }
1978 }
1979 
1980 
assign(const std::vector<UMat> & v) const1981 void _OutputArray::assign(const std::vector<UMat>& v) const
1982 {
1983     _InputArray::KindFlag k = kind();
1984     if (k == STD_VECTOR_UMAT)
1985     {
1986         std::vector<UMat>& this_v = *(std::vector<UMat>*)obj;
1987         CV_Assert(this_v.size() == v.size());
1988 
1989         for (size_t i = 0; i < v.size(); i++)
1990         {
1991             const UMat& m = v[i];
1992             UMat& this_m = this_v[i];
1993             if (this_m.u != NULL && this_m.u == m.u)
1994                 continue; // same object (see dnn::Layer::forward_fallback)
1995             m.copyTo(this_m);
1996         }
1997     }
1998     else if (k == STD_VECTOR_MAT)
1999     {
2000         std::vector<Mat>& this_v = *(std::vector<Mat>*)obj;
2001         CV_Assert(this_v.size() == v.size());
2002 
2003         for (size_t i = 0; i < v.size(); i++)
2004         {
2005             const UMat& m = v[i];
2006             Mat& this_m = this_v[i];
2007             if (this_m.u != NULL && this_m.u == m.u)
2008                 continue; // same object (see dnn::Layer::forward_fallback)
2009             m.copyTo(this_m);
2010         }
2011     }
2012     else
2013     {
2014         CV_Error(Error::StsNotImplemented, "");
2015     }
2016 }
2017 
2018 
assign(const std::vector<Mat> & v) const2019 void _OutputArray::assign(const std::vector<Mat>& v) const
2020 {
2021     _InputArray::KindFlag k = kind();
2022     if (k == STD_VECTOR_UMAT)
2023     {
2024         std::vector<UMat>& this_v = *(std::vector<UMat>*)obj;
2025         CV_Assert(this_v.size() == v.size());
2026 
2027         for (size_t i = 0; i < v.size(); i++)
2028         {
2029             const Mat& m = v[i];
2030             UMat& this_m = this_v[i];
2031             if (this_m.u != NULL && this_m.u == m.u)
2032                 continue; // same object (see dnn::Layer::forward_fallback)
2033             m.copyTo(this_m);
2034         }
2035     }
2036     else if (k == STD_VECTOR_MAT)
2037     {
2038         std::vector<Mat>& this_v = *(std::vector<Mat>*)obj;
2039         CV_Assert(this_v.size() == v.size());
2040 
2041         for (size_t i = 0; i < v.size(); i++)
2042         {
2043             const Mat& m = v[i];
2044             Mat& this_m = this_v[i];
2045             if (this_m.u != NULL && this_m.u == m.u)
2046                 continue; // same object (see dnn::Layer::forward_fallback)
2047             m.copyTo(this_m);
2048         }
2049     }
2050     else
2051     {
2052         CV_Error(Error::StsNotImplemented, "");
2053     }
2054 }
2055 
2056 
2057 static _InputOutputArray _none;
noArray()2058 InputOutputArray noArray() { return _none; }
2059 
2060 } // cv::
2061