/* Copyright 2005-2007 Adobe Systems Incorporated Use, modification and distribution are subject to 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). See http://stlab.adobe.com/gil for most recent version including documentation. */ /*************************************************************************************************/ //////////////////////////////////////////////////////////////////////////////////////// /// \file /// \brief Example on how to create a new model of a pixel reference /// \author Lubomir Bourdev and Hailin Jin \n /// Adobe Systems Incorporated /// \date 2005-2007 \n Last updated on February 26, 2007 ////// //////////////////////////////////////////////////////////////////////////////////////// #ifndef GIL_INTERLEAVED_REF_HPP #define GIL_INTERLEAVED_REF_HPP #include #include #include 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) ///////////////////////////////////////////////////////////////////////// template // A layout (includes the color space and channel ordering) struct interleaved_ref { private: typedef typename channel_traits::value_type channel_t; typedef typename channel_traits::reference channel_reference_t; typedef typename channel_traits::const_reference channel_const_reference_t; typedef typename channel_traits::pointer channel_pointer_t; public: // Required by ColorBaseConcept typedef Layout layout_t; // 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 interleaved_ref(const P& p) : _channels(p._channels) { check_compatible

(); } template bool operator==(const P& p) const { check_compatible

(); return static_equal(*this,p); } template 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 const interleaved_ref& operator=(const P& p) const { check_compatible

(); static_copy(p,*this); return *this; } // Required by PixelConcept typedef pixel value_type; typedef interleaved_ref reference; typedef interleaved_ref const_reference; static const bool is_mutable = channel_traits::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 static void check_compatible() { gil_function_requires >(); } }; // Required by ColorBaseConcept template struct kth_element_type,K> { typedef ChannelReference type; }; template struct kth_element_reference_type,K> { typedef ChannelReference type; }; template struct kth_element_const_reference_type,K> { typedef ChannelReference type; // typedef typename channel_traits::const_reference type; }; // Required by ColorBaseConcept template typename element_reference_type >::type at_c(const interleaved_ref& p) { return p[K]; }; // Required by HomogeneousColorBaseConcept template typename element_reference_type >::type dynamic_at_c(const interleaved_ref& p, std::size_t n) { return p[n]; }; namespace detail { struct swap_fn_t { template 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 void swap(const interleaved_ref& x, const interleaved_ref& y) { static_for_each(x,y,detail::swap_fn_t()); }; // Required by PixelConcept template struct is_pixel > : public boost::mpl::true_ {}; // Required by PixelBasedConcept template struct color_space_type > { typedef typename Layout::color_space_t type; }; // Required by PixelBasedConcept template struct channel_mapping_type > { typedef typename Layout::channel_mapping_t type; }; // Required by PixelBasedConcept template struct is_planar > : mpl::false_ {}; // Required by HomogeneousPixelBasedConcept template struct channel_type > { typedef typename channel_traits::value_type type; }; } } // namespace boost::gil #endif