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
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
00021
00022
00023
00024
00025
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
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
00047 LT = R;
00048
00049
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
00071 size_type subband_size(int k) const {
00072 if(k==0) return size();
00073
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
00078
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
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
00101 size_type offset_in_subband(int k) const { return (pow2(level-k)-1)*(filter_length - 1); }
00102
00103
00104 size_type offset_in_output(int k) const {
00105 int s = my_begin_orig-R;
00106 if(s==0) return 0;
00107 int ss = my_begin_orig + (R-LT);
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
00114 size_type offset_in_reconstruced() const {
00115 if(first) return 0;
00116
00117 int out = (int)(my_begin_orig) - R - R + R - LT;
00118
00119
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;
00128
00129 return 0;
00130 }
00131
00132
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
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
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
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
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
00186 int steps = (RBmax - RBmin)/pow2(level);
00187
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;
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
00201
00202 r.RB = pow2(level)*minK + RBmin;
00203
00204 LT = R - r.RB;
00205
00206
00207 r.my_end_orig = middle;
00208
00209
00210 r.my_end = middle + r.RB;
00211
00212
00213 my_begin_orig = middle;
00214
00215 my_begin = middle - LT;
00216
00217 }
00218 private:
00219
00220
00221 Value my_end;
00222 Value my_begin;
00223
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;
00235 size_t filter_length;
00236 size_t filter_length_low;
00237 size_t level;
00238 int R;
00239 bool first,last;
00240
00241
00242
00243
00244 template<typename RowValue, typename ColValue>
00245 friend class blocked_range2d_segdtwt_segidtwt_auto;
00246
00247 };
00248
00249
00250
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
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
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
00295
00296
00297
00298
00299
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