00001
00002
00003
00004
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 >
00054 class color_convert_deref_fn {
00055 private:
00056 CC _cc;
00057 public:
00058 typedef color_convert_deref_fn const_t;
00059 typedef DstP value_type;
00060 typedef value_type reference;
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
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
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 }
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);
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
00198
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
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
00225 template <typename View> struct __nth_channel_view<View,true> {
00226 private:
00227 typedef typename View::x_iterator src_x_iterator;
00228
00229
00230
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>
00248
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;
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