39.11 dwt2d.h

/*  
 * The 2D Discrete Wavelet Transform.  
 * gse. 2007.  
 */  
template <typename TYPE, class FILTER>  
class dwt2d: public FILTER, public mallok {  
 
 public:  
  dwt2d();  
  ~dwt2d();  
  void analyze(TYPE **signal, int y, int x, int levels);  
  void synthesize(TYPE **signal, int y, int x, int levels);  
  void set_max_line_size(int max_line_size);  
 
 private:  
  TYPE *in_line;  
  TYPE *out_line;  
};  
 
template <typename TYPE, class FILTER>  
dwt2d<TYPE,FILTER>::dwt2d<TYPE,FILTER>() {  
  in_line = (TYPE *)mallok::alloc_1d(1,sizeof(TYPE));  
#if defined DEBUG  
  if(!in_line) {  
    cerr << "dwt2d<TYPE,FILTER>::dwt2d<TYPE,FILTER>: out of memory for \"in_line\"\n";  
    abort();  
  }  
#endif  
  out_line = (TYPE *)mallok::alloc_1d(1,sizeof(TYPE));  
#if defined DEBUG  
  if(!out_line) {  
    cerr << "dwt2d<TYPE,FILTER>::dwt2d<TYPE,FILTER>: out of memory for \"out_line\"\n";  
    abort();  
  }  
#endif  
}  
 
template <typename TYPE, class FILTER>  
dwt2d<TYPE,FILTER>::~dwt2d<TYPE,FILTER>() {  
  mallok::free_1d(out_line);  
  mallok::free_1d(in_line);  
}  
 
template <typename TYPE, class FILTER>  
void dwt2d<TYPE,FILTER>::set_max_line_size(int max_line_size) {  
  mallok::free_1d(out_line);  
  mallok::free_1d(in_line);  
  in_line = (TYPE *)mallok::alloc_1d(max_line_size,sizeof(TYPE));  
  out_line = (TYPE *)mallok::alloc_1d(max_line_size,sizeof(TYPE));  
}  
 
template <typename TYPE, class FILTER>  
void dwt2d<TYPE,FILTER>::analyze(TYPE **signal, int y, int x, int levels) {  
  for(int lv=0;lv<levels;lv++) {  
    int nx = x; x >>= 1;  
    int ny = y; y >>= 1;  
    if(y == 0) y = 1; /* Nuevo */  
    if(x == 0) x = 1; /* Nuevo */  
 
    /* Transformamos las filas */  
    if(nx & 1) { /* N’umero impar de columnas */  
      for(int j=0;j<ny;j++) {  
        memcpy(in_line,signal[j],nx*sizeof(TYPE));  
        odd_analyze(in_line,signal[j],signal[j]+x+1,nx);  
      }  
    } else { /* N’umero par de columnas */  
      for(int j=0;j<ny;j++) {  
        memcpy(in_line,signal[j],nx*sizeof(TYPE));  
        even_analyze(in_line,signal[j],signal[j]+x,nx);  
      }  
    }  
 
    /* Transformamos las columnas */  
    if(ny & 1) { /* N’umero impar de filas */  
      for(int i=0;i<nx;i++) {  
        for(int j=0;j<ny;j++) {  
          in_line[j]=signal[j][i];  
        }  
        odd_analyze(in_line,out_line,out_line+y+1,ny);  
        for(int j=0;j<ny;j++) {  
          signal[j][i]=out_line[j];  
        }  
      }  
    } else { /* N’umero par de filas */  
      for(int i=0;i<nx;i++) {  
        for(int j=0;j<ny;j++) {  
          in_line[j]=signal[j][i];  
        }  
        even_analyze(in_line,out_line,out_line+y,ny);  
        for(int j=0;j<ny;j++) {  
          signal[j][i]=out_line[j];  
        }  
      }  
    }  
  }  
}  
 
template <typename TYPE, class FILTER>  
void dwt2d<TYPE,FILTER>::synthesize(TYPE **signal, int y, int x, int levels) {  
  int nx = x>>levels;  
  int ny = y>>levels;  
 
  for(int lv = levels-1; lv>=0; lv--) {  
    int mx, my;  
    mx = nx; nx=x>>lv;  
    my = ny; ny=y>>lv;  
    if(nx==0) nx=1; /* Nuevo */  
    if(ny==0) ny=1; /* Nuevo */  
 
    /* Transformamos las columnas */  
    if(ny & 1) { /* N’umero de filas impar */  
      for(int i=0;i<nx;i++) {  
        for(int j=0;j<ny;j++) {  
          in_line[j]=signal[j][i];  
        }  
        odd_synthesize(out_line,in_line,in_line+my+1,ny);  
        for(int j=0;j<ny;j++) {  
          signal[j][i]=out_line[j];  
        }  
      }  
    } else { /* N’umero de filas par */  
      for(int i=0;i<nx;i++) {  
        for(int j=0;j<ny;j++) {  
          in_line[j]=signal[j][i];  
        }  
        even_synthesize(out_line,in_line,in_line+my,ny);  
        for(int j=0;j<ny;j++) {  
          signal[j][i]=out_line[j];  
        }  
      }  
    }  
 
    /* Transformamos las columnas (i) */  
    if(nx & 1) { /* N’umero impar de columnas */  
      for(int j=0;j<ny;j++) {  
        memcpy(in_line,signal[j],nx*sizeof(TYPE));  
        odd_synthesize(signal[j],in_line,in_line+mx+1,nx);  
      }  
    } else { /* N’umero par de columas */  
      for(int j=0;j<ny;j++) {  
        memcpy(in_line,signal[j],nx*sizeof(TYPE));  
        even_synthesize(signal[j],in_line,in_line+mx,nx);  
      }  
    }  
  }  
}