interleaved_ref.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. //
  2. // Copyright 2005-2007 Adobe Systems Incorporated
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. #ifndef BOOST_GIL_EXAMPLE_INTERLEAVED_REF_HPP
  9. #define BOOST_GIL_EXAMPLE_INTERLEAVED_REF_HPP
  10. #include <boost/gil.hpp>
  11. #include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
  12. #include <type_traits>
  13. // Example on how to create a new model of a pixel reference
  14. namespace boost { namespace gil {
  15. // A model of an interleaved pixel reference. Holds a pointer to the first channel
  16. // MODELS:
  17. // MutableHomogeneousPixelConcept
  18. // MutableHomogeneousColorBaseConcept
  19. // MutableColorBaseConcept
  20. // HomogeneousColorBaseConcept
  21. // ColorBaseConcept
  22. // HomogeneousPixelBasedConcept
  23. // PixelBasedConcept
  24. //
  25. // For planar reference proxies to work properly, all of their methods must be const-qualified
  26. // and their iterator's reference type must be const-qualified.
  27. // Mutability of the reference proxy is part of its type (in this case, depends on the mutability of ChannelReference)
  28. /// \tparam ChannelReference - Models ChannelConcept.
  29. /// A channel reference, unsigned char& or const unsigned char&
  30. /// \tparam Layout - A layout (includes the color space and channel ordering)
  31. template <typename ChannelReference, typename Layout>
  32. struct interleaved_ref
  33. {
  34. private:
  35. using channel_t = typename channel_traits<ChannelReference>::value_type;
  36. using channel_pointer_t = typename channel_traits<ChannelReference>::pointer;
  37. using channel_reference_t = typename channel_traits<ChannelReference>::reference;
  38. using channel_const_reference_t = typename channel_traits<ChannelReference>::const_reference;
  39. public:
  40. using layout_t = Layout; // Required by ColorBaseConcept
  41. // Copy construction from a compatible type. The copy constructor of references is shallow. The channels themselves are not copied.
  42. interleaved_ref(const interleaved_ref& p) : _channels(p._channels) {}
  43. template <typename P> interleaved_ref(const P& p) : _channels(p._channels) { check_compatible<P>(); }
  44. template <typename P> bool operator==(const P& p) const { check_compatible<P>(); return static_equal(*this,p); }
  45. template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
  46. // Required by MutableColorBaseConcept
  47. // Assignment from a compatible type
  48. const interleaved_ref& operator=(const interleaved_ref& p) const { static_copy(p,*this); return *this; }
  49. template <typename P> const interleaved_ref& operator=(const P& p) const { check_compatible<P>(); static_copy(p,*this); return *this; }
  50. // Required by PixelConcept
  51. using value_type = pixel<channel_t, layout_t>;
  52. using reference = interleaved_ref;
  53. using const_reference = interleaved_ref<channel_const_reference_t, layout_t>;
  54. static const bool is_mutable = channel_traits<ChannelReference>::is_mutable;
  55. // Required by HomogeneousPixelConcept
  56. ChannelReference operator[](std::size_t i) const { return _channels[i]; }
  57. // Custom constructor (not part of any concept)
  58. explicit interleaved_ref(channel_pointer_t channels) : _channels(channels) {}
  59. // This is needed for the reference proxy to work properly
  60. const interleaved_ref* operator->() const { return this; }
  61. private:
  62. channel_pointer_t _channels;
  63. template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,interleaved_ref>>(); }
  64. };
  65. // Required by ColorBaseConcept
  66. template <typename ChannelReference, typename Layout, int K>
  67. struct kth_element_type<interleaved_ref<ChannelReference, Layout>, K>
  68. {
  69. using type = ChannelReference;
  70. };
  71. template <typename ChannelReference, typename Layout, int K>
  72. struct kth_element_reference_type<interleaved_ref<ChannelReference, Layout>, K>
  73. {
  74. using type = ChannelReference;
  75. };
  76. template <typename ChannelReference, typename Layout, int K>
  77. struct kth_element_const_reference_type<interleaved_ref<ChannelReference, Layout>, K>
  78. {
  79. using type = ChannelReference;
  80. // XXX: using type = typename channel_traits<ChannelReference>::const_reference;
  81. };
  82. // Required by ColorBaseConcept
  83. template <int K, typename ChannelReference, typename Layout>
  84. typename element_reference_type<interleaved_ref<ChannelReference,Layout>>::type
  85. at_c(const interleaved_ref<ChannelReference,Layout>& p) { return p[K]; };
  86. // Required by HomogeneousColorBaseConcept
  87. template <typename ChannelReference, typename Layout>
  88. typename element_reference_type<interleaved_ref<ChannelReference,Layout>>::type
  89. dynamic_at_c(const interleaved_ref<ChannelReference,Layout>& p, std::size_t n) { return p[n]; };
  90. namespace detail {
  91. struct swap_fn_t {
  92. template <typename T> void operator()(T& x, T& y) const {
  93. using std::swap;
  94. swap(x,y);
  95. }
  96. };
  97. }
  98. // Required by MutableColorBaseConcept. The default std::swap does not do the right thing for proxy references - it swaps the references, not the values
  99. template <typename ChannelReference, typename Layout>
  100. void swap(const interleaved_ref<ChannelReference,Layout>& x, const interleaved_ref<ChannelReference,Layout>& y) {
  101. static_for_each(x,y,detail::swap_fn_t());
  102. };
  103. // Required by PixelConcept
  104. template <typename ChannelReference, typename Layout>
  105. struct is_pixel<interleaved_ref<ChannelReference,Layout>> : public std::true_type {};
  106. // Required by PixelBasedConcept
  107. template <typename ChannelReference, typename Layout>
  108. struct color_space_type<interleaved_ref<ChannelReference, Layout>>
  109. {
  110. using type = typename Layout::color_space_t;
  111. };
  112. // Required by PixelBasedConcept
  113. template <typename ChannelReference, typename Layout>
  114. struct channel_mapping_type<interleaved_ref<ChannelReference, Layout>>
  115. {
  116. using type = typename Layout::channel_mapping_t;
  117. };
  118. // Required by PixelBasedConcept
  119. template <typename ChannelReference, typename Layout>
  120. struct is_planar<interleaved_ref<ChannelReference,Layout>> : std::false_type {};
  121. // Required by HomogeneousPixelBasedConcept
  122. template <typename ChannelReference, typename Layout>
  123. struct channel_type<interleaved_ref<ChannelReference, Layout>>
  124. {
  125. using type = typename channel_traits<ChannelReference>::value_type;
  126. };
  127. } } // namespace boost::gil
  128. #endif