//GCT minor addition to support the reloading of Worlds and their components. int free_table(Table *t) { t->max_entries = 0; if (t->table) wtfree(t->table); wtfree(t); return EXIT_SUCCESS; }
void free_wavelet(Wavelet *w){ if(wavelet == NULL) return; if(w->_builtin == 0){ // dealocate filters if(w->dec_lo_double != NULL){ wtfree(w->dec_lo_double); w->dec_lo_double = NULL; } if(w->dec_hi_double != NULL){ wtfree(w->dec_hi_double); w->dec_hi_double = NULL; } if(w->rec_lo_double != NULL){ wtfree(w->rec_lo_double); w->rec_lo_double = NULL; } if(w->rec_hi_double != NULL){ wtfree(w->rec_hi_double); w->rec_hi_double = NULL; } if(w->dec_lo_float != NULL){ wtfree(w->dec_lo_float); w->dec_lo_float = NULL; } if(w->dec_hi_float != NULL){ wtfree(w->dec_hi_float); w->dec_hi_float = NULL; } if(w->rec_lo_float != NULL){ wtfree(w->rec_lo_float); w->rec_lo_float = NULL; } if(w->rec_hi_float != NULL){ wtfree(w->rec_hi_float); w->rec_hi_float = NULL; } } // finally free struct wtfree(w); }
int main(){ // Using C API to decompose 1D signal. // Results equivalent to pywt.dwt([1,2,3,4,5,6,7,8], 'db2', 'zpd'). // Compile: gcc -I../src dwt_decompose.c ../src/wt.c ../src/wavelets.c ../src/common.c ../src/convolution.c Wavelet *w = wavelet('d', 2); MODE mode = MODE_ZEROPAD; int i; float input[] = {1,2,3,4,5,6,7,8,9}; float *cA, *cD; index_t input_len, output_len; input_len = sizeof input / sizeof input[0]; output_len = dwt_buffer_length(input_len, w->dec_len, mode); cA = wtcalloc(output_len, sizeof(float)); cD = wtcalloc(output_len, sizeof(float)); printf("Wavelet: %s %d\n\n", w->family_name, w->vanishing_moments_psi); float_dec_a(input, input_len, w, cA, output_len, mode); float_dec_d(input, input_len, w, cD, output_len, mode); for(i=0; i<output_len; i++){ printf("%f ", cA[i]); } printf("\n\n"); for(i=0; i<output_len; i++){ printf("%f ", cD[i]); } printf("\n"); free_wavelet(w); wtfree(cA); wtfree(cD); return 0; }
//GCT minor addition to support the reloading of Worlds and their components. int free_world(World *w) { if (w->vertices) free_table(w->vertices); if (w->walls) free_table(w->walls); if (w->regions) free_table(w->regions); if (w->textures) free_table(w->textures); wtfree(w); return EXIT_SUCCESS; }
// basic SWT step // TODO: optimize INLINE int float_swt_(float input[], index_t input_len, const float filter[], index_t filter_len, float output[], index_t output_len, int level){ float* e_filter; index_t i, e_filter_len; if(level < 1) return -1; if(level > swt_max_level(input_len)) return -2; if(output_len != swt_buffer_length(input_len)) return -1; // TODO: quick hack, optimize if(level > 1){ // allocate filter first e_filter_len = filter_len << (level-1); e_filter = wtcalloc(e_filter_len, sizeof(float)); if(e_filter == NULL) return -1; // compute upsampled filter values for(i = 0; i < filter_len; ++i){ e_filter[i << (level-1)] = filter[i]; } i = float_downsampling_convolution(input, input_len, e_filter, e_filter_len, output, 1, MODE_PERIODIZATION); wtfree(e_filter); return i; } else { return float_downsampling_convolution(input, input_len, filter, filter_len, output, 1, MODE_PERIODIZATION); } }
int $DTYPE$_upsampling_convolution_valid_sf(const $DTYPE$* input, const_index_t N, const $DTYPE$* filter, const_index_t F, $DTYPE$* output, const_index_t O, MODE mode){ $DTYPE$ *ptr_out = output; $DTYPE$ *filter_even, *filter_odd; $DTYPE$ *ptr_base; $DTYPE$ sum_even, sum_odd; #ifdef OPT_UNROLL2 $DTYPE$ sum_even2, sum_odd2; #endif #ifdef OPT_UNROLL4 #ifndef OPT_UNROLL2 $DTYPE$ sum_even2, sum_odd2; #endif $DTYPE$ sum_even3, sum_odd3; $DTYPE$ sum_even4, sum_odd4; #endif index_t i, j; index_t F_2 = F/2; if(mode == MODE_PERIODIZATION) // Special case return $DTYPE$_upsampling_convolution_valid_sf_periodization(input, N, filter, F, output, O); if((F%2) || (N < F_2)) // Filter must have even length. return -1; // Allocate memory for even and odd elements of the filter filter_even = wtmalloc(F_2 * sizeof($DTYPE$)); filter_odd = wtmalloc(F_2 * sizeof($DTYPE$)); if(filter_odd == NULL || filter_odd == NULL){ if(filter_odd == NULL) wtfree(filter_odd); if(filter_even == NULL) wtfree(filter_even); return -1; } // split filter to even and odd values for(i = 0; i < F_2; ++i){ filter_even[i] = filter[i << 1]; filter_odd[i] = filter[(i << 1) + 1]; } /////////////////////////////////////////////////////////////////////////// // Perform _valid_ convolution (only when all filter_even and filter_odd elements // are in range of input data). // // This part is simple, no extra hacks, just two convolutions in one loop ptr_base = ($DTYPE$*)input + F_2 - 1; i = 0; #ifdef OPT_UNROLL4 // manually unroll the loop a bit for(; i < N-(F_2-1+8); i+=4){ // sliding over signal from left to right sum_even = filter_even[0] * ptr_base[i]; sum_even2 = filter_even[0] * ptr_base[i+1]; sum_even3 = filter_even[0] * ptr_base[i+2]; sum_even4 = filter_even[0] * ptr_base[i+3]; sum_odd = filter_odd[0] * ptr_base[i]; sum_odd2 = filter_odd[0] * ptr_base[i+1]; sum_odd3 = filter_odd[0] * ptr_base[i+2]; sum_odd4 = filter_odd[0] * ptr_base[i+3]; for(j = 1; j < F_2; ++j){ sum_even += filter_even[j] * ptr_base[i-j]; sum_even2 += filter_even[j] * ptr_base[(i+1)-j]; sum_even3 += filter_even[j] * ptr_base[(i+2)-j]; sum_even4 += filter_even[j] * ptr_base[(i+3)-j]; sum_odd += filter_odd[j] * ptr_base[i-j]; sum_odd2 += filter_odd[j] * ptr_base[(i+1)-j]; sum_odd3 += filter_odd[j] * ptr_base[(i+2)-j]; sum_odd4 += filter_odd[j] * ptr_base[(i+3)-j]; } *(ptr_out++) += sum_even; *(ptr_out++) += sum_odd; *(ptr_out++) += sum_even2; *(ptr_out++) += sum_odd2; *(ptr_out++) += sum_even3; *(ptr_out++) += sum_odd3; *(ptr_out++) += sum_even4; *(ptr_out++) += sum_odd4; } #endif #ifdef OPT_UNROLL2 // manually unroll the loop a bit for(; i < N-(F_2+1); i+=2){ // sliding over signal from left to right sum_even = filter_even[0] * ptr_base[i]; sum_even2 = filter_even[0] * ptr_base[i+1]; sum_odd = filter_odd[0] * ptr_base[i]; sum_odd2 = filter_odd[0] * ptr_base[i+1]; for(j = 1; j < F_2; ++j){ sum_even += filter_even[j] * ptr_base[i-j]; sum_even2 += filter_even[j] * ptr_base[(i+1)-j]; sum_odd += filter_odd[j] * ptr_base[i-j]; sum_odd2 += filter_odd[j] * ptr_base[(i+1)-j]; } *(ptr_out++) += sum_even; *(ptr_out++) += sum_odd; *(ptr_out++) += sum_even2; *(ptr_out++) += sum_odd2; } #endif for(; i < N-(F_2-1); ++i){ // sliding over signal from left to right sum_even = filter_even[0] * ptr_base[i]; sum_odd = filter_odd[0] * ptr_base[i]; for(j = 1; j < F_2; ++j){ sum_even += filter_even[j] * ptr_base[i-j]; sum_odd += filter_odd[j] * ptr_base[i-j]; } *(ptr_out++) += sum_even; *(ptr_out++) += sum_odd; } // /////////////////////////////////////////////////////////////////////////// wtfree(filter_even); wtfree(filter_odd); return 0; }
int $DTYPE$_upsampling_convolution_valid_sf_periodization(const $DTYPE$* input, const_index_t N, const $DTYPE$* filter, const_index_t F, $DTYPE$* output, const_index_t O) { $DTYPE$ *ptr_out = output; $DTYPE$ *filter_even, *filter_odd; $DTYPE$ *periodization_buf = NULL; $DTYPE$ *periodization_buf_rear = NULL; $DTYPE$ *ptr_base; $DTYPE$ sum_even, sum_odd; index_t i, j, k, N_p = 0; index_t F_2 = F/2; if(F%2) return -3; // Filter must have even-length. /////////////////////////////////////////////////////////////////////////// // Handle special situation when input coeff data is shorter than half of // the filter's length. The coeff array has to be extended periodically. // This can be only valid for PERIODIZATION_MODE if(N < F_2) // ======= { // Input data for periodization mode has to be periodically extended // New length for temporary input N_p = F_2-1 +N; // periodization_buf will hold periodically copied input coeffs values periodization_buf = wtcalloc(N_p, sizeof($DTYPE$)); if(periodization_buf == NULL) return -1; // Copy input data to it's place in the periodization_buf // -> [0 0 0 i1 i2 i3 0 0 0] k = (F_2-1)/2; for(i=k; i < k+N; ++i) periodization_buf[i] = input[(i-k)%N]; //if(N%2) // periodization_buf[i++] = input[N-1]; // [0 0 0 i1 i2 i3 0 0 0] // points here ^^ periodization_buf_rear = periodization_buf+i-1; // copy cyclically () to right // [0 0 0 i1 i2 i3 i1 i2 ...] j = i-k; for(; i < N_p; ++i) periodization_buf[i] = periodization_buf[i-j]; // copy cyclically () to left // [... i2 i3 i1 i2 i3 i1 i2 i3] j = 0; for(i=k-1; i >= 0; --i){ periodization_buf[i] = periodization_buf_rear[j]; --j; } // Now perform the valid convolution if(F_2%2){ $DTYPE$_upsampling_convolution_valid_sf(periodization_buf, N_p, filter, F, output, O, MODE_ZEROPAD); // The F_2%2==0 case needs special result fix (oh my, another one..) } else { // Cheap result fix for short inputs // Memory allocation for temporary output is done. // Computed temporary result is copied to output* ptr_out = wtcalloc(idwt_buffer_length(N, F, MODE_PERIODIZATION), sizeof($DTYPE$)); if(ptr_out == NULL){ wtfree(periodization_buf); return -1; } // Convolve here as for (F_2%2) branch above $DTYPE$_upsampling_convolution_valid_sf(periodization_buf, N_p, filter, F, ptr_out, O, MODE_ZEROPAD); // rewrite result to output for(i=2*N-1; i > 0; --i){ output[i] += ptr_out[i-1]; } // and the first element output[0] += ptr_out[2*N-1]; wtfree(ptr_out); // and voil`a!, ugh } } else { // Otherwise (N >= F_2) // Allocate memory for even and odd elements of the filter filter_even = wtmalloc(F_2 * sizeof($DTYPE$)); filter_odd = wtmalloc(F_2 * sizeof($DTYPE$)); if(filter_odd == NULL || filter_odd == NULL){ if(filter_odd == NULL) wtfree(filter_odd); if(filter_even == NULL) wtfree(filter_even); return -1; } // split filter to even and odd values for(i = 0; i < F_2; ++i){ filter_even[i] = filter[i << 1]; filter_odd[i] = filter[(i << 1) + 1]; } /////////////////////////////////////////////////////////////////////////// // This part is quite complicated and has some wild checking to get results // similar to those from Matlab(TM) Wavelet Toolbox k = F_2-1; // Check if extending is really needed N_p = F_2-1 + (index_t) ceil(k/2.); /*split filter len correct. + extra samples*/ // ok, if is then do: // 1. Allocate buffers for front and rear parts of extended input // 2. Copy periodically appriopriate elements from input to the buffers // 3. Convolve front buffer, input and rear buffer with even and odd // elements of the filter (this results in upsampling) // 4. Free memory if(N_p > 0){ // ======= // Allocate memory only for the front and rear extension parts, not the // whole input periodization_buf = wtcalloc(N_p, sizeof($DTYPE$)); periodization_buf_rear = wtcalloc(N_p, sizeof($DTYPE$)); // Memory checking if(periodization_buf == NULL || periodization_buf_rear == NULL){ if(periodization_buf == NULL) wtfree(periodization_buf); if(periodization_buf_rear == NULL) wtfree(periodization_buf_rear); wtfree(filter_odd); wtfree(filter_even); return -1; } // Fill buffers with appriopriate elements memcpy(periodization_buf + N_p - k, input, k * sizeof($DTYPE$)); // copy from beginning of input to end of buffer for(i = 1; i <= (N_p - k); ++i) // kopiowanie 'cykliczne' od końca input periodization_buf[(N_p - k) - i] = input[N - (i%N)]; memcpy(periodization_buf_rear, input + N - k, k * sizeof($DTYPE$)); // copy from end of input to begginning of buffer for(i = 0; i < (N_p - k); ++i) // kopiowanie 'cykliczne' od początku input periodization_buf_rear[k + i] = input[i%N]; /////////////////////////////////////////////////////////////////// // Convolve filters with the (front) periodization_buf and compute // the first part of output ptr_base = periodization_buf + F_2 - 1; if(k%2 == 1){ sum_odd = 0; for(j = 0; j < F_2; ++j) sum_odd += filter_odd[j] * ptr_base[-j]; *(ptr_out++) += sum_odd; --k; if(k) $DTYPE$_upsampling_convolution_valid_sf(periodization_buf + 1, N_p-1, filter, F, ptr_out, O-1, MODE_ZEROPAD); ptr_out += k; // k0 - 1 // really move backward by 1 } else if(k){ $DTYPE$_upsampling_convolution_valid_sf(periodization_buf, N_p, filter, F, ptr_out, O, MODE_ZEROPAD); ptr_out += k; } } /////////////////////////////////////////////////////////////////////////// // Perform _valid_ convolution (only when all filter_even and filter_odd elements // are in range of input data). // // This part is simple, no extra hacks, just two convolutions in one loop ptr_base = ($DTYPE$*)input + F_2 - 1; for(i = 0; i < N-(F_2-1); ++i){ // sliding over signal from left to right sum_even = 0; sum_odd = 0; for(j = 0; j < F_2; ++j){ sum_even += filter_even[j] * ptr_base[i-j]; sum_odd += filter_odd[j] * ptr_base[i-j]; } *(ptr_out++) += sum_even; *(ptr_out++) += sum_odd; } // /////////////////////////////////////////////////////////////////////////// if(N_p > 0){ // ======= k = F_2-1; if(k%2 == 1){ if(F/2 <= N_p - 1){ // k > 1 ? $DTYPE$_upsampling_convolution_valid_sf(periodization_buf_rear , N_p-1, filter, F, ptr_out, O-1, MODE_ZEROPAD); } ptr_out += k; // move forward anyway -> see lower if(F_2%2 == 0){ // remaining one element ptr_base = periodization_buf_rear + N_p - 1; sum_even = 0; for(j = 0; j < F_2; ++j){ sum_even += filter_even[j] * ptr_base[-j]; } *(--ptr_out) += sum_even; // move backward first } } else { if(k){ $DTYPE$_upsampling_convolution_valid_sf(periodization_buf_rear, N_p, filter, F, ptr_out, O, MODE_ZEROPAD); } } } if(periodization_buf != NULL) wtfree(periodization_buf); if(periodization_buf_rear != NULL) wtfree(periodization_buf_rear); wtfree(filter_even); wtfree(filter_odd); } return 0; }
int $DTYPE$_allocating_downsampling_convolution(const $DTYPE$* input, const_index_t N, const $DTYPE$* filter, const_index_t F, $DTYPE$* output, const_index_t step, MODE mode) { index_t i, j, F_minus_1, N_extended_len, N_extended_right_start; index_t start, stop; $DTYPE$ sum, tmp; $DTYPE$ *buffer; $DTYPE$* ptr_w = output; F_minus_1 = F - 1; start = F_minus_1+step-1; // allocate memory and copy input if(mode != MODE_PERIODIZATION){ N_extended_len = N + 2*F_minus_1; N_extended_right_start = N + F_minus_1; buffer = wtcalloc(N_extended_len, sizeof($DTYPE$)); if(buffer == NULL) return -1; memcpy(buffer+F_minus_1, input, sizeof($DTYPE$) * N); stop = N_extended_len; } else { N_extended_len = N + F-1; N_extended_right_start = N-1 + F/2; buffer = wtcalloc(N_extended_len, sizeof($DTYPE$)); if(buffer == NULL) return -1; memcpy(buffer+F/2-1, input, sizeof($DTYPE$) * N); start -= 1; if(step == 1) stop = N_extended_len-1; else // step == 2 stop = N_extended_len; } // copy extended signal elements switch(mode){ case MODE_PERIODIZATION: if(N%2){ // odd - repeat last element buffer[N_extended_right_start] = input[N-1]; for(j = 1; j < F/2; ++j) buffer[N_extended_right_start+j] = buffer[F/2-2 + j]; // copy from begining of `input` to right for(j = 0; j < F/2-1; ++j) // copy from 'buffer' to left buffer[F/2-2-j] = buffer[N_extended_right_start-j]; } else { for(j = 0; j < F/2; ++j) buffer[N_extended_right_start+j] = input[j%N]; // copy from begining of `input` to right for(j = 0; j < F/2-1; ++j) // copy from 'buffer' to left buffer[F/2-2-j] = buffer[N_extended_right_start-1-j]; } break; case MODE_SYMMETRIC: for(j = 0; j < N; ++j){ buffer[F_minus_1-1-j] = input[j%N]; buffer[N_extended_right_start+j] = input[N-1-(j%N)]; } i=j; // use `buffer` as source for(; j < F_minus_1; ++j){ buffer[F_minus_1-1-j] = buffer[N_extended_right_start-1+i-j]; buffer[N_extended_right_start+j] = buffer[F_minus_1+j-i]; } break; case MODE_ASYMMETRIC: for(j = 0; j < N; ++j){ buffer[F_minus_1-1-j] = input[0] - input[j%N]; buffer[N_extended_right_start+j] = (input[N-1] - input[N-1-(j%N)]); } i=j; // use `buffer` as source for(; j < F_minus_1; ++j){ buffer[F_minus_1-1-j] = buffer[N_extended_right_start-1+i-j]; buffer[N_extended_right_start+j] = buffer[F_minus_1+j-i]; } break; case MODE_SMOOTH: if(N>1){ tmp = input[0]-input[1]; for(j = 0; j < F_minus_1; ++j) buffer[j] = input[0] + (tmp * (F_minus_1-j)); tmp = input[N-1]-input[N-2]; for(j = 0; j < F_minus_1; ++j) buffer[N_extended_right_start+j] = input[N-1] + (tmp*j); break; } case MODE_CONSTANT_EDGE: for(j = 0; j < F_minus_1; ++j){ buffer[j] = input[0]; buffer[N_extended_right_start+j] = input[N-1]; } break; case MODE_PERIODIC: for(j = 0; j < F_minus_1; ++j) buffer[N_extended_right_start+j] = input[j%N]; // copy from beggining of `input` to right for(j = 0; j < F_minus_1; ++j) // copy from 'buffer' to left buffer[F_minus_1-1-j] = buffer[N_extended_right_start-1-j]; break; case MODE_ZEROPAD: default: //memset(buffer, 0, sizeof($DTYPE$)*F_minus_1); //memset(buffer+N_extended_right_start, 0, sizeof($DTYPE$)*F_minus_1); //memcpy(buffer+N_extended_right_start, buffer, sizeof($DTYPE$)*F_minus_1); break; } /////////////////////////////////////////////////////////////////////// // F - N-1 - filter in input range // perform convolution with decimation for(i=start; i < stop; i+=step){ // input elements sum = 0; for(j = 0; j < F; ++j){ sum += buffer[i-j]*filter[j]; } *(ptr_w++) = sum; } // free memory wtfree(buffer); return 0; }
int upsampling_convolution_valid_sf(const DTYPE* input, const int N, const double* filter, const int F, double* output, const int O, const int mode){ double *ptr_out = output; double *filter_even, *filter_odd; DTYPE *periodization_buf = NULL, *periodization_buf_rear = NULL; DTYPE *ptr_base; double sum_even, sum_odd; int i, j, k, N_p = 0; int F_2 = F/2; // F/2 if(F%2) return -3; if(F_2 > N){ if(mode == MODE_PERIODIZATION){ N_p = F_2-1 +N; periodization_buf = (double*) wtcalloc(N_p, sizeof(DTYPE)); k = (F_2-1)/2; for(i=k; i < k+N; ++i) periodization_buf[i] = input[(i-k)%N]; //if(N%2) // periodization_buf[i++] = input[N-1]; periodization_buf_rear = periodization_buf+i-1; j = i-k; for(; i < N_p; ++i) periodization_buf[i] = periodization_buf[i-j]; j = 0; for(i=k-1; i >= 0; --i){ periodization_buf[i] = periodization_buf_rear[j]; --j; } if(F_2%2==0){ // cheap result fix ptr_out = (double*) wtcalloc(idwt_buffer_length(N, F, MODE_PERIODIZATION), sizeof(double)); if(ptr_out == NULL) return -3; upsampling_convolution_valid_sf(periodization_buf, N_p, filter, F, ptr_out, O, MODE_ZEROPAD); for(i=2*N-1; i > 0; --i){ output[i] += ptr_out[i-1]; } output[0] += ptr_out[2*N-1]; wtfree(ptr_out); } else { upsampling_convolution_valid_sf(periodization_buf, N_p, filter, F, output, O, MODE_ZEROPAD); } return 0; } else { return -2; // invalid lengths } } // allocate memory for even and odd elements of filter filter_even = (double*) malloc(F_2 * sizeof(double)); filter_odd = (double*) malloc(F_2 * sizeof(double)); if(filter_odd == NULL || filter_odd == NULL){ return -1; } // copy values for(i = 0; i < F_2; ++i){ filter_even[i] = filter[i << 1]; filter_odd[i] = filter[(i << 1) + 1]; } /////////////////////////////////////////////////////////////////////////// // MODE_PERIODIZATION // this part is quite complicated if(mode == MODE_PERIODIZATION){ k = F_2-1; N_p = F_2-1 + (int) ceil(k/2.); /*split filter len correct. + extra samples*/ if(N_p > 0){ periodization_buf = (double*) calloc(N_p, sizeof(double)); periodization_buf_rear = (double*) calloc(N_p, sizeof(double)); if(k <= N){ memcpy(periodization_buf + N_p - k, input, k * sizeof(double)); // copy from beginning of input to end of buffer for(i = 1; i <= (N_p - k); ++i) // kopiowanie 'cykliczne' od koñca input periodization_buf[(N_p - k) - i] = input[N - (i%N)]; memcpy(periodization_buf_rear, input + N - k, k * sizeof(double)); // copy from end of input to begginning of buffer for(i = 0; i < (N_p - k); ++i) // kopiowanie 'cykliczne' od pocz¹tku input periodization_buf_rear[k + i] = input[i%N]; } else { //printf("see %d line in %s!!\n", __LINE__, __FILE__); // TODO: is this ever called? if yes check for errors for(i = 0; i < k; ++i) periodization_buf[(N_p - k) + i] = input[i % N]; for(i = 1; i < (N_p - k); ++i) periodization_buf[(N_p - k) - i] = input[N - (i%N)]; //for(i = 0; i < N_p; ++i) // printf("%f ", periodization_buf[i]); //printf("--\n"); //for(i = 0; i < N_p; ++i) // printf("%f ", periodization_buf_rear[i]); //printf("\n"); } ptr_base = periodization_buf + F_2 - 1; if(k%2 == 1){ sum_odd = 0; for(j = 0; j < F_2; ++j) sum_odd += filter_odd[j] * ptr_base[-j]; *(ptr_out++) += sum_odd; --k; if(k) upsampling_convolution_valid_sf(periodization_buf + 1, N_p-1, filter, F, ptr_out, O-1, MODE_ZEROPAD); ptr_out += k; // k0 - 1 // really move backward by 1 } else if(k){ upsampling_convolution_valid_sf(periodization_buf, N_p, filter, F, ptr_out, O, MODE_ZEROPAD); ptr_out += k; } } } // MODE_PERIODIZATION /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // perform _valid_ convolution (only when all filter_even and filter_odd elements are in range of input data) // this part is quite simple, no extra hacks ptr_base = (DTYPE*)input + F_2 - 1; for(i = 0; i < N-(F_2-1); ++i){ // sliding over signal from left to right sum_even = 0; sum_odd = 0; // iterate filters elements for(j = 0; j < F_2; ++j){ sum_even += filter_even[j] * ptr_base[i-j]; sum_odd += filter_odd[j] * ptr_base[i-j]; } *(ptr_out++) += sum_even; *(ptr_out++) += sum_odd; } // /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // MODE_PERIODIZATION if(mode == MODE_PERIODIZATION){ if(N_p>0){ k = F_2-1; if(k%2 == 1){ if(F/2 <= N_p - 1) // k > 1 ? upsampling_convolution_valid_sf(periodization_buf_rear , N_p-1, filter, F, ptr_out, O-1, MODE_ZEROPAD); ptr_out += k; // move forward anyway -> see lower if(F_2%2 == 0){ // remaining one element ptr_base = periodization_buf_rear + N_p - 1; sum_even = 0; for(j = 0; j < F_2; ++j) sum_even += filter_even[j] * ptr_base[-j]; *(--ptr_out) += sum_even; // move backward first } } else { if(k) upsampling_convolution_valid_sf(periodization_buf_rear, N_p, filter, F, ptr_out, O, MODE_ZEROPAD); } } if(periodization_buf != NULL) wtfree(periodization_buf); if(periodization_buf_rear != NULL) wtfree(periodization_buf_rear); } // MODE_PERIODIZATION /////////////////////////////////////////////////////////////////////////// wtfree(filter_even); wtfree(filter_odd); return 0; }
Wavelet* wavelet(char name, int order) { Wavelet *w, *wtmp; index_t i; // Haar wavelet if(name == 'h' || name == 'H'){ // the same as db1 w = wavelet('d', 1); w->family_name = "Haar"; w->short_name = "haar"; return w; // Reverse biorthogonal wavelets family } else if (name == 'r' || name == 'R') { // rbio is like bior, only with switched filters wtmp = wavelet('b', order); w = copy_wavelet(wtmp); if(w == NULL) return NULL; w->dec_len = wtmp->rec_len; w->rec_len = wtmp->dec_len; /* w->dec_hi_offset = wtmp->rec_hi_offset; w->rec_hi_offset = wtmp->dec_hi_offset; w->dec_lo_offset = wtmp->rec_lo_offset; w->rec_lo_offset = wtmp->dec_lo_offset; */ for(i = 0; i < w->rec_len; ++i){ w->rec_lo_double[i] = wtmp->dec_lo_double[wtmp->dec_len-1-i]; w->rec_hi_double[i] = wtmp->dec_hi_double[wtmp->dec_len-1-i]; w->rec_lo_float[i] = wtmp->dec_lo_float[wtmp->dec_len-1-i]; w->rec_hi_float[i] = wtmp->dec_hi_float[wtmp->dec_len-1-i]; } for(i = 0; i < w->dec_len; ++i){ w->dec_hi_double[i] = wtmp->rec_hi_double[wtmp->rec_len-1-i]; w->dec_lo_double[i] = wtmp->rec_lo_double[wtmp->rec_len-1-i]; w->dec_hi_float[i] = wtmp->rec_hi_float[wtmp->rec_len-1-i]; w->dec_lo_float[i] = wtmp->rec_lo_float[wtmp->rec_len-1-i]; } w->vanishing_moments_psi = order / 10; // 1st digit w->vanishing_moments_phi = -1; w->family_name = "Reverse biorthogonal"; w->short_name = "rbio"; free_wavelet(wtmp); return w; } w = wtmalloc(sizeof(Wavelet)); if(w == NULL) return NULL; //w->dec_lo_offset = w->rec_lo_offset = 0; //w->dec_hi_offset = w->rec_hi_offset = 0; w->_builtin = 1; switch(name){ // Daubechies wavelets family case 'd': case 'D': w->dec_len = w->rec_len = 2*order; w->vanishing_moments_psi = order; w->vanishing_moments_phi = 0; w->support_width = 2*order - 1; w->orthogonal = 1; w->biorthogonal = 1; w->symmetry = ASYMMETRIC; w->compact_support = 1; w->family_name = "Daubechies"; w->short_name = "db"; switch (order) { case 1: w->dec_lo_double = db1_double[0]; w->dec_hi_double = db1_double[1]; w->rec_lo_double = db1_double[2]; w->rec_hi_double = db1_double[3]; w->dec_lo_float = db1_float[0]; w->dec_hi_float = db1_float[1]; w->rec_lo_float = db1_float[2]; w->rec_hi_float = db1_float[3]; break; case 2: w->dec_lo_double = db2_double[0]; w->dec_hi_double = db2_double[1]; w->rec_lo_double = db2_double[2]; w->rec_hi_double = db2_double[3]; w->dec_lo_float = db2_float[0]; w->dec_hi_float = db2_float[1]; w->rec_lo_float = db2_float[2]; w->rec_hi_float = db2_float[3]; break; case 3: w->dec_lo_double = db3_double[0]; w->dec_hi_double = db3_double[1]; w->rec_lo_double = db3_double[2]; w->rec_hi_double = db3_double[3]; w->dec_lo_float = db3_float[0]; w->dec_hi_float = db3_float[1]; w->rec_lo_float = db3_float[2]; w->rec_hi_float = db3_float[3]; break; case 4: w->dec_lo_double = db4_double[0]; w->dec_hi_double = db4_double[1]; w->rec_lo_double = db4_double[2]; w->rec_hi_double = db4_double[3]; w->dec_lo_float = db4_float[0]; w->dec_hi_float = db4_float[1]; w->rec_lo_float = db4_float[2]; w->rec_hi_float = db4_float[3]; break; case 5: w->dec_lo_double = db5_double[0]; w->dec_hi_double = db5_double[1]; w->rec_lo_double = db5_double[2]; w->rec_hi_double = db5_double[3]; w->dec_lo_float = db5_float[0]; w->dec_hi_float = db5_float[1]; w->rec_lo_float = db5_float[2]; w->rec_hi_float = db5_float[3]; break; case 6: w->dec_lo_double = db6_double[0]; w->dec_hi_double = db6_double[1]; w->rec_lo_double = db6_double[2]; w->rec_hi_double = db6_double[3]; w->dec_lo_float = db6_float[0]; w->dec_hi_float = db6_float[1]; w->rec_lo_float = db6_float[2]; w->rec_hi_float = db6_float[3]; break; case 7: w->dec_lo_double = db7_double[0]; w->dec_hi_double = db7_double[1]; w->rec_lo_double = db7_double[2]; w->rec_hi_double = db7_double[3]; w->dec_lo_float = db7_float[0]; w->dec_hi_float = db7_float[1]; w->rec_lo_float = db7_float[2]; w->rec_hi_float = db7_float[3]; break; case 8: w->dec_lo_double = db8_double[0]; w->dec_hi_double = db8_double[1]; w->rec_lo_double = db8_double[2]; w->rec_hi_double = db8_double[3]; w->dec_lo_float = db8_float[0]; w->dec_hi_float = db8_float[1]; w->rec_lo_float = db8_float[2]; w->rec_hi_float = db8_float[3]; break; case 9: w->dec_lo_double = db9_double[0]; w->dec_hi_double = db9_double[1]; w->rec_lo_double = db9_double[2]; w->rec_hi_double = db9_double[3]; w->dec_lo_float = db9_float[0]; w->dec_hi_float = db9_float[1]; w->rec_lo_float = db9_float[2]; w->rec_hi_float = db9_float[3]; break; case 10: w->dec_lo_double = db10_double[0]; w->dec_hi_double = db10_double[1]; w->rec_lo_double = db10_double[2]; w->rec_hi_double = db10_double[3]; w->dec_lo_float = db10_float[0]; w->dec_hi_float = db10_float[1]; w->rec_lo_float = db10_float[2]; w->rec_hi_float = db10_float[3]; break; case 11: w->dec_lo_double = db11_double[0]; w->dec_hi_double = db11_double[1]; w->rec_lo_double = db11_double[2]; w->rec_hi_double = db11_double[3]; w->dec_lo_float = db11_float[0]; w->dec_hi_float = db11_float[1]; w->rec_lo_float = db11_float[2]; w->rec_hi_float = db11_float[3]; break; case 12: w->dec_lo_double = db12_double[0]; w->dec_hi_double = db12_double[1]; w->rec_lo_double = db12_double[2]; w->rec_hi_double = db12_double[3]; w->dec_lo_float = db12_float[0]; w->dec_hi_float = db12_float[1]; w->rec_lo_float = db12_float[2]; w->rec_hi_float = db12_float[3]; break; case 13: w->dec_lo_double = db13_double[0]; w->dec_hi_double = db13_double[1]; w->rec_lo_double = db13_double[2]; w->rec_hi_double = db13_double[3]; w->dec_lo_float = db13_float[0]; w->dec_hi_float = db13_float[1]; w->rec_lo_float = db13_float[2]; w->rec_hi_float = db13_float[3]; break; case 14: w->dec_lo_double = db14_double[0]; w->dec_hi_double = db14_double[1]; w->rec_lo_double = db14_double[2]; w->rec_hi_double = db14_double[3]; w->dec_lo_float = db14_float[0]; w->dec_hi_float = db14_float[1]; w->rec_lo_float = db14_float[2]; w->rec_hi_float = db14_float[3]; break; case 15: w->dec_lo_double = db15_double[0]; w->dec_hi_double = db15_double[1]; w->rec_lo_double = db15_double[2]; w->rec_hi_double = db15_double[3]; w->dec_lo_float = db15_float[0]; w->dec_hi_float = db15_float[1]; w->rec_lo_float = db15_float[2]; w->rec_hi_float = db15_float[3]; break; case 16: w->dec_lo_double = db16_double[0]; w->dec_hi_double = db16_double[1]; w->rec_lo_double = db16_double[2]; w->rec_hi_double = db16_double[3]; w->dec_lo_float = db16_float[0]; w->dec_hi_float = db16_float[1]; w->rec_lo_float = db16_float[2]; w->rec_hi_float = db16_float[3]; break; case 17: w->dec_lo_double = db17_double[0]; w->dec_hi_double = db17_double[1]; w->rec_lo_double = db17_double[2]; w->rec_hi_double = db17_double[3]; w->dec_lo_float = db17_float[0]; w->dec_hi_float = db17_float[1]; w->rec_lo_float = db17_float[2]; w->rec_hi_float = db17_float[3]; break; case 18: w->dec_lo_double = db18_double[0]; w->dec_hi_double = db18_double[1]; w->rec_lo_double = db18_double[2]; w->rec_hi_double = db18_double[3]; w->dec_lo_float = db18_float[0]; w->dec_hi_float = db18_float[1]; w->rec_lo_float = db18_float[2]; w->rec_hi_float = db18_float[3]; break; case 19: w->dec_lo_double = db19_double[0]; w->dec_hi_double = db19_double[1]; w->rec_lo_double = db19_double[2]; w->rec_hi_double = db19_double[3]; w->dec_lo_float = db19_float[0]; w->dec_hi_float = db19_float[1]; w->rec_lo_float = db19_float[2]; w->rec_hi_float = db19_float[3]; break; case 20: w->dec_lo_double = db20_double[0]; w->dec_hi_double = db20_double[1]; w->rec_lo_double = db20_double[2]; w->rec_hi_double = db20_double[3]; w->dec_lo_float = db20_float[0]; w->dec_hi_float = db20_float[1]; w->rec_lo_float = db20_float[2]; w->rec_hi_float = db20_float[3]; break; default: wtfree(w); return NULL; } break; // Symlets wavelets family case 's': case 'S': w->dec_len = w->rec_len = order << 1; w->vanishing_moments_psi = order; w->vanishing_moments_phi = 0; w->support_width = 2*order - 1; w->orthogonal = 1; w->biorthogonal = 1; w->symmetry = NEAR_SYMMETRIC; w->compact_support = 1; w->family_name = "Symlets"; w->short_name = "sym"; switch (order) { case 2: w->dec_lo_double = sym2_double[0]; w->dec_hi_double = sym2_double[1]; w->rec_lo_double = sym2_double[2]; w->rec_hi_double = sym2_double[3]; w->dec_lo_float = sym2_float[0]; w->dec_hi_float = sym2_float[1]; w->rec_lo_float = sym2_float[2]; w->rec_hi_float = sym2_float[3]; break; case 3: w->dec_lo_double = sym3_double[0]; w->dec_hi_double = sym3_double[1]; w->rec_lo_double = sym3_double[2]; w->rec_hi_double = sym3_double[3]; w->dec_lo_float = sym3_float[0]; w->dec_hi_float = sym3_float[1]; w->rec_lo_float = sym3_float[2]; w->rec_hi_float = sym3_float[3]; break; case 4: w->dec_lo_double = sym4_double[0]; w->dec_hi_double = sym4_double[1]; w->rec_lo_double = sym4_double[2]; w->rec_hi_double = sym4_double[3]; w->dec_lo_float = sym4_float[0]; w->dec_hi_float = sym4_float[1]; w->rec_lo_float = sym4_float[2]; w->rec_hi_float = sym4_float[3]; break; case 5: w->dec_lo_double = sym5_double[0]; w->dec_hi_double = sym5_double[1]; w->rec_lo_double = sym5_double[2]; w->rec_hi_double = sym5_double[3]; w->dec_lo_float = sym5_float[0]; w->dec_hi_float = sym5_float[1]; w->rec_lo_float = sym5_float[2]; w->rec_hi_float = sym5_float[3]; break; case 6: w->dec_lo_double = sym6_double[0]; w->dec_hi_double = sym6_double[1]; w->rec_lo_double = sym6_double[2]; w->rec_hi_double = sym6_double[3]; w->dec_lo_float = sym6_float[0]; w->dec_hi_float = sym6_float[1]; w->rec_lo_float = sym6_float[2]; w->rec_hi_float = sym6_float[3]; break; case 7: w->dec_lo_double = sym7_double[0]; w->dec_hi_double = sym7_double[1]; w->rec_lo_double = sym7_double[2]; w->rec_hi_double = sym7_double[3]; w->dec_lo_float = sym7_float[0]; w->dec_hi_float = sym7_float[1]; w->rec_lo_float = sym7_float[2]; w->rec_hi_float = sym7_float[3]; break; case 8: w->dec_lo_double = sym8_double[0]; w->dec_hi_double = sym8_double[1]; w->rec_lo_double = sym8_double[2]; w->rec_hi_double = sym8_double[3]; w->dec_lo_float = sym8_float[0]; w->dec_hi_float = sym8_float[1]; w->rec_lo_float = sym8_float[2]; w->rec_hi_float = sym8_float[3]; break; case 9: w->dec_lo_double = sym9_double[0]; w->dec_hi_double = sym9_double[1]; w->rec_lo_double = sym9_double[2]; w->rec_hi_double = sym9_double[3]; w->dec_lo_float = sym9_float[0]; w->dec_hi_float = sym9_float[1]; w->rec_lo_float = sym9_float[2]; w->rec_hi_float = sym9_float[3]; break; case 10: w->dec_lo_double = sym10_double[0]; w->dec_hi_double = sym10_double[1]; w->rec_lo_double = sym10_double[2]; w->rec_hi_double = sym10_double[3]; w->dec_lo_float = sym10_float[0]; w->dec_hi_float = sym10_float[1]; w->rec_lo_float = sym10_float[2]; w->rec_hi_float = sym10_float[3]; break; case 11: w->dec_lo_double = sym11_double[0]; w->dec_hi_double = sym11_double[1]; w->rec_lo_double = sym11_double[2]; w->rec_hi_double = sym11_double[3]; w->dec_lo_float = sym11_float[0]; w->dec_hi_float = sym11_float[1]; w->rec_lo_float = sym11_float[2]; w->rec_hi_float = sym11_float[3]; break; case 12: w->dec_lo_double = sym12_double[0]; w->dec_hi_double = sym12_double[1]; w->rec_lo_double = sym12_double[2]; w->rec_hi_double = sym12_double[3]; w->dec_lo_float = sym12_float[0]; w->dec_hi_float = sym12_float[1]; w->rec_lo_float = sym12_float[2]; w->rec_hi_float = sym12_float[3]; break; case 13: w->dec_lo_double = sym13_double[0]; w->dec_hi_double = sym13_double[1]; w->rec_lo_double = sym13_double[2]; w->rec_hi_double = sym13_double[3]; w->dec_lo_float = sym13_float[0]; w->dec_hi_float = sym13_float[1]; w->rec_lo_float = sym13_float[2]; w->rec_hi_float = sym13_float[3]; break; case 14: w->dec_lo_double = sym14_double[0]; w->dec_hi_double = sym14_double[1]; w->rec_lo_double = sym14_double[2]; w->rec_hi_double = sym14_double[3]; w->dec_lo_float = sym14_float[0]; w->dec_hi_float = sym14_float[1]; w->rec_lo_float = sym14_float[2]; w->rec_hi_float = sym14_float[3]; break; case 15: w->dec_lo_double = sym15_double[0]; w->dec_hi_double = sym15_double[1]; w->rec_lo_double = sym15_double[2]; w->rec_hi_double = sym15_double[3]; w->dec_lo_float = sym15_float[0]; w->dec_hi_float = sym15_float[1]; w->rec_lo_float = sym15_float[2]; w->rec_hi_float = sym15_float[3]; break; case 16: w->dec_lo_double = sym16_double[0]; w->dec_hi_double = sym16_double[1]; w->rec_lo_double = sym16_double[2]; w->rec_hi_double = sym16_double[3]; w->dec_lo_float = sym16_float[0]; w->dec_hi_float = sym16_float[1]; w->rec_lo_float = sym16_float[2]; w->rec_hi_float = sym16_float[3]; break; case 17: w->dec_lo_double = sym17_double[0]; w->dec_hi_double = sym17_double[1]; w->rec_lo_double = sym17_double[2]; w->rec_hi_double = sym17_double[3]; w->dec_lo_float = sym17_float[0]; w->dec_hi_float = sym17_float[1]; w->rec_lo_float = sym17_float[2]; w->rec_hi_float = sym17_float[3]; break; case 18: w->dec_lo_double = sym18_double[0]; w->dec_hi_double = sym18_double[1]; w->rec_lo_double = sym18_double[2]; w->rec_hi_double = sym18_double[3]; w->dec_lo_float = sym18_float[0]; w->dec_hi_float = sym18_float[1]; w->rec_lo_float = sym18_float[2]; w->rec_hi_float = sym18_float[3]; break; case 19: w->dec_lo_double = sym19_double[0]; w->dec_hi_double = sym19_double[1]; w->rec_lo_double = sym19_double[2]; w->rec_hi_double = sym19_double[3]; w->dec_lo_float = sym19_float[0]; w->dec_hi_float = sym19_float[1]; w->rec_lo_float = sym19_float[2]; w->rec_hi_float = sym19_float[3]; break; case 20: w->dec_lo_double = sym20_double[0]; w->dec_hi_double = sym20_double[1]; w->rec_lo_double = sym20_double[2]; w->rec_hi_double = sym20_double[3]; w->dec_lo_float = sym20_float[0]; w->dec_hi_float = sym20_float[1]; w->rec_lo_float = sym20_float[2]; w->rec_hi_float = sym20_float[3]; break; default: wtfree(w); return NULL; } break; // Coiflets wavelets family case 'c': case 'C': w->dec_len = w->rec_len = order * 6; w->vanishing_moments_psi = 2*order; w->vanishing_moments_phi = 2*order -1; w->support_width = 6*order - 1; w->orthogonal = 1; w->biorthogonal = 1; w->symmetry = NEAR_SYMMETRIC; w->compact_support = 1; w->family_name = "Coiflets"; w->short_name = "coif"; switch (order) { case 1: w->dec_lo_double = coif1_double[0]; w->dec_hi_double = coif1_double[1]; w->rec_lo_double = coif1_double[2]; w->rec_hi_double = coif1_double[3]; w->dec_lo_float = coif1_float[0]; w->dec_hi_float = coif1_float[1]; w->rec_lo_float = coif1_float[2]; w->rec_hi_float = coif1_float[3]; break; case 2: w->dec_lo_double = coif2_double[0]; w->dec_hi_double = coif2_double[1]; w->rec_lo_double = coif2_double[2]; w->rec_hi_double = coif2_double[3]; w->dec_lo_float = coif2_float[0]; w->dec_hi_float = coif2_float[1]; w->rec_lo_float = coif2_float[2]; w->rec_hi_float = coif2_float[3]; break; case 3: w->dec_lo_double = coif3_double[0]; w->dec_hi_double = coif3_double[1]; w->rec_lo_double = coif3_double[2]; w->rec_hi_double = coif3_double[3]; w->dec_lo_float = coif3_float[0]; w->dec_hi_float = coif3_float[1]; w->rec_lo_float = coif3_float[2]; w->rec_hi_float = coif3_float[3]; break; case 4: w->dec_lo_double = coif4_double[0]; w->dec_hi_double = coif4_double[1]; w->rec_lo_double = coif4_double[2]; w->rec_hi_double = coif4_double[3]; w->dec_lo_float = coif4_float[0]; w->dec_hi_float = coif4_float[1]; w->rec_lo_float = coif4_float[2]; w->rec_hi_float = coif4_float[3]; break; case 5: w->dec_lo_double = coif5_double[0]; w->dec_hi_double = coif5_double[1]; w->rec_lo_double = coif5_double[2]; w->rec_hi_double = coif5_double[3]; w->dec_lo_float = coif5_float[0]; w->dec_hi_float = coif5_float[1]; w->rec_lo_float = coif5_float[2]; w->rec_hi_float = coif5_float[3]; break; default: wtfree(w); return NULL; } break; // Biorthogonal wavelets family case 'b': case 'B': w->vanishing_moments_psi = order/10; w->vanishing_moments_phi = -1; w->support_width = -1; w->orthogonal = 0; w->biorthogonal = 1; w->symmetry = SYMMETRIC; w->compact_support = 1; w->family_name = "Biorthogonal"; w->short_name = "bior"; switch (order) { case 11: w->dec_lo_double = bior1_1_double[0]; w->dec_hi_double = bior1_1_double[1]; w->rec_lo_double = bior1_1_double[2]; w->rec_hi_double = bior1_1_double[3]; w->dec_lo_float = bior1_1_float[0]; w->dec_hi_float = bior1_1_float[1]; w->rec_lo_float = bior1_1_float[2]; w->rec_hi_float = bior1_1_float[3]; w->dec_len = w->rec_len = 2 * 1; break; case 13: w->dec_lo_double = bior1_3_double[0]; w->dec_hi_double = bior1_3_double[1]; w->rec_lo_double = bior1_3_double[2]; w->rec_hi_double = bior1_3_double[3]; w->dec_lo_float = bior1_3_float[0]; w->dec_hi_float = bior1_3_float[1]; w->rec_lo_float = bior1_3_float[2]; w->rec_hi_float = bior1_3_float[3]; w->dec_len = w->rec_len = 2 * 3; break; case 15: w->dec_lo_double = bior1_5_double[0]; w->dec_hi_double = bior1_5_double[1]; w->rec_lo_double = bior1_5_double[2]; w->rec_hi_double = bior1_5_double[3]; w->dec_lo_float = bior1_5_float[0]; w->dec_hi_float = bior1_5_float[1]; w->rec_lo_float = bior1_5_float[2]; w->rec_hi_float = bior1_5_float[3]; w->dec_len = w->rec_len = 2 * 5; break; case 22: w->dec_lo_double = bior2_2_double[0]; w->dec_hi_double = bior2_2_double[1]; w->rec_lo_double = bior2_2_double[2]; w->rec_hi_double = bior2_2_double[3]; w->dec_lo_float = bior2_2_float[0]; w->dec_hi_float = bior2_2_float[1]; w->rec_lo_float = bior2_2_float[2]; w->rec_hi_float = bior2_2_float[3]; w->dec_len = w->rec_len = 2 * 2 + 2; break; case 24: w->dec_lo_double = bior2_4_double[0]; w->dec_hi_double = bior2_4_double[1]; w->rec_lo_double = bior2_4_double[2]; w->rec_hi_double = bior2_4_double[3]; w->dec_lo_float = bior2_4_float[0]; w->dec_hi_float = bior2_4_float[1]; w->rec_lo_float = bior2_4_float[2]; w->rec_hi_float = bior2_4_float[3]; w->dec_len = w->rec_len = 2 * 4 + 2; break; case 26: w->dec_lo_double = bior2_6_double[0]; w->dec_hi_double = bior2_6_double[1]; w->rec_lo_double = bior2_6_double[2]; w->rec_hi_double = bior2_6_double[3]; w->dec_lo_float = bior2_6_float[0]; w->dec_hi_float = bior2_6_float[1]; w->rec_lo_float = bior2_6_float[2]; w->rec_hi_float = bior2_6_float[3]; w->dec_len = w->rec_len = 2 * 6 + 2; break; case 28: w->dec_lo_double = bior2_8_double[0]; w->dec_hi_double = bior2_8_double[1]; w->rec_lo_double = bior2_8_double[2]; w->rec_hi_double = bior2_8_double[3]; w->dec_lo_float = bior2_8_float[0]; w->dec_hi_float = bior2_8_float[1]; w->rec_lo_float = bior2_8_float[2]; w->rec_hi_float = bior2_8_float[3]; w->dec_len = w->rec_len = 2 * 8 + 2; break; case 31: w->dec_lo_double = bior3_1_double[0]; w->dec_hi_double = bior3_1_double[1]; w->rec_lo_double = bior3_1_double[2]; w->rec_hi_double = bior3_1_double[3]; w->dec_lo_float = bior3_1_float[0]; w->dec_hi_float = bior3_1_float[1]; w->rec_lo_float = bior3_1_float[2]; w->rec_hi_float = bior3_1_float[3]; w->dec_len = w->rec_len = 2 * 1 + 2; break; case 33: w->dec_lo_double = bior3_3_double[0]; w->dec_hi_double = bior3_3_double[1]; w->rec_lo_double = bior3_3_double[2]; w->rec_hi_double = bior3_3_double[3]; w->dec_lo_float = bior3_3_float[0]; w->dec_hi_float = bior3_3_float[1]; w->rec_lo_float = bior3_3_float[2]; w->rec_hi_float = bior3_3_float[3]; w->dec_len = w->rec_len = 2 * 3 + 2; break; case 35: w->dec_lo_double = bior3_5_double[0]; w->dec_hi_double = bior3_5_double[1]; w->rec_lo_double = bior3_5_double[2]; w->rec_hi_double = bior3_5_double[3]; w->dec_lo_float = bior3_5_float[0]; w->dec_hi_float = bior3_5_float[1]; w->rec_lo_float = bior3_5_float[2]; w->rec_hi_float = bior3_5_float[3]; w->dec_len = w->rec_len = 2 * 5 + 2; break; case 37: w->dec_lo_double = bior3_7_double[0]; w->dec_hi_double = bior3_7_double[1]; w->rec_lo_double = bior3_7_double[2]; w->rec_hi_double = bior3_7_double[3]; w->dec_lo_float = bior3_7_float[0]; w->dec_hi_float = bior3_7_float[1]; w->rec_lo_float = bior3_7_float[2]; w->rec_hi_float = bior3_7_float[3]; w->dec_len = w->rec_len = 2 * 7 + 2; break; case 39: w->dec_lo_double = bior3_9_double[0]; w->dec_hi_double = bior3_9_double[1]; w->rec_lo_double = bior3_9_double[2]; w->rec_hi_double = bior3_9_double[3]; w->dec_lo_float = bior3_9_float[0]; w->dec_hi_float = bior3_9_float[1]; w->rec_lo_float = bior3_9_float[2]; w->rec_hi_float = bior3_9_float[3]; w->dec_len = w->rec_len = 2 * 9 + 2; break; case 44: w->dec_lo_double = bior4_4_double[0]; w->dec_hi_double = bior4_4_double[1]; w->rec_lo_double = bior4_4_double[2]; w->rec_hi_double = bior4_4_double[3]; w->dec_lo_float = bior4_4_float[0]; w->dec_hi_float = bior4_4_float[1]; w->rec_lo_float = bior4_4_float[2]; w->rec_hi_float = bior4_4_float[3]; w->dec_len = w->rec_len = 2 * 4 + 2; break; case 55: w->dec_lo_double = bior5_5_double[0]; w->dec_hi_double = bior5_5_double[1]; w->rec_lo_double = bior5_5_double[2]; w->rec_hi_double = bior5_5_double[3]; w->dec_lo_float = bior5_5_float[0]; w->dec_hi_float = bior5_5_float[1]; w->rec_lo_float = bior5_5_float[2]; w->rec_hi_float = bior5_5_float[3]; w->dec_len = w->rec_len = 2 * 5 + 2; break; case 68: w->dec_lo_double = bior6_8_double[0]; w->dec_hi_double = bior6_8_double[1]; w->rec_lo_double = bior6_8_double[2]; w->rec_hi_double = bior6_8_double[3]; w->dec_lo_float = bior6_8_float[0]; w->dec_hi_float = bior6_8_float[1]; w->rec_lo_float = bior6_8_float[2]; w->rec_hi_float = bior6_8_float[3]; w->dec_len = w->rec_len = 2 * 8 + 2; break; default: wtfree(w); return NULL; } //## ENDFOR $DTYPE$ break; // Discrete FIR filter approximation of Meyer wavelet case 'm': case 'M': w->vanishing_moments_psi = -1; w->vanishing_moments_phi = -1; w->support_width = -1; w->orthogonal = 1; w->biorthogonal = 1; w->symmetry = SYMMETRIC; w->compact_support = 1; w->family_name = "Discrete Meyer (FIR Approximation)"; w->short_name = "dmey"; w->dec_lo_double = dmey_double[0]; w->dec_hi_double = dmey_double[1]; w->rec_lo_double = dmey_double[2]; w->rec_hi_double = dmey_double[3]; w->dec_lo_float = dmey_float[0]; w->dec_hi_float = dmey_float[1]; w->rec_lo_float = dmey_float[2]; w->rec_hi_float = dmey_float[3]; w->dec_len = w->rec_len = 62; return w; break; default: wtfree(w); return NULL; } return w; }