Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / include / opencv2 / gapi / own / mat.hpp
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 // Copyright (C) 2018-2019 Intel Corporation
6
7
8 #ifndef OPENCV_GAPI_OWN_MAT_HPP
9 #define OPENCV_GAPI_OWN_MAT_HPP
10
11 #include "opencv2/gapi/opencv_includes.hpp"
12 #include "opencv2/gapi/own/types.hpp"
13 #include "opencv2/gapi/own/scalar.hpp"
14 #include "opencv2/gapi/own/saturate.hpp"
15 #include "opencv2/gapi/own/assert.hpp"
16
17 #include <memory>                   //std::shared_ptr
18 #include <cstring>                  //std::memcpy
19 #include "opencv2/gapi/util/throw.hpp"
20
21 namespace cv { namespace gapi { namespace own {
22     namespace detail {
23         template <typename T, unsigned char channels>
24         void assign_row(void* ptr, int cols, Scalar const& s)
25         {
26             auto p = static_cast<T*>(ptr);
27             for (int c = 0; c < cols; c++)
28             {
29                 for (int ch = 0; ch < channels; ch++)
30                 {
31                     p[c * channels + ch] = saturate<T>(s[ch], roundd);
32                 }
33             }
34         }
35
36         inline size_t default_step(int type, int cols)
37         {
38             return CV_ELEM_SIZE(type) * cols;
39         }
40         //Matrix header, i.e. fields that are unique to each Mat object.
41         //Devoted class is needed to implement custom behavior on move (erasing state of moved from object)
42         struct MatHeader{
43             enum { AUTO_STEP = 0};
44             enum { TYPE_MASK = 0x00000FFF  };
45
46             MatHeader() = default;
47
48             MatHeader(int _rows, int _cols, int type, void* _data, size_t _step)
49             : flags((type & TYPE_MASK)), rows(_rows), cols(_cols), data((uchar*)_data), step(_step == AUTO_STEP ? detail::default_step(type, _cols) : _step)
50             {}
51
52             MatHeader(const MatHeader& ) = default;
53             MatHeader(MatHeader&& src) : MatHeader(src) // reuse copy constructor here
54             {
55                 MatHeader empty; //give it a name to call copy(not move) assignment below
56                 src = empty;
57             }
58             MatHeader& operator=(const MatHeader& ) = default;
59             MatHeader& operator=(MatHeader&& src)
60             {
61                 *this = src; //calling a copy assignment here, not move one
62                 MatHeader empty; //give it a name to call copy(not move) assignment below
63                 src = empty;
64                 return *this;
65             }
66             /*! includes several bit-fields:
67                  - depth
68                  - number of channels
69              */
70             int flags = 0;
71
72             //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
73             int rows = 0, cols = 0;
74             //! pointer to the data
75             uchar* data = nullptr;
76             size_t step = 0;
77         };
78     }
79     //concise version of cv::Mat suitable for GAPI needs (used when no dependence on OpenCV is required)
80     class Mat : public detail::MatHeader{
81     public:
82
83         Mat() = default;
84
85         /** @overload
86         @param _rows Number of rows in a 2D array.
87         @param _cols Number of columns in a 2D array.
88         @param _type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
89         CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
90         @param _data Pointer to the user data. Matrix constructors that take data and step parameters do not
91         allocate matrix data. Instead, they just initialize the matrix header that points to the specified
92         data, which means that no data is copied. This operation is very efficient and can be used to
93         process external data using OpenCV functions. The external data is not automatically deallocated, so
94         you should take care of it.
95         @param _step Number of bytes each matrix row occupies. The value should include the padding bytes at
96         the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed
97         and the actual step is calculated as cols*elemSize(). See Mat::elemSize.
98         */
99         Mat(int _rows, int _cols, int _type, void* _data, size_t _step = AUTO_STEP)
100         : MatHeader (_rows, _cols, _type, _data, _step)
101         {}
102
103         Mat(Mat const& src, const Rect& roi )
104         : Mat(src)
105         {
106            rows = roi.height;
107            cols = roi.width;
108            data = ptr(roi.y, roi.x);
109         }
110
111         Mat(Mat const& src) = default;
112         Mat(Mat&& src) = default;
113
114         Mat& operator=(Mat const& src) = default;
115         Mat& operator=(Mat&& src) = default;
116
117         /** @brief Sets all or some of the array elements to the specified value.
118         @param s Assigned scalar converted to the actual array type.
119         */
120         Mat& operator = (const Scalar& s)
121         {
122             constexpr unsigned max_channels = 4; //Scalar can't fit more than 4
123             const auto channels = static_cast<unsigned int>(this->channels());
124             GAPI_Assert(channels <= max_channels);
125
126             using func_p_t = void (*)(void*, int, Scalar const&);
127             using detail::assign_row;
128             #define TABLE_ENTRY(type)  {assign_row<type, 1>, assign_row<type, 2>, assign_row<type, 3>, assign_row<type, 4>}
129             static constexpr func_p_t func_tbl[][max_channels] = {
130                     TABLE_ENTRY(uchar),
131                     TABLE_ENTRY(schar),
132                     TABLE_ENTRY(ushort),
133                     TABLE_ENTRY(short),
134                     TABLE_ENTRY(int),
135                     TABLE_ENTRY(float),
136                     TABLE_ENTRY(double)
137             };
138             #undef TABLE_ENTRY
139
140             static_assert(CV_8U == 0 && CV_8S == 1  && CV_16U == 2 && CV_16S == 3
141                        && CV_32S == 4 && CV_32F == 5 && CV_64F == 6,
142                        "OCV type ids used as indexes to array, thus exact numbers are important!"
143             );
144
145             const auto depth = static_cast<unsigned int>(this->depth());
146             GAPI_Assert(depth < sizeof(func_tbl)/sizeof(func_tbl[0]));
147
148             for (int r = 0; r < rows; ++r)
149             {
150                 auto* f = func_tbl[depth][channels -1];
151                 (*f)(static_cast<void *>(ptr(r)), cols, s );
152             }
153             return *this;
154         }
155
156         /** @brief Returns the matrix element size in bytes.
157
158         The method returns the matrix element size in bytes. For example, if the matrix type is CV_16SC3 ,
159         the method returns 3\*sizeof(short) or 6.
160          */
161         size_t elemSize() const
162         {
163             return CV_ELEM_SIZE(type());
164         }
165         /** @brief Returns the type of a matrix element.
166
167         The method returns a matrix element type. This is an identifier compatible with the CvMat type
168         system, like CV_16SC3 or 16-bit signed 3-channel array, and so on.
169          */
170         int type() const            {return CV_MAT_TYPE(flags);}
171
172         /** @brief Returns the depth of a matrix element.
173
174         The method returns the identifier of the matrix element depth (the type of each individual channel).
175         For example, for a 16-bit signed element array, the method returns CV_16S . A complete list of
176         matrix types contains the following values:
177         -   CV_8U - 8-bit unsigned integers ( 0..255 )
178         -   CV_8S - 8-bit signed integers ( -128..127 )
179         -   CV_16U - 16-bit unsigned integers ( 0..65535 )
180         -   CV_16S - 16-bit signed integers ( -32768..32767 )
181         -   CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
182         -   CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
183         -   CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
184          */
185         int depth() const           {return CV_MAT_DEPTH(flags);}
186
187         /** @brief Returns the number of matrix channels.
188
189         The method returns the number of matrix channels.
190          */
191         int channels() const        {return CV_MAT_CN(flags);}
192
193         /**
194         @param _rows New number of rows.
195         @param _cols New number of columns.
196         @param _type New matrix type.
197          */
198         void create(int _rows, int _cols, int _type)
199         {
200             create({_cols, _rows}, _type);
201         }
202         /** @overload
203         @param _size Alternative new matrix size specification: Size(cols, rows)
204         @param _type New matrix type.
205         */
206         void create(Size _size, int _type)
207         {
208             if (_size != Size{cols, rows} )
209             {
210                 Mat tmp{_size.height, _size.width, _type, nullptr};
211                 tmp.memory.reset(new uchar[ tmp.step * tmp.rows], [](uchar * p){delete[] p;});
212                 tmp.data = tmp.memory.get();
213
214                 *this = std::move(tmp);
215             }
216         }
217
218         /** @brief Copies the matrix to another one.
219
220         The method copies the matrix data to another matrix. Before copying the data, the method invokes :
221         @code
222             m.create(this->size(), this->type());
223         @endcode
224         so that the destination matrix is reallocated if needed. While m.copyTo(m); works flawlessly, the
225         function does not handle the case of a partial overlap between the source and the destination
226         matrices.
227          */
228         void copyTo(Mat& dst) const
229         {
230             dst.create(rows, cols, type());
231             for (int r = 0; r < rows; ++r)
232             {
233                 std::copy_n(ptr(r), detail::default_step(type(),cols), dst.ptr(r));
234             }
235         }
236
237         /** @brief Returns true if the array has no elements.
238
239         The method returns true if Mat::total() is 0 or if Mat::data is NULL. Because of pop_back() and
240         resize() methods `M.total() == 0` does not imply that `M.data == NULL`.
241          */
242         bool empty() const;
243
244         /** @brief Returns the total number of array elements.
245
246         The method returns the number of array elements (a number of pixels if the array represents an
247         image).
248          */
249         size_t total() const
250         {
251             return static_cast<size_t>(rows * cols);
252         }
253
254
255         /** @overload
256         @param roi Extracted submatrix specified as a rectangle.
257         */
258         Mat operator()( const Rect& roi ) const
259         {
260             return Mat{*this, roi};
261         }
262
263
264         /** @brief Returns a pointer to the specified matrix row.
265
266         The methods return `uchar*` or typed pointer to the specified matrix row. See the sample in
267         Mat::isContinuous to know how to use these methods.
268         @param row Index along the dimension 0
269         @param col Index along the dimension 1
270         */
271         uchar* ptr(int row, int col = 0)
272         {
273             return const_cast<uchar*>(const_cast<const Mat*>(this)->ptr(row,col));
274         }
275         /** @overload */
276         const uchar* ptr(int row, int col = 0) const
277         {
278             return data + step * row + CV_ELEM_SIZE(type()) * col;
279         }
280
281
282     private:
283         //actual memory allocated for storage, or nullptr if object is non owning view to over memory
284         std::shared_ptr<uchar> memory;
285     };
286
287 } //namespace own
288 } //namespace gapi
289 } //namespace cv
290
291 #endif /* OPENCV_GAPI_OWN_MAT_HPP */