summaryrefslogtreecommitdiff
path: root/boost/gil/extension/toolbox/image_types/indexed_image.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/gil/extension/toolbox/image_types/indexed_image.hpp')
-rw-r--r--boost/gil/extension/toolbox/image_types/indexed_image.hpp392
1 files changed, 392 insertions, 0 deletions
diff --git a/boost/gil/extension/toolbox/image_types/indexed_image.hpp b/boost/gil/extension/toolbox/image_types/indexed_image.hpp
new file mode 100644
index 0000000000..c413f67533
--- /dev/null
+++ b/boost/gil/extension/toolbox/image_types/indexed_image.hpp
@@ -0,0 +1,392 @@
+/*
+ Copyright 2012 Christian Henning
+ 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).
+*/
+
+/*************************************************************************************************/
+
+#ifndef BOOST_GIL_EXTENSION_TOOLBOX_IMAGE_TYPES_INDEXED_IMAGE_HPP
+#define BOOST_GIL_EXTENSION_TOOLBOX_IMAGE_TYPES_INDEXED_IMAGE_HPP
+
+////////////////////////////////////////////////////////////////////////////////////////
+/// \file indexed_image.hpp
+/// \brief Indexed Image extension
+/// \author Christian Henning \n
+///
+/// \date 2012 \n
+///
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/gil/image.hpp>
+#include <boost/gil/extension/toolbox/metafunctions/is_bit_aligned.hpp>
+
+
+namespace boost{ namespace gil {
+
+typedef boost::gil::point2< std::ptrdiff_t > point_t;
+
+template< typename Locator >
+struct get_pixel_type_locator : mpl::if_< typename is_bit_aligned< typename Locator::value_type >::type
+ , typename Locator::reference
+ , typename Locator::value_type
+ > {};
+
+// used for virtual locator
+template< typename IndicesLoc
+ , typename PaletteLoc
+ >
+struct indexed_image_deref_fn_base
+{
+ typedef IndicesLoc indices_locator_t;
+ typedef PaletteLoc palette_locator_t;
+ //typedef typename get_pixel_type_locator< indices_locator_t >::type index_t;
+
+ typedef indexed_image_deref_fn_base const_t;
+ typedef typename PaletteLoc::value_type value_type;
+ typedef value_type reference;
+ typedef value_type const_reference;
+ typedef point_t argument_type;
+ typedef reference result_type;
+
+ static const bool is_mutable = false;
+
+ indexed_image_deref_fn_base() {}
+
+ indexed_image_deref_fn_base( const indices_locator_t& indices_loc
+ , const palette_locator_t& palette_loc
+ )
+ : _indices_loc( indices_loc )
+ , _palette_loc( palette_loc )
+ {}
+
+ void set_indices( const indices_locator_t& indices_loc ) { _indices_loc = indices_loc; }
+ void set_palette( const palette_locator_t& palette_loc ) { _palette_loc = palette_loc; }
+
+ const indices_locator_t& indices() const { return _indices_loc; }
+ const palette_locator_t& palette() const { return _palette_loc; }
+
+protected:
+
+ indices_locator_t _indices_loc;
+ palette_locator_t _palette_loc;
+};
+
+
+// used for virtual locator
+template< typename IndicesLoc
+ , typename PaletteLoc
+ , typename Enable = void // there is specialization for integral indices
+ >
+struct indexed_image_deref_fn : indexed_image_deref_fn_base< IndicesLoc
+ , PaletteLoc
+ >
+{
+ typedef indexed_image_deref_fn_base< IndicesLoc
+ , PaletteLoc
+ > base_t;
+
+
+ indexed_image_deref_fn()
+ : base_t()
+ {}
+
+ indexed_image_deref_fn( const typename base_t::indices_locator_t& indices_loc
+ , const typename base_t::palette_locator_t& palette_loc
+ )
+ : base_t( indices_loc
+ , palette_loc
+ )
+ {}
+
+ typename base_t::result_type operator()( const point_t& p ) const
+ {
+ return * this->_palette_loc.xy_at( at_c<0>( *this->_indices_loc.xy_at( p )), 0 );
+ }
+};
+
+
+template< typename IndicesLoc
+ , typename PaletteLoc
+ >
+struct indexed_image_deref_fn< IndicesLoc
+ , PaletteLoc
+ , typename boost::enable_if< boost::is_integral< typename IndicesLoc::value_type > >::type
+ > : indexed_image_deref_fn_base< IndicesLoc
+ , PaletteLoc
+ >
+{
+ typedef indexed_image_deref_fn_base< IndicesLoc
+ , PaletteLoc
+ > base_t;
+
+ indexed_image_deref_fn()
+ : base_t()
+ {}
+
+ indexed_image_deref_fn( const typename base_t::indices_locator_t& indices_loc
+ , const typename base_t::palette_locator_t& palette_loc
+ )
+ : base_t( indices_loc
+ , palette_loc
+ )
+ {}
+
+ typename base_t::result_type operator()( const point_t& p ) const
+ {
+ return *this->_palette_loc.xy_at( *this->_indices_loc.xy_at( p ), 0 );
+ }
+};
+
+template< typename IndicesLoc
+ , typename PaletteLoc
+ >
+struct indexed_image_locator_type
+{
+ typedef virtual_2d_locator< indexed_image_deref_fn< IndicesLoc
+ , PaletteLoc
+ >
+ , false
+ > type;
+};
+
+template< typename Locator > // indexed_image_locator_type< ... >::type
+class indexed_image_view : public image_view< Locator >
+{
+public:
+
+ typedef typename Locator::deref_fn_t deref_fn_t;
+ typedef typename deref_fn_t::indices_locator_t indices_locator_t;
+ typedef typename deref_fn_t::palette_locator_t palette_locator_t;
+
+ typedef indexed_image_view< Locator > const_t;
+
+ typedef image_view< indices_locator_t > indices_view_t;
+ typedef image_view< palette_locator_t > palette_view_t;
+
+ indexed_image_view()
+ : image_view< Locator >()
+ , _num_colors( 0 )
+ {}
+
+ indexed_image_view( const point_t& dimensions
+ , std::size_t num_colors
+ , const Locator& locator
+ )
+ : image_view< Locator >( dimensions, locator )
+ , _num_colors( num_colors )
+ {}
+
+ template< typename IndexedView >
+ indexed_image_view( const IndexedView& iv )
+ : image_view< Locator >( iv )
+ , _num_colors( iv._num_colors )
+ {}
+
+ std::size_t num_colors() const { return _num_colors; }
+
+
+ const indices_locator_t& indices() const { return get_deref_fn().indices(); }
+ const palette_locator_t& palette() const { return get_deref_fn().palette(); }
+
+ indices_view_t get_indices_view() const { return indices_view_t(this->dimensions(), indices() );}
+ palette_view_t get_palette_view() const { return palette_view_t(point_t(num_colors(), 1), palette());}
+
+private:
+
+ const deref_fn_t& get_deref_fn() const { return this->pixels().deref_fn(); }
+
+private:
+
+ template< typename Locator2 > friend class indexed_image_view;
+
+ std::size_t _num_colors;
+};
+
+// build an indexed_image_view from two views
+template<typename Index_View, typename Palette_View>
+indexed_image_view
+<
+ typename indexed_image_locator_type
+ <
+ typename Index_View::locator
+ , typename Palette_View::locator
+ >::type
+>
+ view(Index_View iv, Palette_View pv)
+{
+ typedef indexed_image_view<
+ typename indexed_image_locator_type<
+ typename Index_View::locator
+ , typename Palette_View::locator
+ >::type
+ > view_t;
+
+ typedef indexed_image_deref_fn<
+ typename Index_View::locator
+ , typename Palette_View::locator
+ > defer_fn_t;
+
+ return view_t(
+ iv.dimensions()
+ , pv.dimensions().x
+ , typename view_t::locator(point_t(0, 0), point_t(1, 1), defer_fn_t(iv.xy_at(0, 0), pv.xy_at(0, 0)))
+ );
+}
+
+template< typename Index
+ , typename Pixel
+ , typename IndicesAllocator = std::allocator< unsigned char >
+ , typename PalleteAllocator = std::allocator< unsigned char >
+ >
+class indexed_image
+{
+public:
+
+ typedef image< Index, false, IndicesAllocator > indices_t;
+ typedef image< Pixel, false, PalleteAllocator > palette_t;
+
+ typedef typename indices_t::view_t indices_view_t;
+ typedef typename palette_t::view_t palette_view_t;
+
+ typedef typename indices_t::const_view_t indices_const_view_t;
+ typedef typename palette_t::const_view_t palette_const_view_t;
+
+ typedef typename indices_view_t::locator indices_locator_t;
+ typedef typename palette_view_t::locator palette_locator_t;
+
+ typedef typename indexed_image_locator_type< indices_locator_t
+ , palette_locator_t
+ >::type locator_t;
+
+ typedef typename indices_t::coord_t x_coord_t;
+ typedef typename indices_t::coord_t y_coord_t;
+
+
+ typedef indexed_image_view< locator_t > view_t;
+ typedef typename view_t::const_t const_view_t;
+
+ indexed_image( const x_coord_t width = 0
+ , const y_coord_t height = 0
+ , const std::size_t num_colors = 1
+ , const std::size_t indices_alignment = 0
+ , const std::size_t palette_alignment = 0
+ )
+ : _indices( width , height, indices_alignment, IndicesAllocator() )
+ , _palette( num_colors, 1, palette_alignment, PalleteAllocator() )
+ {
+ init( point_t( width, height ), num_colors );
+ }
+
+ indexed_image( const point_t& dimensions
+ , const std::size_t num_colors = 1
+ , const std::size_t indices_alignment = 0
+ , const std::size_t palette_alignment = 0
+ )
+ : _indices( dimensions, indices_alignment, IndicesAllocator() )
+ , _palette( num_colors, 1, palette_alignment, PalleteAllocator() )
+ {
+ init( dimensions, num_colors );
+ }
+
+ indexed_image( const indexed_image& img )
+ : _indices( img._indices )
+ , _palette( img._palette )
+ {}
+
+ template <typename Pixel2, typename Index2>
+ indexed_image( const indexed_image< Pixel2, Index2 >& img )
+ {
+ _indices = img._indices;
+ _palette = img._palette;
+ }
+
+ indexed_image& operator= ( const indexed_image& img )
+ {
+ _indices = img._indices;
+ _palette = img._palette;
+
+ return *this;
+ }
+
+ indices_const_view_t get_indices_const_view() const { return static_cast< indices_const_view_t >( _view.get_indices_view()); }
+ palette_const_view_t get_palette_const_view() const { return static_cast< palette_const_view_t >( _view.get_palette_view()); }
+
+ indices_view_t get_indices_view() { return _view.get_indices_view(); }
+ palette_view_t get_palette_view() { return _view.get_palette_view(); }
+
+public:
+
+ view_t _view;
+
+private:
+
+ void init( const point_t& dimensions
+ , const std::size_t num_colors
+ )
+ {
+ typedef indexed_image_deref_fn< indices_locator_t
+ , palette_locator_t
+ > defer_fn_t;
+
+ defer_fn_t deref_fn( view( _indices ).xy_at( 0, 0 )
+ , view( _palette ).xy_at( 0, 0 )
+ );
+
+ locator_t locator( point_t( 0, 0 ) // p
+ , point_t( 1, 1 ) // step
+ , deref_fn
+ );
+
+ _view = view_t( dimensions
+ , num_colors
+ , locator
+ );
+ }
+
+private:
+
+ indices_t _indices;
+ palette_t _palette;
+};
+
+template< typename Index
+ , typename Pixel
+ >
+inline
+const typename indexed_image< Index, Pixel >::view_t& view( indexed_image< Index, Pixel >& img )
+{
+ return img._view;
+}
+
+template< typename Index
+ , typename Pixel
+ >
+inline
+const typename indexed_image< Index, Pixel >::const_view_t const_view( indexed_image< Index, Pixel >& img )
+{
+ return static_cast< const typename indexed_image< Index, Pixel >::const_view_t>( img._view );
+}
+
+// Whole image has one color and all indices are set to 0.
+template< typename Locator
+ , typename Value
+ >
+void fill_pixels( const indexed_image_view< Locator >& view
+ , const Value& value
+ )
+{
+ typedef indexed_image_view< Locator > view_t;
+
+ fill_pixels( view.get_indices_view(), typename view_t::indices_view_t::value_type( 0 ));
+ *view.get_palette_view().begin() = value;
+}
+
+} // namespace gil
+} // namespace boost
+
+#endif // BOOST_GIL_EXTENSION_TOOLBOX_IMAGE_TYPES_INDEXED_IMAGE_HPP