TuttleOFX  1
OverlayData.hpp
Go to the documentation of this file.
00001 #ifndef OVERLAYDATA_HPP
00002 #define OVERLAYDATA_HPP
00003 
00004 #include "HistogramDefinitions.hpp"
00005 
00006 #include <tuttle/plugin/memory/OfxAllocator.hpp>
00007 #include <tuttle/plugin/ImageEffectGilPlugin.hpp>
00008 
00009 #include <boost/gil/extension/color/hsl.hpp>
00010 #include <boost/multi_array.hpp>
00011 #include <boost/array.hpp>
00012 
00013 namespace tuttle {
00014 namespace plugin {
00015 namespace histogram {
00016 
00017 typedef long Number;
00018 typedef std::vector<Number, OfxAllocator<Number> > HistogramVector;
00019 
00020 /*
00021  * structure of 7 buffers (contains histogram data)
00022  */
00023 struct HistogramBufferData
00024 {
00025         //step
00026         int _step;                                                              //nbStep (for computing and display)
00027         //RGB
00028         HistogramVector _bufferRed;                     //R
00029         HistogramVector _bufferGreen;           //G
00030         HistogramVector _bufferBlue;            //B
00031         ///HLS
00032         HistogramVector _bufferHue;                     //H
00033         HistogramVector _bufferLightness;       //S
00034         HistogramVector _bufferSaturation;      //L
00035         //Alpha
00036         HistogramVector _bufferAlpha;           //alpha
00037 };
00038 
00039 /*
00040  * structure which contains selection average for each channel to display average bar
00041  */
00042 struct AverageBarData
00043 {
00044         //RGB
00045         int _averageRed;                                //R
00046         int _averageGreen;                              //G
00047         int _averageBlue;                               //B
00048         //HSL
00049         int _averageHue;                                //H
00050         int _averageSaturation;                 //S
00051         int _averageLightness;                  //L
00052 };
00053 
00054 /*
00055  *functor to compute selection histograms
00056  */
00057 typedef boost::multi_array<unsigned char,2, OfxAllocator<unsigned char> > bool_2d;
00058 
00059 
00060 struct Pixel_compute_histograms
00061 {
00062     HistogramBufferData& _data;         //HistogramBufferData to fill up
00063         bool_2d& _imgBool;                              //bool selection img (pixels)
00064         std::ssize_t _height;                   //height of src clip
00065         std::ssize_t _width;                    //width of src clip
00066         std::ssize_t _y, _x;                    //position of the current pixel (functor needs to know which pixel is it)
00067         bool _isSelectionMode;                  //do we work on all of the pixels (normal histograms) or only on selection
00068         
00069         Pixel_compute_histograms( bool_2d& selection, HistogramBufferData& data, const bool isSelectionMode )
00070         : _data( data )
00071         , _imgBool( selection )
00072         , _height( _imgBool.shape()[0] )
00073         , _width( _imgBool.shape()[1] )
00074         , _y(0)
00075         , _x(0)
00076         , _isSelectionMode(isSelectionMode)
00077         {
00078 
00079         }
00080         
00081         //basic round function
00082     double round( const double x ) const
00083         {
00084                 if( x >= 0.5 ) { return ceil(x); } else { return floor(x); }
00085         }
00086         
00087         template< typename Pixel>
00088     Pixel operator()( const Pixel& p )
00089     {
00090         using namespace boost::gil;
00091                 bool ok = false;
00092                 
00093                 BOOST_ASSERT( _y >= 0 );
00094                 BOOST_ASSERT( _x >= 0 );
00095                 BOOST_ASSERT( std::ssize_t(_imgBool.shape()[0]) > _y );
00096                 BOOST_ASSERT( std::ssize_t(_imgBool.shape()[1]) > _x );
00097                 
00098                 //int revert_y = (_height-1)-_y;
00099                 
00100                 if(_isSelectionMode == false)
00101                         ok = true;
00102                 else if(_imgBool[_y][_x] && _isSelectionMode)
00103                         ok = true;
00104 
00105                 if(ok) //if current pixel is selected
00106                 {
00107                         int indice;
00108                         double val;
00109                         hsl32f_pixel_t hsl_pix;                 //needed to work in HSL (entry is RGBA)
00110                         rgba32f_pixel_t pix;
00111                         
00112                         color_convert( p, pix );                //convert input to RGBA
00113                         color_convert( pix, hsl_pix );  //convert RGBA tp HSL
00114                 
00115                         //RGBA
00116                         for( int v = 0; v < boost::gil::num_channels<Pixel>::type::value; ++v )
00117                         {
00118                                 val = p[v];          
00119                                 if(val >= 0 && val <= 1)
00120                                 {    
00121                                         double inter = round(val*(_data._step-1));
00122                                         indice = inter;
00123                                         if( v == 0 )
00124                                                 _data._bufferRed.at(indice) += 1;                       //increments red buffer 
00125                                         else if(v == 1)
00126                                                 _data._bufferGreen.at(indice) += 1;                     //increments green buffer 
00127                                         else if(v == 2)
00128                                                 _data._bufferBlue.at(indice) += 1;                      //increments blue buffer 
00129                                         else if(v == 3)
00130                                                 _data._bufferAlpha.at(indice) += 1;                     //increments alpha buffer 
00131                                 }
00132                         }
00133                         
00134                         //HLS
00135                         for(int v = 0; v < boost::gil::num_channels<hsl32f_pixel_t>::type::value; ++v )
00136                         {
00137                                 val = hsl_pix[v];          
00138                                 if(val >= 0 && val <= 1)
00139                                 {    
00140                                         double inter = round(val*(_data._step-1));
00141                                         indice = inter;
00142                                         if(v == 0)
00143                                                 _data._bufferHue.at(indice) += 1;                       //increments hue buffer
00144                                         else if(v == 2)
00145                                                 _data._bufferLightness.at(indice) += 1;         //increments saturation buffer
00146                                         else if(v == 1)
00147                                                 _data._bufferSaturation.at(indice) += 1;        //increments lightness buffer
00148                                 }
00149                         }
00150                 }
00151                 
00152                 //Check pixel position
00153                 ++_x;
00154                 if(_x == _width){++_y;_x=0;}
00155         return p;
00156     }
00157 };
00158 
00159 class OverlayData 
00160 {
00161 public:
00162         typedef boost::gil::rgba32f_view_t SView; // declare current view type
00163         
00164 public:
00165         OverlayData( const OfxPointI& size, const int nbSteps, const int nbStepsCurvesFromSelection);
00166         
00167         /** 
00168          * reset selection data (button clear selection)
00169          */
00170         void clearSelection()
00171         {
00172                 resetHistogramSelectionData();
00173                 removeSelection();
00174                 resetAverages();
00175         }
00176         void clearAll( const OfxPointI& size )
00177         {
00178                 _size = size;
00179                 resetHistogramData();
00180                 resetHistogramSelectionData();
00181                 removeSelection();
00182                 resetAverages();
00183         }
00184         
00185         /**
00186          * Image size checker
00187          * @warning HACK changeClip method doesn't work in nuke when time of source clip is changed so we have to check size of imgBool all the time
00188          */
00189         bool isImageSizeModified( const OfxPointI& size ) const;
00190         
00191         /**
00192          * Histogram computing
00193          */
00194         void computeFullData( OFX::Clip* clipSrc,const OfxTime time, const OfxPointD& renderScale, const bool selectionOnly = false);                   //compute full data (average/selection/histograms)
00195         void computeCurveFromSelectionData( OFX::Clip* clipSrc, const OfxTime time, const OfxPointD& renderScale);                                      //compute only selection to curve data
00196         void setNbStep( const std::size_t nbStep ) { _vNbStep = nbStep; }
00197         
00198         /**
00199          * Current time checker
00200      */
00201         bool isCurrentTimeModified(const OfxTime time) const;
00202         
00203         /**
00204          * HistoramData management
00205          */
00206         void resetCurvesFromSelectionData(); //reset curves from selection data
00207         
00208 private:
00209         /*Histogram management*/
00210         void computeHistogramBufferData( HistogramBufferData& data, SView& srcView, const OfxTime time, const bool isSelection=false);  //compute a HisogramBufferData
00211         void correctHistogramBufferData( HistogramBufferData& toCorrect ) const;                //correct a complete HistogramBufferData
00212         void resetHistogramBufferData( HistogramBufferData& toReset ) const;            //reset a complete HistogramBufferData
00213         
00214         /*Average management*/
00215         void computeAverages();         //compute average of each channel
00216         
00217         /*Reset data*/
00218         void resetHistogramData(); //reset data (if size change for example)
00219         
00220         void resetHistogramSelectionData();     //reset selection data
00221         void resetAverages();           //rest all of the averages
00222         void removeSelection();
00223         
00224         void correctVector( HistogramVector& v ) const;                                                         //correct a specific channel
00225         void resetVectortoZero( HistogramVector& v, const std::size_t size ) const;     //reset a specific channel buffer
00226         int computeAnAverage( const HistogramVector& selection_v ) const;                       //compute average of a specific channel
00227         
00228 public:
00229         ///@todo accessors
00230         HistogramBufferData _data;                              //histogram data
00231         HistogramBufferData _selectionData;             //selection histogram data
00232         HistogramBufferData _curveFromSelection;        //curve from selection histogram data
00233         
00234         AverageBarData _averageData;                    //average bar data used to display average bars
00235         bool_2d _imgBool;                                               //unsigned char 2D (use for display texture on screen)
00236         OfxTime _currentTime;                                   //time of the current frame
00237         std::size_t _vNbStep;                                   //nbStep for buffers
00238         std::size_t _vNbStepCurveFromSelection; //nbStep for curve to selection buffers
00239         bool _isComputing;
00240         
00241         bool _isDataInvalid;
00242         
00243 private:
00244         OfxPointI _size;                                                //source clip size
00245         
00246 };
00247 
00248 }
00249 }
00250 }
00251 
00252 #endif
00253