48 static void PrefilterScan(
float *Data,
int Stride,
int N,
float alpha,
51 const float Eps = 1e-4;
52 float Sum, Weight, Last;
55 n0 = (int)ceil(log(Eps)/log(fabs(alpha)));
63 Sum = Data[0]/(1 - alpha);
70 for(i = Stride; i < iEnd; i += Stride)
73 Sum += Data[i]*Weight;
77 Sum = Data[0]*(1 + alpha);
81 for(i = Stride; i < iEnd; i += Stride)
84 Sum += Data[i]*Weight;
90 iEnd = (N - 1)*Stride;
92 for(i = Stride; i < iEnd; i += Stride)
94 Data[i] += alpha*Last;
101 Last = Data[iEnd] = (alpha*(-Data[iEnd] + (alpha - 1)*alpha*Last))
102 /((alpha - 1)*(alpha*alpha - 1));
105 Data[iEnd] += alpha*Last;
106 Last = Data[iEnd] *= alpha/(alpha - 1);
109 Data[iEnd] += alpha*Last;
110 Last = Data[iEnd] = (alpha/(alpha*alpha - 1))
111 * ( Data[iEnd] + alpha*Data[iEnd - Stride] );
115 for(i = iEnd - Stride; i >= 0; i -= Stride)
117 Data[i] = alpha*(Last - Data[i]);
133 const float *alpha,
int NumFilterPairs,
float ConstantFactor,
136 const int NumPixels = Width*Height;
137 int k, x, y, Channel;
141 ConstantFactor = ConstantFactor*ConstantFactor;
143 for(Channel = 0; Channel < NumChannels; Channel++)
145 for(x = 0; x < Width; x++)
146 for(k = 0; k < NumFilterPairs; k++)
147 PrefilterScan(Data + x, Width, Height, alpha[k], Boundary);
149 for(y = 0; y < Height; y++)
150 for(k = 0; k < NumFilterPairs; k++)
151 PrefilterScan(Data + Width*y, 1, Width, alpha[k], Boundary);
153 for(k = 0; k < NumPixels; k++)
154 Data[k] *= ConstantFactor;
162 float (*Kernel)(float);
164 float (*Psf)(float,
const void*);
170 static float ConvIntegrand(
float t,
const void *Params)
177 return Kernel(t) * Psf(x - t, PsfParams);
181 static float ConvIntegrandNormalized(
float t,
const void *Params)
190 for(r = -R, Sum = 0; r <= R; r++)
191 Sum += Kernel(t - r);
193 return (Kernel(t)/Sum) * Psf(x - t, PsfParams);
215 float (*Psf)(
float,
const void*),
const void *PsfParams,
216 float (*Kernel)(
float),
float KernelRadius,
int KernelNormalize)
218 float (*ConvFun)(float,
const void*) = ConvIntegrand;
222 ConvParams.
Kernel = Kernel;
224 ConvParams.
Psf = Psf;
228 ConvFun = ConvIntegrandNormalized;
230 for(m = 0; m < NumCoeffs; m++)
233 Coeff[m] =
AdaptLob(ConvFun, -KernelRadius, KernelRadius,
234 1e-7f, (
const void *)&ConvParams);
266 static int PsfPreFilterScan(
float *Data,
int Stride,
int ScanSize,
267 int ScanStride,
int NumScans,
int ChannelStride,
int NumChannels,
271 float *Buf = NULL, *CoeffDct = NULL;
273 fftwf_iodim Dims[1], HowManyDims[2];
274 fftw_r2r_kind Kind[1];
275 int i, Scan, Channel, Success = 0;
279 || !(Buf = (
float *)fftwf_malloc(
sizeof(
float)*ScanSize*NumScans*NumChannels))
280 || !(CoeffDct = (
float *)fftwf_malloc(
sizeof(
float)*PadCoeff)))
283 for(i = 0; i < NumCoeffs && i < PadCoeff; i++)
285 for(; i < PadCoeff; i++)
289 if(!(Plan = fftwf_plan_r2r_1d(PadCoeff, Buf, CoeffDct,
290 FFTW_REDFT00, FFTW_ESTIMATE | FFTW_DESTROY_INPUT)))
294 fftwf_destroy_plan(Plan);
297 for(i = 0; i < ScanSize; i++)
298 CoeffDct[i] *= 2*(PadCoeff - 1);
301 Dims[0].n = ScanSize;
304 HowManyDims[0].n = NumChannels;
305 HowManyDims[0].is = ChannelStride;
306 HowManyDims[0].os = ScanSize*NumScans;
307 HowManyDims[1].n = NumScans;
308 HowManyDims[1].is = ScanStride;
309 HowManyDims[1].os = ScanSize;
315 if(!(Plan = fftwf_plan_guru_r2r(1, Dims, 2, HowManyDims, Data,
316 Buf, Kind, FFTW_ESTIMATE | FFTW_DESTROY_INPUT)))
320 fftwf_destroy_plan(Plan);
323 for(Channel = 0; Channel < NumChannels; Channel++)
325 for(Scan = 0; Scan < NumScans; Scan++)
327 for(i = 0; i < ScanSize; i++)
328 Buf[i + ScanSize*(Scan + NumScans*Channel)] /= CoeffDct[i];
333 Dims[0].n = ScanSize;
336 HowManyDims[0].n = NumChannels;
337 HowManyDims[0].is = ScanSize*NumScans;
338 HowManyDims[0].os = ChannelStride;
339 HowManyDims[1].n = NumScans;
340 HowManyDims[1].is = ScanSize;
341 HowManyDims[1].os = ScanStride;
347 if(!(Plan = fftwf_plan_guru_r2r(1, Dims, 2, HowManyDims, Buf,
348 Data, Kind, FFTW_ESTIMATE | FFTW_DESTROY_INPUT)))
352 fftwf_destroy_plan(Plan);
356 fftwf_free(CoeffDct);
386 if(!PsfPreFilterScan(Data, Width, Height, 1, Width, Width*Height,
387 NumChannels, Coeff, NumCoeffs, Boundary))
390 if(!PsfPreFilterScan(Data, 1, Width, Width, Height, Width*Height,
391 NumChannels, Coeff, NumCoeffs, Boundary))