22 static int ConstExtension(
int N,
int i)
39 static int HSymExtension(
int N,
int i)
59 static int WSymExtension(
int N,
int i)
74 {ConstExtension, HSymExtension, WSymExtension};
77 static int FourierScaleScan(
float *Dest,
78 int DestStride,
int DestScanStride,
int DestChannelStride,
int DestScanSize,
80 int SrcStride,
int SrcScanStride,
int SrcChannelStride,
int SrcScanSize,
81 int NumScans,
int NumChannels,
float XStart,
double PsfSigma,
84 const int SrcPadScanSize = 2*(SrcScanSize
88 : (2*DestScanSize - (int)floor((2.0f*DestScanSize)/SrcScanSize + 0.5f));
89 const int ReflectOffset = SrcPadScanSize
91 const int SrcDftSize = SrcPadScanSize/2 + 1;
92 const int DestDftSize = DestPadScanSize/2 + 1;
93 const int BufSpatialNumEl = DestPadScanSize*NumScans*NumChannels;
94 const int BufDftNumEl = 2*DestDftSize*NumScans*NumChannels;
95 float *BufSpatial = NULL, *BufDft = NULL, *Modulation = NULL, *Ptr;
97 fftwf_iodim Dims[1], HowManyDims[1];
99 int i, Scan, Channel, Success = 0;
103 || !(BufSpatial = (
float *)fftwf_malloc(
sizeof(
float)*BufSpatialNumEl))
104 || !(BufDft = (
float *)fftwf_malloc(
sizeof(
float)*BufDftNumEl)))
109 if(!(Modulation = (
float *)
Malloc(
sizeof(
float)*2*DestDftSize)))
112 for(i = 0; i < DestDftSize; i++)
114 Temp = (float)(
M_2PI*XStart*i/SrcPadScanSize);
115 Modulation[2*i + 0] = (float)cos(Temp);
116 Modulation[2*i + 1] = (float)sin(Temp);
121 for(Channel = 0; Channel < NumChannels; Channel++)
123 for(Scan = 0; Scan < NumScans; Scan++)
125 for(i = 0; i < SrcScanSize; i++)
126 BufSpatial[i + SrcPadScanSize*(Scan + NumScans*Channel)]
127 = Src[SrcStride*i + SrcScanStride*Scan + SrcChannelStride*Channel];
129 for(; i < SrcPadScanSize; i++)
130 BufSpatial[i + SrcPadScanSize*(Scan + NumScans*Channel)]
131 = Src[SrcStride*(ReflectOffset - i)
132 + SrcScanStride*Scan + SrcChannelStride*Channel];
139 for(i = 0; i < BufDftNumEl; i++)
143 Dims[0].n = SrcPadScanSize;
146 HowManyDims[0].n = NumScans*NumChannels;
147 HowManyDims[0].is = SrcPadScanSize;
148 HowManyDims[0].os = DestDftSize;
150 if(!(Plan = fftwf_plan_guru_dft_r2c(1, Dims, 1, HowManyDims, BufSpatial,
151 (fftwf_complex *)BufDft, FFTW_ESTIMATE | FFTW_DESTROY_INPUT)))
155 fftwf_destroy_plan(Plan);
158 for(Channel = 0, Ptr = BufDft; Channel < NumChannels; Channel++)
159 for(Scan = 0; Scan < NumScans; Scan++, Ptr += 2*DestDftSize)
160 for(i = 0; i < SrcDftSize; i++)
162 Ptr[2*i + 0] /= SrcPadScanSize;
163 Ptr[2*i + 1] /= SrcPadScanSize;
168 Temp = (float)(SrcPadScanSize / (
M_2PI * PsfSigma));
171 for(i = 0; i < SrcDftSize; i++)
173 if(i <= DestScanSize)
174 Denom = (float)exp(-(i*i)/Temp);
177 -((DestPadScanSize - i)*(DestPadScanSize - i))/Temp);
179 Denom *= SrcPadScanSize;
181 for(Channel = 0; Channel < NumChannels; Channel++)
182 for(Scan = 0; Scan < NumScans; Scan++)
184 BufDft[2*(i + DestDftSize*(Scan + NumScans*Channel)) + 0] /= Denom;
185 BufDft[2*(i + DestDftSize*(Scan + NumScans*Channel)) + 1] /= Denom;
192 for(Channel = 0, Ptr = BufDft; Channel < NumChannels; Channel++)
193 for(Scan = 0; Scan < NumScans; Scan++, Ptr += 2*DestDftSize)
194 for(i = 0; i < SrcDftSize; i++)
197 Temp = Ptr[2*i + 0]*Modulation[2*i + 0]
198 - Ptr[2*i + 1]*Modulation[2*i + 1];
199 Ptr[2*i + 1] = Ptr[2*i + 0]*Modulation[2*i + 1]
200 + Ptr[2*i + 1]*Modulation[2*i + 0];
205 Dims[0].n = DestPadScanSize;
208 HowManyDims[0].n = NumScans*NumChannels;
209 HowManyDims[0].is = DestDftSize;
210 HowManyDims[0].os = DestPadScanSize;
212 if(!(Plan = fftwf_plan_guru_dft_c2r(1, Dims, 1, HowManyDims,
213 (fftwf_complex *)BufDft, BufSpatial,
214 FFTW_ESTIMATE | FFTW_DESTROY_INPUT)))
218 fftwf_destroy_plan(Plan);
221 for(Channel = 0; Channel < NumChannels; Channel++)
223 for(Scan = 0; Scan < NumScans; Scan++)
225 for(i = 0; i < DestScanSize; i++)
226 Dest[DestStride*i + DestScanStride*Scan + DestChannelStride*Channel]
227 = BufSpatial[i + DestPadScanSize*(Scan + NumScans*Channel)];
237 fftwf_free(BufSpatial);
267 int DestHeight,
float YStart,
268 const float *Src,
int SrcWidth,
int SrcHeight,
int NumChannels,
272 unsigned long StartTime, StopTime;
276 if(!Dest || DestWidth < SrcWidth || DestHeight < SrcHeight || !Src
277 || SrcWidth <= 0 || SrcHeight <= 0 || NumChannels <= 0 || PsfSigma < 0
278 || !(Buf = (
float *)
Malloc(
sizeof(
float)*SrcWidth*DestHeight*3)))
284 if(!FourierScaleScan(Buf, SrcWidth, 1, SrcWidth*DestHeight, DestHeight,
285 Src, SrcWidth, 1, SrcWidth*SrcHeight, SrcHeight,
286 SrcWidth, 3, YStart, PsfSigma, Boundary))
290 if(!FourierScaleScan(Dest, 1, DestWidth, DestWidth*DestHeight, DestWidth,
291 Buf, 1, SrcWidth, SrcWidth*DestHeight, SrcWidth,
292 DestHeight, 3, XStart, PsfSigma, Boundary))
296 printf(
"CPU Time: %.3f s\n\n", 0.001*(StopTime - StartTime));