contrib/tbl/vipl/filter/vipl_filter.txx

Go to the documentation of this file.
00001 // This is tbl/vipl/filter/vipl_filter.txx
00002 #ifndef vipl_filter_txx_
00003 #define vipl_filter_txx_
00004 //:
00005 // \file
00006 
00007 #include "vipl_filter.h"
00008 #include <vcl_iostream.h>
00009 #include <vcl_algorithm.h> // for vcl_max and vcl_min
00010 
00011 #ifdef VCL_VC
00012 #pragma warning( disable: 4390 )
00013 #endif
00014 
00015 #if !VCL_STATIC_CONST_INIT_INT_NO_DEFN
00016 template <class ImgIn,class ImgOut,class DataIn,class DataOut,int Arity,class PixelItr>
00017 const VIPL_FILTER_STATE vipl_filter<ImgIn,ImgOut,DataIn,DataOut,Arity,PixelItr>::Not_Ready VCL_STATIC_CONST_INIT_INT_DEFN( 0 );
00018 template <class ImgIn,class ImgOut,class DataIn,class DataOut,int Arity,class PixelItr>
00019 const VIPL_FILTER_STATE vipl_filter<ImgIn,ImgOut,DataIn,DataOut,Arity,PixelItr>::Ready VCL_STATIC_CONST_INIT_INT_DEFN( 1 );
00020 template <class ImgIn,class ImgOut,class DataIn,class DataOut,int Arity,class PixelItr>
00021 const VIPL_FILTER_STATE vipl_filter<ImgIn,ImgOut,DataIn,DataOut,Arity,PixelItr>::Unchanged VCL_STATIC_CONST_INIT_INT_DEFN( 2 );
00022 template <class ImgIn,class ImgOut,class DataIn,class DataOut,int Arity,class PixelItr>
00023 const VIPL_FILTER_STATE vipl_filter<ImgIn,ImgOut,DataIn,DataOut,Arity,PixelItr>::Filter_Owned VCL_STATIC_CONST_INIT_INT_DEFN( 4 );
00024 #endif
00025 
00026 //: A workhorse constructor for this abstract class.
00027 // If dst_image (by default) the output will be generated automatically when
00028 // filtering is about to proceed.
00029 // (Either way, the filter increments refcount when set and
00030 // decrements the refcount of the output when it is destroyed.) Some filters
00031 // support multiple inputs, if ninputs is >1 then this constructor expects
00032 // src_img to be the first element pointer to the input (i.e. src_img+1 is
00033 // the location of input image2). Note that the filter keeps pointers to the
00034 // input (properly refcounted).
00035 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int  Arity, class PixelItr>
00036   vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00037   ::vipl_filter( ImgIn const* src_img ,
00038                  ImgOut* dst_img ,
00039                  int ninputs,
00040                  int img_border ,
00041                  DataOut fill_val )
00042   : hsimage_border_size(img_border),
00043     hsdef_fill_value( fill_val ),
00044     hsinput_state(Ready),
00045     hsfilter_state(Not_Ready),
00046     hsoutput_state(Not_Ready),
00047     hsnuminputs(ninputs),
00048     hsinf(vcl_vector<inimagept>(hsnuminputs)),
00049     hsoutf(dst_img),
00050     hssrc_section (0),
00051     hsinsecp (0),
00052     hsdst_section (0),
00053     hssecp (0),
00054     hsinROA (NULL),
00055     hsROA (NULL),
00056     hsis_input_driven(false)
00057 {
00058 #if 0
00059   for (int j = numinputs()-1; j>=0; --j)
00060     ref_inf()[j] = 0;
00061 #endif
00062   if (dst_img) {
00063     if (UNCHANGED(output_state()))
00064       put_output_state(output_state() ^ Unchanged);
00065     if (FILTER_OWNED(output_state())) {
00066       put_output_state(output_state() ^ Filter_Owned);
00067 #if 0
00068       if (READY(output_state())) FILTER_IMPTR_DEC_REFCOUNT(ref_outf());
00069 #endif
00070     }
00071     if (NOT_READY(output_state()))
00072       put_output_state(output_state() | Ready);
00073 #if 0
00074     FILTER_IMPTR_INC_REFCOUNT(dst_img);
00075 #endif
00076   }
00077   for (int i=0; i< ninputs; i++) {
00078     ref_inf()[i] = src_img;
00079     if (src_img) src_img++; // if real, go to next one
00080 #if 0
00081     if (ref_inf()[i]) FILTER_IMPTR_INC_REFCOUNT(((ImgIn*)ref_inf()[i]));
00082 #endif
00083   }
00084 }
00085 
00086 //: A second workhorse constructor for this abstract class.
00087 // If dst_img is null (by default), the output will be generated automatically
00088 // when filtering is about to proceed. The filter decrements the refcount of the
00089 // output when it is destroyed. Some filters support multiple inputs, if
00090 // ninputs is >1 then this constructor uses non_consecutive input images (with
00091 // their address in a c_vector, i.e. *(src_img+1) is the location of input
00092 // image2). Note that the filter keeps pointers to the input (properly
00093 // refcounted).
00094 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00095   vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00096   ::vipl_filter( ImgIn const** src_img ,
00097                  ImgOut* dst_img ,
00098                  int ninputs,
00099                  int img_border ,
00100                  DataOut fill_val)
00101   : hsimage_border_size(img_border),
00102     hsdef_fill_value( fill_val ),
00103     hsinput_state(Ready),
00104     hsfilter_state(Not_Ready),
00105     hsoutput_state(Not_Ready),
00106     hsnuminputs(ninputs),
00107     hsinf(vcl_vector<inimagept>(hsnuminputs)),
00108     hsoutf(dst_img),
00109     hssrc_section (0),
00110     hsinsecp (0),
00111     hsdst_section (0),
00112     hssecp (0),
00113     hsinROA (NULL),
00114     hsROA (NULL),
00115     hsis_input_driven(false)
00116 {
00117 #if 0
00118   for (int j = numinputs()-1; j>=0; --j)
00119     ref_inf()[j] = 0;
00120 #endif
00121   if (dst_img) {
00122     if (UNCHANGED(output_state()))
00123       put_output_state(output_state() ^ Unchanged);
00124     if (FILTER_OWNED(output_state())) {
00125       put_output_state(output_state() ^ Filter_Owned);
00126 #if 0
00127       if (READY(output_state())) FILTER_IMPTR_DEC_REFCOUNT(ref_outf());
00128 #endif
00129     }
00130     if (NOT_READY(output_state()))
00131       put_output_state(output_state() | Ready);
00132 #if 0
00133     FILTER_IMPTR_INC_REFCOUNT(dst_img);
00134 #endif
00135   }
00136   for (int i=0; i< ninputs; i++, src_img++) {
00137     if (src_img == 0)
00138       vcl_cerr << "filter ctor passed vector will null src_img pointers, ignored them watch out.\n";
00139     else
00140       ref_inf()[i] = *src_img;
00141 #if 0
00142     if (ref_inf()[i]) FILTER_IMPTR_INC_REFCOUNT(((ImgIn*)ref_inf()[i]));
00143 #endif
00144   }
00145 }
00146 
00147 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00148   vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00149   ::~vipl_filter()
00150 {
00151 #ifdef DEBUG
00152   vcl_cout << "destructor for abstract class filter called " << this << vcl_endl;
00153 #endif
00154 #ifndef SMARTPTR
00155   if (ref_src_section()) FILTER_IMPTR_DEC_REFCOUNT(ref_src_section()); // dec_refcount or kill it
00156   if (ref_dst_section()) FILTER_IMPTR_DEC_REFCOUNT(ref_dst_section()); // dec_refcount or kill it
00157   if (ref_secp())        FILTER_IMPTR_DEC_REFCOUNT(ref_secp()); // dec_refcount or kill it
00158   if (ref_insecp())      FILTER_IMPTR_DEC_REFCOUNT(ref_insecp()); // dec_refcount or kill it
00159   if (ref_ROA())         FILTER_IMPTR_DEC_REFCOUNT(ref_ROA()); // dec_refcount or kill it
00160   if (ref_inROA())       FILTER_IMPTR_DEC_REFCOUNT(ref_inROA()); // dec_refcount or kill it
00161 #if 0
00162   for (int i=0; i< numinputs(); i++) {
00163     if (ref_inf()[i]) { // no longer needed with smart pointers
00164       FILTER_IMPTR_DEC_REFCOUNT(
00165 //    ((ImgIn*) (ref_inf()[i]))); //SGI CC doesn't like this...
00166       *((ImgIn**)(ref_inf())+i)); //FIXME, cast cause inf is const Im**
00167     }
00168   }
00169   //???  we did new (poor man's array) so we use delete????
00170   if (ref_inf()) {
00171     delete [] ref_inf();
00172     // free up new'd space
00173     ref_inf() = 0;
00174   }
00175   // delete the output and intermediate functions if they are filter-owned
00176 #if 0
00177     if (FILTER_OWNED(hsoutput_state) && hsoutf)
00178 #else
00179     if (ref_outf())
00180 #endif
00181     {
00182       FILTER_IMPTR_DEC_REFCOUNT(ref_outf());
00183     }
00184 #endif
00185 #endif
00186 }
00187 
00188 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00189   vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00190   ::vipl_filter()
00191   : hsimage_border_size(0),
00192     hsinput_state(Not_Ready),
00193     hsfilter_state(Not_Ready),
00194     hsoutput_state(Not_Ready),
00195     hsnuminputs(1),
00196     hsinf(vcl_vector<inimagept>(hsnuminputs)),
00197     hsoutf(0),
00198     hssrc_section(0),
00199     hsinsecp(0),
00200     hsdst_section(0),
00201     hssecp(0),
00202     hsinROA (NULL),
00203     hsROA (NULL),
00204     hsis_input_driven(false)
00205 {
00206 #if 0
00207   for (int i = 0; i < numinputs(); i++)
00208     ref_inf()[i] = 0;
00209 #endif
00210 }
00211 
00212 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00213   vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00214                          ::vipl_filter(vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr > const& t)
00215   : vipl_filter_abs (t),
00216     hsimage_border_size(t.hsimage_border_size),
00217     hsdef_fill_value(t.hsdef_fill_value),
00218     hsinput_state(t.hsinput_state),
00219     hsfilter_state(t.hsfilter_state),
00220     hsoutput_state(t.hsoutput_state),
00221     hsnuminputs(t.hsnuminputs),
00222     hsinf(vcl_vector<inimagept>(hsnuminputs)),
00223     hsoutf(0),
00224     hssrc_section(t.hssrc_section),
00225     hsinsecp(t.hsinsecp),
00226     hsdst_section(t.hsdst_section),
00227     hssecp(t.hssecp),
00228     hsinROA (t.hsinROA),
00229     hsROA (t.hsROA),
00230     hsis_input_driven(t.hsis_input_driven)
00231 // C++ low-level copy constructor
00232 {
00233   // you can fill special ``copy constructor'' stuff here.
00234   // All dynamic/soft attributes are copied. Thus your
00235   //code should not change any soft attributes (if you
00236   //want to change it here is should be hard because it
00237   //is always changed!) So don't change things without
00238   //knowing their form.
00239   for (int i = 0; i < numinputs(); i++) {
00240     ref_inf()[i] = t.inf()[i];
00241 #if 0
00242     if (ref_inf()[i]) FILTER_IMPTR_INC_REFCOUNT(((ImgIn*)ref_inf()[i]));
00243 #endif
00244   }
00245 #ifndef SMARTPTR
00246   if (ref_outf()) FILTER_IMPTR_INC_REFCOUNT(ref_outf());
00247   if (ref_src_section()) FILTER_IMPTR_INC_REFCOUNT(ref_src_section()); // share so inc_refcount
00248   if (ref_dst_section()) FILTER_IMPTR_INC_REFCOUNT(ref_dst_section()); // share so inc_refcount
00249   if (ref_secp()) FILTER_IMPTR_INC_REFCOUNT(ref_secp()); // share so inc_refcount
00250   if (ref_insecp()) FILTER_IMPTR_INC_REFCOUNT(ref_insecp()); // share so inc_refcount
00251   if (ref_ROA()) FILTER_IMPTR_INC_REFCOUNT(ref_ROA()); // share so inc_refcount
00252   if (ref_inROA()) FILTER_IMPTR_INC_REFCOUNT(ref_inROA()); // share so inc_refcount
00253 #endif
00254   // FIXME should we do deep copy of filter-ownable parameters.???
00255   if (FILTER_OWNED(hsoutput_state))
00256     hsoutput_state ^= Filter_Owned;
00257 }
00258 
00259 //:
00260 // Is the current apply section intersected with the ROA an empty region, if
00261 // so we should not load it. If its empty there is no guarantee that the
00262 // section_start and section_end will not overlap.
00263 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00264   int vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00265                    ::is_section_within_ROA(int axis) const
00266 {
00267   if (is_input_driven()) { // if we are input driven
00268     if (!inROA())
00269   // if we don't have an ROA we must be in it.
00270       return true;
00271     // should this consider insecp???????
00272     if (insecp()) { // ok have a valid section .
00273       for (int i =0; i < Arity; i++){
00274         if ((insecp()->curr_sec_start(axis) > inROA()->curr_sec_end(axis)) ||
00275             (insecp()->curr_sec_end(axis) < inROA()->curr_sec_start(axis)))
00276           return false;
00277       }
00278       return true;
00279   // if we make it this far, must be in
00280     }
00281   } else {
00282     // if we don't have an ROA we must be in it.
00283     if (!ROA())
00284       return true;
00285     // should this consider secp or insecp???????
00286     if (secp()) { // ok have a valid section .
00287       for (int i =0; i < Arity; i++) {
00288         if ((secp()->curr_sec_start(axis) > ROA()->curr_sec_end(axis)) ||
00289             (secp()->curr_sec_end(axis) < ROA()->curr_sec_start(axis)))
00290           return false;
00291       }
00292       return true;
00293   // if we make it this far, must be in
00294     }
00295   }
00296   // error if reaching this point:
00297   vcl_cerr << "Warning: called is_section_within_ROA but no valid sections defined. Returning 0\n";
00298   return 0;
00299 }
00300 
00301 //: What is the ``start coordinate'' for the current apply section.
00302 // This always leaves a border around the section. (E.g. if there is no ROA this
00303 // is actual section start + image_boarder_size;  remember section iteration
00304 // overlaps).  If the current section is outside the ROA, the section_start
00305 // and section_end may be equal.
00306 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00307   int vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00308                      ::start(int axis) const
00309 {
00310   if (is_input_driven()) return start_src(axis);
00311   else  return start_dst(axis);
00312 }
00313 
00314 //: What is the ``start'' coordinate for the current source apply section.
00315 // This always leaves a border around the section. (E.g. if there is no ROA this
00316 // is actual section start + image_boarder_size;  remember section iteration
00317 // overlaps).  If the current section is outside the ROA, the section_start
00318 // and section_end may be equal.
00319 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00320   int vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00321                      ::start_src(int axis) const
00322 {
00323   if (insecp()){ // ok have a valid section
00324     int ibs = image_border_size();
00325     int end = insecp()->curr_sec_end(axis);
00326     int st = insecp()->curr_sec_start(axis);
00327     if (st > end){ // swap hack in case people get it wrong....
00328       int temp = end; end = st; st = temp;
00329     }
00330     st += ibs;
00331     end -= ibs;
00332     if (inROA())
00333       st =vcl_min(end,vcl_max(st,inROA()->curr_sec_start(axis)+ibs));
00334 #ifdef DEBUG
00335     vcl_cerr << "i_ [" << axis << "] st=" << st << " ibs=" << ibs << vcl_endl;
00336 #endif
00337     return st;
00338   }
00339 
00340   // error if reaching this point:
00341   vcl_cerr << "Warning: called start_src but no valid sections defined. Returning 0\n";
00342   return 0;
00343 }
00344 
00345 
00346 //: What is the ``start'' coordinate for the current destination apply section.
00347 // This always leaves a border around the section. (E.g. if there is no ROA this
00348 // is actual section start + image_boarder_size;  remember section iteration
00349 // overlaps).  If the current section is outside the ROA, the section_start
00350 // and section_end may be equal.
00351 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00352   int vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00353                      ::start_dst(int axis) const
00354 {
00355   // should we consider secp or insecp????
00356   if (secp()){ // ok have a valid section
00357     int ibs = image_border_size();
00358     int end = secp()->curr_sec_end(axis);
00359     int st = secp()->curr_sec_start(axis);
00360     if (st > end){ // swap hack in case people get it wrong....
00361       int temp = end; end = st; st = temp;
00362     }
00363     st += ibs;
00364     end -= ibs;
00365     if (ROA())
00366       st = vcl_min(end,vcl_max(st,ROA()->curr_sec_start(axis)+ibs));
00367 #ifdef DEBUG
00368     vcl_cerr << "o_ [" << axis << "] st=" << st << " ibs=" << ibs << vcl_endl;
00369 #endif
00370     return st;
00371   }
00372 
00373   // error if reaching this point:
00374   vcl_cerr << "Warning: called start_dst but no valid sections defined. Returning 0\n";
00375   return 0;
00376 }
00377 
00378 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00379   int vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00380                      ::start(int axis, int /*other_axis_value*/) const
00381 { return start(axis); }
00382 
00383 //: What is the ``stopping'' coordinate for the current apply section.
00384 // This always leaves a border around the section. (E.g. if there is no ROA this
00385 // is actual section end - image_boarder_size;  remember section iteration
00386 // overlaps).  If the current section is outside the ROA, the section_start
00387 // and section_end may be equal.
00388 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00389   int vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00390                      ::stop(int axis) const
00391 {
00392   if (is_input_driven()) return stop_src(axis);
00393   else  return stop_dst(axis);
00394 }
00395 
00396 
00397 //: What is the ``stopping'' coordinate for the current apply section.
00398 // This always leaves a border around the section. (E.g. if there is no ROA this
00399 // is actual section end - image_boarder_size;  remember section iteration
00400 // overlaps).  If the current section is outside the ROA, the section_start
00401 // and section_end may be equal.
00402 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00403   int vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00404                      ::stop_src(int axis) const
00405 {
00406   if (insecp()){ // ok have a valid section
00407     int ibs = image_border_size();
00408     int end = insecp()->curr_sec_end(axis);
00409     int st = insecp()->curr_sec_start(axis);
00410     if (st > end){ // hack in case people get it wrong....
00411       end = st;
00412     }
00413     end -= ibs;
00414 #ifdef DEBUG
00415     vcl_cerr << "_i [" << axis << "] end=" << end << " ibs=" << ibs << vcl_endl;
00416 #endif
00417     return end;
00418   }
00419 
00420   // error if reaching this point:
00421   vcl_cerr << "Warning: called stop_src but no valid sections defined. Returning 0\n";
00422   return 0;
00423 }
00424 
00425 
00426 //: What is the ``stopping'' coordinate for the current apply section.
00427 // This always leaves a border around the section. (E.g. if there is no ROA this
00428 // is actual section end - image_boarder_size;  remember section iteration
00429 // overlaps).  If the current section is outside the ROA, the section_start
00430 // and section_end may be equal.
00431 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00432   int vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00433                      ::stop_dst(int axis) const
00434 {
00435   // should we consider secp or insecp????
00436   if (secp()){ // ok have a valid section
00437     int ibs = image_border_size();
00438     int end = secp()->curr_sec_end(axis);
00439     int st = secp()->curr_sec_start(axis);
00440     if (st > end){ // hack in case people get it wrong....
00441       end = st;
00442     }
00443     end -= ibs;
00444 #ifdef DEBUG
00445     vcl_cerr << "_o [" << axis << "] end=" << end << " ibs=" << ibs << vcl_endl;
00446 #endif
00447     return end;
00448   }
00449 
00450   // error if reaching this point:
00451   vcl_cerr << "Warning: called stop_dst but no valid sections defined. Returning 0\n";
00452   return 0;
00453 }
00454 
00455 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00456   int vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00457                      ::stop(int axis, int /*other_axis_value*/) const
00458 { return stop(axis); }
00459 
00460 // Put the given pointer into the array of input ``functions'' at the
00461 // provided index. Decrements old objects refcount, Inc's newobjects
00462 // refcount
00463 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00464   bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00465                         ::put_in_data_ptr(ImgIn const* fpointer , int index)
00466 {
00467   if (UNCHANGED(input_state()) || NOT_READY(input_state()))
00468     ref_input_state() = Ready;
00469   if ( 0 <= index && index < numinputs()) {
00470 #if 0
00471     if (ref_inf()[index]) { // no longer needed for smart pointers
00472       // FILTER_IMPTR_DEC_REFCOUNT(((ImgIn*)ref_inf()[index])); //SGI CC doesn't like this...
00473       FILTER_IMPTR_DEC_REFCOUNT(*((ImgIn**)(ref_inf())+index)); // release old
00474     }
00475 #endif
00476     ref_inf()[index] = fpointer;
00477 #if 0
00478     if (fpointer) FILTER_IMPTR_INC_REFCOUNT(((ImgIn*)fpointer)); // mark new
00479 #endif
00480     return true;
00481   }
00482   // error if reaching this point:
00483   vcl_cerr << "Warning: index out of range in put_in_data_ptr, ignored\n";
00484   return false;
00485 }
00486 
00487 // Return a pointer to the input ``functions'' at the provided
00488 // index. Increments refcount before returning
00489 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00490   ImgIn const* vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00491                           ::in_data_ptr(int index)
00492 {
00493   if (index < 0 || index >= numinputs()) {
00494     vcl_cerr << "Warning: index " << index << " out of range, returning data at 0 instead\n";
00495     index = 0;
00496   }
00497   return inf()[index];
00498 }
00499 
00500 //: Return a ref to the input ``data object'' at the provided index.
00501 // (dereferences the internal pointer)
00502 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00503   const ImgIn& vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr>
00504                            ::in_data(int index) const
00505 {
00506   if (0 <= index && index < numinputs()) {
00507     if (inf()[index])
00508       return *inf()[index];
00509     else {
00510       vcl_cerr << "Warning: input pointer is null returning image at index 0\n";
00511       return *inf()[0];
00512     }
00513   } //else
00514    vcl_cerr << "Warning: out of range is null, a new val, it will leak\n";
00515    return *inf()[0];
00516 }
00517 
00518 //: Put the given pointer into output data at the given index location.
00519 // Decrements old putput refcount, increments newobjects refcount.
00520 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00521   bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00522                         ::put_out_data_ptr(ImgOut* fpointer , int /*index*/)
00523 {
00524   if (UNCHANGED(output_state()))    put_output_state(output_state() ^ Unchanged);
00525   if (FILTER_OWNED(output_state())) put_output_state(output_state() ^ Filter_Owned);
00526 #if 0
00527   if (ref_outf())                   FILTER_IMPTR_DEC_REFCOUNT(ref_outf());
00528 #endif
00529   if (NOT_READY(output_state()))    put_output_state(output_state() | Ready);
00530 #if 0
00531   FILTER_IMPTR_INC_REFCOUNT(fpointer); // we will keep a pointer, inc it
00532 #endif
00533   put_outf(fpointer);
00534   return true;
00535 }
00536 
00537 //: Get ptr to specified output data item given index location.
00538 // Inc's refcount before returning ptr.
00539 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00540   ImgOut* vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00541                      ::out_data_ptr(int /*index*/)
00542 {
00543   if (READY(output_state()) || UNCHANGED(output_state()))
00544     put_output_state(output_state() ^ Unchanged);
00545   if (READY(output_state()) )
00546     return ref_outf();
00547   else {
00548     vcl_cerr << "Warning: Tried to reference a NOT READY output-data, returned 0\n";
00549     return 0;
00550   }
00551 }
00552 
00553 //: Get ref to specified output data item given index location.
00554 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00555    ImgOut& vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr>
00556                             ::out_data(int /*index*/) const
00557 {
00558   if (READY(output_state()) )
00559     return *outf();
00560   else {
00561     vcl_cerr << "Warning: Tried to reference a NOT READY output-returning old input, may coredump\n";
00562     return *outf();
00563   }
00564 }
00565 
00566 //: This function gets called for every iteration of the filtering operation, before the actual filtering routine.
00567 // Can be used for input normalization or such. Default op is noop.
00568 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00569   bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00570                       ::preop()
00571 {
00572   return true;
00573 }
00574 
00575 //: This function gets called after every iteration of the actual filtering routine.
00576 // Can be used for post_processing normalization or cleaning up the edges. Default op is noop.
00577 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00578   bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00579                       ::postop()
00580 {
00581   return true;
00582 }
00583 
00584 //: This is the method that implements the basic form for the filtering operation.
00585 // For each section, this method runs before section_applyop. Default at this
00586 // level is noop. (lower level class redefine it to ``fill'' the image borders).
00587 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00588   bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00589                       ::section_preop()
00590 {
00591   return true;
00592 }
00593 
00594 //: For each section, this method runs after section_applyop.
00595 // Default is noop
00596 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00597   bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00598                      ::section_postop()
00599 {
00600   return true;
00601 }
00602 
00603 //: This is the method that implements the filtering inside each section.
00604 // You must supply this function.
00605 // If a section is pointer safe, then this function is called to filter
00606 // it. Default is just to call the non-pointer section_applyop
00607 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00608   bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00609                       ::ptr_based_section_applyop()
00610 {
00611   return section_applyop();
00612 }
00613 
00614 //:
00615 // Before this function can run to completion, all arguments must be set via
00616 // the respective ``put_*'' functions (or be supplied at
00617 // construction time). Particularly important is the filter input. The
00618 // programmer should take a look at the concrete child classes of filter to
00619 // see what additional parameters they need before the actual filter
00620 // operation can proceed.
00621 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00622   bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00623                      ::filter()
00624 {
00625   bool proceed_anyway = false;
00626   if (NOT_READY(input_state())) {
00627     // first make sure that the filter is ready to proceed
00628     ref_filter_state() = Not_Ready;
00629     vcl_cerr << "Warning: filtering without valid input\n";
00630     return false;
00631   } else if (UNCHANGED(input_state())) {
00632     ref_filter_state() |= Unchanged;
00633   } else
00634     ref_filter_state() |= Ready;
00635   if (NOT_READY(output_state()) || (FILTER_OWNED(output_state()) &&
00636                                     CHANGED(input_state()))) {
00637     // be conservative - if input has changed, then may need to regen the
00638     // output since we can not compare respective sizes .
00639 #if 0
00640     if (outf()) FILTER_IMPTR_DEC_REFCOUNT(ref_outf());
00641 #endif
00642     vcl_cerr << "Warning: Input changed after output set.  Sizes may not match...\n";
00643   }
00644   if ((check_params_1(proceed_anyway) &&
00645       READY(filter_state()) && CHANGED(filter_state())) || proceed_anyway) {
00646     return applyop();
00647   }
00648   return proceed_anyway;
00649 }
00650 
00651 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00652   bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00653                        ::is_ready() const
00654 {
00655   bool proceeding=false;
00656   return check_params_1(proceeding) && !proceeding;
00657 }
00658 
00659 //:
00660 // For those filters that only need one input and output set (after
00661 // construction), the following function allows one to treat the filter
00662 // object more like a function calling
00663 //     obj.process(inimg, outimg)
00664 // will set the input and output then call filter()
00665 // It does not require pointers but takes the address of its
00666 // inputs, set the fields in the filter
00667 // does the filter and un-sets the in/out fields in the filter.
00668 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00669 bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00670                      ::process( ImgIn const& inimg, ImgOut& outimg)
00671 {
00672   put_in_data_ptr(&inimg);
00673   put_out_data_ptr(&outimg);
00674   bool ret = filter(); // do the real work
00675   put_in_data_ptr(0);  // reset input
00676   put_out_data_ptr(0); // reset output
00677   return ret;
00678 }
00679 
00680 //: second process form passing imgs by ptr.
00681 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00682 bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00683                      ::process( ImgIn const* inimg, ImgOut* outimg)
00684 {
00685   put_in_data_ptr(inimg);
00686   put_out_data_ptr(outimg);
00687   bool ret = filter(); // do the real work
00688   put_in_data_ptr(0);  // reset input
00689   put_out_data_ptr(0); // reset output
00690   return ret;
00691 }
00692 
00693 //:
00694 // Called by \usemethod {filter()} and checks additional parameters required
00695 // before the filtering operation can proceed. Default is empty_func
00696 // returning true, but subclasses can define as then need.  check_parms_1
00697 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00698   bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00699                         ::check_params_1( bool& proceed_on_warn) const
00700 {
00701   proceed_on_warn = true;
00702   // check input and output are OK.
00703   return !NOT_READY(output_state()) && !NOT_READY(input_state());
00704 }
00705 
00706 #ifdef USE_COMPOSE_WITH
00707 //:
00708 // Try to set the output of this filter to be the input of ``to'', and
00709 // if possible make the filtering more efficient than just sequential
00710 // calls. Currently unimplemented so far this function does
00711 // nothing. Arg should be a nonconst ref because composition may
00712 // change the filter!
00713 template < class ImgIn, class ImgOut, class DataIn, class DataOut, int Arity, class PixelItr>
00714   bool vipl_filter< ImgIn, ImgOut, DataIn, DataOut, Arity, PixelItr >
00715                       ::compose_with(vipl_filter_abs& to)
00716 {
00717   vcl_cerr << "Warning: called unimplemented method compose_with\n";
00718   return false;
00719 }
00720 #endif
00721 
00722 #endif // vipl_filter_txx_

Generated on Sat Nov 22 05:13:28 2008 for contrib/tbl/vipl by  doxygen 1.5.1