core/image_view_factory.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2006 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://opensource.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef GIL_IMAGE_VIEW_FACTORY_HPP
00010 #define GIL_IMAGE_VIEW_FACTORY_HPP
00011 
00021 
00023 #include <cassert>
00024 #include <cstddef>
00025 #include "gil_config.hpp"
00026 #include "metafunctions.hpp"
00027 #include "gray.hpp"
00028 
00029 ADOBE_GIL_NAMESPACE_BEGIN
00030 struct default_color_converter;
00031 
00035 
00037 
00039 template <typename Iterator>
00040 inline typename type_from_x_iterator<Iterator>::view_t interleaved_view(int width, int height, Iterator pixels, std::ptrdiff_t rowsize_in_bytes) {
00041     typedef typename type_from_x_iterator<Iterator>::view_t RVIEW;
00042     return RVIEW(width, height, typename RVIEW::locator(pixels, rowsize_in_bytes));
00043 }
00044 
00046 
00048 
00049 
00053 template <typename SrcConstRefP, typename DstP, typename CC=default_color_converter >        // const_reference to the source pixel and destination pixel value
00054 class color_convert_deref_fn {
00055 private:
00056     CC _cc;                     // color-converter
00057 public:
00058     typedef color_convert_deref_fn const_t;
00059     typedef DstP                   value_type;
00060     typedef value_type             reference;      // read-only dereferencing
00061     typedef const value_type&      const_reference;
00062     typedef SrcConstRefP           argument_type;
00063     typedef reference              result_type;
00064     BOOST_STATIC_CONSTANT(bool,    is_mutable=false);
00065 
00066     color_convert_deref_fn() {}
00067     color_convert_deref_fn(CC cc_in) : _cc(cc_in) {}
00068 
00069     result_type operator()(argument_type srcP) const {
00070         result_type dstP;
00071         _cc(srcP,dstP);
00072         return dstP;
00073     }
00074 };
00075 
00076 namespace detail {
00077     // Add color converter upon dereferencing
00078     template <typename SrcView, typename CC, typename DstP, typename SrcP>
00079     struct _color_converted_view_type {
00080     private:
00081         typedef color_convert_deref_fn<typename SrcView::const_t::reference,DstP,CC> deref_t;
00082         typedef typename SrcView::template add_deref<deref_t> add_ref_t;
00083     public:
00084         typedef typename add_ref_t::type type;
00085         static type make(const SrcView& sv,CC cc) {return add_ref_t::make(sv,deref_t(cc));}
00086     };
00087 
00088     // If the Src view has the same pixel type as the target, there is no need for color conversion
00089     template <typename SrcView, typename CC, typename DstP>
00090     struct _color_converted_view_type<SrcView,CC,DstP,DstP> {
00091         typedef SrcView type;
00092         static type make(const SrcView& sv,CC) {return sv;}
00093     };
00094 } // namespace detail
00095 
00099 
00102 template <typename SrcView, typename DstP, typename CC=default_color_converter>
00103 struct color_converted_view_type : public detail::_color_converted_view_type<SrcView,
00104                                                                              CC,
00105                                                                              DstP,
00106                                                                              typename SrcView::pixel_t> {
00107     GIL_CLASS_REQUIRE(SrcView, GIL, ImageViewConcept);
00108     GIL_CLASS_REQUIRE(DstP, GIL, MutablePixelConcept);//why does it have to MutablePixelConcept???
00109 };
00110 
00111 
00113 
00115 template <typename DstP, typename View, typename CC>
00116 inline typename color_converted_view_type<View,DstP,CC>::type color_converted_view(const View& src,CC cc) {
00117     return color_converted_view_type<View,DstP,CC>::make(src,cc);
00118 }
00119 
00121 template <typename DstP, typename View>
00122 inline typename color_converted_view_type<View,DstP>::type
00123 color_converted_view(const View& src) {
00124     return color_converted_view<DstP>(src,default_color_converter());
00125 }
00126 
00128 template <typename View>
00129 inline typename View::dynamic_y_step_t flipped_up_down_view(const View& src) { 
00130     typedef typename View::dynamic_y_step_t RVIEW;
00131     return RVIEW(src.dimensions(),typename RVIEW::xy_locator(src.xy_at(0,src.height()-1),-1));
00132 }
00133 
00135 template <typename View> 
00136 inline typename View::dynamic_x_step_t flipped_left_right_view(const View& src) {
00137     typedef typename View::dynamic_x_step_t RVIEW;
00138     return RVIEW(src.dimensions(),typename RVIEW::xy_locator(src.xy_at(src.width()-1,0),-1,1));
00139 }
00140 
00142 template <typename View>
00143 inline typename View::dynamic_xy_step_transposed_t transposed_view(const View& src) {
00144     typedef typename View::dynamic_xy_step_transposed_t RVIEW;
00145     return RVIEW(src.height(),src.width(),typename RVIEW::xy_locator(src.xy_at(0,0),1,1,true));
00146 }
00147 
00149 template <typename View> 
00150 inline typename View::dynamic_xy_step_transposed_t rotated90cw_view(const View& src) {
00151     typedef typename View::dynamic_xy_step_transposed_t RVIEW;
00152     return RVIEW(src.height(),src.width(),typename RVIEW::xy_locator(src.xy_at(0,src.height()-1),-1,1,true));
00153 }
00154 
00156 template <typename View> 
00157 inline typename View::dynamic_xy_step_transposed_t rotated90ccw_view(const View& src) {
00158     typedef typename View::dynamic_xy_step_transposed_t RVIEW;
00159     return RVIEW(src.height(),src.width(),typename RVIEW::xy_locator(src.xy_at(src.width()-1,0),1,-1,true));
00160 }
00161 
00163 template <typename View> 
00164 inline typename View::dynamic_xy_step_t rotated180_view(const View& src) {
00165     typedef typename View::dynamic_xy_step_t RVIEW;
00166     return RVIEW(src.dimensions(),typename RVIEW::xy_locator(src.xy_at(src.width()-1,src.height()-1),-1,-1));
00167 }
00168 
00170 template <typename View> 
00171 inline View subimage_view(const View& src, const typename View::point_t& topleft, const typename View::point_t& dimensions) {
00172     return View(dimensions,src.xy_at(topleft));
00173 }
00174 template <typename View> 
00175 inline View subimage_view(const View& src, int xMin, int yMin, int width, int height) {
00176     return View(width,height,src.xy_at(xMin,yMin));
00177 }
00178 
00180 template <typename View> 
00181 inline typename View::dynamic_xy_step_t subsampled_view(const View& src, typename View::coord_t xStep, typename View::coord_t yStep) {
00182     assert(xStep>0 && yStep>0);
00183     typedef typename View::dynamic_xy_step_t RVIEW;
00184     return RVIEW((src.width()+(xStep-1))/xStep,(src.height()+(yStep-1))/yStep,
00185                                           typename RVIEW::xy_locator(src.xy_at(0,0),xStep,yStep));
00186 }
00187 
00189 template <typename View> 
00190 inline typename View::dynamic_xy_step_t subsampled_view(const View& src, const typename View::point_t& step) { 
00191     return subsampled_view(src,step.x,step.y);
00192 }
00193 
00194 namespace detail {
00195     template <typename View, bool AreChannelsTogether> struct __nth_channel_view_basic;
00196 
00197     // nth_channel_view when the channels are not adjacent in memory. This can happen for multi-channel interleaved images 
00198     // or images with a step
00199     template <typename View>
00200     struct __nth_channel_view_basic<View,false> {
00201         typedef typename view_type<typename View::channel_t, gray_t, false, true, view_is_mutable<View>::value>::type type;
00202 
00203         static type make(const View& src, int n) {
00204             typedef typename type::xy_locator                             locator_t;
00205             typedef typename type::x_iterator                            x_iterator_t;
00206             typedef typename pixel_iterator_traits<x_iterator_t>::base_t x_iterator_base_t;
00207             x_iterator_t sit(x_iterator_base_t(&(src(0,0)[n])),src.pixels().pix_bytestep());
00208             return type(src.dimensions(),locator_t(sit, src.pixels().row_bytes()));
00209         }
00210     };
00211 
00212     // nth_channel_view when the channels are together in memory (true for simple grayscale or planar images)
00213     template <typename View>
00214     struct __nth_channel_view_basic<View,true> {
00215         typedef typename view_type<typename View::channel_t, gray_t, false, false, view_is_mutable<View>::value>::type type;
00216         static type make(const View& src, int n) {
00217             typedef typename type::x_iterator x_iterator_t;
00218             return interleaved_view(src.width(),src.height(),(x_iterator_t)&(src(0,0)[n]), src.pixels().row_bytes());
00219         }
00220     };
00221 
00222     template <typename View, bool IsBasic> struct __nth_channel_view;
00223 
00224     // For basic (memory-based) views dispatch to __nth_channel_view_basic
00225     template <typename View> struct __nth_channel_view<View,true> {
00226     private:
00227         typedef typename View::x_iterator src_x_iterator;
00228 
00229         // Determines whether the channels of a given pixel iterator are adjacent in memory.
00230         // Planar and grayscale iterators have channels adjacent in memory, whereas multi-channel interleaved and iterators with non-fundamental step do not.
00231         BOOST_STATIC_CONSTANT(bool, adjacent=
00232                               !iterator_is_step<src_x_iterator>::value &&
00233                               (pixel_iterator_traits<src_x_iterator>::is_planar ||
00234                                pixel_iterator_traits<src_x_iterator>::color_space_t::num_channels==1));
00235     public:
00236         typedef typename __nth_channel_view_basic<View,adjacent>::type type;
00237 
00238         static type make(const View& src, int n) {
00239             return __nth_channel_view_basic<View,adjacent>::make(src,n);
00240         }
00241     };
00242 
00247     template <typename SrcP>        // SrcP models PixelConcept (could be pixel value or const/non-const reference)
00248                                     // Examples: pixel<T,C>, pixel<T,C>&, const pixel<T,C>&, planar_ref<T&,C>, planar_ref<const T&,C>
00249     struct nth_channel_deref_fn {
00250         BOOST_STATIC_CONSTANT(bool, is_mutable=is_pixel_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value);
00251     private:
00252         typedef typename pixel_traits<SrcP>::channel_t       channel_t;
00253         typedef typename pixel_traits<SrcP>::const_reference const_ref_t;
00254                 typedef typename pixel_reference_type<channel_t,gray_t,false,is_mutable>::type ref_t;
00255     public:
00256         typedef nth_channel_deref_fn<const_ref_t>                                 const_t;
00257         typedef pixel<channel_t,gray_t>                                           value_type;
00258         typedef typename pixel_reference_type<channel_t,gray_t,false,false>::type const_reference;
00259         typedef SrcP                                                              argument_type;
00260         typedef typename boost::mpl::if_c<is_mutable, ref_t, value_type>::type    reference;
00261         typedef reference                                                         result_type;
00262 
00263         nth_channel_deref_fn(int n=0) : _n(n) {}
00264         template <typename P> nth_channel_deref_fn(const nth_channel_deref_fn<P>& d) : _n(d._n) {}
00265 
00266         int _n;        // the channel to use
00267 
00268         result_type operator()(argument_type srcP) const { 
00269             return result_type(srcP[_n]); 
00270         }
00271     };
00272 
00273     template <typename View> struct __nth_channel_view<View,false> {
00274     private:
00275         typedef nth_channel_deref_fn<typename View::reference> deref_t;
00276         typedef typename View::template add_deref<deref_t>   AD;
00277     public:
00278         typedef typename AD::type type;
00279         static type make(const View& src, int n) {
00280             return AD::make(src, deref_t(n));
00281         }
00282     };
00283 }
00284 
00291 template <typename View>
00292 struct nth_channel_view_type {
00293 private:
00294     GIL_CLASS_REQUIRE(View, GIL, ImageViewConcept);
00295     typedef detail::__nth_channel_view<View,view_is_basic<View>::value> VB;
00296 public:
00297     typedef typename VB::type type;
00298     static type make(const View& src, int n) { return VB::make(src,n); }
00299 };
00300 
00301 
00303 template <typename View>
00304 typename nth_channel_view_type<View>::type nth_channel_view(const View& src, int n) {
00305     return nth_channel_view_type<View>::make(src,n);
00306 }
00307 
00309 
00310 ADOBE_GIL_NAMESPACE_END
00311 
00312 #endif

Copyright © 2006 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google