TuttleOFX  1
indexed_image.hpp
Go to the documentation of this file.
00001 // Copyright 2009 Christian Henning.
00002 // Distributed under the Boost Software License, Version 1.0. (See
00003 // accompanying file LICENSE_1_0.txt or copy at
00004 // http://www.boost.org/LICENSE_1_0.txt)
00005 
00006 /*************************************************************************************************/
00007 
00008 #ifndef BOOST_GIL_EXTENSION_TOOLBOX_INDEXED_IMAGE_HPP_INCLUDED
00009 #define BOOST_GIL_EXTENSION_TOOLBOX_INDEXED_IMAGE_HPP_INCLUDED
00010 
00011 ////////////////////////////////////////////////////////////////////////////////////////
00012 /// \file   indexed_image.hpp
00013 /// \brief  Indexed Image extension
00014 /// \author Christian Henning \n
00015 ////////////////////////////////////////////////////////////////////////////////////////
00016 
00017 #include <boost/type_traits/is_integral.hpp>
00018 #include <boost/utility/enable_if.hpp>
00019 
00020 #include <boost/gil/image.hpp>
00021 
00022 #include <boost/gil/extension/toolbox/gil_extensions.hpp>
00023 
00024 namespace boost { namespace gil {
00025 
00026 typedef boost::gil::point2< std::ptrdiff_t > point_t;
00027 
00028 template< typename Locator >
00029 struct get_pixel_type_locator : mpl::if_< typename is_bit_aligned< typename Locator::value_type >::type
00030                                         , typename Locator::reference
00031                                         , typename Locator::value_type
00032                                         > {};
00033 
00034 // used for virtual locator
00035 template< typename IndicesLoc
00036         , typename PaletteLoc
00037         >
00038 struct indexed_image_deref_fn_base
00039 {
00040     typedef IndicesLoc indices_locator_t;
00041     typedef PaletteLoc palette_locator_t;
00042     //typedef typename get_pixel_type_locator< indices_locator_t >::type index_t;
00043  
00044     typedef IndicesLoc indices_locator_t;
00045     typedef PaletteLoc palette_locator_t;
00046 
00047     typedef indexed_image_deref_fn_base     const_t;
00048     typedef typename PaletteLoc::value_type value_type;
00049     typedef value_type                      reference;
00050     typedef value_type                      const_reference;
00051     typedef point_t                         argument_type;
00052     typedef reference                       result_type;
00053 
00054     static const bool is_mutable = false;
00055 
00056     indexed_image_deref_fn_base() {}
00057 
00058     indexed_image_deref_fn_base( const indices_locator_t& indices_loc
00059                                , const palette_locator_t& palette_loc
00060                                )
00061     : _indices_loc( indices_loc )
00062     , _palette_loc( palette_loc )
00063     {}
00064 
00065     void set_indices( const indices_locator_t& indices_loc ) { _indices_loc = indices_loc; }
00066     void set_palette( const palette_locator_t& palette_loc ) { _palette_loc = palette_loc; }
00067 
00068     const indices_locator_t& indices() const { return _indices_loc; }
00069     const palette_locator_t& palette() const { return _palette_loc; }
00070 
00071 protected:
00072 
00073     indices_locator_t _indices_loc;
00074     palette_locator_t _palette_loc;
00075 };
00076 
00077 
00078 // used for virtual locator
00079 template< typename IndicesLoc
00080         , typename PaletteLoc
00081         , typename Enable = void // there is specilization for integral indices
00082         >
00083 struct indexed_image_deref_fn : indexed_image_deref_fn_base< IndicesLoc
00084                                                            , PaletteLoc
00085                                                            >
00086 {
00087     indexed_image_deref_fn()
00088     : indexed_image_deref_fn_base()
00089     {}
00090 
00091     indexed_image_deref_fn( const indices_locator_t& indices_loc
00092                           , const palette_locator_t& palette_loc
00093                           )
00094     : indexed_image_deref_fn_base( indices_loc
00095                                  , palette_loc
00096                                  )
00097     {}
00098 
00099     result_type operator()( const point_t& p ) const
00100     {
00101         return *_palette_loc.xy_at( at_c<0>( *_indices_loc.xy_at( p )), 0 );
00102     }
00103 };
00104 
00105 
00106 template< typename IndicesLoc
00107         , typename PaletteLoc
00108         >
00109 struct indexed_image_deref_fn< IndicesLoc
00110                              , PaletteLoc
00111                              , typename boost::enable_if< boost::is_integral< typename IndicesLoc::value_type > >::type
00112                              > : indexed_image_deref_fn_base< IndicesLoc
00113                                                             , PaletteLoc
00114                                                             >
00115 {
00116     indexed_image_deref_fn()
00117     : indexed_image_deref_fn_base()
00118     {}
00119 
00120     indexed_image_deref_fn( const indices_locator_t& indices_loc
00121                           , const palette_locator_t& palette_loc
00122                           )
00123     : indexed_image_deref_fn_base( indices_loc
00124                                  , palette_loc
00125                                  )
00126     {}
00127 
00128     result_type operator()( const point_t& p ) const
00129     {
00130         return *_palette_loc.xy_at( *_indices_loc.xy_at( p ), 0 );
00131     }
00132 };
00133 
00134 template< typename IndicesLoc
00135         , typename PaletteLoc
00136         >
00137 struct indexed_image_locator_type
00138 {
00139     typedef virtual_2d_locator< indexed_image_deref_fn< IndicesLoc
00140                                                       , PaletteLoc
00141                                                       >
00142                               , false
00143                               > type;
00144 };
00145 
00146 template< typename Locator > // indexed_image_locator_type< ... >::type
00147 class indexed_image_view : public image_view< Locator >
00148 {
00149 public:
00150 
00151     typedef typename Locator::deref_fn_t deref_fn_t;
00152     typedef typename deref_fn_t::indices_locator_t indices_locator_t;
00153     typedef typename deref_fn_t::palette_locator_t palette_locator_t;
00154 
00155     typedef indexed_image_view< Locator > const_t;
00156 
00157     typedef image_view< indices_locator_t > indices_view_t;
00158     typedef image_view< palette_locator_t > palette_view_t;
00159 
00160     indexed_image_view()
00161     : image_view()
00162     , _num_colors( 0 )
00163     {}
00164 
00165     indexed_image_view( const point_t& dimensions
00166                       , std::size_t    num_colors
00167                       , const Locator& locator
00168                       )
00169     : image_view( dimensions, locator )
00170     , _num_colors( num_colors )
00171     {}
00172 
00173     template< typename IndexedView >
00174     indexed_image_view( const IndexedView& iv )
00175     : image_view( iv )
00176     , _num_colors( iv._num_colors )
00177     {}
00178 
00179     const std::size_t num_colors() const { return _num_colors; }
00180 
00181     
00182     const indices_locator_t& indices() const { return get_deref_fn().indices(); }
00183     const palette_locator_t& palette() const { return get_deref_fn().palette(); }
00184 
00185     const indices_view_t get_indices_view() const { return indices_view_t( dimensions(), indices() ); }
00186     const palette_view_t get_palette_view() const { return palette_view_t( point_t( num_colors(), 1 )
00187                                                                          , palette()
00188                                                                          ); }
00189 
00190 private:
00191 
00192     const deref_fn_t& get_deref_fn() const { return pixels().deref_fn(); }
00193 
00194 private:
00195 
00196     template< typename Locator2 > friend class indexed_image_view;
00197 
00198     std::size_t _num_colors;
00199 };
00200 
00201 
00202 template< typename Index
00203         , typename Pixel
00204         , typename IndicesAllocator = std::allocator< unsigned char >
00205         , typename PalleteAllocator = std::allocator< unsigned char >
00206         >
00207 class indexed_image
00208 {
00209 public:
00210 
00211     typedef image< Index, false, IndicesAllocator > indices_t;
00212     typedef image< Pixel, false, PalleteAllocator > palette_t;
00213 
00214     typedef typename indices_t::view_t indices_view_t;
00215     typedef typename palette_t::view_t palette_view_t;
00216 
00217     typedef typename indices_t::const_view_t indices_const_view_t;
00218     typedef typename palette_t::const_view_t palette_const_view_t;
00219 
00220     typedef typename indices_view_t::locator indices_locator_t;
00221     typedef typename palette_view_t::locator palette_locator_t;
00222 
00223     typedef typename indexed_image_locator_type< indices_locator_t
00224                                                , palette_locator_t
00225                                                >::type locator_t;
00226 
00227     typedef typename indices_t::coord_t x_coord_t;
00228     typedef typename indices_t::coord_t y_coord_t;
00229 
00230 
00231     typedef indexed_image_view< locator_t > view_t;
00232     typedef typename view_t::const_t        const_view_t;
00233 
00234     indexed_image( const x_coord_t   width = 0
00235                  , const y_coord_t   height = 0
00236                  , const std::size_t num_colors = 1
00237                  , const std::size_t indices_alignment = 0
00238                  , const std::size_t palette_alignment = 0
00239                  )
00240     : _indices( width     , height, indices_alignment, IndicesAllocator() )
00241     , _palette( num_colors,      1, palette_alignment, PalleteAllocator() )
00242     {
00243         init( point_t( width, height ), num_colors );
00244     }
00245 
00246     indexed_image( const point_t&    dimensions
00247                  , const std::size_t num_colors = 1
00248                  , const std::size_t indices_alignment = 0
00249                  , const std::size_t palette_alignment = 0
00250                  )
00251     : _indices( dimensions,    indices_alignment, IndicesAllocator() )
00252     , _palette( num_colors, 1, palette_alignment, PalleteAllocator() )
00253     {
00254         init( dimensions, num_colors );
00255     }
00256 
00257     indexed_image( const indexed_image& img )
00258     : _indices( img._indices )
00259     , _palette( img._palette )
00260     {}
00261 
00262     template <typename Pixel2, typename Index2>
00263     indexed_image( const indexed_image< Pixel2, Index2 >& img )
00264     {
00265         _indices = img._indices;
00266         _palette = img._palette;
00267     }
00268 
00269     indexed_image& operator= ( const indexed_image& img )
00270     {
00271         _indices = img._indices;
00272         _palette = img._palette;
00273 
00274         return *this;
00275     }
00276 
00277     indices_const_view_t get_indices_const_view() const { return static_cast< indices_const_view_t >( _view.get_indices_view()); }
00278     palette_const_view_t get_palette_const_view() const { return static_cast< palette_const_view_t >( _view.get_palette_view()); }
00279 
00280     indices_view_t get_indices_view() { return _view.get_indices_view(); }
00281     palette_view_t get_palette_view() { return _view.get_palette_view(); }
00282 
00283 public:
00284 
00285     view_t _view;
00286 
00287 private:
00288 
00289     void init( const point_t&    dimensions
00290              , const std::size_t num_colors
00291              )
00292     {
00293         typedef indexed_image_deref_fn< indices_locator_t
00294                                       , palette_locator_t
00295                                       > defer_fn_t;
00296 
00297         defer_fn_t deref_fn( view( _indices ).xy_at( 0, 0 )
00298                            , view( _palette ).xy_at( 0, 0 )
00299                            );
00300 
00301         locator_t locator( point_t( 0, 0 )
00302                          , point_t( 1, 1 )
00303                          , deref_fn
00304                          );
00305 
00306         _view = view_t( dimensions
00307                       , num_colors
00308                       , locator
00309                       );
00310     }
00311 
00312 private:
00313 
00314     indices_t _indices;
00315     palette_t _palette;
00316 };
00317 
00318 template< typename Index
00319         , typename Pixel
00320         >
00321 inline 
00322 const typename indexed_image< Index, Pixel >::view_t& view( indexed_image< Index, Pixel >& img )
00323 {
00324     return img._view;
00325 }
00326 
00327 template< typename Index
00328         , typename Pixel
00329         >
00330 inline 
00331 const typename indexed_image< Index, Pixel >::const_view_t const_view( indexed_image< Index, Pixel >& img )
00332 {
00333     return static_cast< const typename indexed_image< Index, Pixel >::const_view_t>( img._view );
00334 }
00335 
00336 // Whole image has one color and all indices are set to 0.
00337 template< typename Locator
00338         , typename Value
00339         >
00340 void fill_pixels( const indexed_image_view< Locator >& view
00341                 , const Value&                         value
00342                 )
00343 {
00344     typedef indexed_image_view< Locator > view_t;
00345 
00346     fill_pixels( view.get_indices_view(), view_t::indices_view_t::value_type( 0 ));
00347     *view.get_palette_view().begin() = value;
00348 }
00349 
00350 } // gil
00351 } // boost
00352 
00353 #endif // BOOST_GIL_EXTENSION_TOOLBOX_INDEXED_IMAGE_HPP_INCLUDED