1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*M///////////////////////////////////////////////////////////////////////////////////////
2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  By downloading, copying, installing or using the software you agree to this license.
6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  If you do not agree to this license, do not download, install,
7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//  copy or use the software.
8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//                           License Agreement
11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//                For Open Source Computer Vision Library
12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Copyright (C) 2014, Itseez Inc., all rights reserved.
14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Third party copyrights are property of their respective owners.
15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Redistribution and use in source and binary forms, with or without modification,
17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// are permitted provided that the following conditions are met:
18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * Redistribution's of source code must retain the above copyright notice,
20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     this list of conditions and the following disclaimer.
21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * Redistribution's in binary form must reproduce the above copyright notice,
23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     this list of conditions and the following disclaimer in the documentation
24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     and/or other materials provided with the distribution.
25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//   * The name of the copyright holders may not be used to endorse or promote products
27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//     derived from this software without specific prior written permission.
28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// This software is provided by the copyright holders and contributors "as is" and
30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// any express or implied warranties, including, but not limited to, the implied
31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// warranties of merchantability and fitness for a particular purpose are disclaimed.
32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// In no event shall the Intel Corporation or contributors be liable for any direct,
33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// indirect, incidental, special, exemplary, or consequential damages
34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// (including, but not limited to, procurement of substitute goods or services;
35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// loss of use, data, or profits; or business interruption) however caused
36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// and on any theory of liability, whether in contract, strict liability,
37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// or tort (including negligence or otherwise) arising in any way out of
38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// the use of this software, even if advised of the possibility of such damage.
39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//
40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//M*/
41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "precomp.hpp"
43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "opencl_kernels_core.hpp"
44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler///////////////////////////////// UMat implementation ///////////////////////////////
46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslernamespace cv {
48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// it should be a prime number for the best hash function
50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerenum { UMAT_NLOCKS = 31 };
51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic Mutex umatLocks[UMAT_NLOCKS];
52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
53793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMatData::UMatData(const MatAllocator* allocator)
54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    prevAllocator = currAllocator = allocator;
56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    urefcount = refcount = 0;
57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    data = origdata = 0;
58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size = 0;
59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    flags = 0;
60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    handle = 0;
61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    userdata = 0;
62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    allocatorFlags_ = 0;
63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
65793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMatData::~UMatData()
66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    prevAllocator = currAllocator = 0;
68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    urefcount = refcount = 0;
69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    data = origdata = 0;
70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size = 0;
71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    flags = 0;
72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    handle = 0;
73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    userdata = 0;
74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    allocatorFlags_ = 0;
75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid UMatData::lock()
78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    umatLocks[(size_t)(void*)this % UMAT_NLOCKS].lock();
80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid UMatData::unlock()
83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    umatLocks[(size_t)(void*)this % UMAT_NLOCKS].unlock();
85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
88793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMatAllocator* UMat::getStdAllocator()
89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef HAVE_OPENCL
91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( ocl::haveOpenCL() && ocl::useOpenCL() )
92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return ocl::getOpenCLAllocator();
93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return Mat::getStdAllocator();
95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid swap( UMat& a, UMat& b )
98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::swap(a.flags, b.flags);
100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::swap(a.dims, b.dims);
101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::swap(a.rows, b.rows);
102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::swap(a.cols, b.cols);
103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::swap(a.allocator, b.allocator);
104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::swap(a.u, b.u);
105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::swap(a.offset, b.offset);
106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::swap(a.size.p, b.size.p);
108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::swap(a.step.p, b.step.p);
109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::swap(a.step.buf[0], b.step.buf[0]);
110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    std::swap(a.step.buf[1], b.step.buf[1]);
111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( a.step.p == b.step.buf )
113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        a.step.p = a.step.buf;
115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        a.size.p = &a.rows;
116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( b.step.p == a.step.buf )
119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        b.step.p = b.step.buf;
121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        b.size.p = &b.rows;
122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic inline void setSize( UMat& m, int _dims, const int* _sz,
127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            const size_t* _steps, bool autoSteps=false )
128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert( 0 <= _dims && _dims <= CV_MAX_DIM );
130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( m.dims != _dims )
131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( m.step.p != m.step.buf )
133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            fastFree(m.step.p);
135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m.step.p = m.step.buf;
136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m.size.p = &m.rows;
137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( _dims > 2 )
139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m.step.p = (size_t*)fastMalloc(_dims*sizeof(m.step.p[0]) + (_dims+1)*sizeof(m.size.p[0]));
141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m.size.p = (int*)(m.step.p + _dims) + 1;
142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m.size.p[-1] = _dims;
143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m.rows = m.cols = -1;
144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m.dims = _dims;
148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !_sz )
149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return;
150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size_t esz = CV_ELEM_SIZE(m.flags), total = esz;
152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i;
153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = _dims-1; i >= 0; i-- )
154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int s = _sz[i];
156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert( s >= 0 );
157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.size.p[i] = s;
158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( _steps )
160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m.step.p[i] = i < _dims-1 ? _steps[i] : esz;
161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else if( autoSteps )
162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m.step.p[i] = total;
164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int64 total1 = (int64)total*s;
165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( (uint64)total1 != (size_t)total1 )
166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_Error( CV_StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" );
167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            total = (size_t)total1;
168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( _dims == 1 )
172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.dims = 2;
174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.cols = 1;
175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.step[1] = esz;
176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void updateContinuityFlag(UMat& m)
180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i, j;
182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < m.dims; i++ )
183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( m.size[i] > 1 )
185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( j = m.dims-1; j > i; j-- )
189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( m.step[j]*m.size[j] < m.step[j-1] )
191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint64 total = (uint64)m.step[0]*m.size[0];
195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( j <= i && total == (size_t)total )
196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.flags |= UMat::CONTINUOUS_FLAG;
197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.flags &= ~UMat::CONTINUOUS_FLAG;
199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void finalizeHdr(UMat& m)
203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    updateContinuityFlag(m);
205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int d = m.dims;
206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( d > 2 )
207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.rows = m.cols = -1;
208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
210793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat Mat::getUMat(int accessFlags, UMatUsageFlags usageFlags) const
211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat hdr;
213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if(!data)
214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return hdr;
215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMatData* temp_u = u;
216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if(!temp_u)
217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        MatAllocator *a = allocator, *a0 = getStdAllocator();
219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if(!a)
220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            a = a0;
221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        temp_u = a->allocate(dims, size.p, type(), data, step.p, accessFlags, usageFlags);
222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        temp_u->refcount = 1;
223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat::getStdAllocator()->allocate(temp_u, accessFlags, usageFlags); // TODO result is not checked
225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.flags = flags;
226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    setSize(hdr, dims, size.p, step.p);
227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    finalizeHdr(hdr);
228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.u = temp_u;
229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.offset = data - datastart;
230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.addref();
231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return hdr;
232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid UMat::create(int d, const int* _sizes, int _type, UMatUsageFlags _usageFlags)
235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    this->usageFlags = _usageFlags;
237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i;
239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert(0 <= d && d <= CV_MAX_DIM && _sizes);
240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _type = CV_MAT_TYPE(_type);
241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( u && (d == dims || (d == 1 && dims <= 2)) && _type == type() )
243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( d == 2 && rows == _sizes[0] && cols == _sizes[1] )
245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return;
246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( i = 0; i < d; i++ )
247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( size[i] != _sizes[i] )
248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( i == d && (d > 1 || size[1] == 1))
250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return;
251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    release();
254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( d == 0 )
255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return;
256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    flags = (_type & CV_MAT_TYPE_MASK) | MAGIC_VAL;
257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    setSize(*this, d, _sizes, 0, true);
258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    offset = 0;
259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( total() > 0 )
261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        MatAllocator *a = allocator, *a0 = getStdAllocator();
263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if(!a)
264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            a = a0;
265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        try
266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            u = a->allocate(dims, size, _type, 0, step.p, 0, usageFlags);
268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_Assert(u != 0);
269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        catch(...)
271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if(a != a0)
273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                u = a0->allocate(dims, size, _type, 0, step.p, 0, usageFlags);
274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_Assert(u != 0);
275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) );
277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    finalizeHdr(*this);
280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    addref();
281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid UMat::copySize(const UMat& m)
284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    setSize(*this, m.dims, 0, 0);
286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( int i = 0; i < dims; i++ )
287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        size[i] = m.size[i];
289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        step[i] = m.step[i];
290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
294793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat::~UMat()
295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    release();
297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( step.p != step.buf )
298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        fastFree(step.p);
299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid UMat::deallocate()
302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    u->currAllocator->deallocate(u);
304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    u = NULL;
305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
308793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat::UMat(const UMat& m, const Range& _rowRange, const Range& _colRange)
309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert( m.dims >= 2 );
312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( m.dims > 2 )
313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        AutoBuffer<Range> rs(m.dims);
315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        rs[0] = _rowRange;
316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        rs[1] = _colRange;
317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( int i = 2; i < m.dims; i++ )
318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            rs[i] = Range::all();
319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        *this = m(rs);
320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return;
321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    *this = m;
324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( _rowRange != Range::all() && _rowRange != Range(0,rows) )
325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert( 0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows );
327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        rows = _rowRange.size();
328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        offset += step*_rowRange.start;
329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        flags |= SUBMATRIX_FLAG;
330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( _colRange != Range::all() && _colRange != Range(0,cols) )
333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert( 0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols );
335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cols = _colRange.size();
336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        offset += _colRange.start*elemSize();
337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        flags &= cols < m.cols ? ~CONTINUOUS_FLAG : -1;
338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        flags |= SUBMATRIX_FLAG;
339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( rows == 1 )
342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        flags |= CONTINUOUS_FLAG;
343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( rows <= 0 || cols <= 0 )
345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        release();
347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        rows = cols = 0;
348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
352793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat::UMat(const UMat& m, const Rect& roi)
353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    : flags(m.flags), dims(2), rows(roi.height), cols(roi.width),
354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    allocator(m.allocator), usageFlags(m.usageFlags), u(m.u), offset(m.offset + roi.y*m.step[0]), size(&rows)
355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert( m.dims <= 2 );
357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    flags &= roi.width < m.cols ? ~CONTINUOUS_FLAG : -1;
358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    flags |= roi.height == 1 ? CONTINUOUS_FLAG : 0;
359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size_t esz = CV_ELEM_SIZE(flags);
361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    offset += roi.x*esz;
362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler              0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( u )
365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_XADD(&(u->urefcount), 1);
366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( roi.width < m.cols || roi.height < m.rows )
367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        flags |= SUBMATRIX_FLAG;
368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    step[0] = m.step[0]; step[1] = esz;
370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( rows <= 0 || cols <= 0 )
372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        release();
374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        rows = cols = 0;
375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
379793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat::UMat(const UMat& m, const Range* ranges)
380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    : flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i, d = m.dims;
383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert(ranges);
385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < d; i++ )
386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        Range r = ranges[i];
388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert( r == Range::all() || (0 <= r.start && r.start < r.end && r.end <= m.size[i]) );
389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    *this = m;
391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < d; i++ )
392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        Range r = ranges[i];
394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( r != Range::all() && r != Range(0, size.p[i]))
395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            size.p[i] = r.end - r.start;
397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            offset += r.start*step.p[i];
398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            flags |= SUBMATRIX_FLAG;
399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    updateContinuityFlag(*this);
402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
404793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::diag(int d) const
405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert( dims <= 2 );
407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat m = *this;
408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size_t esz = elemSize();
409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int len;
410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( d >= 0 )
412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        len = std::min(cols - d, rows);
414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.offset += esz*d;
415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        len = std::min(rows + d, cols);
419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.offset -= step[0]*d;
420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_DbgAssert( len > 0 );
422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m.size[0] = m.rows = len;
424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m.size[1] = m.cols = 1;
425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m.step[0] += (len > 1 ? esz : 0);
426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( m.rows > 1 )
428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.flags &= ~CONTINUOUS_FLAG;
429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.flags |= CONTINUOUS_FLAG;
431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( size() != Size(1,1) )
433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        m.flags |= SUBMATRIX_FLAG;
434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return m;
436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid UMat::locateROI( Size& wholeSize, Point& ofs ) const
439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert( dims <= 2 && step[0] > 0 );
441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size_t esz = elemSize(), minstep;
442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ptrdiff_t delta1 = (ptrdiff_t)offset, delta2 = (ptrdiff_t)u->size;
443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( delta1 == 0 )
445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ofs.x = ofs.y = 0;
446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ofs.y = (int)(delta1/step[0]);
449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ofs.x = (int)((delta1 - step[0]*ofs.y)/esz);
450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_DbgAssert( offset == (size_t)(ofs.y*step[0] + ofs.x*esz) );
451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    minstep = (ofs.x + cols)*esz;
453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    wholeSize.height = (int)((delta2 - minstep)/step[0] + 1);
454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    wholeSize.height = std::max(wholeSize.height, ofs.y + rows);
455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    wholeSize.width = (int)((delta2 - step*(wholeSize.height-1))/esz);
456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    wholeSize.width = std::max(wholeSize.width, ofs.x + cols);
457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
460793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat& UMat::adjustROI( int dtop, int dbottom, int dleft, int dright )
461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert( dims <= 2 && step[0] > 0 );
463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Size wholeSize; Point ofs;
464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size_t esz = elemSize();
465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    locateROI( wholeSize, ofs );
466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int row1 = std::max(ofs.y - dtop, 0), row2 = std::min(ofs.y + rows + dbottom, wholeSize.height);
467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int col1 = std::max(ofs.x - dleft, 0), col2 = std::min(ofs.x + cols + dright, wholeSize.width);
468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    offset += (row1 - ofs.y)*step + (col1 - ofs.x)*esz;
469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    rows = row2 - row1; cols = col2 - col1;
470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size.p[0] = rows; size.p[1] = cols;
471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( esz*cols == step[0] || rows == 1 )
472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        flags |= CONTINUOUS_FLAG;
473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        flags &= ~CONTINUOUS_FLAG;
475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return *this;
476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
479793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::reshape(int new_cn, int new_rows) const
480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int cn = channels();
482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat hdr = *this;
483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( dims > 2 && new_rows == 0 && new_cn != 0 && size[dims-1]*cn % new_cn == 0 )
485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn-1) << CV_CN_SHIFT);
487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        hdr.step[dims-1] = CV_ELEM_SIZE(hdr.flags);
488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        hdr.size[dims-1] = hdr.size[dims-1]*cn / new_cn;
489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return hdr;
490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert( dims <= 2 );
493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( new_cn == 0 )
495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        new_cn = cn;
496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int total_width = cols * cn;
498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 )
500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        new_rows = rows * total_width / new_cn;
501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( new_rows != 0 && new_rows != rows )
503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int total_size = total_width * rows;
505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( !isContinuous() )
506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_Error( CV_BadStep,
507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            "The matrix is not continuous, thus its number of rows can not be changed" );
508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( (unsigned)new_rows > (unsigned)total_size )
510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_Error( CV_StsOutOfRange, "Bad new number of rows" );
511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        total_width = total_size / new_rows;
513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( total_width * new_rows != total_size )
515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_Error( CV_StsBadArg, "The total number of matrix elements "
516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                    "is not divisible by the new number of rows" );
517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        hdr.rows = new_rows;
519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        hdr.step[0] = total_width * elemSize1();
520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int new_width = total_width / new_cn;
523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( new_width * new_cn != total_width )
525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Error( CV_BadNumChannels,
526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        "The total width is not divisible by the new number of channels" );
527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.cols = new_width;
529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn-1) << CV_CN_SHIFT);
530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.step[1] = CV_ELEM_SIZE(hdr.flags);
531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return hdr;
532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
534793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::diag(const UMat& d)
535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert( d.cols == 1 || d.rows == 1 );
537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int len = d.rows + d.cols - 1;
538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat m(len, len, d.type(), Scalar(0));
539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat md = m.diag();
540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( d.cols == 1 )
541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        d.copyTo(md);
542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        transpose(d, md);
544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return m;
545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint UMat::checkVector(int _elemChannels, int _depth, bool _requireContinuous) const
548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (depth() == _depth || _depth <= 0) &&
550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        (isContinuous() || !_requireContinuous) &&
551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ((dims == 2 && (((rows == 1 || cols == 1) && channels() == _elemChannels) ||
552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        (cols == _elemChannels && channels() == 1))) ||
553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        (dims == 3 && channels() == 1 && size.p[2] == _elemChannels && (size.p[0] == 1 || size.p[1] == 1) &&
554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler         (isContinuous() || step.p[1] == step.p[2]*size.p[2])))
555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ? (int)(total()*channels()/_elemChannels) : -1;
556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
558793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::reshape(int _cn, int _newndims, const int* _newsz) const
559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if(_newndims == dims)
561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if(_newsz == 0)
563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return reshape(_cn);
564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if(_newndims == 2)
565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return reshape(_cn, _newsz[0]);
566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Error(CV_StsNotImplemented, "");
569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // TBD
570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return UMat();
571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
574793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerMat UMat::getMat(int accessFlags) const
575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if(!u)
577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return Mat();
578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    u->currAllocator->map(u, accessFlags | ACCESS_READ); // TODO Support ACCESS_WRITE without unnecessary data transfers
579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert(u->data != 0);
580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Mat hdr(dims, size.p, type(), u->data + offset, step.p);
581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.flags = flags;
582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.u = u;
583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.datastart = u->data;
584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.data = u->data + offset;
585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    hdr.datalimit = hdr.dataend = u->data + u->size;
586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_XADD(&hdr.u->refcount, 1);
587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return hdr;
588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid* UMat::handle(int accessFlags) const
591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !u )
593793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return 0;
594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // check flags: if CPU copy is newer, copy it back to GPU.
596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( u->deviceCopyObsolete() )
597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert(u->refcount == 0);
599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        u->currAllocator->unmap(u);
600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if ((accessFlags & ACCESS_WRITE) != 0)
603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        u->markHostCopyObsolete(true);
604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return u->handle;
606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid UMat::ndoffset(size_t* ofs) const
609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    // offset = step[0]*ofs[0] + step[1]*ofs[1] + step[2]*ofs[2] + ...;
611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size_t val = offset;
612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( int i = 0; i < dims; i++ )
613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        size_t s = step.p[i];
615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ofs[i] = val / s;
616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        val -= ofs[i]*s;
617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid UMat::copyTo(OutputArray _dst) const
621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int dtype = _dst.type();
623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( _dst.fixedType() && dtype != type() )
624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert( channels() == CV_MAT_CN(dtype) );
626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        convertTo( _dst, dtype );
627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return;
628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( empty() )
631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _dst.release();
633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return;
634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size_t i, sz[CV_MAX_DIM], srcofs[CV_MAX_DIM], dstofs[CV_MAX_DIM], esz = elemSize();
637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < (size_t)dims; i++ )
638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        sz[i] = size.p[i];
639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    sz[dims-1] *= esz;
640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ndoffset(srcofs);
641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    srcofs[dims-1] *= esz;
642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _dst.create( dims, size.p, type() );
644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( _dst.isUMat() )
645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        UMat dst = _dst.getUMat();
647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( u == dst.u && dst.offset == offset )
648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return;
649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (u->currAllocator == dst.u->currAllocator)
651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            dst.ndoffset(dstofs);
653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            dstofs[dims-1] *= esz;
654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            u->currAllocator->copy(u, dst.u, dims, sz, srcofs, step.p, dstofs, dst.step.p, false);
655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return;
656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Mat dst = _dst.getMat();
660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    u->currAllocator->download(u, dst.ptr(), dims, sz, srcofs, step.p, dst.step.p);
661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid UMat::copyTo(OutputArray _dst, InputArray _mask) const
664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( _mask.empty() )
666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        copyTo(_dst);
668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return;
669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef HAVE_OPENCL
671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int cn = channels(), mtype = _mask.type(), mdepth = CV_MAT_DEPTH(mtype), mcn = CV_MAT_CN(mtype);
672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert( mdepth == CV_8U && (mcn == 1 || mcn == cn) );
673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (ocl::useOpenCL() && _dst.isUMat() && dims <= 2)
675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        UMatData * prevu = _dst.getUMat().u;
677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _dst.create( dims, size, type() );
678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        UMat dst = _dst.getUMat();
680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        bool haveDstUninit = false;
682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( prevu != dst.u ) // do not leave dst uninitialized
683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            haveDstUninit = true;
684793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        String opts = format("-D COPY_TO_MASK -D T1=%s -D scn=%d -D mcn=%d%s",
686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                             ocl::memopTypeToStr(depth()), cn, mcn,
687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                             haveDstUninit ? " -D HAVE_DST_UNINIT" : "");
688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ocl::Kernel k("copyToMask", ocl::core::copyset_oclsrc, opts);
690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (!k.empty())
691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            k.args(ocl::KernelArg::ReadOnlyNoSize(*this),
693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                   ocl::KernelArg::ReadOnlyNoSize(_mask.getUMat()),
694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                   haveDstUninit ? ocl::KernelArg::WriteOnly(dst) :
695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                   ocl::KernelArg::ReadWrite(dst));
696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            size_t globalsize[2] = { cols, rows };
698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (k.run(2, globalsize, NULL, false))
699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_IMPL_ADD(CV_IMPL_OCL);
701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return;
702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Mat src = getMat(ACCESS_READ);
707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    src.copyTo(_dst, _mask);
708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid UMat::convertTo(OutputArray _dst, int _type, double alpha, double beta) const
711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bool noScale = std::fabs(alpha - 1) < DBL_EPSILON && std::fabs(beta) < DBL_EPSILON;
713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int stype = type(), cn = CV_MAT_CN(stype);
714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( _type < 0 )
716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _type = _dst.fixedType() ? _dst.type() : stype;
717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _type = CV_MAKETYPE(CV_MAT_DEPTH(_type), cn);
719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int sdepth = CV_MAT_DEPTH(stype), ddepth = CV_MAT_DEPTH(_type);
721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( sdepth == ddepth && noScale )
722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        copyTo(_dst);
724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return;
725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef HAVE_OPENCL
727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bool needDouble = sdepth == CV_64F || ddepth == CV_64F;
729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( dims <= 2 && cn && _dst.isUMat() && ocl::useOpenCL() &&
730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            ((needDouble && doubleSupport) || !needDouble) )
731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int wdepth = std::max(CV_32F, sdepth), rowsPerWI = 4;
733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        char cvt[2][40];
735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ocl::Kernel k("convertTo", ocl::core::convert_oclsrc,
736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                      format("-D srcT=%s -D WT=%s -D dstT=%s -D convertToWT=%s -D convertToDT=%s%s",
737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                             ocl::typeToStr(sdepth), ocl::typeToStr(wdepth), ocl::typeToStr(ddepth),
738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                             ocl::convertTypeStr(sdepth, wdepth, 1, cvt[0]),
739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                             ocl::convertTypeStr(wdepth, ddepth, 1, cvt[1]),
740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                             doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (!k.empty())
742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            UMat src = *this;
744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            _dst.create( size(), _type );
745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            UMat dst = _dst.getUMat();
746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            float alphaf = (float)alpha, betaf = (float)beta;
748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            ocl::KernelArg srcarg = ocl::KernelArg::ReadOnlyNoSize(src),
749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    dstarg = ocl::KernelArg::WriteOnly(dst, cn);
750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
751793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (wdepth == CV_32F)
752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                k.args(srcarg, dstarg, alphaf, betaf, rowsPerWI);
753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                k.args(srcarg, dstarg, alpha, beta, rowsPerWI);
755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            size_t globalsize[2] = { dst.cols * cn, (dst.rows + rowsPerWI - 1) / rowsPerWI };
757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (k.run(2, globalsize, NULL, false))
758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_IMPL_ADD(CV_IMPL_OCL);
760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return;
761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
763793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Mat m = getMat(ACCESS_READ);
766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m.convertTo(_dst, _type, alpha, beta);
767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
769793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat& UMat::setTo(InputArray _value, InputArray _mask)
770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bool haveMask = !_mask.empty();
772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef HAVE_OPENCL
773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int tp = type(), cn = CV_MAT_CN(tp), d = CV_MAT_DEPTH(tp);
774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( dims <= 2 && cn <= 4 && CV_MAT_DEPTH(tp) < CV_64F && ocl::useOpenCL() )
776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        Mat value = _value.getMat();
778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_Assert( checkScalar(value, type(), _value.kind(), _InputArray::UMAT) );
779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int kercn = haveMask || cn == 3 ? cn : std::max(cn, ocl::predictOptimalVectorWidth(*this)),
780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                kertp = CV_MAKE_TYPE(d, kercn);
781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        double buf[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                           0, 0, 0, 0, 0, 0, 0, 0 };
784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        convertAndUnrollScalar(value, tp, (uchar *)buf, kercn / cn);
785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int scalarcn = kercn == 3 ? 4 : kercn, rowsPerWI = ocl::Device::getDefault().isIntel() ? 4 : 1;
787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        String opts = format("-D dstT=%s -D rowsPerWI=%d -D dstST=%s -D dstT1=%s -D cn=%d",
788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                             ocl::memopTypeToStr(kertp), rowsPerWI,
789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                             ocl::memopTypeToStr(CV_MAKETYPE(d, scalarcn)),
790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                             ocl::memopTypeToStr(d), kercn);
791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ocl::Kernel setK(haveMask ? "setMask" : "set", ocl::core::copyset_oclsrc, opts);
793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( !setK.empty() )
794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            ocl::KernelArg scalararg(0, 0, 0, 0, buf, CV_ELEM_SIZE(d) * scalarcn);
796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            UMat mask;
797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( haveMask )
799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                mask = _mask.getUMat();
801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_Assert( mask.size() == size() && mask.type() == CV_8UC1 );
802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                ocl::KernelArg maskarg = ocl::KernelArg::ReadOnlyNoSize(mask),
803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        dstarg = ocl::KernelArg::ReadWrite(*this);
804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                setK.args(maskarg, dstarg, scalararg);
805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                ocl::KernelArg dstarg = ocl::KernelArg::WriteOnly(*this, cn, kercn);
809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                setK.args(dstarg, scalararg);
810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            size_t globalsize[] = { cols * cn / kercn, (rows + rowsPerWI - 1) / rowsPerWI };
813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( setK.run(2, globalsize, NULL, false) )
814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_IMPL_ADD(CV_IMPL_OCL);
816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return *this;
817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Mat m = getMat(haveMask ? ACCESS_RW : ACCESS_WRITE);
822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m.setTo(_value, _mask);
823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return *this;
824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
826793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat& UMat::operator = (const Scalar& s)
827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    setTo(s);
829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return *this;
830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
831793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
832793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::t() const
833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat m;
835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    transpose(*this, m);
836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return m;
837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
839793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::inv(int method) const
840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat m;
842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    invert(*this, m, method);
843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return m;
844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
846793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::mul(InputArray m, double scale) const
847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
848793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat dst;
849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    multiply(*this, m, dst, scale);
850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return dst;
851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef HAVE_OPENCL
854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_dot( InputArray _src1, InputArray _src2, double & res )
856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat src1 = _src1.getUMat().reshape(1), src2 = _src2.getUMat().reshape(1);
858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int type = src1.type(), depth = CV_MAT_DEPTH(type),
860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            kercn = ocl::predictOptimalVectorWidth(src1, src2);
861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if ( !doubleSupport && depth == CV_64F )
864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return false;
865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int dbsize = ocl::Device::getDefault().maxComputeUnits();
867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size_t wgs = ocl::Device::getDefault().maxWorkGroupSize();
868793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int ddepth = std::max(CV_32F, depth);
869793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
870793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int wgs2_aligned = 1;
871793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (wgs2_aligned < (int)wgs)
872793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        wgs2_aligned <<= 1;
873793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    wgs2_aligned >>= 1;
874793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
875793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    char cvt[40];
876793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ocl::Kernel k("reduce", ocl::core::reduce_oclsrc,
877793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                  format("-D srcT=%s -D srcT1=%s -D dstT=%s -D dstTK=%s -D ddepth=%d -D convertToDT=%s -D OP_DOT "
878793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         "-D WGS=%d -D WGS2_ALIGNED=%d%s%s%s -D kercn=%d",
879793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)), ocl::typeToStr(depth),
880793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         ocl::typeToStr(ddepth), ocl::typeToStr(CV_MAKE_TYPE(ddepth, kercn)),
881793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         ddepth, ocl::convertTypeStr(depth, ddepth, kercn, cvt),
882793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         (int)wgs, wgs2_aligned, doubleSupport ? " -D DOUBLE_SUPPORT" : "",
883793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         _src1.isContinuous() ? " -D HAVE_SRC_CONT" : "",
884793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         _src2.isContinuous() ? " -D HAVE_SRC2_CONT" : "", kercn));
885793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (k.empty())
886793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return false;
887793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
888793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat db(1, dbsize, ddepth);
889793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
890793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ocl::KernelArg src1arg = ocl::KernelArg::ReadOnlyNoSize(src1),
891793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            src2arg = ocl::KernelArg::ReadOnlyNoSize(src2),
892793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            dbarg = ocl::KernelArg::PtrWriteOnly(db);
893793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
894793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    k.args(src1arg, src1.cols, (int)src1.total(), dbsize, dbarg, src2arg);
895793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
896793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    size_t globalsize = dbsize * wgs;
897793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (k.run(1, &globalsize, &wgs, false))
898793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
899793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        res = sum(db.getMat(ACCESS_READ))[0];
900793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return true;
901793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
902793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return false;
903793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
904793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
905793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
906793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
907793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerdouble UMat::dot(InputArray m) const
908793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
909793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_Assert(m.sameSize(*this) && m.type() == type());
910793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
911793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef HAVE_OPENCL
912793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    double r = 0;
913793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_OCL_RUN_(dims <= 2, ocl_dot(*this, m, r), r)
914793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
915793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
916793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return getMat(ACCESS_READ).dot(m);
917793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
918793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
919793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::zeros(int rows, int cols, int type)
920793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
921793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return UMat(rows, cols, type, Scalar::all(0));
922793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
923793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
924793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::zeros(Size size, int type)
925793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
926793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return UMat(size, type, Scalar::all(0));
927793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
928793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
929793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::zeros(int ndims, const int* sz, int type)
930793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
931793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return UMat(ndims, sz, type, Scalar::all(0));
932793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
933793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
934793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::ones(int rows, int cols, int type)
935793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
936793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return UMat::ones(Size(cols, rows), type);
937793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
938793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
939793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::ones(Size size, int type)
940793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
941793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return UMat(size, type, Scalar(1));
942793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
943793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
944793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::ones(int ndims, const int* sz, int type)
945793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
946793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return UMat(ndims, sz, type, Scalar(1));
947793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
948793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
949793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::eye(int rows, int cols, int type)
950793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
951793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return UMat::eye(Size(cols, rows), type);
952793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
953793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
954793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerUMat UMat::eye(Size size, int type)
955793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
956793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UMat m(size, type);
957793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    setIdentity(m);
958793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return m;
959793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
960793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
961793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
962793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
963793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* End of file. */
964