TuttleOFX  1
components.hpp
Go to the documentation of this file.
00001 #ifndef _TERRY_COLOR_COMPONENTS_HPP_
00002 #define _TERRY_COLOR_COMPONENTS_HPP_
00003 
00004 #include <boost/gil/gil_config.hpp>
00005 #include <boost/gil/pixel.hpp>
00006 #include <boost/gil/color_base_algorithm.hpp>
00007 
00008 namespace terry {
00009 namespace color {
00010 namespace components{
00011 
00012 using namespace boost::gil;
00013 
00014 enum EConvertToGray{
00015         eConvertToGrayMean = 0,
00016         eConvertToGrayRec601,
00017         eConvertToGrayRec709,
00018         eConvertToGraySelectRed,
00019         eConvertToGraySelectGreen,
00020         eConvertToGraySelectBlue,
00021         eConvertToGraySelectAlpha
00022 };
00023 
00024 struct ConvertionParameters{
00025         EConvertToGray grayMethod;
00026         bool           premultiplied;
00027         ConvertionParameters():
00028                 grayMethod(eConvertToGrayRec709),
00029                 premultiplied(false)
00030         {}
00031 };
00032 
00033 // overload GIL to be sure to do unpremultiplied conversion
00034 template < typename PixelSrc, typename PixelDst >
00035 struct notPremutliplied_t
00036 {
00037         GIL_FORCEINLINE
00038         PixelDst operator()( const PixelSrc& src ) const
00039         {
00040                 PixelDst dst ;
00041                 get_color( dst, red_t() )   = get_color( src, red_t() );
00042                 get_color( dst, green_t() ) = get_color( src, green_t() );
00043                 get_color( dst, blue_t() )  = get_color( src, blue_t() );
00044                 return dst;
00045         }
00046 };
00047 
00048 template < typename PixelSrc, typename PixelDst >
00049 struct notPremutlipliedRGBA_t
00050 {
00051         GIL_FORCEINLINE
00052         PixelDst operator()( const PixelSrc& src ) const
00053         {
00054                 return PixelDst( src );
00055         }
00056 };
00057 
00058 template < typename PixelSrc, typename PixelDst >
00059 struct premutliplied_t
00060 {
00061         GIL_FORCEINLINE
00062         PixelDst operator()( const PixelSrc& src ) const
00063         {
00064                 PixelDst dst ;
00065                 get_color( dst, red_t() )   = 1.f * get_color( src, red_t() )   * get_color( src, alpha_t() );
00066                 get_color( dst, green_t() ) = 1.f * get_color( src, green_t() ) * get_color( src, alpha_t() );
00067                 get_color( dst, blue_t() )  = 1.f * get_color( src, blue_t() )  * get_color( src, alpha_t() );
00068                 return dst;
00069         }
00070 };
00071 
00072 template < typename PixelSrc, typename PixelDst >
00073 struct premutlipliedRGBA_t
00074 {
00075         GIL_FORCEINLINE
00076         PixelDst operator()( const PixelSrc& src ) const
00077         {
00078                 PixelDst dst ;
00079                 get_color( dst, red_t() )   = 1.f * get_color( src, red_t() )   * get_color( src, alpha_t() );
00080                 get_color( dst, green_t() ) = 1.f * get_color( src, green_t() ) * get_color( src, alpha_t() );
00081                 get_color( dst, blue_t() )  = 1.f * get_color( src, blue_t() )  * get_color( src, alpha_t() );
00082                 get_color( dst, alpha_t() ) = get_color( src, alpha_t() );
00083                 return dst;
00084         }
00085 };
00086 
00087 template < typename PixelSrc, typename PixelDst >
00088 struct grayMean_t
00089 {
00090         GIL_FORCEINLINE
00091         PixelDst operator()( const PixelSrc& src ) const
00092         {
00093                 PixelDst dst ;
00094                 get_color( dst, gray_color_t() ) = 1.f/3 * ( get_color( src, red_t() ) + get_color( src, green_t() ) + get_color( src, blue_t() ) );
00095                 return dst;
00096         }
00097 };
00098 
00099 template < typename PixelSrc, typename PixelDst >
00100 struct grayRec601_t
00101 {
00102         GIL_FORCEINLINE
00103         PixelDst operator()( const PixelSrc& src ) const
00104         {
00105                 PixelDst dst ;
00106                 // Y' = 0.299 R' + 0.587 G' + 0.114 B'
00107                 get_color( dst, gray_color_t() ) = ( 0.299f * get_color( src, red_t() ) + 0.587f * get_color( src, green_t() ) + 0.114f * get_color( src, blue_t() ) );
00108                 return dst;
00109         }
00110 };
00111 
00112 template < typename PixelSrc, typename PixelDst >
00113 struct grayRec709_t
00114 {
00115         GIL_FORCEINLINE
00116         PixelDst operator()( const PixelSrc& src ) const
00117         {
00118                 PixelDst dst ;
00119                 // Y' = 0.2126 R' + 0.7152 G' + 0.0722 B'
00120                 get_color( dst, gray_color_t() ) = ( 0.2126f * get_color( src, red_t() ) + 0.7152f * get_color( src, green_t() ) + 0.0722f * get_color( src, blue_t() ) );
00121                 return dst;
00122         }
00123 };
00124 
00125 template < typename PixelSrc, typename PixelDst >
00126 struct grayFromRed_t
00127 {
00128         GIL_FORCEINLINE
00129         PixelDst operator()( const PixelSrc& src ) const
00130         {
00131                 PixelDst dst ;
00132                 get_color( dst, gray_color_t() ) = get_color( src, red_t() );
00133                 return dst;
00134         }
00135 };
00136 
00137 template < typename PixelSrc, typename PixelDst >
00138 struct grayFromGreen_t
00139 {
00140         GIL_FORCEINLINE
00141         PixelDst operator()( const PixelSrc& src ) const
00142         {
00143                 PixelDst dst ;
00144                 get_color( dst, gray_color_t() ) = get_color( src, green_t() ) ;
00145                 return dst;
00146         }
00147 };
00148 
00149 template < typename PixelSrc, typename PixelDst >
00150 struct grayFromBlue_t
00151 {
00152         GIL_FORCEINLINE
00153         PixelDst operator()( const PixelSrc& src ) const
00154         {
00155                 PixelDst dst ;
00156                 get_color( dst, gray_color_t() ) = get_color( src, blue_t() ) ;
00157                 return dst;
00158         }
00159 };
00160 
00161 template < typename PixelSrc, typename PixelDst >
00162 struct grayFromAlpha_t
00163 {
00164         GIL_FORCEINLINE
00165         /*PixelDst operator()( const PixelSrc& src ) const
00166         {
00167                 PixelDst dst ;
00168                 get_color( dst, gray_color_t() ) = get_color( src, alpha_t() ) ;
00169                 return dst;
00170         }*/
00171         PixelDst operator()( const rgba32f_pixel_t& src ) const
00172         {
00173                 PixelDst dst ;
00174                 get_color( dst, gray_color_t() ) = get_color( src, alpha_t() ) ;
00175                 return dst;
00176         }
00177         PixelDst operator()( const rgba16_pixel_t& src ) const
00178         {
00179                 PixelDst dst ;
00180                 get_color( dst, gray_color_t() ) = get_color( src, alpha_t() ) ;
00181                 return dst;
00182         }
00183         PixelDst operator()( const rgba8_pixel_t& src ) const
00184         {
00185                 PixelDst dst ;
00186                 get_color( dst, gray_color_t() ) = get_color( src, alpha_t() ) ;
00187                 return dst;
00188         }
00189         PixelDst operator()( const rgb32f_pixel_t& src ) const
00190         {
00191                 PixelDst dst ;
00192                 get_color( dst, gray_color_t() ) = 0 ;
00193                 return dst;
00194         }
00195         PixelDst operator()( const rgb16_pixel_t& src ) const
00196         {
00197                 PixelDst dst ;
00198                 get_color( dst, gray_color_t() ) = 0 ;
00199                 return dst;
00200         }
00201         PixelDst operator()( const rgb8_pixel_t& src ) const
00202         {
00203                 PixelDst dst ;
00204                 get_color( dst, gray_color_t() ) = 0 ;
00205                 return dst;
00206         }
00207 };
00208 
00209 template < typename PixelSrc, typename PixelDst >
00210 struct rgbToRgba_t
00211 {
00212         GIL_FORCEINLINE
00213         PixelDst operator()( const PixelSrc& src ) const
00214         {
00215                 PixelDst dst ;
00216                 get_color( dst, red_t() )   = get_color( src, red_t() ) ;
00217                 get_color( dst, green_t() ) = get_color( src, green_t() ) ;
00218                 get_color( dst, blue_t() )  = get_color( src, blue_t() ) ;
00219                 get_color( dst, alpha_t() ) = 0 ;
00220                 return dst;
00221         }
00222 };
00223 
00224 template < typename PixelSrc, typename PixelDst >
00225 struct grayToRgb_t
00226 {
00227         GIL_FORCEINLINE
00228         PixelDst operator()( const PixelSrc& src ) const
00229         {
00230                 PixelDst dst ;
00231                 get_color( dst, red_t() )   = get_color( src, gray_color_t() ) ;
00232                 get_color( dst, green_t() ) = get_color( src, gray_color_t() ) ;
00233                 get_color( dst, blue_t() )  = get_color( src, gray_color_t() ) ;
00234                 return dst;
00235         }
00236 };
00237 
00238 template < typename PixelSrc, typename PixelDst >
00239 struct grayToRgba_t
00240 {
00241         GIL_FORCEINLINE
00242         PixelDst operator()( const PixelSrc& src ) const
00243         {
00244                 PixelDst dst ;
00245                 get_color( dst, red_t() )   = get_color( src, gray_color_t() ) ;
00246                 get_color( dst, green_t() ) = get_color( src, gray_color_t() ) ;
00247                 get_color( dst, blue_t() )  = get_color( src, gray_color_t() ) ;
00248                 get_color( dst, alpha_t() ) = 0 ;
00249                 return dst;
00250         }
00251 };
00252 
00253 template<class SView, class DView>
00254 DView& convertPremultipliedView( SView& src, DView& dst, bool premultiplied=false )
00255 {
00256         assert( src.dimensions() == dst.dimensions() );
00257         assert( src.dimensions() == dst.dimensions() );
00258         if( premultiplied )
00259         {
00260                 transform_pixels(
00261                                 src,
00262                                 dst,
00263                                 premutliplied_t< typename SView::value_type, typename DView::value_type >() );
00264         }
00265         else
00266         {
00267                 transform_pixels(
00268                                 src,
00269                                 dst,
00270                                 notPremutliplied_t< typename SView::value_type, typename DView::value_type >() );
00271         }
00272         return dst;
00273 }
00274 
00275 template<class SView, class DView>
00276 DView& convertPremultipliedRGBAView( SView& src, DView& dst, bool premultiplied=false )
00277 {
00278         assert( src.dimensions() == dst.dimensions() );
00279         assert( src.dimensions() == dst.dimensions() );
00280         if( premultiplied )
00281         {
00282                 transform_pixels(
00283                                 src,
00284                                 dst,
00285                                 premutlipliedRGBA_t< typename SView::value_type, typename DView::value_type >() );
00286         }
00287         else
00288         {
00289                 transform_pixels(
00290                                 src,
00291                                 dst,
00292                                 notPremutlipliedRGBA_t< typename SView::value_type, typename DView::value_type >() );
00293         }
00294         return dst;
00295 }
00296 
00297 template<class SView, class DView>
00298 DView& convertToGrayView( SView& src, DView& dst, EConvertToGray& grayMethod, bool premultiplied=false )
00299 {
00300         assert( src.dimensions() == dst.dimensions() );
00301         assert( src.dimensions() == dst.dimensions() );
00302         switch( grayMethod )
00303         {
00304                 case eConvertToGrayMean :
00305                         transform_pixels(
00306                                 src,
00307                                 dst,
00308                                 grayMean_t< typename SView::value_type, typename DView::value_type >() );
00309                         break;
00310                 case eConvertToGrayRec601 :
00311                         transform_pixels(
00312                                 src,
00313                                 dst,
00314                                 grayRec601_t< typename SView::value_type, typename DView::value_type >() );
00315                         break;
00316                 case eConvertToGrayRec709 :
00317                         transform_pixels(
00318                                 src,
00319                                 dst,
00320                                 grayRec709_t< typename SView::value_type, typename DView::value_type >() );
00321                         break;
00322                 case eConvertToGraySelectRed :
00323                         transform_pixels(
00324                                 src,
00325                                 dst,
00326                                 grayFromRed_t< typename SView::value_type, typename DView::value_type >() );
00327                         break;
00328                 case eConvertToGraySelectGreen :
00329                         transform_pixels(
00330                                 src,
00331                                 dst,
00332                                 grayFromGreen_t< typename SView::value_type, typename DView::value_type >() );
00333                         break;
00334                 case eConvertToGraySelectBlue :
00335                         transform_pixels(
00336                                 src,
00337                                 dst,
00338                                 grayFromBlue_t< typename SView::value_type, typename DView::value_type >() );
00339                         break;
00340                 case eConvertToGraySelectAlpha :
00341                         transform_pixels(
00342                                 src,
00343                                 dst,
00344                                 grayFromAlpha_t< typename SView::value_type, typename DView::value_type >() );
00345                         break;
00346         }
00347         return dst;
00348 }
00349 
00350 template<class SView, class DView>
00351 DView& addAlphaChannelOnView( SView& src, DView& dst, bool premultiplied=false )
00352 {
00353         assert( src.dimensions() == dst.dimensions() );
00354         assert( src.dimensions() == dst.dimensions() );
00355 
00356         transform_pixels(
00357                 src,
00358                 dst,
00359                 rgbToRgba_t< typename SView::value_type, typename DView::value_type >() );
00360         return dst;
00361 }
00362 
00363 template<class SView, class DView>
00364 DView& convertToRgbViewAndAddAlpha( SView& src, DView& dst, bool unpremultiplied=false )
00365 {
00366         assert( src.dimensions() == dst.dimensions() );
00367         assert( src.dimensions() == dst.dimensions() );
00368         
00369         transform_pixels(
00370                 src,
00371                 dst,
00372                 grayToRgba_t< typename SView::value_type, typename DView::value_type >() );
00373         return dst;
00374 }
00375 
00376 template<class SView, class DView>
00377 DView& convertToRgbView( SView& src, DView& dst, bool unpremultiplied=false )
00378 {
00379         assert( src.dimensions() == dst.dimensions() );
00380         assert( src.dimensions() == dst.dimensions() );
00381         
00382         transform_pixels(
00383                 src,
00384                 dst,
00385                 grayToRgb_t< typename SView::value_type, typename DView::value_type >() );
00386         return dst;
00387 }
00388 
00389 // generic template: use for identical components:
00390 // RGB  => RGB
00391 // Gray => Gray
00392 template<class SView, class DView>
00393 void convertComponentsView( SView& src, DView& dst, ConvertionParameters& parameters )
00394 {
00395         assert( src.dimensions() == dst.dimensions() );
00396         assert( src.dimensions() == dst.dimensions() );
00397         // if SView is similar to DView, only copy
00398         copy_and_convert_pixels( src, dst );
00399 }
00400 
00401 template<>
00402 void convertComponentsView<rgba32f_view_t, rgba32f_view_t>( rgba32f_view_t& src, rgba32f_view_t& dst, ConvertionParameters& parameters )
00403 {
00404         convertPremultipliedRGBAView( src, dst, parameters.premultiplied );
00405 }
00406 
00407 template<>
00408 void convertComponentsView<rgba16_view_t, rgba16_view_t>( rgba16_view_t& src, rgba16_view_t& dst, ConvertionParameters& parameters )
00409 {
00410         convertPremultipliedRGBAView( src, dst, parameters.premultiplied );
00411 }
00412 
00413 template<>
00414 void convertComponentsView<rgba8_view_t, rgba8_view_t>( rgba8_view_t& src, rgba8_view_t& dst, ConvertionParameters& parameters )
00415 {
00416         convertPremultipliedRGBAView( src, dst, parameters.premultiplied );
00417 }
00418 
00419 
00420 template<>
00421 void convertComponentsView<rgba32f_view_t, rgb32f_view_t>( rgba32f_view_t& src, rgb32f_view_t& dst, ConvertionParameters& parameters )
00422 {
00423         convertPremultipliedView( src, dst, parameters.premultiplied );
00424 }
00425 
00426 template<>
00427 void convertComponentsView<rgba16_view_t, rgb16_view_t>( rgba16_view_t& src, rgb16_view_t& dst, ConvertionParameters& parameters )
00428 {
00429         convertPremultipliedView( src, dst, parameters.premultiplied );
00430 }
00431 
00432 template<>
00433 void convertComponentsView<rgba8_view_t, rgb8_view_t>( rgba8_view_t& src, rgb8_view_t& dst, ConvertionParameters& parameters )
00434 {
00435         convertPremultipliedView( src, dst, parameters.premultiplied );
00436 }
00437 
00438 template<>
00439 void convertComponentsView<rgba32f_view_t, gray32f_view_t>( rgba32f_view_t& src, gray32f_view_t& dst, ConvertionParameters& parameters )
00440 {
00441         convertToGrayView( src, dst, parameters.grayMethod, parameters.premultiplied );
00442 }
00443 
00444 template<>
00445 void convertComponentsView<rgba16_view_t, gray16_view_t>( rgba16_view_t& src, gray16_view_t& dst, ConvertionParameters& parameters )
00446 {
00447         convertToGrayView( src, dst, parameters.grayMethod, parameters.premultiplied );
00448 }
00449 
00450 template<>
00451 void convertComponentsView<rgba8_view_t, gray8_view_t>( rgba8_view_t& src, gray8_view_t& dst, ConvertionParameters& parameters )
00452 {
00453         convertToGrayView( src, dst, parameters.grayMethod, parameters.premultiplied );
00454 }
00455 
00456 template<>
00457 void convertComponentsView<rgb32f_view_t, rgba32f_view_t>( rgb32f_view_t& src, rgba32f_view_t& dst, ConvertionParameters& parameters )
00458 {
00459         addAlphaChannelOnView( src, dst, parameters.premultiplied );
00460 }
00461 
00462 template<>
00463 void convertComponentsView<rgb16_view_t, rgba16_view_t>( rgb16_view_t& src, rgba16_view_t& dst, ConvertionParameters& parameters )
00464 {
00465         addAlphaChannelOnView( src, dst, parameters.premultiplied );
00466 }
00467 
00468 template<>
00469 void convertComponentsView<rgb8_view_t, rgba8_view_t>( rgb8_view_t& src, rgba8_view_t& dst, ConvertionParameters& parameters )
00470 {
00471         addAlphaChannelOnView( src, dst, parameters.premultiplied );
00472 }
00473 
00474 template<>
00475 void convertComponentsView<rgb32f_view_t, gray32f_view_t>( rgb32f_view_t& src, gray32f_view_t& dst, ConvertionParameters& parameters )
00476 {
00477         convertToGrayView( src, dst, parameters.grayMethod );
00478 }
00479 
00480 template<>
00481 void convertComponentsView<rgb16_view_t, gray16_view_t>( rgb16_view_t& src, gray16_view_t& dst, ConvertionParameters& parameters )
00482 {
00483         convertToGrayView( src, dst, parameters.grayMethod );
00484 }
00485 
00486 template<>
00487 void convertComponentsView<rgb8_view_t, gray8_view_t>( rgb8_view_t& src, gray8_view_t& dst, ConvertionParameters& parameters )
00488 {
00489         convertToGrayView( src, dst, parameters.grayMethod );
00490 }
00491 
00492 template<>
00493 void convertComponentsView<gray32f_view_t, rgba32f_view_t>( gray32f_view_t& src, rgba32f_view_t& dst, ConvertionParameters& parameters )
00494 {
00495         convertToRgbViewAndAddAlpha( src, dst );
00496 }
00497 
00498 template<>
00499 void convertComponentsView<gray16_view_t, rgba16_view_t>( gray16_view_t& src, rgba16_view_t& dst, ConvertionParameters& parameters )
00500 {
00501         convertToRgbViewAndAddAlpha( src, dst );
00502 }
00503 
00504 template<>
00505 void convertComponentsView<gray8_view_t, rgba8_view_t>( gray8_view_t& src, rgba8_view_t& dst, ConvertionParameters& parameters )
00506 {
00507         convertToRgbViewAndAddAlpha( src, dst );
00508 }
00509 
00510 template<>
00511 void convertComponentsView<gray32f_view_t, rgb32f_view_t>( gray32f_view_t& src, rgb32f_view_t& dst, ConvertionParameters& parameters )
00512 {
00513         convertToRgbView( src, dst );
00514 }
00515 
00516 template<>
00517 void convertComponentsView<gray16_view_t, rgb16_view_t>( gray16_view_t& src, rgb16_view_t& dst, ConvertionParameters& parameters )
00518 {
00519         convertToRgbView( src, dst );
00520 }
00521 
00522 template<>
00523 void convertComponentsView<gray8_view_t, rgb8_view_t>( gray8_view_t& src, rgb8_view_t& dst, ConvertionParameters& parameters )
00524 {
00525         convertToRgbView( src, dst );
00526 }
00527 
00528 }
00529 }
00530 }
00531 
00532 #endif