00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef GIL_IMAGE_VIEW_FACTORY_HPP
00014 #define GIL_IMAGE_VIEW_FACTORY_HPP
00015
00025
00027 #include <cassert>
00028 #include <cstddef>
00029 #include "gil_config.hpp"
00030 #include "metafunctions.hpp"
00031 #include "gray.hpp"
00032 #include "color_convert.hpp"
00033
00037
00041
00042 namespace boost { namespace gil {
00043 struct default_color_converter;
00044
00045 template <typename T> struct dynamic_x_step_type;
00046 template <typename T> struct dynamic_y_step_type;
00047 template <typename T> struct transposed_type;
00048
00051 template <typename View>
00052 struct dynamic_xy_step_type : public dynamic_y_step_type<typename dynamic_x_step_type<View>::type> {};
00053
00056 template <typename View>
00057 struct dynamic_xy_step_transposed_type : public dynamic_xy_step_type<typename transposed_type<View>::type> {};
00058
00059
00062 template <typename Iterator>
00063 typename type_from_x_iterator<Iterator>::view_t
00064 interleaved_view(std::size_t width, std::size_t height,
00065 Iterator pixels, std::ptrdiff_t rowsize_in_bytes) {
00066 typedef typename type_from_x_iterator<Iterator>::view_t RView;
00067 return RView(width, height, typename RView::locator(pixels, rowsize_in_bytes));
00068 }
00069
00072 template <typename Iterator>
00073 typename type_from_x_iterator<Iterator>::view_t
00074 interleaved_view(point2<std::size_t> dim,
00075 Iterator pixels, std::ptrdiff_t rowsize_in_bytes) {
00076 typedef typename type_from_x_iterator<Iterator>::view_t RView;
00077 return RView(dim, typename RView::locator(pixels, rowsize_in_bytes));
00078 }
00079
00081
00083
00084 namespace detail {
00085 template <typename View, bool IsMutable> struct channel_pointer_type_impl;
00086
00087 template <typename View> struct channel_pointer_type_impl<View, true> {
00088 typedef typename channel_type<View>::type* type;
00089 };
00090 template <typename View> struct channel_pointer_type_impl<View, false> {
00091 typedef const typename channel_type<View>::type* type;
00092 };
00093
00094 template <typename View> struct channel_pointer_type
00095 : public channel_pointer_type_impl<View, view_is_mutable<View>::value> {};
00096 };
00097
00100 template <typename HomogeneousView>
00101 typename detail::channel_pointer_type<HomogeneousView>::type interleaved_view_get_raw_data(const HomogeneousView& view) {
00102 BOOST_STATIC_ASSERT((!is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value));
00103 BOOST_STATIC_ASSERT((boost::is_pointer<typename HomogeneousView::x_iterator>::value));
00104
00105 return &at_c<0>(view(0,0));
00106 }
00107
00110 template <typename HomogeneousView>
00111 typename detail::channel_pointer_type<HomogeneousView>::type planar_view_get_raw_data(const HomogeneousView& view, int plane_index) {
00112 BOOST_STATIC_ASSERT((is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value));
00113 return dynamic_at_c(view.row_begin(0),plane_index);
00114 }
00115
00116
00120
00125 template <typename SrcConstRefP, typename DstP, typename CC=default_color_converter >
00126 class color_convert_deref_fn : public deref_base<color_convert_deref_fn<SrcConstRefP,DstP,CC>, DstP, DstP, const DstP&, SrcConstRefP, DstP, false> {
00127 private:
00128 CC _cc;
00129 public:
00130 color_convert_deref_fn() {}
00131 color_convert_deref_fn(CC cc_in) : _cc(cc_in) {}
00132
00133 DstP operator()(SrcConstRefP srcP) const {
00134 DstP dstP;
00135 _cc(srcP,dstP);
00136 return dstP;
00137 }
00138 };
00139
00140 namespace detail {
00141
00142 template <typename SrcView, typename CC, typename DstP, typename SrcP>
00143 struct _color_converted_view_type {
00144 private:
00145 typedef color_convert_deref_fn<typename SrcView::const_t::reference,DstP,CC> deref_t;
00146 typedef typename SrcView::template add_deref<deref_t> add_ref_t;
00147 public:
00148 typedef typename add_ref_t::type type;
00149 static type make(const SrcView& sv,CC cc) {return add_ref_t::make(sv,deref_t(cc));}
00150 };
00151
00152
00153 template <typename SrcView, typename CC, typename DstP>
00154 struct _color_converted_view_type<SrcView,CC,DstP,DstP> {
00155 typedef SrcView type;
00156 static type make(const SrcView& sv,CC) {return sv;}
00157 };
00158 }
00159
00160
00163 template <typename SrcView, typename DstP, typename CC=default_color_converter>
00164 struct color_converted_view_type : public detail::_color_converted_view_type<SrcView,
00165 CC,
00166 DstP,
00167 typename SrcView::value_type> {
00168 GIL_CLASS_REQUIRE(DstP, boost::gil, MutablePixelConcept)
00169 };
00170
00171
00174 template <typename DstP, typename View, typename CC>
00175 inline typename color_converted_view_type<View,DstP,CC>::type color_converted_view(const View& src,CC cc) {
00176 return color_converted_view_type<View,DstP,CC>::make(src,cc);
00177 }
00178
00181 template <typename DstP, typename View>
00182 inline typename color_converted_view_type<View,DstP>::type
00183 color_converted_view(const View& src) {
00184 return color_converted_view<DstP>(src,default_color_converter());
00185 }
00186
00190
00192 template <typename View>
00193 inline typename dynamic_y_step_type<View>::type flipped_up_down_view(const View& src) {
00194 typedef typename dynamic_y_step_type<View>::type RView;
00195 return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1));
00196 }
00197
00201
00203 template <typename View>
00204 inline typename dynamic_x_step_type<View>::type flipped_left_right_view(const View& src) {
00205 typedef typename dynamic_x_step_type<View>::type RView;
00206 return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,0),-1,1));
00207 }
00208
00212
00214 template <typename View>
00215 inline typename dynamic_xy_step_transposed_type<View>::type transposed_view(const View& src) {
00216 typedef typename dynamic_xy_step_transposed_type<View>::type RView;
00217 return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,0),1,1,true));
00218 }
00219
00223
00225 template <typename View>
00226 inline typename dynamic_xy_step_transposed_type<View>::type rotated90cw_view(const View& src) {
00227 typedef typename dynamic_xy_step_transposed_type<View>::type RView;
00228 return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1,1,true));
00229 }
00230
00234
00236 template <typename View>
00237 inline typename dynamic_xy_step_transposed_type<View>::type rotated90ccw_view(const View& src) {
00238 typedef typename dynamic_xy_step_transposed_type<View>::type RView;
00239 return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(src.width()-1,0),1,-1,true));
00240 }
00241
00245
00247 template <typename View>
00248 inline typename dynamic_xy_step_type<View>::type rotated180_view(const View& src) {
00249 typedef typename dynamic_xy_step_type<View>::type RView;
00250 return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,src.height()-1),-1,-1));
00251 }
00252
00256
00258 template <typename View>
00259 inline View subimage_view(const View& src, const typename View::point_t& topleft, const typename View::point_t& dimensions) {
00260 return View(dimensions,src.xy_at(topleft));
00261 }
00262
00264 template <typename View>
00265 inline View subimage_view(const View& src, int xMin, int yMin, int width, int height) {
00266 return View(width,height,src.xy_at(xMin,yMin));
00267 }
00268
00272
00274 template <typename View>
00275 inline typename dynamic_xy_step_type<View>::type subsampled_view(const View& src, typename View::coord_t xStep, typename View::coord_t yStep) {
00276 assert(xStep>0 && yStep>0);
00277 typedef typename dynamic_xy_step_type<View>::type RView;
00278 return RView((src.width()+(xStep-1))/xStep,(src.height()+(yStep-1))/yStep,
00279 typename RView::xy_locator(src.xy_at(0,0),xStep,yStep));
00280 }
00281
00283 template <typename View>
00284 inline typename dynamic_xy_step_type<View>::type subsampled_view(const View& src, const typename View::point_t& step) {
00285 return subsampled_view(src,step.x,step.y);
00286 }
00287
00291
00292 namespace detail {
00293 template <typename View, bool AreChannelsTogether> struct __nth_channel_view_basic;
00294
00295
00296
00297 template <typename View>
00298 struct __nth_channel_view_basic<View,false> {
00299 typedef typename view_type<typename channel_type<View>::type, gray_layout_t, false, true, view_is_mutable<View>::value>::type type;
00300
00301 static type make(const View& src, int n) {
00302 typedef typename type::xy_locator locator_t;
00303 typedef typename type::x_iterator x_iterator_t;
00304 typedef typename iterator_adaptor_get_base<x_iterator_t>::type x_iterator_base_t;
00305 x_iterator_t sit(x_iterator_base_t(&(src(0,0)[n])),src.pixels().pixel_size());
00306 return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
00307 }
00308 };
00309
00310
00311 template <typename View>
00312 struct __nth_channel_view_basic<View,true> {
00313 typedef typename view_type<typename channel_type<View>::type, gray_layout_t, false, false, view_is_mutable<View>::value>::type type;
00314 static type make(const View& src, int n) {
00315 typedef typename type::x_iterator x_iterator_t;
00316 return interleaved_view(src.width(),src.height(),(x_iterator_t)&(src(0,0)[n]), src.pixels().row_size());
00317 }
00318 };
00319
00320 template <typename View, bool IsBasic> struct __nth_channel_view;
00321
00322
00323 template <typename View> struct __nth_channel_view<View,true> {
00324 private:
00325 typedef typename View::x_iterator src_x_iterator;
00326
00327
00328
00329 BOOST_STATIC_CONSTANT(bool, adjacent=
00330 !iterator_is_step<src_x_iterator>::value &&
00331 (is_planar<src_x_iterator>::value ||
00332 num_channels<View>::value==1));
00333 public:
00334 typedef typename __nth_channel_view_basic<View,adjacent>::type type;
00335
00336 static type make(const View& src, int n) {
00337 return __nth_channel_view_basic<View,adjacent>::make(src,n);
00338 }
00339 };
00340
00345 template <typename SrcP>
00346
00347 struct nth_channel_deref_fn {
00348 BOOST_STATIC_CONSTANT(bool, is_mutable=pixel_is_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value);
00349 private:
00350 typedef typename remove_reference<SrcP>::type src_pixel_t;
00351 typedef typename channel_type<src_pixel_t>::type channel_t;
00352 typedef typename src_pixel_t::const_reference const_ref_t;
00353 typedef typename pixel_reference_type<channel_t,gray_layout_t,false,is_mutable>::type ref_t;
00354 public:
00355 typedef nth_channel_deref_fn<const_ref_t> const_t;
00356 typedef typename pixel_value_type<channel_t,gray_layout_t>::type value_type;
00357 typedef typename pixel_reference_type<channel_t,gray_layout_t,false,false>::type const_reference;
00358 typedef SrcP argument_type;
00359 typedef typename mpl::if_c<is_mutable, ref_t, value_type>::type reference;
00360 typedef reference result_type;
00361
00362 nth_channel_deref_fn(int n=0) : _n(n) {}
00363 template <typename P> nth_channel_deref_fn(const nth_channel_deref_fn<P>& d) : _n(d._n) {}
00364
00365 int _n;
00366
00367 result_type operator()(argument_type srcP) const {
00368 return result_type(srcP[_n]);
00369 }
00370 };
00371
00372 template <typename View> struct __nth_channel_view<View,false> {
00373 private:
00374 typedef nth_channel_deref_fn<typename View::reference> deref_t;
00375 typedef typename View::template add_deref<deref_t> AD;
00376 public:
00377 typedef typename AD::type type;
00378 static type make(const View& src, int n) {
00379 return AD::make(src, deref_t(n));
00380 }
00381 };
00382 }
00383
00390 template <typename View>
00391 struct nth_channel_view_type {
00392 private:
00393 GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept)
00394 typedef detail::__nth_channel_view<View,view_is_basic<View>::value> VB;
00395 public:
00396 typedef typename VB::type type;
00397 static type make(const View& src, int n) { return VB::make(src,n); }
00398 };
00399
00400
00402 template <typename View>
00403 typename nth_channel_view_type<View>::type nth_channel_view(const View& src, int n) {
00404 return nth_channel_view_type<View>::make(src,n);
00405 }
00406
00407
00408
00409
00410
00411
00412
00416
00417 namespace detail {
00418 template <int K, typename View, bool AreChannelsTogether> struct __kth_channel_view_basic;
00419
00420
00421
00422 template <int K, typename View>
00423 struct __kth_channel_view_basic<K,View,false> {
00424 private:
00425 typedef typename kth_element_type<typename View::value_type,K>::type channel_t;
00426 public:
00427 typedef typename view_type<channel_t, gray_layout_t, false, true, view_is_mutable<View>::value>::type type;
00428
00429 static type make(const View& src) {
00430 typedef typename type::xy_locator locator_t;
00431 typedef typename type::x_iterator x_iterator_t;
00432 typedef typename iterator_adaptor_get_base<x_iterator_t>::type x_iterator_base_t;
00433 x_iterator_t sit(x_iterator_base_t(&at_c<K>(src(0,0))),src.pixels().pixel_size());
00434 return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
00435 }
00436 };
00437
00438
00439 template <int K, typename View>
00440 struct __kth_channel_view_basic<K,View,true> {
00441 private:
00442 typedef typename kth_element_type<typename View::value_type, K>::type channel_t;
00443 public:
00444 typedef typename view_type<channel_t, gray_layout_t, false, false, view_is_mutable<View>::value>::type type;
00445 static type make(const View& src) {
00446 typedef typename type::x_iterator x_iterator_t;
00447 return interleaved_view(src.width(),src.height(),(x_iterator_t)&at_c<K>(src(0,0)), src.pixels().row_size());
00448 }
00449 };
00450
00451 template <int K, typename View, bool IsBasic> struct __kth_channel_view;
00452
00453
00454 template <int K, typename View> struct __kth_channel_view<K,View,true> {
00455 private:
00456 typedef typename View::x_iterator src_x_iterator;
00457
00458
00459
00460 BOOST_STATIC_CONSTANT(bool, adjacent=
00461 !iterator_is_step<src_x_iterator>::value &&
00462 (is_planar<src_x_iterator>::value ||
00463 num_channels<View>::value==1));
00464 public:
00465 typedef typename __kth_channel_view_basic<K,View,adjacent>::type type;
00466
00467 static type make(const View& src) {
00468 return __kth_channel_view_basic<K,View,adjacent>::make(src);
00469 }
00470 };
00471
00476 template <int K, typename SrcP>
00477
00478 struct kth_channel_deref_fn {
00479 BOOST_STATIC_CONSTANT(bool, is_mutable=pixel_is_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value);
00480 private:
00481 typedef typename remove_reference<SrcP>::type src_pixel_t;
00482 typedef typename kth_element_type<src_pixel_t, K>::type channel_t;
00483 typedef typename src_pixel_t::const_reference const_ref_t;
00484 typedef typename pixel_reference_type<channel_t,gray_layout_t,false,is_mutable>::type ref_t;
00485 public:
00486 typedef kth_channel_deref_fn<K,const_ref_t> const_t;
00487 typedef typename pixel_value_type<channel_t,gray_layout_t>::type value_type;
00488 typedef typename pixel_reference_type<channel_t,gray_layout_t,false,false>::type const_reference;
00489 typedef SrcP argument_type;
00490 typedef typename mpl::if_c<is_mutable, ref_t, value_type>::type reference;
00491 typedef reference result_type;
00492
00493 kth_channel_deref_fn() {}
00494 template <typename P> kth_channel_deref_fn(const kth_channel_deref_fn<K,P>&) {}
00495
00496 result_type operator()(argument_type srcP) const {
00497 return result_type(at_c<K>(srcP));
00498 }
00499 };
00500
00501 template <int K, typename View> struct __kth_channel_view<K,View,false> {
00502 private:
00503 typedef kth_channel_deref_fn<K,typename View::reference> deref_t;
00504 typedef typename View::template add_deref<deref_t> AD;
00505 public:
00506 typedef typename AD::type type;
00507 static type make(const View& src) {
00508 return AD::make(src, deref_t());
00509 }
00510 };
00511 }
00512
00519 template <int K, typename View>
00520 struct kth_channel_view_type {
00521 private:
00522 GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept)
00523 typedef detail::__kth_channel_view<K,View,view_is_basic<View>::value> VB;
00524 public:
00525 typedef typename VB::type type;
00526 static type make(const View& src) { return VB::make(src); }
00527 };
00528
00530 template <int K, typename View>
00531 typename kth_channel_view_type<K,View>::type kth_channel_view(const View& src) {
00532 return kth_channel_view_type<K,View>::make(src);
00533 }
00534
00535 } }
00536
00537 #endif