resample.c (PDL-2.081) | : | resample.c (PDL-2.082) | ||
---|---|---|---|---|
skipping to change at line 184 | skipping to change at line 184 | |||
mmax = istep; | mmax = istep; | |||
} | } | |||
} /* reverse_tanh_kernel() */ | } /* reverse_tanh_kernel() */ | |||
#undef KERNEL_SW | #undef KERNEL_SW | |||
/*-------------------------------------------------------------------------*/ | /*-------------------------------------------------------------------------*/ | |||
/** | /** | |||
@name generate_tanh_kernel | @name generate_tanh_kernel | |||
@memo Generate a hyperbolic tangent kernel. | @memo Generate a hyperbolic tangent kernel. | |||
@param steep Steepness of the hyperbolic tangent parts. | @param steep Steepness of the hyperbolic tangent parts. | |||
@return 1 pointer to a newly allocated array of doubles. | @param samples Number of samples | |||
@param kernel Block of (samples) * long double | ||||
@doc | @doc | |||
The following function builds up a good approximation of a box filter. It | The following function builds up a good approximation of a box filter. It | |||
is built from a product of hyperbolic tangents. It has the following | is built from a product of hyperbolic tangents. It has the following | |||
properties: | properties: | |||
\begin{itemize} | \begin{itemize} | |||
\item It converges very quickly towards +/- 1. | \item It converges very quickly towards +/- 1. | |||
\item The converging transition is very sharp. | \item The converging transition is very sharp. | |||
\item It is infinitely differentiable everywhere (i.e. smooth). | \item It is infinitely differentiable everywhere (i.e. smooth). | |||
\item The transition sharpness is scalable. | \item The transition sharpness is scalable. | |||
\end{itemize} | \end{itemize} | |||
The returned array must be deallocated using free(). | ||||
*/ | */ | |||
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |||
#define hk_gen(x,s) (((tanh(s*(x+0.5))+1)/2)*((tanh(s*(-x+0.5))+1)/2)) | #define hk_gen(x,s) (((tanh(s*(x+0.5))+1)/2)*((tanh(s*(-x+0.5))+1)/2)) | |||
long double * generate_tanh_kernel(long double steep) | void generate_tanh_kernel(long double steep, int samples, long double *kernel) | |||
{ | { | |||
long double * kernel ; | ||||
long double * x ; | long double * x ; | |||
long double width ; | long double width ; | |||
long double inv_np ; | long double inv_np ; | |||
long double ind ; | long double ind ; | |||
int i ; | int i ; | |||
int np ; | int np ; | |||
int samples ; | ||||
width = (long double)TABSPERPIX / 2.0 ; | width = (long double)TABSPERPIX / 2.0 ; | |||
samples = KERNEL_SAMPLES ; | ||||
np = 32768 ; /* Hardcoded: should never be changed */ | np = 32768 ; /* Hardcoded: should never be changed */ | |||
inv_np = 1.00 / (long double)np ; | inv_np = 1.00 / (long double)np ; | |||
/* | /* | |||
* Generate the kernel expression in Fourier space | * Generate the kernel expression in Fourier space | |||
* with a correct frequency ordering to allow standard FT | * with a correct frequency ordering to allow standard FT | |||
*/ | */ | |||
x = (long double *) malloc((2*np+1)*sizeof(long double)) ; | x = (long double *) malloc((2*np+1)*sizeof(long double)) ; | |||
for (i=0 ; i<np/2 ; i++) { | for (i=0 ; i<np/2 ; i++) { | |||
ind = (long double)i * 2.0 * width * inv_np ; | ind = (long double)i * 2.0 * width * inv_np ; | |||
skipping to change at line 242 | skipping to change at line 238 | |||
x[2*i] = hk_gen(ind, steep) ; | x[2*i] = hk_gen(ind, steep) ; | |||
x[2*i+1] = 0.00 ; | x[2*i+1] = 0.00 ; | |||
} | } | |||
/* | /* | |||
* Reverse Fourier to come back to image space | * Reverse Fourier to come back to image space | |||
*/ | */ | |||
reverse_tanh_kernel(x, np) ; | reverse_tanh_kernel(x, np) ; | |||
/* | /* | |||
* Allocate and fill in returned array | * fill in passed-in array | |||
*/ | */ | |||
kernel = (long double *) malloc(samples * sizeof(long double)) ; | ||||
for (i=0 ; i<samples ; i++) { | for (i=0 ; i<samples ; i++) { | |||
kernel[i] = 2.0 * width * x[2*i] * inv_np ; | kernel[i] = 2.0 * width * x[2*i] * inv_np ; | |||
} | } | |||
free(x) ; | free(x) ; | |||
return kernel ; | ||||
} /* generate_tanh_kernel() */ | } /* generate_tanh_kernel() */ | |||
/*-------------------------------------------------------------------------*/ | /*-------------------------------------------------------------------------*/ | |||
/** | /** | |||
@name generate_interpolation_kernel | @name generate_interpolation_kernel | |||
@memo Generate an interpolation kernel to use in this module. | @memo Generate an interpolation kernel to use in this module. | |||
@param kernel_type Type of interpolation kernel. | @param kernel_type Type of interpolation kernel. | |||
@return 1 newly allocated array of doubles. | @param samples Number of samples | |||
@param kernel Block of (samples) * long double | ||||
@return true on success | ||||
@doc | @doc | |||
Provide the name of the kernel you want to generate. Supported kernel | Provide the name of the kernel you want to generate. Supported kernel | |||
types are: | types are: | |||
\begin{tabular}{ll} | \begin{tabular}{ll} | |||
NULL & default kernel, currently "tanh" \\ | NULL & default kernel, currently "tanh" \\ | |||
"default" & default kernel, currently "tanh" \\ | "default" & default kernel, currently "tanh" \\ | |||
"tanh" & Hyperbolic tangent \\ | "tanh" & Hyperbolic tangent \\ | |||
"sinc2" & Square sinc \\ | "sinc2" & Square sinc \\ | |||
"lanczos" & Lanczos2 kernel \\ | "lanczos" & Lanczos2 kernel \\ | |||
"hamming" & Hamming kernel \\ | "hamming" & Hamming kernel \\ | |||
"hann" & Hann kernel | "hann" & Hann kernel | |||
\end{tabular} | \end{tabular} | |||
The returned array of doubles is ready of use in the various re-sampling | The filled-in array of long doubles is ready to use in the various re-sampling | |||
functions in this module. It must be deallocated using free(). | functions in this module. | |||
*/ | */ | |||
/*--------------------------------------------------------------------------*/ | /*--------------------------------------------------------------------------*/ | |||
long double * | char | |||
generate_interpolation_kernel(char * kernel_type) | generate_interpolation_kernel(char *kernel_type, int samples, long double *tab) | |||
{ | { | |||
long double * tab ; | ||||
int i ; | int i ; | |||
long double x ; | long double x ; | |||
long double alpha ; | long double alpha ; | |||
long double inv_norm ; | long double inv_norm ; | |||
int samples = KERNEL_SAMPLES ; | if (kernel_type==NULL || !strcmp(kernel_type, "default") || !strcmp(kerne | |||
l_type, "tanh")) { | ||||
if (kernel_type==NULL) { | generate_tanh_kernel(TANH_STEEPNESS, samples, tab) ; | |||
tab = generate_interpolation_kernel("tanh") ; | ||||
} else if (!strcmp(kernel_type, "default")) { | ||||
tab = generate_interpolation_kernel("tanh") ; | ||||
} else if (!strcmp(kernel_type, "sinc")) { | } else if (!strcmp(kernel_type, "sinc")) { | |||
tab = (long double *) malloc(samples * sizeof(long double)) ; | ||||
tab[0] = 1.0 ; | tab[0] = 1.0 ; | |||
tab[samples-1] = 0.0 ; | tab[samples-1] = 0.0 ; | |||
for (i=1 ; i<samples ; i++) { | for (i=1 ; i<samples ; i++) { | |||
x = (long double)KERNEL_WIDTH * (long double)i/(long doub le)(samples-1) ; | x = (long double)KERNEL_WIDTH * (long double)i/(long doub le)(samples-1) ; | |||
tab[i] = sinc(x) ; | tab[i] = sinc(x) ; | |||
} | } | |||
} else if (!strcmp(kernel_type, "sinc2")) { | } else if (!strcmp(kernel_type, "sinc2")) { | |||
tab = (long double *) malloc(samples * sizeof(long double)) ; | ||||
tab[0] = 1.0 ; | tab[0] = 1.0 ; | |||
tab[samples-1] = 0.0 ; | tab[samples-1] = 0.0 ; | |||
for (i=1 ; i<samples ; i++) { | for (i=1 ; i<samples ; i++) { | |||
x = 2.0 * (long double)i/(long double)(samples-1) ; | x = 2.0 * (long double)i/(long double)(samples-1) ; | |||
tab[i] = sinc(x) ; | tab[i] = sinc(x) ; | |||
tab[i] *= tab[i] ; | tab[i] *= tab[i] ; | |||
} | } | |||
} else if (!strcmp(kernel_type, "lanczos")) { | } else if (!strcmp(kernel_type, "lanczos")) { | |||
tab = (long double *) malloc(samples * sizeof(long double)) ; | ||||
for (i=0 ; i<samples ; i++) { | for (i=0 ; i<samples ; i++) { | |||
x = (long double)KERNEL_WIDTH * (long double)i/(long doub le)(samples-1) ; | x = (long double)KERNEL_WIDTH * (long double)i/(long doub le)(samples-1) ; | |||
if (fabs(x)<2) { | if (fabs(x)<2) { | |||
tab[i] = sinc(x) * sinc(x/2) ; | tab[i] = sinc(x) * sinc(x/2) ; | |||
} else { | } else { | |||
tab[i] = 0.00 ; | tab[i] = 0.00 ; | |||
} | } | |||
} | } | |||
} else if (!strcmp(kernel_type, "hamming")) { | } else if (!strcmp(kernel_type, "hamming")) { | |||
tab = (long double *) malloc(samples * sizeof(long double)) ; | ||||
alpha = 0.54 ; | alpha = 0.54 ; | |||
inv_norm = 1.00 / (long double)(samples - 1) ; | inv_norm = 1.00 / (long double)(samples - 1) ; | |||
for (i=0 ; i<samples ; i++) { | for (i=0 ; i<samples ; i++) { | |||
x = (long double)i ; | x = (long double)i ; | |||
if (i<(samples-1)/2) { | if (i<(samples-1)/2) { | |||
tab[i] = alpha + (1-alpha) * cos(2.0*PI_NUMB*x*in v_norm) ; | tab[i] = alpha + (1-alpha) * cos(2.0*PI_NUMB*x*in v_norm) ; | |||
} else { | } else { | |||
tab[i] = 0.0 ; | tab[i] = 0.0 ; | |||
} | } | |||
} | } | |||
} else if (!strcmp(kernel_type, "hann")) { | } else if (!strcmp(kernel_type, "hann")) { | |||
tab = (long double *) malloc(samples * sizeof(long double)) ; | ||||
alpha = 0.50 ; | alpha = 0.50 ; | |||
inv_norm = 1.00 / (long double)(samples - 1) ; | inv_norm = 1.00 / (long double)(samples - 1) ; | |||
for (i=0 ; i<samples ; i++) { | for (i=0 ; i<samples ; i++) { | |||
x = (long double)i ; | x = (long double)i ; | |||
if (i<(samples-1)/2) { | if (i<(samples-1)/2) { | |||
tab[i] = alpha + (1-alpha) * cos(2.0*PI_NUMB*x*in v_norm) ; | tab[i] = alpha + (1-alpha) * cos(2.0*PI_NUMB*x*in v_norm) ; | |||
} else { | } else { | |||
tab[i] = 0.0 ; | tab[i] = 0.0 ; | |||
} | } | |||
} | } | |||
} else if (!strcmp(kernel_type, "tanh")) { | ||||
tab = generate_tanh_kernel(TANH_STEEPNESS) ; | ||||
} else { | } else { | |||
/** | /** | |||
** trapped at perl level, so should never reach here | ** trapped at perl level, so should never reach here | |||
e_error("unrecognized kernel type [%s]: aborting generation", | e_error("unrecognized kernel type [%s]: aborting generation", | |||
kernel_type) ; | kernel_type) ; | |||
**/ | **/ | |||
return NULL ; | return 0; | |||
} | } | |||
return 1; | ||||
return tab ; | ||||
} /* generate_interpolation_kernel() */ | } /* generate_interpolation_kernel() */ | |||
void kernel_free( void *p ) { | ||||
#undef free | ||||
free( p ); | ||||
} | ||||
/*********** | ||||
*** END *** | ||||
***********/ | ||||
End of changes. 23 change blocks. | ||||
34 lines changed or deleted | 16 lines changed or added |