14#include <lagrange/image/ImageStorage.h>
17#include <lagrange/utils/warnoff.h>
18#include <tbb/parallel_for.h>
19#include <lagrange/utils/warnon.h>
34 virtual ImagePrecision get_precision()
const = 0;
35 virtual ImageChannel get_channel()
const = 0;
36 virtual bool is_compact_row()
const = 0;
37 virtual bool is_compact()
const = 0;
38 virtual const void* get_data()
const = 0;
39 virtual void* get_data() = 0;
42 Eigen::Matrix<size_t, 2, 1> get_view_size()
const {
return m_view_size; }
43 Eigen::Matrix<size_t, 2, 1> get_view_stride_in_byte()
const {
return m_view_stride_in_byte; }
44 Eigen::Matrix<size_t, 2, 1> get_view_offset_in_byte()
const {
return m_view_offset_in_byte; }
45 std::shared_ptr<ImageStorage> get_storage() {
return m_storage; }
48 Eigen::Matrix<size_t, 2, 1> m_view_size;
49 Eigen::Matrix<size_t, 2, 1> m_view_stride_in_byte;
50 Eigen::Matrix<size_t, 2, 1> m_view_offset_in_byte;
51 std::shared_ptr<ImageStorage> m_storage;
59 ImageView(
size_t width,
size_t height,
size_t alignment);
61 std::shared_ptr<ImageStorage> _storage,
64 const size_t stride_0_in_byte =
sizeof(T),
65 const size_t stride_1_in_row = 1,
66 const size_t offset_0_in_byte = 0,
67 const size_t offset_1_in_row = 0);
78 bool resize(
size_t width,
size_t height,
size_t alignment);
82 std::shared_ptr<ImageStorage> _storage,
85 const size_t stride_0_in_byte =
sizeof(T),
86 const size_t stride_1_in_row = 1,
87 const size_t offset_0_in_byte = 0,
88 const size_t offset_1_in_row = 0);
90 ImageStorage::aligned_vector<unsigned char> pack()
const;
91 bool unpack(
const ImageStorage::aligned_vector<unsigned char>& buf);
93 template <
typename S,
typename CONVERTOR>
94 bool convert_from(
const ImageView<S>& other,
size_t alignment,
const CONVERTOR& convertor);
96 bool convert_from(
const ImageView<S>& other,
size_t alignment);
98 void clear(
const T val);
102 T& operator()(
size_t x,
size_t y);
103 const T& operator()(
size_t x,
size_t y)
const;
108 virtual bool is_compact_row()
const final {
return sizeof(T) == m_view_stride_in_byte(0); }
109 virtual bool is_compact()
const final
111 return sizeof(T) * m_view_size(0) == m_view_stride_in_byte(1);
113 virtual const void* get_data()
const final
115 return reinterpret_cast<const void*
>(&(operator()(0, 0)));
117 virtual void* get_data()
final {
return reinterpret_cast<void*
>(&(operator()(0, 0))); };
126ImageView<T>::ImageView(
size_t width,
size_t height,
size_t alignment)
128 if (!resize(width, height, alignment)) {
129 throw std::runtime_error(
"ImageView::ImageView, cannot resize!");
133ImageView<T>::ImageView(
134 std::shared_ptr<ImageStorage> _storage,
137 size_t stride_0_in_byte,
138 size_t stride_1_in_row,
139 size_t offset_0_in_byte,
140 size_t offset_1_in_row)
150 throw std::runtime_error(
"ImageView::ImageView, cannot construct from ImageStorage!");
154ImageView<T>::ImageView(
const ImageView<T>& other)
159ImageView<T>::ImageView(ImageView<T>&& other)
165ImageView<T>& ImageView<T>::operator=(
const ImageView<T>& other)
167 m_view_size = other.m_view_size;
168 m_view_stride_in_byte = other.m_view_stride_in_byte;
169 m_view_offset_in_byte = other.m_view_offset_in_byte;
170 m_storage = other.m_storage;
174ImageView<T>& ImageView<T>::operator=(ImageView<T>&& other)
176 m_view_size = other.m_view_size;
177 m_view_stride_in_byte = other.m_view_stride_in_byte;
178 m_view_offset_in_byte = other.m_view_offset_in_byte;
179 m_storage = std::move(other.m_storage);
184void ImageView<T>::reset()
187 m_view_size.setZero();
188 m_view_stride_in_byte.setZero();
189 m_view_offset_in_byte.setZero();
192bool ImageView<T>::resize(
size_t width,
size_t height,
size_t alignment)
194 if (0 == width || 0 == height) {
198 m_storage = std::make_shared<ImageStorage>(width *
sizeof(T), height, alignment);
199 m_view_size = {width, height};
200 m_view_stride_in_byte(0) =
sizeof(T);
201 m_view_stride_in_byte(1) = m_storage->get_full_stride();
202 m_view_offset_in_byte.setZero();
208bool ImageView<T>::view(
209 std::shared_ptr<ImageStorage> _storage,
212 size_t stride_0_in_byte,
213 size_t stride_1_in_row,
214 size_t offset_0_in_byte,
215 size_t offset_1_in_row)
217 if (_storage && 0 < width && 0 < height) {
218 auto full_size = _storage->get_full_size();
219 auto full_stride = _storage->get_full_stride();
220 if (
sizeof(T) <= stride_0_in_byte &&
221 offset_0_in_byte + stride_0_in_byte * width <= full_size(0) && 0 < stride_1_in_row &&
222 offset_1_in_row + stride_1_in_row * height <= full_size(1)) {
223 m_storage = _storage;
224 m_view_size = {width, height};
225 m_view_stride_in_byte = {stride_0_in_byte, stride_1_in_row * full_stride};
226 m_view_offset_in_byte = {offset_0_in_byte, offset_1_in_row * full_stride};
235ImageStorage::aligned_vector<unsigned char> ImageView<T>::pack()
const
237 ImageStorage::aligned_vector<unsigned char> buf(
sizeof(T) * m_view_size(0) * m_view_size(1));
240 reinterpret_cast<const unsigned char*
>(&(
operator()(0, 0))),
243 }
else if (
sizeof(T) == m_view_stride_in_byte(0)) {
244 auto src =
reinterpret_cast<const unsigned char*
>(&(operator()(0, 0)));
245 auto dst = buf.data();
246 auto dst_stride_in_byte_row =
sizeof(T) * m_view_size(0);
247 for (
size_t row = 0; row < m_view_size(1); ++row) {
248 std::copy_n(src, dst_stride_in_byte_row, dst);
249 src += m_view_stride_in_byte(1);
250 dst += dst_stride_in_byte_row;
253 auto src_row =
reinterpret_cast<const unsigned char*
>(&(operator()(0, 0)));
254 auto dst_row = buf.data();
255 auto dst_stride_in_byte_col =
sizeof(T);
256 auto dst_stride_in_byte_row =
sizeof(T) * m_view_size(0);
257 for (
size_t row = 0; row < m_view_size(1); ++row) {
258 auto src_pix = src_row;
259 auto dst_pix = dst_row;
260 for (
size_t col = 0; col < m_view_size(0); ++col) {
261 *
reinterpret_cast<T*
>(dst_pix) = *
reinterpret_cast<const T*
>(src_pix);
262 src_pix += m_view_stride_in_byte(0);
263 dst_pix += dst_stride_in_byte_col;
265 src_row += m_view_stride_in_byte(1);
266 dst_row += dst_stride_in_byte_row;
272bool ImageView<T>::unpack(
const ImageStorage::aligned_vector<unsigned char>& buf)
274 if (
sizeof(T) * m_view_size(0) * m_view_size(1) != buf.size()) {
279 std::copy_n(buf.data(), buf.size(),
reinterpret_cast<unsigned char*
>(&(
operator()(0, 0))));
280 }
else if (
sizeof(T) == m_view_stride_in_byte(0)) {
281 auto dst =
reinterpret_cast<unsigned char*
>(&(operator()(0, 0)));
282 auto src = buf.data();
283 auto src_stride_in_byte_row =
sizeof(T) * m_view_size(0);
284 for (
size_t row = 0; row < m_view_size(1); ++row) {
285 std::copy_n(src, src_stride_in_byte_row, dst);
286 dst += m_view_stride_in_byte(1);
287 src += src_stride_in_byte_row;
290 auto dst_row =
reinterpret_cast<unsigned char*
>(&(operator()(0, 0)));
291 auto src_row = buf.data();
292 auto src_stride_in_byte_col =
sizeof(T);
293 auto src_stride_in_byte_row =
sizeof(T) * m_view_size(0);
294 for (
size_t row = 0; row < m_view_size(1); ++row) {
295 auto dst_pix = dst_row;
296 auto src_pix = src_row;
297 for (
size_t col = 0; col < m_view_size(0); ++col) {
298 *
reinterpret_cast<T*
>(dst_pix) = *
reinterpret_cast<const T*
>(src_pix);
299 dst_pix += m_view_stride_in_byte(0);
300 src_pix += src_stride_in_byte_col;
302 dst_row += m_view_stride_in_byte(1);
303 src_row += src_stride_in_byte_row;
310template <
typename S,
typename CONVERTOR>
311bool ImageView<T>::convert_from(
312 const ImageView<S>& other,
314 const CONVERTOR& convertor)
316 const auto other_view_size = other.get_view_size();
317 if (!resize(other_view_size(0), other_view_size(1), alignment)) {
321 const char* src =
reinterpret_cast<const char*
>(&(other(0, 0)));
322 char* dst =
reinterpret_cast<char*
>(&(operator()(0, 0)));
323 const auto other_view_stride_in_byte = other.get_view_stride_in_byte();
324 tbb::parallel_for(
static_cast<size_t>(0), other_view_size(1), [&](
size_t y) {
325 const char* src_row = src + other_view_stride_in_byte(1) * y;
326 char* dst_row = dst + m_view_stride_in_byte(1) * y;
327 for (
size_t x = 0; x < other_view_size(0); ++x) {
329 reinterpret_cast<const S*
>(src_row + other_view_stride_in_byte(0) * x);
330 T* dst_pix =
reinterpret_cast<T*
>(dst_row + m_view_stride_in_byte(0) * x);
331 convertor(*src_pix, *dst_pix);
339bool ImageView<T>::convert_from(
const ImageView<S>& other,
size_t alignment)
341 return convert_from(other, alignment, convert_image_pixel<S, T>());
345void ImageView<T>::clear(
const T val)
347 tbb::parallel_for(
static_cast<size_t>(0), m_view_size(1), [&](
size_t h) {
348 auto* ptr =
reinterpret_cast<unsigned char*
>(&((*this)(0, h)));
349 for (
size_t w = 0; w < m_view_size(0); ++w) {
350 auto* p =
reinterpret_cast<T*
>(ptr + w * m_view_stride_in_byte(0));
357T& ImageView<T>::operator()(
size_t x,
size_t y)
359 auto total_offset = m_view_offset_in_byte(0) + m_view_offset_in_byte(1) +
360 m_view_stride_in_byte(0) * x + m_view_stride_in_byte(1) * y;
361 return *
reinterpret_cast<T*
>(m_storage->data() + total_offset);
364const T& ImageView<T>::operator()(
size_t x,
size_t y)
const
366 auto total_offset = m_view_offset_in_byte(0) + m_view_offset_in_byte(1) +
367 m_view_stride_in_byte(0) * x + m_view_stride_in_byte(1) * y;
368 return *
reinterpret_cast<T*
>(m_storage->data() + total_offset);
Definition: ImageView.h:28
Definition: ImageView.h:56
Main namespace for Lagrange.
Definition: AABBIGL.h:30
Definition: ImageType.h:58