Boost GIL


image_view_factory.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2005-2007 Adobe Systems Incorporated
3 
4  Use, modification and distribution are subject to the Boost Software License,
5  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6  http://www.boost.org/LICENSE_1_0.txt).
7 
8  See http://opensource.adobe.com/gil for most recent version including documentation.
9 */
10 
11 /*************************************************************************************************/
12 
13 #ifndef GIL_IMAGE_VIEW_FACTORY_HPP
14 #define GIL_IMAGE_VIEW_FACTORY_HPP
15 
25 
27 #include <cassert>
28 #include <cstddef>
29 #include "gil_config.hpp"
30 #include "metafunctions.hpp"
31 #include "gray.hpp"
32 #include "color_convert.hpp"
33 
37 
41 
42 namespace boost { namespace gil {
43 struct default_color_converter;
44 
45 template <typename T> struct dynamic_x_step_type;
46 template <typename T> struct dynamic_y_step_type;
47 template <typename T> struct transposed_type;
48 
51 template <typename View>
52 struct dynamic_xy_step_type : public dynamic_y_step_type<typename dynamic_x_step_type<View>::type> {};
53 
56 template <typename View>
57 struct dynamic_xy_step_transposed_type : public dynamic_xy_step_type<typename transposed_type<View>::type> {};
58 
59 
62 template <typename Iterator>
64 interleaved_view(std::size_t width, std::size_t height,
65  Iterator pixels, std::ptrdiff_t rowsize_in_bytes) {
66  typedef typename type_from_x_iterator<Iterator>::view_t RView;
67  return RView(width, height, typename RView::locator(pixels, rowsize_in_bytes));
68 }
69 
72 template <typename Iterator>
73 typename type_from_x_iterator<Iterator>::view_t
75  Iterator pixels, std::ptrdiff_t rowsize_in_bytes) {
76  typedef typename type_from_x_iterator<Iterator>::view_t RView;
77  return RView(dim, typename RView::locator(pixels, rowsize_in_bytes));
78 }
79 
81 // interleaved_view_get_raw_data, planar_view_get_raw_data - return pointers to the raw data (the channels) of a basic homogeneous view.
83 
84 namespace detail {
85  template <typename View, bool IsMutable> struct channel_pointer_type_impl;
86 
87  template <typename View> struct channel_pointer_type_impl<View, true> {
88  typedef typename channel_type<View>::type* type;
89  };
90  template <typename View> struct channel_pointer_type_impl<View, false> {
91  typedef const typename channel_type<View>::type* type;
92  };
93 
94  template <typename View> struct channel_pointer_type
95  : public channel_pointer_type_impl<View, view_is_mutable<View>::value> {};
96 } // namespace detail
97 
100 template <typename HomogeneousView>
101 typename detail::channel_pointer_type<HomogeneousView>::type interleaved_view_get_raw_data(const HomogeneousView& view) {
102  BOOST_STATIC_ASSERT((!is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value));
103  BOOST_STATIC_ASSERT((boost::is_pointer<typename HomogeneousView::x_iterator>::value));
104 
105  return &gil::at_c<0>(view(0,0));
106 }
107 
110 template <typename HomogeneousView>
111 typename detail::channel_pointer_type<HomogeneousView>::type planar_view_get_raw_data(const HomogeneousView& view, int plane_index) {
112  BOOST_STATIC_ASSERT((is_planar<HomogeneousView>::value && view_is_basic<HomogeneousView>::value));
113  return dynamic_at_c(view.row_begin(0),plane_index);
114 }
115 
116 
120 
125 template <typename SrcConstRefP, typename DstP, typename CC=default_color_converter > // const_reference to the source pixel and destination pixel value
126 class color_convert_deref_fn : public deref_base<color_convert_deref_fn<SrcConstRefP,DstP,CC>, DstP, DstP, const DstP&, SrcConstRefP, DstP, false> {
127 private:
128  CC _cc; // color-converter
129 public:
131  color_convert_deref_fn(CC cc_in) : _cc(cc_in) {}
132 
133  DstP operator()(SrcConstRefP srcP) const {
134  DstP dstP;
135  _cc(srcP,dstP);
136  return dstP;
137  }
138 };
139 
140 namespace detail {
141  // Add color converter upon dereferencing
142  template <typename SrcView, typename CC, typename DstP, typename SrcP>
143  struct _color_converted_view_type {
144  private:
146  typedef typename SrcView::template add_deref<deref_t> add_ref_t;
147  public:
148  typedef typename add_ref_t::type type;
149  static type make(const SrcView& sv,CC cc) {return add_ref_t::make(sv,deref_t(cc));}
150  };
151 
152  // If the Src view has the same pixel type as the target, there is no need for color conversion
153  template <typename SrcView, typename CC, typename DstP>
154  struct _color_converted_view_type<SrcView,CC,DstP,DstP> {
155  typedef SrcView type;
156  static type make(const SrcView& sv,CC) {return sv;}
157  };
158 } // namespace detail
159 
160 
163 template <typename SrcView, typename DstP, typename CC=default_color_converter>
164 struct color_converted_view_type : public detail::_color_converted_view_type<SrcView,
165  CC,
166  DstP,
167  typename SrcView::value_type> {
168  GIL_CLASS_REQUIRE(DstP, boost::gil, MutablePixelConcept)//why does it have to be mutable???
169 };
170 
171 
174 template <typename DstP, typename View, typename CC>
177 }
178 
181 template <typename DstP, typename View>
182 inline typename color_converted_view_type<View,DstP>::type
183 color_converted_view(const View& src) {
184  return color_converted_view<DstP>(src,default_color_converter());
185 }
186 
190 
192 template <typename View>
193 inline typename dynamic_y_step_type<View>::type flipped_up_down_view(const View& src) {
194  typedef typename dynamic_y_step_type<View>::type RView;
195  return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1));
196 }
197 
201 
203 template <typename View>
204 inline typename dynamic_x_step_type<View>::type flipped_left_right_view(const View& src) {
205  typedef typename dynamic_x_step_type<View>::type RView;
206  return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,0),-1,1));
207 }
208 
212 
214 template <typename View>
215 inline typename dynamic_xy_step_transposed_type<View>::type transposed_view(const View& src) {
216  typedef typename dynamic_xy_step_transposed_type<View>::type RView;
217  return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,0),1,1,true));
218 }
219 
223 
225 template <typename View>
226 inline typename dynamic_xy_step_transposed_type<View>::type rotated90cw_view(const View& src) {
227  typedef typename dynamic_xy_step_transposed_type<View>::type RView;
228  return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(0,src.height()-1),-1,1,true));
229 }
230 
234 
236 template <typename View>
237 inline typename dynamic_xy_step_transposed_type<View>::type rotated90ccw_view(const View& src) {
238  typedef typename dynamic_xy_step_transposed_type<View>::type RView;
239  return RView(src.height(),src.width(),typename RView::xy_locator(src.xy_at(src.width()-1,0),1,-1,true));
240 }
241 
245 
247 template <typename View>
248 inline typename dynamic_xy_step_type<View>::type rotated180_view(const View& src) {
249  typedef typename dynamic_xy_step_type<View>::type RView;
250  return RView(src.dimensions(),typename RView::xy_locator(src.xy_at(src.width()-1,src.height()-1),-1,-1));
251 }
252 
256 
258 template <typename View>
259 inline View subimage_view(const View& src, const typename View::point_t& topleft, const typename View::point_t& dimensions) {
260  return View(dimensions,src.xy_at(topleft));
261 }
262 
264 template <typename View>
265 inline View subimage_view(const View& src, int xMin, int yMin, int width, int height) {
266  return View(width,height,src.xy_at(xMin,yMin));
267 }
268 
272 
274 template <typename View>
275 inline typename dynamic_xy_step_type<View>::type subsampled_view(const View& src, typename View::coord_t xStep, typename View::coord_t yStep) {
276  assert(xStep>0 && yStep>0);
277  typedef typename dynamic_xy_step_type<View>::type RView;
278  return RView((src.width()+(xStep-1))/xStep,(src.height()+(yStep-1))/yStep,
279  typename RView::xy_locator(src.xy_at(0,0),xStep,yStep));
280 }
281 
283 template <typename View>
284 inline typename dynamic_xy_step_type<View>::type subsampled_view(const View& src, const typename View::point_t& step) {
285  return subsampled_view(src,step.x,step.y);
286 }
287 
291 
292 namespace detail {
293  template <typename View, bool AreChannelsTogether> struct __nth_channel_view_basic;
294 
295  // nth_channel_view when the channels are not adjacent in memory. This can happen for multi-channel interleaved images
296  // or images with a step
297  template <typename View>
298  struct __nth_channel_view_basic<View,false> {
299  typedef typename view_type<typename channel_type<View>::type, gray_layout_t, false, true, view_is_mutable<View>::value>::type type;
300 
301  static type make(const View& src, int n) {
302  typedef typename type::xy_locator locator_t;
303  typedef typename type::x_iterator x_iterator_t;
304  typedef typename iterator_adaptor_get_base<x_iterator_t>::type x_iterator_base_t;
305  x_iterator_t sit(x_iterator_base_t(&(src(0,0)[n])),src.pixels().pixel_size());
306  return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
307  }
308  };
309 
310  // nth_channel_view when the channels are together in memory (true for simple grayscale or planar images)
311  template <typename View>
312  struct __nth_channel_view_basic<View,true> {
313  typedef typename view_type<typename channel_type<View>::type, gray_layout_t, false, false, view_is_mutable<View>::value>::type type;
314  static type make(const View& src, int n) {
315  typedef typename type::x_iterator x_iterator_t;
316  return interleaved_view(src.width(),src.height(),(x_iterator_t)&(src(0,0)[n]), src.pixels().row_size());
317  }
318  };
319 
320  template <typename View, bool IsBasic> struct __nth_channel_view;
321 
322  // For basic (memory-based) views dispatch to __nth_channel_view_basic
323  template <typename View> struct __nth_channel_view<View,true> {
324  private:
325  typedef typename View::x_iterator src_x_iterator;
326 
327  // Determines whether the channels of a given pixel iterator are adjacent in memory.
328  // Planar and grayscale iterators have channels adjacent in memory, whereas multi-channel interleaved and iterators with non-fundamental step do not.
329  BOOST_STATIC_CONSTANT(bool, adjacent=
330  !iterator_is_step<src_x_iterator>::value &&
331  (is_planar<src_x_iterator>::value ||
332  num_channels<View>::value==1));
333  public:
334  typedef typename __nth_channel_view_basic<View,adjacent>::type type;
335 
336  static type make(const View& src, int n) {
337  return __nth_channel_view_basic<View,adjacent>::make(src,n);
338  }
339  };
340 
345  template <typename SrcP> // SrcP is a reference to PixelConcept (could be pixel value or const/non-const reference)
346  // Examples: pixel<T,L>, pixel<T,L>&, const pixel<T,L>&, planar_pixel_reference<T&,L>, planar_pixel_reference<const T&,L>
348  BOOST_STATIC_CONSTANT(bool, is_mutable=pixel_is_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value);
349  private:
350  typedef typename remove_reference<SrcP>::type src_pixel_t;
351  typedef typename channel_type<src_pixel_t>::type channel_t;
352  typedef typename src_pixel_t::const_reference const_ref_t;
354  public:
358  typedef SrcP argument_type;
359  typedef typename mpl::if_c<is_mutable, ref_t, value_type>::type reference;
360  typedef reference result_type;
361 
362  nth_channel_deref_fn(int n=0) : _n(n) {}
363  template <typename P> nth_channel_deref_fn(const nth_channel_deref_fn<P>& d) : _n(d._n) {}
364 
365  int _n; // the channel to use
366 
367  result_type operator()(argument_type srcP) const {
368  return result_type(srcP[_n]);
369  }
370  };
371 
372  template <typename View> struct __nth_channel_view<View,false> {
373  private:
375  typedef typename View::template add_deref<deref_t> AD;
376  public:
377  typedef typename AD::type type;
378  static type make(const View& src, int n) {
379  return AD::make(src, deref_t(n));
380  }
381  };
382 } // namespace detail
383 
390 template <typename View>
392 private:
393  GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept)
394  typedef detail::__nth_channel_view<View,view_is_basic<View>::value> VB;
395 public:
396  typedef typename VB::type type;
397  static type make(const View& src, int n) { return VB::make(src,n); }
398 };
399 
400 
402 template <typename View>
403 typename nth_channel_view_type<View>::type nth_channel_view(const View& src, int n) {
404  return nth_channel_view_type<View>::make(src,n);
405 }
406 
407 
408 
409 
410 
411 
412 
416 
417 namespace detail {
418  template <int K, typename View, bool AreChannelsTogether> struct __kth_channel_view_basic;
419 
420  // kth_channel_view when the channels are not adjacent in memory. This can happen for multi-channel interleaved images
421  // or images with a step
422  template <int K, typename View>
423  struct __kth_channel_view_basic<K,View,false> {
424  private:
425  typedef typename kth_element_type<typename View::value_type,K>::type channel_t;
426  public:
427  typedef typename view_type<channel_t, gray_layout_t, false, true, view_is_mutable<View>::value>::type type;
428 
429  static type make(const View& src) {
430  typedef typename type::xy_locator locator_t;
431  typedef typename type::x_iterator x_iterator_t;
432  typedef typename iterator_adaptor_get_base<x_iterator_t>::type x_iterator_base_t;
433  x_iterator_t sit(x_iterator_base_t(&gil::at_c<K>(src(0,0))),src.pixels().pixel_size());
434  return type(src.dimensions(),locator_t(sit, src.pixels().row_size()));
435  }
436  };
437 
438  // kth_channel_view when the channels are together in memory (true for simple grayscale or planar images)
439  template <int K, typename View>
440  struct __kth_channel_view_basic<K,View,true> {
441  private:
442  typedef typename kth_element_type<typename View::value_type, K>::type channel_t;
443  public:
444  typedef typename view_type<channel_t, gray_layout_t, false, false, view_is_mutable<View>::value>::type type;
445  static type make(const View& src) {
446  typedef typename type::x_iterator x_iterator_t;
447  return interleaved_view(src.width(),src.height(),(x_iterator_t)&gil::at_c<K>(src(0,0)), src.pixels().row_size());
448  }
449  };
450 
451  template <int K, typename View, bool IsBasic> struct __kth_channel_view;
452 
453  // For basic (memory-based) views dispatch to __kth_channel_view_basic
454  template <int K, typename View> struct __kth_channel_view<K,View,true> {
455  private:
456  typedef typename View::x_iterator src_x_iterator;
457 
458  // Determines whether the channels of a given pixel iterator are adjacent in memory.
459  // Planar and grayscale iterators have channels adjacent in memory, whereas multi-channel interleaved and iterators with non-fundamental step do not.
460  BOOST_STATIC_CONSTANT(bool, adjacent=
461  !iterator_is_step<src_x_iterator>::value &&
462  (is_planar<src_x_iterator>::value ||
463  num_channels<View>::value==1));
464  public:
465  typedef typename __kth_channel_view_basic<K,View,adjacent>::type type;
466 
467  static type make(const View& src) {
468  return __kth_channel_view_basic<K,View,adjacent>::make(src);
469  }
470  };
471 
476  template <int K, typename SrcP> // SrcP is a reference to PixelConcept (could be pixel value or const/non-const reference)
477  // Examples: pixel<T,L>, pixel<T,L>&, const pixel<T,L>&, planar_pixel_reference<T&,L>, planar_pixel_reference<const T&,L>
479  BOOST_STATIC_CONSTANT(bool, is_mutable=pixel_is_reference<SrcP>::value && pixel_reference_is_mutable<SrcP>::value);
480  private:
481  typedef typename remove_reference<SrcP>::type src_pixel_t;
482  typedef typename kth_element_type<src_pixel_t, K>::type channel_t;
483  typedef typename src_pixel_t::const_reference const_ref_t;
485  public:
489  typedef SrcP argument_type;
490  typedef typename mpl::if_c<is_mutable, ref_t, value_type>::type reference;
491  typedef reference result_type;
492 
494  template <typename P> kth_channel_deref_fn(const kth_channel_deref_fn<K,P>&) {}
495 
496  result_type operator()(argument_type srcP) const {
497  return result_type(gil::at_c<K>(srcP));
498  }
499  };
500 
501  template <int K, typename View> struct __kth_channel_view<K,View,false> {
502  private:
504  typedef typename View::template add_deref<deref_t> AD;
505  public:
506  typedef typename AD::type type;
507  static type make(const View& src) {
508  return AD::make(src, deref_t());
509  }
510  };
511 } // namespace detail
512 
519 template <int K, typename View>
521 private:
522  GIL_CLASS_REQUIRE(View, boost::gil, ImageViewConcept)
523  typedef detail::__kth_channel_view<K,View,view_is_basic<View>::value> VB;
524 public:
525  typedef typename VB::type type;
526  static type make(const View& src) { return VB::make(src); }
527 };
528 
530 template <int K, typename View>
531 typename kth_channel_view_type<K,View>::type kth_channel_view(const View& src) {
533 }
534 
535 } } // namespace boost::gil
536 
537 #endif
Returns the type of a transposed view that has a dynamic step along both X and Y. ...
Definition: image_view_factory.hpp:57
Support for grayscale color space and variants.
A lightweight object that interprets memory as a 2D array of pixels. Models ImageViewConcept,PixelBasedConcept,HasDynamicXStepTypeConcept,HasDynamicYStepTypeConcept,HasTransposedTypeConcept.
Definition: image_view.hpp:68
Represents a pixel value (a container of channels). Models: HomogeneousColorBaseValueConcept, PixelValueConcept, HomogeneousPixelBasedConcept.
Definition: metafunctions.hpp:44
Function object that given a source pixel, returns it converted to a given color space and channel de...
Definition: image_view_factory.hpp:126
Returns the type of a view that has a dynamic step along both X and Y.
Definition: image_view_factory.hpp:52
Given a source image view type View, returns the type of an image view over a single channel of ViewI...
Definition: image_view_factory.hpp:391
Helper base class for pixel dereference adaptors.
Definition: utilities.hpp:182
metafunctions that construct types or return type properties
Function object that returns a grayscale reference of the K-th channel (specified as a template param...
Definition: image_view_factory.hpp:478
type_from_x_iterator< Iterator >::view_t interleaved_view(point2< std::size_t > dim, Iterator pixels, std::ptrdiff_t rowsize_in_bytes)
Constructing image views from raw interleaved pixel data.
Definition: image_view_factory.hpp:74
Returns the type of a view that does color conversion upon dereferencing its pixels.
Definition: image_view_factory.hpp:164
Determines if the given pixel reference is mutable (i.e. its channels can be changed) ...
Definition: metafunctions.hpp:184
Function object that returns a grayscale reference of the N-th channel of a given reference...
Definition: image_view_factory.hpp:347
detail::channel_pointer_type< HomogeneousView >::type planar_view_get_raw_data(const HomogeneousView &view, int plane_index)
Returns C pointer to the the channels of a given color plane of a planar homogeneous view...
Definition: image_view_factory.hpp:111
Pixel concept that allows for changing its channels.
Definition: gil_concept.hpp:921
Returns the type of a homogeneous pixel reference given the channel type, layout, whether it operates...
Definition: metafunctions.hpp:217
detail::channel_pointer_type< HomogeneousView >::type interleaved_view_get_raw_data(const HomogeneousView &view)
Returns C pointer to the the channels of an interleaved homogeneous view.
Definition: image_view_factory.hpp:101
GIL's 2-dimensional view over immutable GIL pixels.
Definition: gil_concept.hpp:1942
const image< Pixel, IsPlanar, Alloc >::view_t & view(image< Pixel, IsPlanar, Alloc > &img)
Returns the non-constant-pixel view of an image.
Definition: image.hpp:480
color_converted_view_type< View, DstP >::type color_converted_view(const View &src)
overload of generic color_converted_view with the default color-converter
Definition: image_view_factory.hpp:183
GIL configuration file.
Given a model of a pixel, determines whether the model represents a pixel reference (as opposed to pi...
Definition: metafunctions.hpp:174
2D point both axes of which have the same dimension typeModels: Point2DConcept
Definition: gil_concept.hpp:52
class for color-converting one pixel to another
Definition: color_convert.hpp:297
Basic views must be over basic locators.
Definition: metafunctions.hpp:114
Given a source image view type View, returns the type of an image view over a given channel of View...
Definition: image_view_factory.hpp:520
GIL default color space conversions.