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