• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2020 Huawei Technologies Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MINI_MAT_H_
18 #define MINI_MAT_H_
19 
20 #include <string>
21 #include <memory>
22 
23 #include "include/api/types.h"
24 
25 namespace mindspore {
26 namespace dataset {
27 constexpr int kAlign = 16;
28 constexpr size_t kMaxDims = 3;
29 
30 template <typename T>
31 struct Chn1 {
Chn1Chn132   Chn1(T c1) : c1(c1) {}
33   T c1;
34 };
35 
36 template <typename T>
37 struct Chn2 {
Chn2Chn238   Chn2(T c1, T c2) : c1(c1), c2(c2) {}
39   T c1;
40   T c2;
41 };
42 
43 template <typename T>
44 struct Chn3 {
Chn3Chn345   Chn3(T c1, T c2, T c3) : c1(c1), c2(c2), c3(c3) {}
46   T c1;
47   T c2;
48   T c3;
49 };
50 
51 template <typename T>
52 struct Chn4 {
Chn4Chn453   Chn4(T c1, T c2, T c3, T c4) : c1(c1), c2(c2), c3(c3), c4(c4) {}
54   T c1;
55   T c2;
56   T c3;
57   T c4;
58 };
59 
60 /// \brief Struct representing the location of pixel.
61 /// \note Location usually starts from the left top of image.
62 /// \par Example
63 /// \code
64 ///    // Define a point p points to the pixel at (X=10,Y=5).
65 ///    Point p = Point(10, 5);
66 /// \endcode
67 struct Point {
68   float x;  ///< X location of pixel.
69   float y;  ///< Y location of pixel.
70 
PointPoint71   Point() : x(0), y(0) {}                      ///< Constructor.
PointPoint72   Point(float _x, float _y) : x(_x), y(_y) {}  ///< Constructor.
73 };
74 
75 typedef struct imageToolsImage {
76   int w;
77   int h;
78   int stride;
79   int dataType;
80   void *image_buff;
81 } imageToolsImage_t;
82 
83 using BOOL_C1 = Chn1<bool>;
84 using BOOL_C2 = Chn2<bool>;
85 using BOOL_C3 = Chn3<bool>;
86 using BOOL_C4 = Chn4<bool>;
87 
88 using UINT8_C1 = Chn1<uint8_t>;
89 using UINT8_C2 = Chn2<uint8_t>;
90 using UINT8_C3 = Chn3<uint8_t>;
91 using UINT8_C4 = Chn4<uint8_t>;
92 
93 using INT8_C1 = Chn1<int8_t>;
94 using INT8_C2 = Chn2<int8_t>;
95 using INT8_C3 = Chn3<int8_t>;
96 using INT8_C4 = Chn4<int8_t>;
97 
98 using UINT16_C1 = Chn1<uint16_t>;
99 using UINT16_C2 = Chn2<uint16_t>;
100 using UINT16_C3 = Chn3<uint16_t>;
101 using UINT16_C4 = Chn4<uint16_t>;
102 
103 using INT16_C1 = Chn1<int16_t>;
104 using INT16_C2 = Chn2<int16_t>;
105 using INT16_C3 = Chn3<int16_t>;
106 using INT16_C4 = Chn4<int16_t>;
107 
108 using UINT32_C1 = Chn1<uint32_t>;
109 using UINT32_C2 = Chn2<uint32_t>;
110 using UINT32_C3 = Chn3<uint32_t>;
111 using UINT32_C4 = Chn4<uint32_t>;
112 
113 using INT32_C1 = Chn1<int32_t>;
114 using INT32_C2 = Chn2<int32_t>;
115 using INT32_C3 = Chn3<int32_t>;
116 using INT32_C4 = Chn4<int32_t>;
117 
118 using UINT64_C1 = Chn1<uint64_t>;
119 using UINT64_C2 = Chn2<uint64_t>;
120 using UINT64_C3 = Chn3<uint64_t>;
121 using UINT64_C4 = Chn4<uint64_t>;
122 
123 using INT64_C1 = Chn1<int64_t>;
124 using INT64_C2 = Chn2<int64_t>;
125 using INT64_C3 = Chn3<int64_t>;
126 using INT64_C4 = Chn4<int64_t>;
127 
128 using FLOAT32_C1 = Chn1<float>;
129 using FLOAT32_C2 = Chn2<float>;
130 using FLOAT32_C3 = Chn3<float>;
131 using FLOAT32_C4 = Chn4<float>;
132 
133 using FLOAT64_C1 = Chn1<double>;
134 using FLOAT64_C2 = Chn2<double>;
135 using FLOAT64_C3 = Chn3<double>;
136 using FLOAT64_C4 = Chn4<double>;
137 
138 enum LPixelType {
139   BGR = 0,       /**< Pixel in BGR type. */
140   RGB = 1,       /**< Pixel in RGB type. */
141   RGBA = 2,      /**< Pixel in RGBA type. */
142   RGBA2GRAY = 3, /**< Convert image from RGBA to GRAY. */
143   RGBA2BGR = 4,  /**< Convert image from RGBA to BGR. */
144   RGBA2RGB = 5,  /**< Convert image from RGBA to RGB. */
145   NV212BGR = 6,  /**< Convert image from NV21 to BGR. */
146   NV122BGR = 7,  /**< Convert image from NV12 to BGR. */
147 };
148 
149 enum WARP_BORDER_MODE { WARP_BORDER_MODE_CONSTANT };
150 
151 /// \brief Class representing the data type.
152 /// \note  Supported data type list:
153 ///     - LDataType::BOOL
154 ///     - LDataType::INT8
155 ///     - LDataType::UINT8
156 ///     - LDataType::INT16
157 ///     - LDataType::INT32
158 ///     - LDataType::UINT32
159 ///     - LDataType::INT64
160 ///     - LDataType::UINT64
161 ///     - LDataType::FLOAT16
162 ///     - LDataType::FLOAT32
163 ///     - LDataType::FLOAT64
164 ///     - LDataType::DOUBLE
165 class DATASET_API LDataType {
166  public:
167   enum Type : uint8_t {
168     UNKNOWN = 0, /**< Unknown data type. */
169     BOOL,        /**< BOOL data type. */
170     INT8,        /**< INT8 data type. */
171     UINT8,       /**< UINT8 data type. */
172     INT16,       /**< INT16 data type. */
173     UINT16,      /**< UINT16 data type. */
174     INT32,       /**< INT32 data type. */
175     UINT32,      /**< UINT32 data type. */
176     INT64,       /**< INT64 data type. */
177     UINT64,      /**< UINT64 data type. */
178     FLOAT16,     /**< FLOAT16 data type. */
179     FLOAT32,     /**< FLOAT32 data type. */
180     FLOAT64,     /**< FLOAT64 data type. */
181     DOUBLE,      /**< DOUBLE data type. */
182     NUM_OF_TYPES /**< number of types. */
183   };
184 
185   /// \brief Constructor.
LDataType()186   LDataType() : type_(UNKNOWN) {}
187 
LDataType(Type d)188   LDataType(Type d) : type_(d) {}
189 
190   /// \brief Destructor.
191   ~LDataType() = default;
192 
Value()193   inline Type Value() const { return type_; }
194 
195   inline bool operator==(const LDataType &ps) const { return this->type_ == ps.type_; }
196 
197   inline bool operator!=(const LDataType &ps) const { return this->type_ != ps.type_; }
198 
199   /// \brief Function to return the length of data type.
200   /// \return Memory length of data type.
SizeInBytes()201   uint8_t SizeInBytes() const {
202     if (type_ < LDataType::NUM_OF_TYPES) {
203       return SIZE_IN_BYTES[type_];
204     } else {
205       return 0;
206     }
207   }
208 
209  public:
210   static inline const uint8_t SIZE_IN_BYTES[] = {
211     0, /**< Unknown size. */
212     1, /**< Size of BOOL. */
213     1, /**< Size of INT8. */
214     1, /**< Size of UINT8. */
215     2, /**< Size of INT16. */
216     2, /**< Size of UINT16. */
217     4, /**< Size of INT32. */
218     4, /**< Size of UINT32. */
219     8, /**< Size of INT64. */
220     8, /**< Size of UINT64. */
221     2, /**< Size of FLOAT16. */
222     4, /**< Size of FLOAT32. */
223     8, /**< Size of FLOAT64. */
224     8, /**< Size of DOUBLE. */
225   };
226 
227   Type type_;
228 };
229 
230 /// \brief Basic class storing the image data.
231 class DATASET_API LiteMat {
232  public:
233   /// \brief Constructor.
234   LiteMat();
235 
236   /// \brief Function to create an LiteMat object.
237   /// \param[in] width The width of the input object.
238   /// \param[in] data_type The data type of the input object.
239   explicit LiteMat(int width, LDataType data_type = LDataType::UINT8);
240 
241   /// \brief Function to create an LiteMat object.
242   /// \param[in] width The width of the input object.
243   /// \param[in] height The height of the input object.
244   /// \param[in] data_type The data type of the input object.
245   LiteMat(int width, int height, LDataType data_type = LDataType::UINT8);
246 
247   /// \brief Function to create an LiteMat object.
248   /// \param[in] width The width of the input object.
249   /// \param[in] height The height of the input object.
250   /// \param[in] p_data The pointer data of the input object.
251   /// \param[in] data_type The data type of the input object.
252   LiteMat(int width, int height, void *p_data, LDataType data_type = LDataType::UINT8);
253 
254   /// \brief Function to create an LiteMat object.
255   /// \param[in] width The width of the input object.
256   /// \param[in] height The height of the input object.
257   /// \param[in] channel The channel of the input object.
258   /// \param[in] data_type The data type of the input object.
259   LiteMat(int width, int height, int channel, LDataType data_type = LDataType::UINT8);
260 
261   /// \brief Function to create an LiteMat object.
262   /// \param[in] width The width of the input object.
263   /// \param[in] height The height of the input object.
264   /// \param[in] channel The channel of the input object.
265   /// \param[in] p_data The pointer data of the input object.
266   /// \param[in] data_type The data type of the input object.
267   LiteMat(int width, int height, int channel, void *p_data, LDataType data_type = LDataType::UINT8);
268 
269   /// \brief Destructor.
270   ~LiteMat();
271 
272   LiteMat(const LiteMat &m);
273 
274   /// \brief Perform Init operation on given LiteMat
275   /// \param[in] width Set width for given LiteMat.
276   /// \param[in] data_type Set data type for given LiteMat.
277   void Init(int width, LDataType data_type = LDataType::UINT8);
278 
279   /// \brief Perform Init operation on given LiteMat
280   /// \param[in] width Set width for given LiteMat.
281   /// \param[in] height Set height for given LiteMat.
282   /// \param[in] data_type Set data type for given LiteMat.
283   void Init(int width, int height, LDataType data_type = LDataType::UINT8);
284 
285   /// \brief Perform Init operation on given LiteMat
286   /// \param[in] width Set width for given LiteMat.
287   /// \param[in] height Set height for given LiteMat.
288   /// \param[in] p_data Set pointer data for given LiteMat.
289   /// \param[in] data_type Set data type for given LiteMat.
290   void Init(int width, int height, void *p_data, LDataType data_type = LDataType::UINT8);
291 
292   /// \brief Perform Init operation on given LiteMat
293   /// \param[in] width Set width for given LiteMat.
294   /// \param[in] height Set height for given LiteMat.
295   /// \param[in] channel Set channel for given LiteMat.
296   /// \param[in] data_type Set data type for given LiteMat.
297   /// \param[in] align_memory Whether malloc align memory or not, default is true,
298   ///     which is better for doing acceleration.
299   void Init(int width, int height, int channel, const LDataType &data_type = LDataType::UINT8,
300             bool align_memory = true);
301 
302   /// \brief Perform Init operation on given LiteMat
303   /// \param[in] width Set width for given LiteMat.
304   /// \param[in] height Set height for given LiteMat.
305   /// \param[in] channel Set channel for given LiteMat.
306   /// \param[in] p_data Set pointer data for given LiteMat.
307   /// \param[in] data_type Set data type for given LiteMat.
308   void Init(int width, int height, int channel, void *p_data, LDataType data_type = LDataType::UINT8);
309 
310   bool GetROI(int x, int y, int w, int h, LiteMat &dst);  // NOLINT
311 
312   bool IsEmpty() const;
313 
314   void Release();
315 
316   LiteMat &operator=(const LiteMat &m);
317 
318   template <typename T>
319   operator T *() {
320     return reinterpret_cast<T *>(data_ptr_);
321   }
322 
323   template <typename T>
324   operator const T *() const {
325     return reinterpret_cast<const T *>(data_ptr_);
326   }
327 
328   template <typename T>
ptr(int w)329   inline T *ptr(int w) const {
330     if (w >= height_) {
331       return nullptr;
332     }
333     if (IsEmpty()) {
334       return nullptr;
335     }
336     return reinterpret_cast<T *>(reinterpret_cast<unsigned char *>(data_ptr_) + steps_[0] * w);
337   }
338 
339  private:
340   /// \brief Apply for memory alignment
341   /// \param[in] size The size of the requested memory alignment.
342   void *AlignMalloc(unsigned int size);
343 
344   /// \brief Free memory
345   /// \param[in] ptr Pointer to free memory.
346   void AlignFree(void *ptr);
347 
348   /// \brief Initialize the element size of different types of data.
349   /// \param[in] data_type Type of data.
350   void InitElemSize(LDataType data_type);
351 
352   /// \brief Add value of reference count.
353   /// \param[in] p The point of references count.
354   /// \param[in] value The value of new added references.
355   /// \return return reference count.
356   static int addRef(int *p, int value);
357 
358   /// \brief Set the step size of the pixels in the Litemat array.
359   /// \param[in] c0 The number used to set teh value of step[0].
360   /// \param[in] c1 The number used to set teh value of step[1].
361   /// \param[in] c2 The number used to set teh value of step[2].
362   void setSteps(size_t c0, size_t c1, size_t c2);
363 
364   bool CheckLiteMat() const;
365 
366  public:
367   void *data_ptr_ = nullptr;
368   int elem_size_;
369   int width_;
370   int height_;
371   int channel_;
372   int c_step_;
373   int dims_;
374   size_t size_;
375   LDataType data_type_;
376   int *ref_count_;
377   size_t steps_[kMaxDims]{};
378   bool release_flag_;
379 };
380 
381 /// \brief Given image A and image B and calculate the difference of them (A - B).
382 ///      This is an element by element operation by subtracting corresponding elements of inputs.
383 /// \param[in] src_a Input image data.
384 /// \param[in] src_b Input image data.
385 /// \param[in] dst The difference of input images.
386 /// \par Example
387 /// \code
388 ///     std::vector<uint8_t> mat1 = {3, 3, 3, 3};
389 ///     LiteMat lite_mat_src;
390 ///     lite_mat_src.Init(2, 2, 1, mat1.data(), LDataType::UINT8);
391 ///
392 ///     std::vector<uint8_t> mat2 = {2, 2, 2, 2};
393 ///     LiteMat lite_mat_src2;
394 ///     lite_mat_src2.Init(2, 2, 1, mat2.data(), LDataType::UINT8);
395 ///
396 ///     /* Calculate the difference of images */
397 ///     LiteMat diff;
398 ///     Subtract(lite_mat_src, lite_mat_src2, &diff);
399 ///     for (int i = 0; i < diff.height_; i++) {
400 ///       for (int j = 0; j < diff.width_; j++) {
401 ///         std::cout << std::to_string(diff.ptr<uint8_t>(i)[j]) << ", ";
402 ///       }
403 ///       std::cout << std::endl;
404 ///     }
405 /// \endcode
406 /// \return Return true if transform successfully.
407 bool DATASET_API Subtract(const LiteMat &src_a, const LiteMat &src_b, LiteMat *dst);
408 
409 /// \brief Given image A and image B and calculate the division of them (A / B).
410 ///      This is an element by element operation.
411 /// \param[in] src_a Input image data.
412 /// \param[in] src_b Input image data.
413 /// \param[in] dst The division of input images.
414 /// \par Example
415 /// \code
416 ///     std::vector<uint8_t> mat1 = {8, 8, 8, 8};
417 ///     LiteMat lite_mat_src;
418 ///     lite_mat_src.Init(2, 2, 1, mat1.data(), LDataType::UINT8);
419 ///
420 ///     std::vector<uint8_t> mat2 = {2, 2, 2, 2};
421 ///     LiteMat lite_mat_src2;
422 ///     lite_mat_src2.Init(2, 2, 1, mat2.data(), LDataType::UINT8);
423 ///
424 ///     /* Calculate the division of images */
425 ///     LiteMat div;
426 ///     Divide(lite_mat_src, lite_mat_src2, &div);
427 ///     for (int i = 0; i < div.height_; i++) {
428 ///       for (int j = 0; j < div.width_; j++) {
429 ///         std::cout << std::to_string(div.ptr<uint8_t>(i)[j]) << ", ";
430 ///       }
431 ///       std::cout << std::endl;
432 ///     }
433 /// \endcode
434 /// \return Return true if transform successfully.
435 bool DATASET_API Divide(const LiteMat &src_a, const LiteMat &src_b, LiteMat *dst);
436 
437 /// \brief Given image A and image B and calculate the product of them (A * B).
438 ///      This is an element by element operation by multiplying corresponding elements of inputs.
439 /// \param[in] src_a Input image data.
440 /// \param[in] src_b Input image data.
441 /// \param[in] dst The product of input images.
442 /// \par Example
443 /// \code
444 ///     std::vector<uint8_t> mat1 = {4, 4, 4, 4};
445 ///     LiteMat lite_mat_src;
446 ///     lite_mat_src.Init(2, 2, 1, mat1.data(), LDataType::UINT8);
447 ///
448 ///     std::vector<uint8_t> mat2 = {2, 2, 2, 2};
449 ///     LiteMat lite_mat_src2;
450 ///     lite_mat_src2.Init(2, 2, 1, mat2.data(), LDataType::UINT8);
451 ///
452 ///     /* Calculate the product of images */
453 ///     LiteMat mut;
454 ///     Multiply(lite_mat_src, lite_mat_src2, &mut);
455 ///     for (int i = 0; i < mut.height_; i++) {
456 ///       for (int j = 0; j < mut.width_; j++) {
457 ///         std::cout << std::to_string(mut.ptr<uint8_t>(i)[j]) << ", ";
458 ///       }
459 ///       std::cout << std::endl;
460 ///     }
461 /// \endcode
462 /// \return Return true if transform successfully.
463 bool DATASET_API Multiply(const LiteMat &src_a, const LiteMat &src_b, LiteMat *dst);
464 
465 #define RETURN_FALSE_IF_LITEMAT_EMPTY(_m) \
466   do {                                    \
467     if ((_m).IsEmpty()) {                 \
468       return false;                       \
469     }                                     \
470   } while (false)
471 
472 #define RETURN_IF_LITEMAT_EMPTY(_m) \
473   do {                              \
474     if ((_m).IsEmpty()) {           \
475       return;                       \
476     }                               \
477   } while (false)
478 
479 }  // namespace dataset
480 }  // namespace mindspore
481 #endif  // MINI_MAT_H_
482