File indexing completed on 2026-05-10 08:42:08
0001 #pragma once
0002
0003 #include "../bits/H5Inspector_decl.hpp"
0004 #include "../H5Exception.hpp"
0005
0006 #include <opencv2/opencv.hpp>
0007
0008 #include "../bits/convert_size_vector.hpp"
0009
0010 namespace HighFive {
0011 namespace details {
0012
0013
0014 template <class T>
0015 struct inspector<cv::Mat_<T>> {
0016 using type = cv::Mat_<T>;
0017 using value_type = T;
0018 using base_type = typename inspector<value_type>::base_type;
0019 using hdf5_type = base_type;
0020
0021 static void assert_row_major(const type& type) {
0022
0023
0024 int rank = type.dims;
0025 size_t ld = sizeof(T);
0026 for (int i = rank - 1; i >= 0; --i) {
0027 if (static_cast<size_t>(type.step[i]) != ld) {
0028 throw DataSetException("Padded cv::Mat_ are not supported.");
0029 }
0030
0031 ld *= static_cast<size_t>(type.size[i]);
0032 }
0033 }
0034
0035
0036 static constexpr size_t min_ndim = 2 + inspector<value_type>::min_ndim;
0037 static constexpr size_t max_ndim = 1024 + inspector<value_type>::max_ndim;
0038
0039
0040
0041
0042 static constexpr bool is_trivially_copyable = std::is_trivially_copyable<value_type>::value &&
0043 inspector<value_type>::is_trivially_nestable;
0044 static constexpr bool is_trivially_nestable = false;
0045
0046 static size_t getRank(const type& val) {
0047 if (val.empty()) {
0048 return min_ndim;
0049
0050 } else {
0051 return static_cast<size_t>(val.dims) +
0052 inspector<value_type>::getRank(getAnyElement(val));
0053 }
0054 }
0055
0056 static const T& getAnyElement(const type& val) {
0057 return *reinterpret_cast<T const*>(val.data);
0058 }
0059
0060 static T& getAnyElement(type& val) {
0061 return *reinterpret_cast<T*>(val.data);
0062 }
0063
0064 static size_t getLocalRank(const type& val) {
0065 return static_cast<size_t>(val.dims);
0066 }
0067
0068 static std::vector<size_t> getDimensions(const type& val) {
0069 auto local_rank = getLocalRank(val);
0070 auto rank = getRank(val);
0071 std::vector<size_t> dims(rank, 1ul);
0072
0073 if (val.empty()) {
0074 dims[0] = 0ul;
0075 dims[1] = 1ul;
0076 return dims;
0077 }
0078
0079 for (size_t i = 0; i < local_rank; ++i) {
0080 dims[i] = static_cast<size_t>(val.size[static_cast<int>(i)]);
0081 }
0082
0083 auto s = inspector<value_type>::getDimensions(getAnyElement(val));
0084 std::copy(s.cbegin(), s.cend(), dims.begin() + static_cast<int>(local_rank));
0085 return dims;
0086 }
0087
0088 static void prepare(type& val, const std::vector<size_t>& dims) {
0089 auto subdims = detail::convertSizeVector<int>(dims);
0090 val.create(static_cast<int>(subdims.size()), subdims.data());
0091 }
0092
0093 static hdf5_type* data(type& val) {
0094 assert_row_major(val);
0095
0096 if (!is_trivially_copyable) {
0097 throw DataSetException("Invalid used of `inspector<Eigen::Matrix<...>>::data`.");
0098 }
0099
0100 if (val.empty()) {
0101 return nullptr;
0102 }
0103
0104 return inspector<value_type>::data(getAnyElement(val));
0105 }
0106
0107 static const hdf5_type* data(const type& val) {
0108 assert_row_major(val);
0109
0110 if (!is_trivially_copyable) {
0111 throw DataSetException("Invalid used of `inspector<Eigen::Matrix<...>>::data`.");
0112 }
0113
0114 if (val.empty()) {
0115 return nullptr;
0116 }
0117
0118 return inspector<value_type>::data(getAnyElement(val));
0119 }
0120
0121 static void serialize(const type& val, const std::vector<size_t>& dims, hdf5_type* m) {
0122 if (val.empty()) {
0123 return;
0124 }
0125
0126 auto local_rank = val.dims;
0127 auto subdims = std::vector<size_t>(dims.begin() + local_rank, dims.end());
0128 auto subsize = compute_total_size(subdims);
0129 for (auto it = val.begin(); it != val.end(); ++it) {
0130 inspector<value_type>::serialize(*it, subdims, m);
0131 m += subsize;
0132 }
0133 }
0134
0135 static void unserialize(const hdf5_type* vec_align,
0136 const std::vector<size_t>& dims,
0137 type& val) {
0138 auto local_rank = val.dims;
0139 auto subdims = std::vector<size_t>(dims.begin() + local_rank, dims.end());
0140 auto subsize = compute_total_size(subdims);
0141 for (auto it = val.begin(); it != val.end(); ++it) {
0142 inspector<value_type>::unserialize(vec_align, subdims, *it);
0143 vec_align += subsize;
0144 }
0145 }
0146 };
0147
0148 }
0149 }