summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/gil/example/interleaved_ref.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/gil/example/interleaved_ref.hpp')
-rw-r--r--src/boost/libs/gil/example/interleaved_ref.hpp158
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