image_view_factory.hppGo to the documentation of this file.00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 00004 Use, modification and distribution are subject to the Boost Software License, 00005 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 00006 http://www.boost.org/LICENSE_1_0.txt). 00007 00008 See http://opensource.adobe.com/gil for most recent version including documentation. 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 // interleaved_view_get_raw_data, planar_view_get_raw_data - return pointers to the raw data (the channels) of a basic homogeneous view. 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 } // namespace detail 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 > // const_reference to the source pixel and destination pixel value 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; // color-converter 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 // Add color converter upon dereferencing 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 // If the Src view has the same pixel type as the target, there is no need for color conversion 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 } // namespace detail 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)//why does it have to be mutable??? 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 // nth_channel_view when the channels are not adjacent in memory. This can happen for multi-channel interleaved images 00296 // or images with a step 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 // nth_channel_view when the channels are together in memory (true for simple grayscale or planar images) 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 // For basic (memory-based) views dispatch to __nth_channel_view_basic 00323 template <typename View> struct __nth_channel_view<View,true> { 00324 private: 00325 typedef typename View::x_iterator src_x_iterator; 00326 00327 // Determines whether the channels of a given pixel iterator are adjacent in memory. 00328 // Planar and grayscale iterators have channels adjacent in memory, whereas multi-channel interleaved and iterators with non-fundamental step do not. 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> // SrcP is a reference to PixelConcept (could be pixel value or const/non-const reference) 00346 // Examples: pixel<T,L>, pixel<T,L>&, const pixel<T,L>&, planar_pixel_reference<T&,L>, planar_pixel_reference<const T&,L> 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; // the channel to use 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 } // namespace detail 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 // kth_channel_view when the channels are not adjacent in memory. This can happen for multi-channel interleaved images 00421 // or images with a step 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 // kth_channel_view when the channels are together in memory (true for simple grayscale or planar images) 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 // For basic (memory-based) views dispatch to __kth_channel_view_basic 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 // Determines whether the channels of a given pixel iterator are adjacent in memory. 00459 // Planar and grayscale iterators have channels adjacent in memory, whereas multi-channel interleaved and iterators with non-fundamental step do not. 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> // SrcP is a reference to PixelConcept (could be pixel value or const/non-const reference) 00477 // Examples: pixel<T,L>, pixel<T,L>&, const pixel<T,L>&, planar_pixel_reference<T&,L>, planar_pixel_reference<const T&,L> 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 } // namespace detail 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 } } // namespace boost::gil 00536 00537 #endif Generated on Sat May 2 13:50:14 2009 for Generic Image Library by 1.5.6 |