123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- //
- // Copyright 2005-2007 Adobe Systems Incorporated
- //
- // Distributed under the Boost Software License, Version 1.0
- // See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt
- //
- #ifndef BOOST_GIL_EXAMPLE_INTERLEAVED_REF_HPP
- #define BOOST_GIL_EXAMPLE_INTERLEAVED_REF_HPP
- #include <boost/gil.hpp>
- #include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
- #include <type_traits>
- // Example on how to create a new model of a pixel reference
- namespace boost { namespace gil {
- // A model of an interleaved pixel reference. Holds a pointer to the first channel
- // MODELS:
- // MutableHomogeneousPixelConcept
- // MutableHomogeneousColorBaseConcept
- // MutableColorBaseConcept
- // HomogeneousColorBaseConcept
- // ColorBaseConcept
- // HomogeneousPixelBasedConcept
- // PixelBasedConcept
- //
- // For planar reference proxies to work properly, all of their methods must be const-qualified
- // and their iterator's reference type must be const-qualified.
- // Mutability of the reference proxy is part of its type (in this case, depends on the mutability of ChannelReference)
- /// \tparam ChannelReference - Models ChannelConcept.
- /// A channel reference, unsigned char& or const unsigned char&
- /// \tparam Layout - A layout (includes the color space and channel ordering)
- template <typename ChannelReference, typename Layout>
- struct interleaved_ref
- {
- private:
- using channel_t = typename channel_traits<ChannelReference>::value_type;
- using channel_pointer_t = typename channel_traits<ChannelReference>::pointer;
- using channel_reference_t = typename channel_traits<ChannelReference>::reference;
- using channel_const_reference_t = typename channel_traits<ChannelReference>::const_reference;
- public:
- using layout_t = Layout; // Required by ColorBaseConcept
- // Copy construction from a compatible type. The copy constructor of references is shallow. The channels themselves are not copied.
- interleaved_ref(const interleaved_ref& p) : _channels(p._channels) {}
- template <typename P> interleaved_ref(const P& p) : _channels(p._channels) { check_compatible<P>(); }
- template <typename P> bool operator==(const P& p) const { check_compatible<P>(); return static_equal(*this,p); }
- template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
- // Required by MutableColorBaseConcept
- // Assignment from a compatible type
- const interleaved_ref& operator=(const interleaved_ref& p) const { static_copy(p,*this); return *this; }
- template <typename P> const interleaved_ref& operator=(const P& p) const { check_compatible<P>(); static_copy(p,*this); return *this; }
- // Required by PixelConcept
- using value_type = pixel<channel_t, layout_t>;
- using reference = interleaved_ref;
- using const_reference = interleaved_ref<channel_const_reference_t, layout_t>;
- static const bool is_mutable = channel_traits<ChannelReference>::is_mutable;
- // Required by HomogeneousPixelConcept
- ChannelReference operator[](std::size_t i) const { return _channels[i]; }
- // Custom constructor (not part of any concept)
- explicit interleaved_ref(channel_pointer_t channels) : _channels(channels) {}
- // This is needed for the reference proxy to work properly
- const interleaved_ref* operator->() const { return this; }
- private:
- channel_pointer_t _channels;
- template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,interleaved_ref>>(); }
- };
- // Required by ColorBaseConcept
- template <typename ChannelReference, typename Layout, int K>
- struct kth_element_type<interleaved_ref<ChannelReference, Layout>, K>
- {
- using type = ChannelReference;
- };
- template <typename ChannelReference, typename Layout, int K>
- struct kth_element_reference_type<interleaved_ref<ChannelReference, Layout>, K>
- {
- using type = ChannelReference;
- };
- template <typename ChannelReference, typename Layout, int K>
- struct kth_element_const_reference_type<interleaved_ref<ChannelReference, Layout>, K>
- {
- using type = ChannelReference;
- // XXX: using type = typename channel_traits<ChannelReference>::const_reference;
- };
- // Required by ColorBaseConcept
- template <int K, typename ChannelReference, typename Layout>
- typename element_reference_type<interleaved_ref<ChannelReference,Layout>>::type
- at_c(const interleaved_ref<ChannelReference,Layout>& p) { return p[K]; };
- // Required by HomogeneousColorBaseConcept
- template <typename ChannelReference, typename Layout>
- typename element_reference_type<interleaved_ref<ChannelReference,Layout>>::type
- dynamic_at_c(const interleaved_ref<ChannelReference,Layout>& p, std::size_t n) { return p[n]; };
- namespace detail {
- struct swap_fn_t {
- template <typename T> void operator()(T& x, T& y) const {
- using std::swap;
- swap(x,y);
- }
- };
- }
- // Required by MutableColorBaseConcept. The default std::swap does not do the right thing for proxy references - it swaps the references, not the values
- template <typename ChannelReference, typename Layout>
- void swap(const interleaved_ref<ChannelReference,Layout>& x, const interleaved_ref<ChannelReference,Layout>& y) {
- static_for_each(x,y,detail::swap_fn_t());
- };
- // Required by PixelConcept
- template <typename ChannelReference, typename Layout>
- struct is_pixel<interleaved_ref<ChannelReference,Layout>> : public std::true_type {};
- // Required by PixelBasedConcept
- template <typename ChannelReference, typename Layout>
- struct color_space_type<interleaved_ref<ChannelReference, Layout>>
- {
- using type = typename Layout::color_space_t;
- };
- // Required by PixelBasedConcept
- template <typename ChannelReference, typename Layout>
- struct channel_mapping_type<interleaved_ref<ChannelReference, Layout>>
- {
- using type = typename Layout::channel_mapping_t;
- };
- // Required by PixelBasedConcept
- template <typename ChannelReference, typename Layout>
- struct is_planar<interleaved_ref<ChannelReference,Layout>> : std::false_type {};
- // Required by HomogeneousPixelBasedConcept
- template <typename ChannelReference, typename Layout>
- struct channel_type<interleaved_ref<ChannelReference, Layout>>
- {
- using type = typename channel_traits<ChannelReference>::value_type;
- };
- } } // namespace boost::gil
- #endif
|