contrib/tbl/vipl/section/vipl_section_container.txx
Go to the documentation of this file.
00001 // This is tbl/vipl/section/vipl_section_container.txx
00002 #ifndef vipl_section_container_txx_
00003 #define vipl_section_container_txx_
00004 
00005 #include "vipl_section_container.h"
00006 #include <vipl/filter/vipl_filter_abs.h> // for filter_abs::X_Axis()
00007 #include <vipl/section/vipl_section_iterator.txx>
00008 #include <vipl/section/vipl_section_descriptor.txx>
00009 #include <vcl_iostream.h>
00010 
00011 // The pointer ``the'' is just assigned
00012 template < class DataType >
00013   vipl_section_container< DataType > ::vipl_section_container( vipl_section_container< DataType >* pt)
00014   : hsthe(pt),
00015     hsimgsz (2,0),
00016     hsimgstart (2,0),
00017     hssecsz (2,0),
00018     hsoverlap (2,0),
00019     hsrawdata (0),
00020     hsimgptr (0),
00021     refcount_ (1)
00022 {}
00023 
00024 // The pointer is deep copied
00025 template < class DataType >
00026   vipl_section_container< DataType > ::vipl_section_container( const vipl_section_container< DataType >* pt , int t)
00027   : hsthe(0),
00028     hsimgsz (2,0),
00029     hsimgstart (2,0),
00030     hssecsz (2,0),
00031     hsoverlap (2,0),
00032     hsrawdata (0),
00033     hsimgptr (0),
00034     refcount_ (1)
00035 {
00036   hsthe = pt->virtual_copy();
00037 }
00038 
00039 template < class DataType >
00040   vipl_section_container< DataType > ::~vipl_section_container()
00041 {
00042 // if we have initialized meta_class, free soft slots. Do Not delete this
00043   if (hsthe && (hsthe != this)) FILTER_IMPTR_DEC_REFCOUNT(hsthe);
00044 }
00045 
00046 template < class DataType >
00047   vipl_section_container< DataType > ::vipl_section_container()
00048   : hsthe(this),
00049     hsimgsz (2,0),
00050     hsimgstart (2,0),
00051     hssecsz (2,0),
00052     hsoverlap (2,0),
00053     hsrawdata (0),
00054     hsimgptr (0),
00055     refcount_ (1)
00056 // C++ auto-generated low-level constructor
00057 {}
00058 
00059 template < class DataType >
00060   vipl_section_container< DataType > ::vipl_section_container(const vipl_section_container< DataType > &t)
00061   : hsthe(0),
00062     hsimgsz(t.hsimgsz),
00063     hsimgstart(t.hsimgstart),
00064     hssecsz(t.hssecsz),
00065     hsoverlap(t.hsoverlap),
00066     hsrawdata(t.hsrawdata),
00067     hsimgptr(t.hsimgptr),
00068     refcount_ (1)
00069 // C++ auto-generated low-level copy constructor
00070 {
00071   // you can fill special ``copy constructor'' stuff here.
00072   // All dynamic/soft attributes are copied. Thus your
00073   //code should not change any soft attributes (if you
00074   //want to change it here is should be hard because it
00075   //is always changed!) So don't change things without
00076   //knowing their form.
00077   hsthe = t.hsthe->virtual_copy();
00078 }
00079 
00080 template < class DataType >
00081    vipl_section_iterator< DataType > vipl_section_container< DataType > ::begin()
00082 {
00083   vipl_section_descriptor<DataType> *ptr = new vipl_section_descriptor<DataType>(0, virtual_copy());
00084   ptr->put_real_descriptor(ptr);
00085   ptr->ref_i_curr_sec_start()[0] = 0;
00086   ptr->ref_i_curr_sec_start()[1] = 0;
00087   ptr->ref_i_curr_sec_end()[0] = secsz()[0] + overlap()[0];
00088   ptr->ref_i_curr_sec_end()[1] = secsz()[1] + overlap()[1];
00089   if (ptr->ref_i_curr_sec_end()[0] > image_size(0))
00090     ptr->ref_i_curr_sec_end()[0] = image_size(0);
00091   if (ptr->ref_i_curr_sec_end()[1] > image_size(1))
00092     ptr->ref_i_curr_sec_end()[1] = image_size(1);
00093   ptr->ref_i_curr_sec_size()[0] = ptr->ref_i_curr_sec_end()[0];
00094   ptr->ref_i_curr_sec_size()[1] = ptr->ref_i_curr_sec_end()[1];
00095   vipl_section_iterator<DataType> i(ptr, virtual_copy());
00096   return i;
00097 }
00098 
00099 template < class DataType >
00100    vipl_section_iterator< DataType > vipl_section_container< DataType > ::end()
00101 {
00102   // the "end" iterator has 0 as the real_descriptor
00103   vipl_section_iterator<DataType> i(0, virtual_copy());
00104   return i;
00105 }
00106 
00107 template < class DataType >
00108   const vipl_section_iterator< DataType > vipl_section_container< DataType > ::begin() const
00109 {
00110   vipl_section_descriptor<DataType> *ptr =
00111     new vipl_section_descriptor<DataType>(0, virtual_copy());
00112   ptr->put_real_descriptor(ptr);
00113   ptr->ref_i_curr_sec_start()[0] = 0;
00114   ptr->ref_i_curr_sec_start()[1] = 0;
00115   if (ptr->ref_i_curr_sec_end()[0] > image_size(0))
00116     ptr->ref_i_curr_sec_end()[0] = image_size(0);
00117   if (ptr->ref_i_curr_sec_end()[1] > image_size(1))
00118     ptr->ref_i_curr_sec_end()[1] = image_size(1);
00119   ptr->ref_i_curr_sec_size()[0] = ptr->ref_i_curr_sec_end()[0];
00120   ptr->ref_i_curr_sec_size()[1] = ptr->ref_i_curr_sec_end()[1];
00121   vipl_section_iterator<DataType> i(ptr, virtual_copy());
00122   return i;
00123 }
00124 
00125 template < class DataType >
00126   const vipl_section_iterator< DataType > vipl_section_container< DataType > ::end() const
00127 {
00128   // the "end" iterator has 0 as the real_descriptor
00129   vipl_section_iterator<DataType> i(0, virtual_copy());
00130   return i;
00131 }
00132 
00133 // True only if the internal filterable image associated with b is the same as for this.
00134 template < class DataType >
00135   bool vipl_section_container< DataType > ::operator==( const vipl_section_container< DataType >& b) const
00136 {
00137   if (this == &b) return true;
00138   // silly, the only time the test below is true is the test above is true!
00139   // if (hsthe == b.hsthe) return true;
00140   // FIXME below
00141   return hsimgptr == b.hsimgptr;
00142 }
00143 
00144 template < class DataType >
00145   bool vipl_section_container< DataType > ::operator!=( const vipl_section_container< DataType >& b) const
00146 {
00147   return !(*this == b);
00148 }
00149 
00150 template < class DataType >
00151   vipl_section_container< DataType >& vipl_section_container< DataType > ::operator=( const vipl_section_container< DataType >& b)
00152 {
00153   if (this != &b) {
00154     if (hsthe != this) FILTER_IMPTR_DEC_REFCOUNT(hsthe);
00155     hsthe = b.hsthe->virtual_copy();
00156     // FIXME - the following is a protoDataType hack
00157     put_imgsz(b.imgsz());
00158     put_secsz(b.secsz());
00159   }
00160   return *this;
00161 }
00162 
00163 template < class DataType >
00164   int vipl_section_container< DataType > ::size() const
00165 {
00166   return ((imgsz()[0] / secsz()[0]) + ((imgsz()[0] % secsz()[0]) ? 1 : 0)) *
00167     ((imgsz()[1] / secsz()[1]) + ((imgsz()[1] % secsz()[1]) ? 1 : 0));
00168 }
00169 
00170 template < class DataType >
00171   int vipl_section_container< DataType > ::max_size() const
00172 { return size(); }
00173 
00174 template < class DataType >
00175   bool vipl_section_container< DataType > ::empty()
00176 { return false; }
00177 
00178 // None of the comparison operators are implemented yet. FIXME
00179 
00180 template < class DataType >
00181   bool vipl_section_container< DataType > ::operator<( const vipl_section_container< DataType >& ) const
00182 {
00183   vcl_cerr << "Warning: called unimplemented method vipl_section_container::operator<\n";
00184   return false;
00185 }
00186 
00187 template < class DataType >
00188   bool vipl_section_container< DataType > ::operator>( const vipl_section_container< DataType >& ) const
00189 {
00190   vcl_cerr << "Warning: called unimplemented method vipl_section_container::operator>\n";
00191   return false;
00192 }
00193 
00194 template < class DataType >
00195   bool vipl_section_container< DataType > ::operator<=( const vipl_section_container< DataType >& ) const
00196 {
00197   vcl_cerr << "Warning: called unimplemented method vipl_section_container::operator<=\n";
00198   return false;
00199 }
00200 
00201 template < class DataType >
00202   bool vipl_section_container< DataType > ::operator>=( const vipl_section_container< DataType >& ) const
00203 {
00204   vcl_cerr << "Warning: called unimplemented method vipl_section_container::operator>=\n";
00205   return false;
00206 }
00207 
00208 template < class DataType >
00209   void vipl_section_container< DataType > ::swap( const vipl_section_container< DataType >& ) const
00210 {
00211   vcl_cerr << "Warning: called unimplemented method vipl_section_container::swap\n";
00212 }
00213 
00214 // Modifies the passed in descriptor to point to the next section . This is
00215 // used by the default iterators for the operator++ method. Returns TRUE if
00216 // successfully incremented the variable. Used so we don't have to copy
00217 // descriptors a zillion times. Unfortunately STL usage implies we do copy
00218 // more often then we'd like.
00219 // This might seem like a method for the iterator but we want to keep that
00220 // class more "pure" (it would need too much state)
00221 template < class DataType >
00222   bool vipl_section_container< DataType > ::next_section(
00223   vipl_section_descriptor< DataType >& in_out)
00224   const
00225 {
00226   // alg: if section is at the right edge, then go to the next row
00227   // next-row if section is at the bottom edge call
00228   // bogus prototype alert! FIXME
00229   // This function should really be pure
00230   bool incremented_Y=0, incremented_X=0;
00231 #if 0 // commented out
00232   int xi = image_size(vipl_filter_abs::X_Axis()) - in_out.curr_sec_end(vipl_filter_abs::X_Axis());
00233   int yi = image_size(vipl_filter_abs::Y_Axis()) - in_out.curr_sec_end(vipl_filter_abs::Y_Axis());
00234   if (xi > section_size(vipl_filter_abs::X_Axis())) xi = section_size(vipl_filter_abs::X_Axis());
00235   if (yi > section_size(vipl_filter_abs::Y_Axis())) yi = section_size(vipl_filter_abs::Y_Axis());
00236   // this method should really be defined at a more concrete class
00237   // as is, this just a hack to have sections up and running with
00238   // scalar_image_2d_of<FOO>
00239   // first increment X if possible
00240   if (xi > 0) {
00241     incremented_X = 1;
00242     in_out.ref_i_curr_sec_start()[vipl_filter_abs::X_Axis()] += xi;
00243     in_out.ref_i_curr_sec_end()[vipl_filter_abs::X_Axis()] += xi;
00244     in_out.ref_i_curr_sec_size()[vipl_filter_abs::X_Axis()] = xi;
00245   }
00246   else if (yi > 0) {
00247     incremented_Y = 1;
00248     // typewriter "spring"
00249     in_out.ref_i_curr_sec_start()[vipl_filter_abs::X_Axis()] = 0;
00250     in_out.ref_i_curr_sec_start()[vipl_filter_abs::Y_Axis()] += yi;
00251     in_out.ref_i_curr_sec_end()[vipl_filter_abs::X_Axis()] = xi;
00252     in_out.ref_i_curr_sec_end()[vipl_filter_abs::Y_Axis()] += yi;
00253     in_out.ref_i_curr_sec_size()[vipl_filter_abs::X_Axis()] = xi;
00254     in_out.ref_i_curr_sec_size()[vipl_filter_abs::Y_Axis()] = yi;
00255   }
00256 #endif
00257   //int xs = in_out.curr_sec_start(vipl_filter_abs::X_Axis());
00258   //int ys = in_out.curr_sec_start(vipl_filter_abs::Y_Axis());
00259   int xi = image_size(vipl_filter_abs::X_Axis())
00260            - in_out.curr_sec_end(vipl_filter_abs::X_Axis());
00261   int yi = image_size(vipl_filter_abs::Y_Axis())
00262            - in_out.curr_sec_end(vipl_filter_abs::Y_Axis());
00263   if (xi > section_size(vipl_filter_abs::X_Axis()))
00264     xi = section_size(vipl_filter_abs::X_Axis());
00265   if (yi > section_size(vipl_filter_abs::Y_Axis()))
00266     yi = section_size(vipl_filter_abs::Y_Axis());
00267   // this method should really be defined at a more concrete class
00268   // as is, this just a hack to have sections up and running with
00269   // scalar_image_2d_of<FOO>
00270   // first increment X if possible
00271   if (xi > 0) {
00272     incremented_X = 1;
00273     // if start != 0 we just increment it by size, else we add overlap
00274     if (in_out.ref_i_curr_sec_start()[vipl_filter_abs::X_Axis()] > 0){
00275       in_out.ref_i_curr_sec_start()[vipl_filter_abs::X_Axis()]
00276         += section_size(vipl_filter_abs::X_Axis());
00277       in_out.ref_i_curr_sec_end()[vipl_filter_abs::X_Axis()]
00278         += section_size(vipl_filter_abs::X_Axis());
00279     }
00280     else {
00281       // we are in the "first" block so we have to include overlap stuff
00282       in_out.ref_i_curr_sec_start()[vipl_filter_abs::X_Axis()]
00283         += section_size(vipl_filter_abs::X_Axis())
00284         - overlap()[vipl_filter_abs::X_Axis()];
00285       in_out.ref_i_curr_sec_end()[vipl_filter_abs::X_Axis()]
00286         = in_out.ref_i_curr_sec_start()[vipl_filter_abs::X_Axis()]
00287         + section_size(vipl_filter_abs::X_Axis())
00288         + 2*overlap()[vipl_filter_abs::X_Axis()];
00289     }
00290     if (in_out.ref_i_curr_sec_end()[vipl_filter_abs::X_Axis()]
00291         > image_size(vipl_filter_abs::X_Axis()))
00292       in_out.ref_i_curr_sec_end()[vipl_filter_abs::X_Axis()] =
00293         image_size(vipl_filter_abs::X_Axis());
00294     in_out.ref_i_curr_sec_size()[vipl_filter_abs::X_Axis()] =
00295       in_out.i_curr_sec_end()[vipl_filter_abs::X_Axis()]
00296       - in_out.i_curr_sec_start()[vipl_filter_abs::X_Axis()];
00297   }
00298   else if (yi > 0) {
00299     incremented_Y = 1;
00300     // typewriter "spring"
00301     in_out.ref_i_curr_sec_start()[vipl_filter_abs::X_Axis()] = 0;
00302       in_out.ref_i_curr_sec_end()[vipl_filter_abs::X_Axis()]
00303         = section_size(vipl_filter_abs::X_Axis())
00304         + overlap()[vipl_filter_abs::X_Axis()];
00305     // if y != 0 we increment, else we must include overlap as well
00306     if (in_out.ref_i_curr_sec_start()[vipl_filter_abs::Y_Axis()] > 0 ){
00307       in_out.ref_i_curr_sec_start()[vipl_filter_abs::Y_Axis()] +=
00308         section_size(vipl_filter_abs::Y_Axis());
00309       in_out.ref_i_curr_sec_end()[vipl_filter_abs::Y_Axis()] +=
00310         section_size(vipl_filter_abs::Y_Axis());
00311     }
00312     else {
00313       in_out.ref_i_curr_sec_start()[vipl_filter_abs::Y_Axis()] =
00314         section_size(vipl_filter_abs::Y_Axis())
00315         - overlap()[vipl_filter_abs::Y_Axis()];
00316       in_out.ref_i_curr_sec_end()[vipl_filter_abs::Y_Axis()] =
00317         in_out.ref_i_curr_sec_start()[vipl_filter_abs::Y_Axis()]
00318         + section_size(vipl_filter_abs::Y_Axis())
00319         + 2*overlap()[vipl_filter_abs::Y_Axis()];
00320     }
00321     in_out.ref_i_curr_sec_size()[vipl_filter_abs::X_Axis()] =
00322       in_out.i_curr_sec_end()[vipl_filter_abs::X_Axis()]
00323       - in_out.i_curr_sec_start()[vipl_filter_abs::X_Axis()];
00324     in_out.ref_i_curr_sec_size()[vipl_filter_abs::Y_Axis()] =
00325       in_out.i_curr_sec_end()[vipl_filter_abs::Y_Axis()]
00326       - in_out.i_curr_sec_start()[vipl_filter_abs::Y_Axis()];
00327     if (in_out.ref_i_curr_sec_end()[vipl_filter_abs::X_Axis()]
00328         > image_size(vipl_filter_abs::X_Axis()))
00329       in_out.ref_i_curr_sec_end()[vipl_filter_abs::X_Axis()]
00330         = image_size(vipl_filter_abs::X_Axis());
00331     if (in_out.ref_i_curr_sec_end()[vipl_filter_abs::Y_Axis()]
00332         > image_size(vipl_filter_abs::Y_Axis()))
00333       in_out.ref_i_curr_sec_end()[vipl_filter_abs::Y_Axis()] =
00334         image_size(vipl_filter_abs::Y_Axis());
00335   }
00336   if (in_out.real_container() == the()) {
00337     vcl_cout << "next_section() for 0x" << (void *)&in_out << vcl_endl;
00338   }
00339   return incremented_Y | incremented_X;
00340 }
00341 
00342 // Given the axis, returns the starting coordinate of the related image in
00343 // the specified axis. The values of \usearg {axis} increase from
00344 // 0. Rationale for this is the span of the image in pixels in the first
00345 // (i.e. 0) axis, the second (i.e. 1) axis etc... The Axes have const values
00346 // in the class filter, e.g. vipl_filter::X_Axis
00347 template < class DataType >
00348   int vipl_section_container< DataType > ::image_start(int /*axis*/) const
00349 {
00350   return 0;
00351 }
00352 
00353 // Given the axis, returns the size of the related image in the specified
00354 // axis. The values of \usearg {axis} increase from 0. Rationale for this is
00355 // the span of the image in pixels in the first (i.e. 0) axis, the second
00356 // (i.e. 1) axis etc...
00357 template < class DataType >
00358   int vipl_section_container< DataType > ::image_size( int axis) const
00359 {
00360   return imgsz()[axis];
00361 }
00362 
00363 // Given the axis, returns the end coordinate of the related image in the
00364 // specified axis. The values of \usearg {axis} increase from 0. Rationale
00365 // for this is the span of the image in pixels in the first (i.e. 0) axis,
00366 // the second (i.e. 1) axis etc...
00367 template < class DataType >
00368   int vipl_section_container< DataType > ::image_end( int axis) const
00369 {
00370   return imgsz()[axis] +
00371    imgstart()[axis];
00372  }
00373 
00374 // Given the axis, returns the size of the related section size in the
00375 // specified axis. The values of \usearg {axis} increase from 0. Rationale
00376 // for this is the span of the image in pixels in the first (i.e. 0) axis,
00377 // the second (i.e. 1) axis etc... If the section container does not use
00378 // fixed sized sections then this should return -1
00379 
00380 template < class DataType >
00381   int vipl_section_container< DataType > ::section_size( int axis) const
00382 {
00383   return secsz()[axis];
00384 }
00385 
00386 // Returns true if the \useclass {section_descriptor}s will have valid
00387 // pointer values. By default they are if and only if the raw_data_pointer is
00388 // set.
00389 template < class DataType >
00390   bool vipl_section_container< DataType > ::is_pointer_safe() const
00391 {
00392   return false;
00393 }
00394 
00395 // Does the correct copy. It's a bit tricky due to the fact that an instance
00396 // has a pointer to its ``real instance''.
00397 template < class DataType >
00398    vipl_section_container< DataType >* vipl_section_container< DataType > ::virtual_copy() const
00399 {
00400   vipl_section_container< DataType >*rtn = new vipl_section_container<DataType> (0);
00401   rtn->put_the(rtn);
00402   rtn->put_imgsz(imgsz());
00403   rtn->put_secsz(secsz());
00404   rtn->put_imgptr(imgptr());
00405   rtn->put_overlap(overlap());
00406   return rtn;
00407 }
00408 
00409 #endif // vipl_section_container_txx_