TuttleOFX  1
FloodFillProcess.tcc
Go to the documentation of this file.
00001 #include "FloodFillPlugin.hpp"
00002 
00003 #include <tuttle/plugin/ofxToGil/rect.hpp>
00004 #include <tuttle/plugin/ofxToGil/point.hpp>
00005 #include <tuttle/plugin/numeric/rectOp.hpp>
00006 #include <tuttle/plugin/memory/OfxAllocator.hpp>
00007 
00008 #include <terry/globals.hpp>
00009 #include <terry/filter/floodFill.hpp>
00010 #include <terry/algorithm/transform_pixels_progress.hpp>
00011 #include <terry/draw/fill.hpp>
00012 
00013 #include <terry/numeric/operations.hpp>
00014 #include <terry/numeric/minmax.hpp>
00015 #include <terry/channel_view.hpp>
00016 
00017 namespace tuttle {
00018 namespace plugin {
00019 namespace floodFill {
00020 
00021 template<class View>
00022 FloodFillProcess<View>::FloodFillProcess( FloodFillPlugin &effect )
00023 : ImageGilFilterProcessor<View>( effect, eImageOrientationIndependant )
00024 , _plugin( effect )
00025 {
00026         this->setNoMultiThreading();
00027 }
00028 
00029 template<class View>
00030 void FloodFillProcess<View>::setup( const OFX::RenderArguments& args )
00031 {
00032         ImageGilFilterProcessor<View>::setup( args );
00033         
00034         using namespace terry;
00035         using namespace terry::numeric;
00036 
00037         _params = _plugin.getProcessParams( args.renderScale );
00038         
00039         if( _params._relativeMinMax )
00040         {
00041 //              typedef channel_view_type<red_t,View> LocalView;
00042                 typedef kth_channel_view_type<0,View> LocalView;
00043                 typename LocalView::type localView( LocalView::make(this->_srcView) );
00044                 pixel_minmax_by_channel_t<typename LocalView::type::value_type> minmax( localView(0,0) );
00045                 terry::algorithm::transform_pixels_progress(
00046                         localView,
00047                         minmax,
00048                         *this );
00049                 
00050                 _isConstantImage = minmax.max[0] == minmax.min[0];
00051                 _lowerThres = (_params._lowerThres * (minmax.max[0]-minmax.min[0])) + minmax.min[0];
00052                 _upperThres = (_params._upperThres * (minmax.max[0]-minmax.min[0])) + minmax.min[0];
00053         }
00054         else
00055         {
00056                 _isConstantImage = false;
00057                 _lowerThres = _params._lowerThres;
00058                 _upperThres = _params._upperThres;
00059         }
00060 }
00061 
00062 /**
00063  * @brief Function called by rendering thread each time a process must be done.
00064  * @param[in] procWindowRoW  Processing window
00065  */
00066 template<class View>
00067 void FloodFillProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW )
00068 {
00069         using namespace boost::gil;
00070         using namespace terry;
00071         OfxRectI procWindowOutput = this->translateRoWToOutputClipCoordinates( procWindowRoW );
00072         
00073         static const unsigned int border = 1;
00074         const OfxRectI srcRodCrop = rectangleReduce( this->_srcPixelRod, border );
00075         const OfxRectI procWindowRoWCrop = rectanglesIntersection( procWindowRoW, srcRodCrop );
00076 
00077         terry::draw::fill_pixels( this->_dstView, ofxToGil(procWindowOutput), get_black<Pixel>() );
00078 
00079         if( _isConstantImage )
00080                 return;
00081 
00082         using namespace terry::filter::floodFill;
00083         
00084         switch( _params._method )
00085         {
00086                 case eParamMethod4:
00087                 {
00088                         flood_fill<Connexity4, IsUpper<Scalar>, IsUpper<Scalar>, View, View, OfxAllocator>(
00089                                 this->_srcView, ofxToGil(this->_srcPixelRod),
00090                                 this->_dstView, ofxToGil(this->_dstPixelRod),
00091                                 ofxToGil(procWindowRoWCrop),
00092                                 IsUpper<Scalar>(_upperThres),
00093                                 IsUpper<Scalar>(_lowerThres)
00094                                 );
00095                         break;
00096                 }
00097                 case eParamMethod8:
00098                 {
00099                         flood_fill<Connexity8, IsUpper<Scalar>, IsUpper<Scalar>, View, View, OfxAllocator>(
00100                                 this->_srcView, ofxToGil(this->_srcPixelRod),
00101                                 this->_dstView, ofxToGil(this->_dstPixelRod),
00102                                 ofxToGil(procWindowRoWCrop),
00103                                 IsUpper<Scalar>(_upperThres),
00104                                 IsUpper<Scalar>(_lowerThres)
00105                                 );
00106                         break;
00107                 }
00108                 case eParamMethodBruteForce: // not in production
00109                 {
00110 //                      flood_fill_bruteForce<IsUpper<Scalar>, IsUpper<Scalar>, View, View>(
00111 //                              this->_srcView, ofxToGil(this->_srcPixelRod),
00112 //                              this->_dstView, ofxToGil(this->_dstPixelRod),
00113 //                              ofxToGil(procWindowRoWCrop),
00114 //                              IsUpper<Scalar>(_upperThres),
00115 //                              IsUpper<Scalar>(_lowerThres)
00116 //                              );
00117                         break;
00118                 }
00119         }
00120 }
00121 
00122 }
00123 }
00124 }