diff options
Diffstat (limited to 'src/boost/libs/gil/example/interleaved_ref.hpp')
-rw-r--r-- | src/boost/libs/gil/example/interleaved_ref.hpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/src/boost/libs/gil/example/interleaved_ref.hpp b/src/boost/libs/gil/example/interleaved_ref.hpp new file mode 100644 index 000000000..837e7f222 --- /dev/null +++ b/src/boost/libs/gil/example/interleaved_ref.hpp @@ -0,0 +1,158 @@ +// +// 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 |