Warning, file /include/boost/gil/image_view_factory.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GIL_IMAGE_VIEW_FACTORY_HPP
0009 #define BOOST_GIL_IMAGE_VIEW_FACTORY_HPP
0010
0011 #include <boost/gil/color_convert.hpp>
0012 #include <boost/gil/dynamic_step.hpp>
0013 #include <boost/gil/gray.hpp>
0014 #include <boost/gil/image_view.hpp>
0015 #include <boost/gil/metafunctions.hpp>
0016 #include <boost/gil/point.hpp>
0017 #include <boost/gil/detail/mp11.hpp>
0018
0019 #include <boost/assert.hpp>
0020
0021 #include <cstddef>
0022 #include <type_traits>
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 namespace boost { namespace gil {
0037
0038 struct default_color_converter;
0039
0040 template <typename T> struct transposed_type;
0041
0042
0043
0044 template <typename View>
0045 struct dynamic_xy_step_type
0046 : dynamic_y_step_type<typename dynamic_x_step_type<View>::type> {};
0047
0048
0049
0050 template <typename View>
0051 struct dynamic_xy_step_transposed_type
0052 : dynamic_xy_step_type<typename transposed_type<View>::type> {};
0053
0054
0055
0056 template <typename Iterator>
0057 auto interleaved_view(
0058 std::size_t width, std::size_t height,
0059 Iterator pixels, std::ptrdiff_t rowsize_in_bytes)
0060 -> typename type_from_x_iterator<Iterator>::view_t
0061 {
0062 using RView = typename type_from_x_iterator<Iterator>::view_t;
0063 return RView(width, height, typename RView::locator(pixels, rowsize_in_bytes));
0064 }
0065
0066
0067
0068 template <typename Iterator>
0069 auto interleaved_view(
0070 point<std::ptrdiff_t> dim, Iterator pixels,
0071 std::ptrdiff_t rowsize_in_bytes)
0072 -> typename type_from_x_iterator<Iterator>::view_t
0073 {
0074 using RView = typename type_from_x_iterator<Iterator>::view_t;
0075 return RView(dim, typename RView::locator(pixels, rowsize_in_bytes));
0076 }
0077
0078
0079
0080
0081
0082 namespace detail {
0083 template <typename View, bool IsMutable>
0084 struct channel_pointer_type_impl;
0085
0086 template <typename View>
0087 struct channel_pointer_type_impl<View, true>
0088 {
0089 using type = typename channel_type<View>::type*;
0090 };
0091
0092 template <typename View>
0093 struct channel_pointer_type_impl<View, false>
0094 {
0095 using type = const typename channel_type<View>::type*;
0096 };
0097
0098 template <typename View>
0099 struct channel_pointer_type
0100 : public channel_pointer_type_impl<View, view_is_mutable<View>::value> {};
0101 }
0102
0103
0104
0105 template <typename HomogeneousView>
0106 auto interleaved_view_get_raw_data(HomogeneousView const& view)
0107 -> typename detail::channel_pointer_type<HomogeneousView>::type
0108 {
0109 static_assert(!is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value, "");
0110 static_assert(std::is_pointer<typename HomogeneousView::x_iterator>::value, "");
0111
0112 return &gil::at_c<0>(view(0,0));
0113 }
0114
0115
0116
0117 template <typename HomogeneousView>
0118 auto planar_view_get_raw_data(HomogeneousView const& view, int plane_index)
0119 -> typename detail::channel_pointer_type<HomogeneousView>::type
0120 {
0121 static_assert(is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value, "");
0122 return dynamic_at_c(view.row_begin(0),plane_index);
0123 }
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 template <typename SrcConstRefP, typename DstP, typename CC=default_color_converter >
0135 class color_convert_deref_fn : public deref_base<color_convert_deref_fn<SrcConstRefP,DstP,CC>, DstP, DstP, const DstP&, SrcConstRefP, DstP, false> {
0136 private:
0137 CC _cc;
0138 public:
0139 color_convert_deref_fn() {}
0140 color_convert_deref_fn(CC cc_in) : _cc(cc_in) {}
0141
0142 DstP operator()(SrcConstRefP srcP) const {
0143 DstP dstP;
0144 _cc(srcP,dstP);
0145 return dstP;
0146 }
0147 };
0148
0149 namespace detail {
0150
0151 template <typename SrcView, typename CC, typename DstP, typename SrcP>
0152 struct _color_converted_view_type {
0153 private:
0154 using deref_t = color_convert_deref_fn<typename SrcView::const_t::reference,DstP,CC>;
0155 using add_ref_t = typename SrcView::template add_deref<deref_t>;
0156 public:
0157 using type = typename add_ref_t::type;
0158 static type make(const SrcView& sv,CC cc) {return add_ref_t::make(sv,deref_t(cc));}
0159 };
0160
0161
0162 template <typename SrcView, typename CC, typename DstP>
0163 struct _color_converted_view_type<SrcView,CC,DstP,DstP> {
0164 using type = SrcView;
0165 static type make(const SrcView& sv,CC) {return sv;}
0166 };
0167 }
0168
0169
0170
0171
0172 template <typename SrcView, typename DstP, typename CC=default_color_converter>
0173 struct color_converted_view_type : public detail::_color_converted_view_type<SrcView,
0174 CC,
0175 DstP,
0176 typename SrcView::value_type> {
0177 BOOST_GIL_CLASS_REQUIRE(DstP, boost::gil, MutablePixelConcept)
0178 };
0179
0180
0181
0182
0183 template <typename DstP, typename View, typename CC>
0184 inline auto color_converted_view(View const& src,CC cc)
0185 -> typename color_converted_view_type<View,DstP,CC>::type
0186 {
0187 return color_converted_view_type<View,DstP,CC>::make(src,cc);
0188 }
0189
0190
0191
0192 template <typename DstP, typename View>
0193 inline auto color_converted_view(View const& src)
0194 -> typename color_converted_view_type<View,DstP>::type
0195 {
0196 return color_converted_view<DstP>(src,default_color_converter());
0197 }
0198
0199
0200
0201
0202
0203
0204 template <typename View>
0205 inline auto flipped_up_down_view(View const& src)
0206 -> typename dynamic_y_step_type<View>::type
0207 {
0208 using RView = typename dynamic_y_step_type<View>::type;
0209 return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1));
0210 }
0211
0212
0213
0214
0215
0216
0217 template <typename View>
0218 inline auto flipped_left_right_view(View const& src)
0219 -> typename dynamic_x_step_type<View>::type
0220 {
0221 using RView = typename dynamic_x_step_type<View>::type;
0222 return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,0),-1,1));
0223 }
0224
0225
0226
0227
0228
0229
0230 template <typename View>
0231 inline auto transposed_view(View const& src)
0232 -> typename dynamic_xy_step_transposed_type<View>::type
0233 {
0234 using RView = typename dynamic_xy_step_transposed_type<View>::type;
0235 return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,0),1,1,true));
0236 }
0237
0238
0239
0240
0241
0242
0243 template <typename View>
0244 inline auto rotated90cw_view(View const& src)
0245 -> typename dynamic_xy_step_transposed_type<View>::type
0246 {
0247 using RView = typename dynamic_xy_step_transposed_type<View>::type;
0248 return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1,1,true));
0249 }
0250
0251
0252
0253
0254
0255
0256 template <typename View>
0257 inline auto rotated90ccw_view(View const& src)
0258 -> typename dynamic_xy_step_transposed_type<View>::type
0259 {
0260 using RView = typename dynamic_xy_step_transposed_type<View>::type;
0261 return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(src.width()-1,0),1,-1,true));
0262 }
0263
0264
0265
0266
0267
0268
0269 template <typename View>
0270 inline auto rotated180_view(View const& src)
0271 -> typename dynamic_xy_step_type<View>::type
0272 {
0273 using RView = typename dynamic_xy_step_type<View>::type;
0274 return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,src.height()-1),-1,-1));
0275 }
0276
0277
0278
0279
0280
0281
0282 template <typename View>
0283 inline View subimage_view(
0284 View const& src,
0285 typename View::point_t const& topleft,
0286 typename View::point_t const& dimensions)
0287 {
0288 return View(dimensions, src.xy_at(topleft));
0289 }
0290
0291
0292 template <typename View>
0293 inline View subimage_view(View const& src,
0294 typename View::coord_t x_min,
0295 typename View::coord_t y_min,
0296 typename View::coord_t width,
0297 typename View::coord_t height)
0298 {
0299 return View(width, height, src.xy_at(x_min, y_min));
0300 }
0301
0302
0303
0304
0305
0306
0307 template <typename View>
0308 inline
0309 auto subsampled_view(View const& src, typename View::coord_t x_step, typename View::coord_t y_step)
0310 -> typename dynamic_xy_step_type<View>::type
0311 {
0312 BOOST_ASSERT(x_step > 0 && y_step > 0);
0313 using view_t =typename dynamic_xy_step_type<View>::type;
0314 return view_t(
0315 (src.width() + (x_step - 1)) / x_step,
0316 (src.height() + (y_step - 1)) / y_step,
0317 typename view_t::xy_locator(src.xy_at(0,0), x_step, y_step));
0318 }
0319
0320
0321 template <typename View>
0322 inline auto subsampled_view(View const& src, typename View::point_t const& step)
0323 -> typename dynamic_xy_step_type<View>::type
0324 {
0325 return subsampled_view(src, step.x, step.y);
0326 }
0327
0328
0329
0330
0331
0332 namespace detail {
0333 template <typename View, bool AreChannelsTogether> struct __nth_channel_view_basic;
0334
0335
0336
0337 template <typename View>
0338 struct __nth_channel_view_basic<View,false> {
0339 using type = typename view_type<typename channel_type<View>::type, gray_layout_t, false, true, view_is_mutable<View>::value>::type;
0340
0341 static type make(View const& src, int n) {
0342 using locator_t = typename type::xy_locator;
0343 using x_iterator_t = typename type::x_iterator;
0344 using x_iterator_base_t = typename iterator_adaptor_get_base<x_iterator_t>::type;
0345 x_iterator_t sit(x_iterator_base_t(&(src(0,0)[n])),src.pixels().pixel_size());
0346 return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
0347 }
0348 };
0349
0350
0351 template <typename View>
0352 struct __nth_channel_view_basic<View,true> {
0353 using type = typename view_type<typename channel_type<View>::type, gray_layout_t, false, false, view_is_mutable<View>::value>::type;
0354 static type make(View const& src, int n) {
0355 using x_iterator_t = typename type::x_iterator;
0356 return interleaved_view(src.width(),src.height(),(x_iterator_t)&(src(0,0)[n]), src.pixels().row_size());
0357 }
0358 };
0359
0360 template <typename View, bool IsBasic> struct __nth_channel_view;
0361
0362
0363 template <typename View>
0364 struct __nth_channel_view<View,true>
0365 {
0366 private:
0367 using src_x_iterator = typename View::x_iterator;
0368
0369
0370
0371 static constexpr bool adjacent =
0372 !iterator_is_step<src_x_iterator>::value &&
0373 (is_planar<src_x_iterator>::value || num_channels<View>::value == 1);
0374
0375 public:
0376 using type = typename __nth_channel_view_basic<View,adjacent>::type;
0377
0378 static type make(View const& src, int n) {
0379 return __nth_channel_view_basic<View,adjacent>::make(src,n);
0380 }
0381 };
0382
0383
0384
0385
0386
0387 template <typename SrcP>
0388
0389 struct nth_channel_deref_fn
0390 {
0391 static constexpr bool is_mutable =
0392 pixel_is_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value;
0393 private:
0394 using src_pixel_t = typename std::remove_reference<SrcP>::type;
0395 using channel_t = typename channel_type<src_pixel_t>::type;
0396 using const_ref_t = typename src_pixel_t::const_reference;
0397 using ref_t = typename pixel_reference_type<channel_t,gray_layout_t,false,is_mutable>::type;
0398 public:
0399 using const_t = nth_channel_deref_fn<const_ref_t>;
0400 using value_type = typename pixel_value_type<channel_t,gray_layout_t>::type;
0401 using const_reference = typename pixel_reference_type<channel_t,gray_layout_t,false,false>::type;
0402 using argument_type = SrcP;
0403 using reference = mp11::mp_if_c<is_mutable, ref_t, value_type>;
0404 using result_type = reference;
0405
0406 nth_channel_deref_fn(int n=0) : _n(n) {}
0407 template <typename P>
0408 nth_channel_deref_fn(const nth_channel_deref_fn<P>& d) : _n(d._n) {}
0409
0410 int _n;
0411
0412 auto operator()(argument_type srcP) const -> result_type
0413 {
0414 return result_type(srcP[_n]);
0415 }
0416 };
0417
0418 template <typename View> struct __nth_channel_view<View,false> {
0419 private:
0420 using deref_t = nth_channel_deref_fn<typename View::reference>;
0421 using AD = typename View::template add_deref<deref_t>;
0422 public:
0423 using type = typename AD::type;
0424 static type make(View const& src, int n) {
0425 return AD::make(src, deref_t(n));
0426 }
0427 };
0428 }
0429
0430
0431
0432
0433
0434
0435
0436 template <typename View>
0437 struct nth_channel_view_type {
0438 private:
0439 BOOST_GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept)
0440 using VB = detail::__nth_channel_view<View,view_is_basic<View>::value>;
0441 public:
0442 using type = typename VB::type;
0443 static type make(View const& src, int n) { return VB::make(src,n); }
0444 };
0445
0446
0447 template <typename View>
0448 typename nth_channel_view_type<View>::type nth_channel_view(View const& src, int n) {
0449 return nth_channel_view_type<View>::make(src,n);
0450 }
0451
0452
0453
0454
0455
0456 namespace detail {
0457 template <int K, typename View, bool AreChannelsTogether> struct __kth_channel_view_basic;
0458
0459
0460
0461 template <int K, typename View>
0462 struct __kth_channel_view_basic<K,View,false> {
0463 private:
0464 using channel_t = typename kth_element_type<typename View::value_type,K>::type;
0465 public:
0466 using type = typename view_type<channel_t, gray_layout_t, false, true, view_is_mutable<View>::value>::type;
0467
0468 static type make(View const& src) {
0469 using locator_t = typename type::xy_locator;
0470 using x_iterator_t = typename type::x_iterator;
0471 using x_iterator_base_t = typename iterator_adaptor_get_base<x_iterator_t>::type;
0472 x_iterator_t sit(x_iterator_base_t(&gil::at_c<K>(src(0,0))),src.pixels().pixel_size());
0473 return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
0474 }
0475 };
0476
0477
0478 template <int K, typename View>
0479 struct __kth_channel_view_basic<K,View,true> {
0480 private:
0481 using channel_t = typename kth_element_type<typename View::value_type, K>::type;
0482 public:
0483 using type = typename view_type<channel_t, gray_layout_t, false, false, view_is_mutable<View>::value>::type;
0484 static type make(View const& src) {
0485 using x_iterator_t = typename type::x_iterator;
0486 return interleaved_view(src.width(),src.height(),(x_iterator_t)&gil::at_c<K>(src(0,0)), src.pixels().row_size());
0487 }
0488 };
0489
0490 template <int K, typename View, bool IsBasic> struct __kth_channel_view;
0491
0492
0493 template <int K, typename View> struct __kth_channel_view<K,View,true>
0494 {
0495 private:
0496 using src_x_iterator = typename View::x_iterator;
0497
0498
0499
0500 static constexpr bool adjacent =
0501 !iterator_is_step<src_x_iterator>::value &&
0502 (is_planar<src_x_iterator>::value || num_channels<View>::value == 1);
0503
0504 public:
0505 using type = typename __kth_channel_view_basic<K,View,adjacent>::type;
0506
0507 static type make(View const& src) {
0508 return __kth_channel_view_basic<K,View,adjacent>::make(src);
0509 }
0510 };
0511
0512
0513
0514
0515
0516
0517
0518 template <int K, typename SrcP>
0519 struct kth_channel_deref_fn
0520 {
0521 static constexpr bool is_mutable =
0522 pixel_is_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value;
0523
0524 private:
0525 using src_pixel_t = typename std::remove_reference<SrcP>::type;
0526 using channel_t = typename kth_element_type<src_pixel_t, K>::type;
0527 using const_ref_t = typename src_pixel_t::const_reference;
0528 using ref_t = typename pixel_reference_type<channel_t,gray_layout_t,false,is_mutable>::type;
0529
0530 public:
0531 using const_t = kth_channel_deref_fn<K,const_ref_t>;
0532 using value_type = typename pixel_value_type<channel_t,gray_layout_t>::type;
0533 using const_reference = typename pixel_reference_type<channel_t,gray_layout_t,false,false>::type;
0534 using argument_type = SrcP;
0535 using reference = mp11::mp_if_c<is_mutable, ref_t, value_type>;
0536 using result_type = reference;
0537
0538 kth_channel_deref_fn() {}
0539 template <typename P>
0540 kth_channel_deref_fn(const kth_channel_deref_fn<K,P>&) {}
0541
0542 result_type operator()(argument_type srcP) const {
0543 return result_type(gil::at_c<K>(srcP));
0544 }
0545 };
0546
0547 template <int K, typename View> struct __kth_channel_view<K,View,false> {
0548 private:
0549 using deref_t = kth_channel_deref_fn<K,typename View::reference>;
0550 using AD = typename View::template add_deref<deref_t>;
0551 public:
0552 using type = typename AD::type;
0553 static type make(View const& src) {
0554 return AD::make(src, deref_t());
0555 }
0556 };
0557 }
0558
0559
0560
0561
0562
0563
0564
0565 template <int K, typename View>
0566 struct kth_channel_view_type {
0567 private:
0568 BOOST_GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept)
0569 using VB = detail::__kth_channel_view<K,View,view_is_basic<View>::value>;
0570 public:
0571 using type = typename VB::type;
0572 static type make(View const& src) { return VB::make(src); }
0573 };
0574
0575
0576 template <int K, typename View>
0577 auto kth_channel_view(View const& src)
0578 -> typename kth_channel_view_type<K,View>::type
0579 {
0580 return kth_channel_view_type<K,View>::make(src);
0581 }
0582
0583 } }
0584
0585 #endif