contrib/tbl/vipl/filter/vipl_filter_2d.txx
Go to the documentation of this file.
00001 // This is tbl/vipl/filter/vipl_filter_2d.txx
00002 #ifndef vipl_filter_2d_txx_
00003 #define vipl_filter_2d_txx_
00004 
00005 #include "vipl_filter_2d.h"
00006 #include <vcl_compiler.h>
00007 #include <vcl_iostream.h>
00008 
00009 // Main constructor for this abstract class. If dst_image
00010 // (by default) the output will be generated automatically when
00011 // filtering is about to proceed. (Either way, the filter
00012 // decrements the refcount of the output when it is destroyed.)
00013 // Some filters support multiple inputs, if ninputs is >1 then
00014 // this constructor expects src_img to be the first element
00015 // pointer to the input (i.e. src_img+1 is the location of input
00016 // image2). Note that the filter keeps pointers to the input
00017 // (properly refcounted). Actually the main filter constructor
00018 // does all the work
00019 template < class ImgIn,class ImgOut,class DataIn,class DataOut, class PixelItr >
00020   vipl_filter_2d< ImgIn,ImgOut,DataIn,DataOut,PixelItr >
00021   ::vipl_filter_2d(const ImgIn* src_img ,
00022                    ImgOut* dst_img ,
00023                    int ninputs,
00024                    int img_border ,
00025                    DataOut fill_val)
00026     : vipl_filter<ImgIn, ImgOut, DataIn, DataOut, 2 VCL_DFL_TMPL_ARG(vipl_trivial_pixeliter)>
00027       (src_img, dst_img, ninputs, img_border, fill_val)
00028 {}
00029 
00030 // A second the workhorse constructor for this class. If dst_img is null (by
00031 // default), the output will be generated automatically when filtering is
00032 // about to proceed. The filter decrements the refcount of the output when it
00033 // is destroyed. Some filters support multiple inputs, if ninputs is >1 then
00034 // this constructor uses non_consecutive input images (with their address in a
00035 // c_vector, i.e. *(src_img+1) is the location of input image2). Note that
00036 // the filter keeps pointers to the input (properly refcounted). Actually the
00037 // main filter constructor does all the work
00038 template < class ImgIn,class ImgOut,class DataIn,class DataOut, class PixelItr >
00039   vipl_filter_2d< ImgIn,ImgOut,DataIn,DataOut,PixelItr > ::vipl_filter_2d(
00040                 const ImgIn** src_img ,
00041                 ImgOut* dst_img ,
00042                 int ninputs,
00043                 int img_border ,
00044                 DataOut fill_val)
00045      : vipl_filter<ImgIn, ImgOut, DataIn, DataOut, 2 VCL_DFL_TMPL_ARG(vipl_trivial_pixeliter)>
00046        (src_img, dst_img, ninputs, img_border, fill_val)
00047 {}
00048 
00049 template < class ImgIn,class ImgOut,class DataIn,class DataOut, class PixelItr >
00050   vipl_filter_2d< ImgIn,ImgOut,DataIn,DataOut,PixelItr >
00051   ::vipl_filter_2d(const vipl_filter_2d< ImgIn,ImgOut,DataIn,DataOut,PixelItr > &t)
00052   :
00053   vipl_filter< ImgIn, ImgOut, DataIn, DataOut, 2 VCL_DFL_TMPL_ARG(vipl_trivial_pixeliter)> (t)
00054 // C++ special low-level copy constructor
00055 {}
00056 
00057 // This is the method that walks over the sections calling
00058 // section_applyop. Now that we know the dim we can write the loop...
00059 template < class ImgIn,class ImgOut,class DataIn,class DataOut, class PixelItr >
00060   bool vipl_filter_2d< ImgIn,ImgOut,DataIn,DataOut,PixelItr > ::applyop()
00061 {
00062   typedef typename vipl_section_container< DataIn  >::iterator iter_in;
00063   typedef typename vipl_section_container< DataOut >::iterator iter_out;
00064 
00065   // assuming that the coordinate space of input, intermediate and output are
00066   // "locked" by sectioning
00067   if (!this->ref_outf()) {
00068     vcl_cerr << "Warning: empty output image in vipl_filter_2d::applyop, returning without processing\n";
00069     return false;
00070   }
00071   // the name of the section container generator.
00072   // do not generate a new one if there is one already.
00073   if (!this->ref_dst_section()) {
00074     this->ref_dst_section() = vipl_filterable_section_container_generator(*this->ref_outf(),(DataOut*)0);
00075   }
00076   if (!this->ref_dst_section()) {
00077     vcl_cerr << "Warning: empty dst section in vipl_filter_2d::applyop, returning without processing\n";
00078     return false;
00079   }
00080   if (!this->ref_src_section()) {
00081     this->ref_src_section() = vipl_filterable_section_container_generator(*this->ref_inf()[0],(DataIn*)0);
00082   }
00083   if (!this->ref_src_section()) {
00084     vcl_cerr << "Warning: empty src section in vipl_filter_2d::applyop, presuming output driving but cannot be ptr safe\n";
00085   }
00086   this->preop(); // virtual function call
00087   this->ref_dst_section()->ref_overlap()[0] = this->image_border_size();
00088   this->ref_dst_section()->ref_overlap()[1] = this->image_border_size();
00089   if (this->ref_src_section()) {
00090     this->ref_src_section()->ref_overlap()[0] = this->image_border_size();
00091     this->ref_src_section()->ref_overlap()[1] = this->image_border_size();
00092   }
00093   iter_out enddstitr, dstitr;
00094   iter_in endsrcitr, srcitr;
00095   if (this->ref_src_section()) {
00096     endsrcitr = (*this->ref_src_section()).end();
00097     srcitr = (*this->ref_src_section()).begin();
00098   }
00099   if (this->ref_dst_section()) {
00100     enddstitr = (*this->ref_dst_section()).end();
00101     dstitr = (*this->ref_dst_section()).begin();
00102   }
00103   if (this->is_input_driven())
00104   {
00105     iter_in enditr = (*this->ref_src_section()).end();
00106     for (iter_in it = (*this->ref_src_section()).begin(); it != enditr; ++it)
00107     {
00108       if (dstitr ==enddstitr) {
00109         vcl_cerr << "Warning: In vipl_filter_2d, output iter ran out of items before input.  resetting to beginning\n";
00110         dstitr = (*this->ref_dst_section()).begin();
00111       }
00112 #ifdef VCL_VC_6 // this awkward construction is to get around a VC60 compiler bug
00113       vipl_section_descriptor<DataOut>& secDesc = *dstitr;
00114       put_secp( new vipl_section_descriptor<DataOut> (secDesc) );
00115 #else
00116       vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::put_secp( new vipl_section_descriptor<DataOut> (*dstitr));
00117 #endif
00118       this->ref_dst_section()->ref_overlap()[0] = this->image_border_size();
00119       this->ref_dst_section()->ref_overlap()[1] = this->image_border_size();
00120       if (this->ref_src_section()) {
00121 #ifdef VCL_VC_6 // this awkward construction is to get around a VC60 compiler bug
00122         vipl_section_descriptor<DataIn>& inSecDesc = *it;
00123         put_insecp( new vipl_section_descriptor<DataIn> (inSecDesc));
00124 #else
00125         vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::put_insecp( new vipl_section_descriptor<DataIn> (*it));
00126 #endif
00127         this->ref_src_section()->ref_overlap()[0] = this->image_border_size();
00128         this->ref_src_section()->ref_overlap()[1] = this->image_border_size();
00129       }
00130       this->section_preop(); // virtual function call
00131       this->section_applyop(); // virtual function call
00132       this->section_postop(); // virtual function call
00133       if (this->ref_secp()) {
00134         FILTER_IMPTR_DEC_REFCOUNT(this->ref_secp()); // ??really what we want or a kludge??
00135         ++dstitr;
00136       }
00137       if (this->ref_insecp()) {
00138         FILTER_IMPTR_DEC_REFCOUNT(this->ref_insecp());
00139       }
00140     }
00141   }
00142   else
00143   {
00144     iter_out enditr = (*this->ref_dst_section()).end();
00145     for (iter_out it = (*this->ref_dst_section()).begin(); it != enditr; ++it)
00146     {
00147       if (srcitr == endsrcitr) {
00148         vcl_cerr << "Warning: In vipl_filter_2d, input iter ran out of items before output.  resetting to beginning\n";
00149         srcitr = (*this->ref_src_section()).begin();
00150       }
00151 #ifdef VCL_VC_6 // this awkward construction is to get around a VC60 compiler bug
00152       vipl_section_descriptor<DataOut>& secDesc2 = *it;
00153       put_secp( new vipl_section_descriptor<DataOut> (secDesc2));
00154 #else
00155       vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::put_secp( new vipl_section_descriptor<DataOut> (*it));
00156 #endif
00157       this->ref_dst_section()->ref_overlap()[0] = this->image_border_size();
00158       this->ref_dst_section()->ref_overlap()[1] = this->image_border_size();
00159       if (this->ref_src_section()) {
00160 #ifdef VCL_VC_6 // this awkward construction is to get around a VC60 compiler bug
00161         vipl_section_descriptor<DataIn>& inSecDesc2 = *srcitr;
00162         put_insecp( new vipl_section_descriptor<DataIn> (inSecDesc2));
00163 #else
00164         vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::put_insecp( new vipl_section_descriptor<DataIn> (*srcitr));
00165 #endif
00166         this->ref_src_section()->ref_overlap()[0] = this->image_border_size();
00167         this->ref_src_section()->ref_overlap()[1] = this->image_border_size();
00168       }
00169       this->section_preop(); // virtual function call
00170       this->section_applyop(); // virtual function call
00171       this->section_postop(); // virtual function call
00172       if (this->ref_secp()) {
00173         FILTER_IMPTR_DEC_REFCOUNT(this->ref_secp()); // ??really what we want or a kludge??
00174       }
00175       if (this->ref_insecp()) {
00176         FILTER_IMPTR_DEC_REFCOUNT(this->ref_insecp());
00177         ++srcitr;
00178       }
00179     }
00180   }
00181   this->postop(); // virtual function call
00182   return true;
00183 }
00184 
00185 #endif // vipl_filter_2d_txx_