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