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 namespace mindspore { 24 namespace dataset { 25 26 #define ALIGN 16 27 #define MAX_DIMS 3 28 29 template <typename T> 30 struct Chn1 { Chn1Chn131 Chn1(T c1) : c1(c1) {} 32 T c1; 33 }; 34 35 template <typename T> 36 struct Chn2 { Chn2Chn237 Chn2(T c1, T c2) : c1(c1), c2(c2) {} 38 T c1; 39 T c2; 40 }; 41 42 template <typename T> 43 struct Chn3 { Chn3Chn344 Chn3(T c1, T c2, T c3) : c1(c1), c2(c2), c3(c3) {} 45 T c1; 46 T c2; 47 T c3; 48 }; 49 50 template <typename T> 51 struct Chn4 { Chn4Chn452 Chn4(T c1, T c2, T c3, T c4) : c1(c1), c2(c2), c3(c3), c4(c4) {} 53 T c1; 54 T c2; 55 T c3; 56 T c4; 57 }; 58 59 struct Point { 60 float x; 61 float y; PointPoint62 Point() : x(0), y(0) {} PointPoint63 Point(float _x, float _y) : x(_x), y(_y) {} 64 }; 65 66 typedef struct imageToolsImage { 67 int w; 68 int h; 69 int stride; 70 int dataType; 71 void *image_buff; 72 } imageToolsImage_t; 73 74 using BOOL_C1 = Chn1<bool>; 75 using BOOL_C2 = Chn2<bool>; 76 using BOOL_C3 = Chn3<bool>; 77 using BOOL_C4 = Chn4<bool>; 78 79 using UINT8_C1 = Chn1<uint8_t>; 80 using UINT8_C2 = Chn2<uint8_t>; 81 using UINT8_C3 = Chn3<uint8_t>; 82 using UINT8_C4 = Chn4<uint8_t>; 83 84 using INT8_C1 = Chn1<int8_t>; 85 using INT8_C2 = Chn2<int8_t>; 86 using INT8_C3 = Chn3<int8_t>; 87 using INT8_C4 = Chn4<int8_t>; 88 89 using UINT16_C1 = Chn1<uint16_t>; 90 using UINT16_C2 = Chn2<uint16_t>; 91 using UINT16_C3 = Chn3<uint16_t>; 92 using UINT16_C4 = Chn4<uint16_t>; 93 94 using INT16_C1 = Chn1<int16_t>; 95 using INT16_C2 = Chn2<int16_t>; 96 using INT16_C3 = Chn3<int16_t>; 97 using INT16_C4 = Chn4<int16_t>; 98 99 using UINT32_C1 = Chn1<uint32_t>; 100 using UINT32_C2 = Chn2<uint32_t>; 101 using UINT32_C3 = Chn3<uint32_t>; 102 using UINT32_C4 = Chn4<uint32_t>; 103 104 using INT32_C1 = Chn1<int32_t>; 105 using INT32_C2 = Chn2<int32_t>; 106 using INT32_C3 = Chn3<int32_t>; 107 using INT32_C4 = Chn4<int32_t>; 108 109 using UINT64_C1 = Chn1<uint64_t>; 110 using UINT64_C2 = Chn2<uint64_t>; 111 using UINT64_C3 = Chn3<uint64_t>; 112 using UINT64_C4 = Chn4<uint64_t>; 113 114 using INT64_C1 = Chn1<int64_t>; 115 using INT64_C2 = Chn2<int64_t>; 116 using INT64_C3 = Chn3<int64_t>; 117 using INT64_C4 = Chn4<int64_t>; 118 119 using FLOAT32_C1 = Chn1<float>; 120 using FLOAT32_C2 = Chn2<float>; 121 using FLOAT32_C3 = Chn3<float>; 122 using FLOAT32_C4 = Chn4<float>; 123 124 using FLOAT64_C1 = Chn1<double>; 125 using FLOAT64_C2 = Chn2<double>; 126 using FLOAT64_C3 = Chn3<double>; 127 using FLOAT64_C4 = Chn4<double>; 128 129 enum LPixelType { 130 BGR = 0, /**< Pixel in BGR type. */ 131 RGB = 1, /**< Pixel in RGB type. */ 132 RGBA = 2, /**< Pixel in RGBA type. */ 133 RGBA2GRAY = 3, /**< Convert image from RGBA to GRAY. */ 134 RGBA2BGR = 4, /**< Convert image from RGBA to BGR. */ 135 RGBA2RGB = 5, /**< Convert image from RGBA to RGB. */ 136 NV212BGR = 6, /**< Convert image from NV21 to BGR. */ 137 NV122BGR = 7, /**< Convert image from NV12 to BGR. */ 138 }; 139 140 enum WARP_BORDER_MODE { WARP_BORDER_MODE_CONSTANT }; 141 142 class LDataType { 143 public: 144 enum Type : uint8_t { 145 UNKNOWN = 0, /**< Unknown data type. */ 146 BOOL, /**< BOOL data type. */ 147 INT8, /**< INT8 data type. */ 148 UINT8, /**< UINT8 data type. */ 149 INT16, /**< INT16 data type. */ 150 UINT16, /**< UINT16 data type. */ 151 INT32, /**< INT32 data type. */ 152 UINT32, /**< UINT32 data type. */ 153 INT64, /**< INT64 data type. */ 154 UINT64, /**< UINT64 data type. */ 155 FLOAT16, /**< FLOAT16 data type. */ 156 FLOAT32, /**< FLOAT32 data type. */ 157 FLOAT64, /**< FLOAT64 data type. */ 158 DOUBLE, /**< DOUBLE data type. */ 159 NUM_OF_TYPES /**< number of types. */ 160 }; 161 LDataType()162 LDataType() : type_(UNKNOWN) {} 163 LDataType(Type d)164 LDataType(Type d) : type_(d) {} 165 166 ~LDataType() = default; 167 Value()168 inline Type Value() const { return type_; } 169 inline bool operator==(const LDataType &ps) const { return this->type_ == ps.type_; } 170 171 inline bool operator!=(const LDataType &ps) const { return this->type_ != ps.type_; } 172 SizeInBytes()173 uint8_t SizeInBytes() const { 174 if (type_ < LDataType::NUM_OF_TYPES) 175 return SIZE_IN_BYTES[type_]; 176 else 177 return 0; 178 } 179 180 public: 181 static inline const uint8_t SIZE_IN_BYTES[] = { 182 0, /**< Unknown size. */ 183 1, /**< Size of BOOL. */ 184 1, /**< Size of INT8. */ 185 1, /**< Size of UINT8. */ 186 2, /**< Size of INT16. */ 187 2, /**< Size of UINT16. */ 188 4, /**< Size of INT32. */ 189 4, /**< Size of UINT32. */ 190 8, /**< Size of INT64. */ 191 8, /**< Size of UINT64. */ 192 2, /**< Size of FLOAT16. */ 193 4, /**< Size of FLOAT32. */ 194 8, /**< Size of FLOAT64. */ 195 8, /**< Size of DOUBLE. */ 196 }; 197 198 Type type_; 199 }; 200 201 class LiteMat { 202 // Class that represents a lite Mat of a Image. 203 public: 204 /// \brief Constructor 205 LiteMat(); 206 207 /// \brief Function to create an LiteMat object. 208 /// \param[in] width The width of the input object. 209 /// \param[in] data_type The data type of the input object. 210 explicit LiteMat(int width, LDataType data_type = LDataType::UINT8); 211 212 /// \brief Function to create an LiteMat object. 213 /// \param[in] width The width of the input object. 214 /// \param[in] height The height of the input object. 215 /// \param[in] data_type The data type of the input object. 216 LiteMat(int width, int height, LDataType data_type = LDataType::UINT8); 217 218 /// \brief Function to create an LiteMat object. 219 /// \param[in] width The width of the input object. 220 /// \param[in] height The height of the input object. 221 /// \param[in] p_data The pointer data of the input object. 222 /// \param[in] data_type The data type of the input object. 223 LiteMat(int width, int height, void *p_data, LDataType data_type = LDataType::UINT8); 224 225 /// \brief Function to create an LiteMat object. 226 /// \param[in] width The width of the input object. 227 /// \param[in] height The height of the input object. 228 /// \param[in] channel The channel of the input object. 229 /// \param[in] data_type The data type of the input object. 230 LiteMat(int width, int height, int channel, LDataType data_type = LDataType::UINT8); 231 232 /// \brief Function to create an LiteMat object. 233 /// \param[in] width The width of the input object. 234 /// \param[in] height The height of the input object. 235 /// \param[in] channel The channel of the input object. 236 /// \param[in] p_data The pointer data of the input object. 237 /// \param[in] data_type The data type of the input object. 238 LiteMat(int width, int height, int channel, void *p_data, LDataType data_type = LDataType::UINT8); 239 240 /// \brief Destructor of LiteMat. 241 ~LiteMat(); 242 243 LiteMat(const LiteMat &m); 244 245 /// \brief Perform Init operation on given LiteMat 246 /// \param[in] width Set width for given LiteMat. 247 /// \param[in] data_type Set data type for given LiteMat. 248 void Init(int width, LDataType data_type = LDataType::UINT8); 249 250 /// \brief Perform Init operation on given LiteMat 251 /// \param[in] width Set width for given LiteMat. 252 /// \param[in] height Set height for given LiteMat. 253 /// \param[in] data_type Set data type for given LiteMat. 254 void Init(int width, int height, LDataType data_type = LDataType::UINT8); 255 256 /// \brief Perform Init operation on given LiteMat 257 /// \param[in] width Set width for given LiteMat. 258 /// \param[in] height Set height for given LiteMat. 259 /// \param[in] p_data Set pointer data for given LiteMat. 260 /// \param[in] data_type Set data type for given LiteMat. 261 void Init(int width, int height, void *p_data, LDataType data_type = LDataType::UINT8); 262 263 /// \brief Perform Init operation on given LiteMat 264 /// \param[in] width Set width for given LiteMat. 265 /// \param[in] height Set height for given LiteMat. 266 /// \param[in] channel Set channel for given LiteMat. 267 /// \param[in] data_type Set data type for given LiteMat. 268 /// \param[in] align_memory Whether malloc align memory or not, default is true, 269 /// which is better for doing acceleration. 270 void Init(int width, int height, int channel, const LDataType &data_type = LDataType::UINT8, 271 bool align_memory = true); 272 273 /// \brief Perform Init operation on given LiteMat 274 /// \param[in] width Set width for given LiteMat. 275 /// \param[in] height Set height for given LiteMat. 276 /// \param[in] channel Set channel for given LiteMat. 277 /// \param[in] p_data Set pointer data for given LiteMat. 278 /// \param[in] data_type Set data type for given LiteMat. 279 void Init(int width, int height, int channel, void *p_data, LDataType data_type = LDataType::UINT8); 280 281 bool GetROI(int x, int y, int w, int h, LiteMat &dst); // NOLINT 282 283 bool IsEmpty() const; 284 285 void Release(); 286 287 LiteMat &operator=(const LiteMat &m); 288 289 template <typename T> 290 operator T *() { 291 return reinterpret_cast<T *>(data_ptr_); 292 } 293 294 template <typename T> 295 operator const T *() const { 296 return reinterpret_cast<const T *>(data_ptr_); 297 } 298 299 template <typename T> ptr(int w)300 inline T *ptr(int w) const { 301 if (w >= height_) { 302 return nullptr; 303 } 304 if (IsEmpty()) { 305 return nullptr; 306 } 307 return reinterpret_cast<T *>(reinterpret_cast<unsigned char *>(data_ptr_) + steps_[0] * w); 308 } 309 310 private: 311 /// \brief Apply for memory alignment 312 /// \param[in] size The size of the requested memory alignment. 313 void *AlignMalloc(unsigned int size); 314 315 /// \brief Free memory 316 /// \param[in] ptr Pointer to free memory. 317 void AlignFree(void *ptr); 318 319 /// \brief Initialize the element size of different types of data. 320 /// \param[in] data_type Type of data. 321 void InitElemSize(LDataType data_type); 322 323 /// \brief Add value of reference count. 324 /// \param[in] p The point of references count. 325 /// \param[in] value The value of new added references. 326 /// \return return reference count. 327 int addRef(int *p, int value); 328 329 /// \brief Set the step size of the pixels in the Litemat array. 330 /// \param[in] c0 The number used to set teh value of step[0]. 331 /// \param[in] c1 The number used to set teh value of step[1]. 332 /// \param[in] c2 The number used to set teh value of step[2]. 333 void setSteps(int c0, int c1, int c2); 334 335 bool CheckLiteMat(); 336 337 public: 338 void *data_ptr_ = nullptr; 339 int elem_size_; 340 int width_; 341 int height_; 342 int channel_; 343 int c_step_; 344 int dims_; 345 size_t size_; 346 LDataType data_type_; 347 int *ref_count_; 348 size_t steps_[MAX_DIMS]; 349 bool release_flag; 350 }; 351 352 /// \brief Calculates the difference between the two images for each element 353 bool Subtract(const LiteMat &src_a, const LiteMat &src_b, LiteMat *dst); 354 355 /// \brief Calculates the division between the two images for each element 356 bool Divide(const LiteMat &src_a, const LiteMat &src_b, LiteMat *dst); 357 358 /// \brief Calculates the multiply between the two images for each element 359 bool Multiply(const LiteMat &src_a, const LiteMat &src_b, LiteMat *dst); 360 361 #define RETURN_FALSE_IF_LITEMAT_EMPTY(_m) \ 362 do { \ 363 if ((_m).IsEmpty()) { \ 364 return false; \ 365 } \ 366 } while (false) 367 368 #define RETURN_IF_LITEMAT_EMPTY(_m) \ 369 do { \ 370 if ((_m).IsEmpty()) { \ 371 return; \ 372 } \ 373 } while (false) 374 375 } // namespace dataset 376 } // namespace mindspore 377 #endif // MINI_MAT_H_ 378