TuttleOFX
1
|
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