• Main Page
  • Classes
  • Files
  • File List
  • File Members

rangeSegDTWTauto.h

00001 #ifndef __TBB_blocked_range_segdtwt_segidtwt_auto_H
00002 #define __TBB_blocked_range_segdtwt_segidtwt_auto_H
00003 #include "tbb/tbb_stddef.h"
00004 #include "types.h"
00005 
00006 namespace tbb {
00007  
00008 
00009  template<typename Value>
00010 /* 
00011 připravené pro begin = 0, end = width + 2*r(J)
00012 
00013 
00014 */
00015  class blocked_range_segdtwt_segidtwt_auto{
00016  public:
00017     typedef Value const_iterator;
00018     typedef size_t size_type;
00019     blocked_range_segdtwt_segidtwt_auto() : my_begin(), my_end(), first(true), last(true) { }
00020         // grainsize musí být větší než (2^J)
00021         // my_begin =0 my_end = width + 2*R;
00022         // my_begin a my_end sou "ostrý" hodnoty pro výpočet
00023         // my_begin_orig=R a my_end_orig = width-R
00024         // begin_ a end_ jsou původní rozměry 0-width
00025         // filter_length je délka nejdelšího použitého filtru
00026 
00027         bool isFirst() const {return first;}
00028         bool isLast() const {return last;}
00029 
00030      blocked_range_segdtwt_segidtwt_auto( Value begin_, Value end_, size_t filter_length,size_t filter_length_low,size_t level,size_type grainsize_=1 ) : 
00031          filter_length(filter_length) , level(level), my_grainsize(grainsize_), filter_length_low(filter_length_low)
00032      {
00033                  __TBB_ASSERT( my_grainsize>=(Value)pow2(level), "grainsize must be 2*2^level or bigger" );
00034                 // počet společných prvků dvou sousedních segmentů
00035                  R = (pow2(level)-1)*(filter_length - 1);       
00036 
00037                  my_end = (end_-begin_) + 2*R;
00038                  my_begin = begin_;
00039 
00040                  my_begin_orig = my_begin + R;
00041                  my_end_orig = end_ + R; 
00042 
00043                 first = true;
00044                 last = true;
00045 
00046                 // levé prodloužení prvního segmentu je vždycky R 
00047                 LT = R;
00048 
00049                 // pravé prodloužení aktuálního sezmentu nastav prozatím na R (kdyby byl jen jeden)
00050         RB = R;
00051 
00052                 begin_whole = my_begin_orig;
00053                 end_whole = my_end_orig;
00054      }
00055  
00056     const_iterator begin() const {return my_begin;}
00057  
00058     const_iterator end() const {return my_end;}
00059 
00060         int begin_orig() const {return my_begin_orig;}
00061 
00062         int end_orig() const {return my_end_orig;}
00063 
00064     size_type size() const {  return size_type(my_end-my_begin);  }
00065 
00066         size_type size_orig() const { return size_type(my_end_orig - my_begin_orig);  }
00067 
00068     size_type grainsize() const {return my_grainsize;}
00069 
00070          // tolik koeficientů v úrovni k je třeba zkopírovat na výstup
00071           size_type subband_size(int k) const {
00072                   if(k==0) return size();
00073                   // pokud segment není poslední segment
00074                   if(!last)
00075                         return floor((float)(size())/pow2(k)+(1.0f/pow2(k)-1)*(filter_length-1)) - (pow2(level-k)-1)*(filter_length - 1);
00076                   else{
00077                           /* jinak je třeba vzít v úvahu, že poslední segment může být velikosti [1-s], ve vyšších úrovních dekompozice pak
00078                           navíc může být 0 koeficientů
00079                           */
00080 
00081                         return max(0, floor( (float)((my_end_orig - my_begin)/pow2(k) )) - (pow2(level-k)-1)*(filter_length - 1)    );
00082                   }
00083      }
00084 
00085           // tolik koeficientů v úrovni k je třeba zkopírovat + úprava na různé délky filtrů, závislá je ne ní pouze velikost posledního segmentu
00086           size_type subband_size(int k,int filter_actual) const {
00087                   if(k==0) return size();
00088                   if(!last){
00089                                 return (size_type)( max(0,floor((float)(size())/pow2(k)+(1.0f/pow2(k)-1)*(filter_length-1)) - (pow2(level-k)-1)*(filter_length - 1)) );
00090                   }else{
00091                           int pokus = (int) ((filter_actual - (int)filter_length_low )/2);
00092                           int vracim = (int) ( max(0, floor( (float)((my_end_orig - my_begin - R + (pow2(level)-1)*(filter_length_low-1)   )/pow2(k) ) ) - (pow2(level-k)-1)*(filter_length_low - 1) + pokus )  );
00093 return (size_type) vracim;
00094                         
00095                 
00096                   }
00097      }
00098 
00099 
00100       // od tohoto indexu začnu vyčítat koeficienty v k-té úrovni odpovídá r(J-k), 
00101           size_type offset_in_subband(int k) const {  return (pow2(level-k)-1)*(filter_length - 1);  }
00102         
00103           // index na kterém začíná aktuální segment ve výstupním subbandu 
00104           size_type offset_in_output(int k) const {
00105                   int s = my_begin_orig-R; // délka fiktivního 1. segmentu (jakoby spojené všechny předchozí)
00106                   if(s==0) return 0;
00107                   int ss = my_begin_orig + (R-LT); // délka prodlouženého fiktivního 1. segmentu
00108                   return (size_type) floor(ss/pow2(k)+(1.0f/pow2(k)-1)*(filter_length-1)) - (pow2(level-k)-1)*(filter_length - 1) + 1;  
00109           }
00110 
00111 
00112           /******* Metody pro inverzní transformaci ****/
00114           size_type offset_in_reconstruced() const {
00115                   if(first) return 0;
00116                            // delka 1. segmentu    prvních r(J) bylo ostraněno           pravé prodloužení předchozího segmentu  
00117                   int out = (int)(my_begin_orig) - R             - R                       + R - LT;
00118 
00119                   // pokud bych se ve výstupu dostal do těch r(J) na začátku, který rovnou odstraňuju
00120                   return max(0,out); 
00121           }
00122 
00123         
00124           size_type offset_in_reconstructed_segment() const{
00125           if(first) return R; 
00126 
00127           if(my_begin < begin_whole) return begin_whole - my_begin; // úprava offsetu v aktuálním segmentu. Nutné aby se začalo koeficienty, které začínají až za r(J)
00128 
00129           return 0;
00130           }
00131 
00132                 // počet vzorkůzískaných inverzní transformací, první aposlední zkráceny o R
00133                 size_type inverse_size() const { 
00134                         size_type size = 0;
00135                 if(first && last) size = size_type(my_end-my_begin - 2*R);
00136                 else if(first || last) size = size_type(my_end-my_begin - R);
00137                 else size = size_type(my_end-my_begin - offset_in_reconstructed_segment());  
00138 
00139                 int over = size + my_begin + offset_in_reconstructed_segment() - end_whole;
00140                 if( over > 0 ) size = size - over;
00141 
00142                 return size;
00143                 }
00144 
00145 
00146         
00147      //------------------------------------------------------------------------
00148      // Methods that implement Range concept
00149      //------------------------------------------------------------------------
00150  
00151      bool empty() const {return !(my_begin<my_end);}
00152  
00153          bool is_divisible() const {
00154                  int size_oo = size_orig();
00155                  
00156                  return size_oo>((int)my_grainsize) && (size_oo/2)>=pow2(level);
00157          }
00158 
00159          // splitting konstruktor r je "původní", konstruktor tvoří "nový"
00160      blocked_range_segdtwt_segidtwt_auto( blocked_range_segdtwt_segidtwt_auto& r, split ): 
00161          my_end_orig(r.my_end_orig),my_end(r.my_end),RB(r.RB),my_grainsize(r.my_grainsize), 
00162                  level(r.level),filter_length(r.filter_length),R(r.R),filter_length_low(r.filter_length_low){
00163 
00164                 this->last = r.last;
00165                 this->first = false;
00166                 r.last = false;
00167 
00168                 this->begin_whole = r.begin_whole;
00169                 this->end_whole = r.end_whole;
00170                 
00171  
00172 
00173                 // Value middle = (r.my_end_orig - r.my_begin_orig)/2 + r.my_begin_orig;
00174                 Value middle = (r.my_end_orig - r.my_begin_orig)/2 + r.my_begin_orig;
00175                 Value middle_orig = middle - R;
00176                 int size1 = middle - r.my_begin_orig;
00177                 int size2 = r.my_end_orig - middle;
00178 
00179         
00180                 Value RBmin, RBmax;
00181                  // pravé prodloužení původního segmentu vypočítané z rozměrů předchozího segmentu
00182                  RBmin = (Value) ( pow2(level)*ceil((float)((int)middle_orig)/pow2(level)) - (int)middle_orig);
00183                  RBmax = (Value) (pow2(level)*floor((float)(middle_orig+R)/pow2(level)) - middle_orig);
00184 
00185                 // tady musí určitě vyjít celé číslo
00186                  int steps = (RBmax - RBmin)/pow2(level);
00187                 // __TBB_ASSERT( ((RBmax - RBmin)/pow2(level))!=steps, "Chyba v prodlouzenich" );
00188 
00189                  int minK = 0;
00190                  int temp = r.LT - RB - R + size1 - size2;
00191                  int minimum =  abs( (int) (temp + 2*RBmin)  );
00192 
00193                  for(int k=1;k<=steps;k++){
00194                          if(pow2(level)*k + RBmin + r.my_end_orig > end_whole) break; //test jestli prodloužení s aktuálním k nebude mimo rozsah
00195                          if(    minimum > abs((int)( temp + 2*RBmin + 2*pow2(level)*k ))){
00196                                 minK = k;
00197                                 minimum = abs((int)( temp + 2*RBmin + 2*pow2(level)*k ));
00198                                 }
00199                  }
00200         //      minK = 0;
00201 
00202                 r.RB = pow2(level)*minK + RBmin;
00203 
00204                 LT = R - r.RB;
00205 
00206                 // konec původního segmentu v originálních rozměrech
00207                  r.my_end_orig = middle;
00208 
00209                  // prodloužený konec
00210                  r.my_end = middle + r.RB;
00211 
00212                 // nový segment začíná na
00213                  my_begin_orig = middle;
00214                  // levé prodloužení
00215                  my_begin = middle - LT;
00216 
00217                  }
00218  private:
00219         // prodloužená velikost 0-s_width + 2*R(J)
00220         // 
00221     Value my_end; 
00222     Value my_begin;
00223         // původni velikost 0-width 
00224         // 
00225         Value my_end_orig;
00226     Value my_begin_orig;
00227 
00228 
00229         Value end_whole;
00230     Value begin_whole;
00231 
00232     size_type my_grainsize;
00233 
00234         size_t LT,RB; // prodloužení pro aktuální segment
00235         size_t filter_length; // délka nejdelšího filtru
00236         size_t filter_length_low; // délka dolní propusti
00237         size_t level; // stupen dekompozice
00238         int R;
00239         bool first,last;
00240 
00241         // left je původní,
00242 //      static void do_split(blocked_range_segdtwt_segidtwt_auto& left,blocked_range_segdtwt_segidtwt_auto& right){     }
00243 
00244      template<typename RowValue, typename ColValue>
00245      friend class blocked_range2d_segdtwt_segidtwt_auto;
00246  
00247  };
00248 
00249 
00250  // blocked range pro obrazové bloky
00251  template<typename RowValue, typename ColValue=RowValue>
00252  class blocked_range2d_segdtwt_segidtwt_auto {
00253  public:
00254      typedef blocked_range_segdtwt_segidtwt_auto<RowValue> row_range_type;
00255     typedef blocked_range_segdtwt_segidtwt_auto<ColValue> col_range_type;
00256  
00257  private:
00258      row_range_type my_rows;
00259      col_range_type my_cols;
00260  
00261  public:
00262      blocked_range2d_segdtwt_segidtwt_auto( RowValue row_begin, RowValue row_end, RowValue row_filter_length,RowValue row_filter_length_low,typename row_range_type::size_type row_grainsize,
00263                       ColValue col_begin, ColValue col_end,  RowValue col_filter_length,RowValue col_filter_length_low,typename col_range_type::size_type col_grainsize, size_t level ) : 
00264          my_rows(row_begin,row_end,row_filter_length,row_filter_length_low,level,row_grainsize),
00265          my_cols(col_begin,col_end,col_filter_length,col_filter_length_low,level,col_grainsize) {}
00266  
00267      blocked_range2d_segdtwt_segidtwt_auto( RowValue row_begin, RowValue row_end,
00268                       ColValue col_begin, ColValue col_end ) : 
00269          my_rows(row_begin,row_end),
00270          my_cols(col_begin,col_end){}
00271 
00272      bool empty() const {
00273          // Yes, it is a logical OR here, not AND.
00274          return my_rows.empty() || my_cols.empty();
00275      }
00276      bool is_divisible() const {
00277          return my_rows.is_divisible() || my_cols.is_divisible();
00278      }
00279  
00280      blocked_range2d_segdtwt_segidtwt_auto( blocked_range2d_segdtwt_segidtwt_auto& r, split )
00281      {
00282         
00283         //       std::cout<<r.my_rows.is_divisible() <<" "<< r.my_cols.is_divisible() <<std::endl;
00284 
00285 
00286                  if(r.my_rows.is_divisible()){
00287                         my_cols = r.my_cols;
00288                         my_rows =  row_range_type(r.my_rows,split());
00289                  } else {
00290                         my_rows = r.my_rows;
00291                         my_cols =  col_range_type(r.my_cols,split());
00292                  }
00293 /*
00294                  if( (r.my_rows.size() < r.my_cols.size()) ) {
00295                         my_rows = r.my_rows;
00296                         my_cols =  col_range_type(r.my_cols,split());
00297         } else {
00298                         my_cols = r.my_cols;
00299                         my_rows =  row_range_type(r.my_rows,split());
00300          }*/
00301 
00302 
00303      }
00304  
00305     const row_range_type& rows() const {return my_rows;}
00306  
00307      const col_range_type& cols() const {return my_cols;}
00308  };
00309 
00310 
00311 
00312 
00313 
00314  }
00315 #endif

Generated on Wed Nov 24 2010 21:26:30 for SegDTWT2D by  doxygen 1.7.1