123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- //
- // Copyright 2012 Christian Henning
- //
- // 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_EXTENSION_TOOLBOX_IMAGE_TYPES_INDEXED_IMAGE_HPP
- #define BOOST_GIL_EXTENSION_TOOLBOX_IMAGE_TYPES_INDEXED_IMAGE_HPP
- #include <boost/gil/extension/toolbox/metafunctions/is_bit_aligned.hpp>
- #include <boost/gil/image.hpp>
- #include <boost/gil/point.hpp>
- #include <boost/gil/virtual_locator.hpp>
- #include <boost/gil/detail/is_channel_integral.hpp>
- #include <boost/gil/detail/mp11.hpp>
- #include <cstddef>
- #include <memory>
- namespace boost { namespace gil {
- template< typename Locator >
- struct get_pixel_type_locator
- {
- using type = mp11::mp_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
- {
- using indices_locator_t = IndicesLoc;
- using palette_locator_t = PaletteLoc;
- //using index_t = typename get_pixel_type_locator<indices_locator_t>::type;
- using const_t = indexed_image_deref_fn_base<IndicesLoc, PaletteLoc>;
- using value_type = typename PaletteLoc::value_type;
- using reference = value_type;
- using const_reference = value_type;
- using argument_type = point_t;
- using result_type = reference;
- 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
- >
- {
- using base_t = indexed_image_deref_fn_base
- <
- IndicesLoc,
- PaletteLoc
- >;
- 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 std::enable_if
- <
- detail::is_channel_integral<typename IndicesLoc::value_type>::value
- >::type
- > : indexed_image_deref_fn_base<IndicesLoc, PaletteLoc>
- {
- using base_t = indexed_image_deref_fn_base<IndicesLoc, PaletteLoc>;
- indexed_image_deref_fn() : base_t() {}
- indexed_image_deref_fn(
- typename base_t::indices_locator_t const& indices_loc,
- typename base_t::palette_locator_t const& palette_loc)
- : base_t(indices_loc, palette_loc)
- {
- }
- typename base_t::result_type operator()(point_t const& 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
- {
- using type = virtual_2d_locator
- <
- indexed_image_deref_fn<IndicesLoc, PaletteLoc>,
- false
- >;
- };
- template< typename Locator > // indexed_image_locator_type< ... >::type
- class indexed_image_view : public image_view< Locator >
- {
- public:
- using deref_fn_t = typename Locator::deref_fn_t;
- using indices_locator_t = typename deref_fn_t::indices_locator_t;
- using palette_locator_t = typename deref_fn_t::palette_locator_t;
- using const_t = indexed_image_view<Locator>;
- using indices_view_t = image_view<indices_locator_t>;
- using palette_view_t = image_view<palette_locator_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)
- {
- using view_t = indexed_image_view
- <
- typename indexed_image_locator_type
- <
- typename Index_View::locator,
- typename Palette_View::locator
- >::type
- >;
- using defer_fn_t = indexed_image_deref_fn
- <
- typename Index_View::locator,
- typename Palette_View::locator
- >;
- 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:
- using indices_t = image<Index, false, IndicesAllocator>;
- using palette_t = image<Pixel, false, PalleteAllocator>;
- using indices_view_t = typename indices_t::view_t;
- using palette_view_t = typename palette_t::view_t;
- using indices_const_view_t = typename indices_t::const_view_t;
- using palette_const_view_t = typename palette_t::const_view_t;
- using indices_locator_t = typename indices_view_t::locator;
- using palette_locator_t = typename palette_view_t::locator;
- using locator_t = typename indexed_image_locator_type
- <
- indices_locator_t,
- palette_locator_t
- >::type;
- using x_coord_t = typename indices_t::coord_t;
- using y_coord_t = typename indices_t::coord_t;
- using view_t = indexed_image_view<locator_t>;
- using const_view_t = typename view_t::const_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
- )
- {
- using defer_fn_t = indexed_image_deref_fn
- <
- indices_locator_t,
- palette_locator_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
- )
- {
- using view_t = indexed_image_view<Locator>;
- 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
|