21 #define CLAMP(X,A,B)    (((X) < (A)) ? (A) : (((X) > (B)) ? (B) : (X))) 
   42     int nStart, 
int nStep, 
int nEnd)
 
   44     const int SrcStrideStep = SrcStride*nStep;
 
   45     const int LeftmostTap = 1 - Filter.
Delay - Filter.
Length;
 
   46     const int StartInterior = 
CLAMP(-LeftmostTap, 0, N - 1);
 
   47     const int EndInterior = (Filter.
Delay <  0) ?
 
   48                             (N + Filter.
Delay - 1) : (N - 1);
 
   49     const float *SrcN, *SrcK;
 
   54     if(nEnd < nStart || nStep <= 0 || N <= 0)
 
   58     for(n = nStart; n < StartInterior; n += nStep, Dest += DestStride)
 
   60         for(k = 0, Accum = 0; k < Filter.
Length; k++)
 
   61             Accum += Filter.
Coeff[k]
 
   62                 * Boundary(Src, SrcStride, N, n - Filter.
Delay - k);
 
   78     SrcN = (LeftmostTap <= 0) ? Src : (Src + SrcStride*LeftmostTap);
 
   81     SrcN += SrcStride*(n - StartInterior);
 
   83     for(; n <= EndInterior; n += nStep, SrcN += SrcStrideStep, Dest += DestStride)
 
   91             Accum += Filter.
Coeff[--k] * (*SrcK);
 
   99     for(; n <= nEnd; n += nStep, Dest += DestStride)
 
  101         for(k = 0, Accum = 0; k < Filter.
Length; k++)
 
  102             Accum += Filter.
Coeff[k]
 
  103                 * Boundary(Src, SrcStride, N, n - Filter.
Delay - k);
 
  125     int Width, 
int Height, 
int NumChannels)
 
  127     const int NumPixels = Width*Height;
 
  130     for(Channel = 0; Channel < NumChannels; Channel++)
 
  133         for(i = 0; i < Height; i++)
 
  134             Conv1D(Buffer + Width*i, 1, Src + Width*i, 1,
 
  135                 FilterX, Boundary, Width);
 
  138         for(i = 0; i < Width; i++)
 
  139             Conv1D(Dest + i, Width, Buffer + i, Width, FilterY,
 
  153     Filter.
Coeff = Coeff;
 
  154     Filter.
Delay = Delay;
 
  165     if(Length > 0 && (Coeff = (
float *)
Malloc(
sizeof(
float)*Length)))
 
  175     return (Filter.
Coeff == NULL) ? 1:0;
 
  207             for(r = -R, Sum = 0; r <= R; r++)
 
  209                 Filter.
Coeff[R + r] = (float)exp(-r*r/(2*Sigma*Sigma));
 
  210                 Sum += Filter.
Coeff[R + r];
 
  213             for(r = -R; r <= R; r++)
 
  214                 Filter.
Coeff[R + r] /= Sum;
 
  222 static float ZeroPaddedExtension(
const float *Src, 
int Stride, 
int N, 
int n)
 
  224     return (0 <= n && n < N) ? Src[Stride*n] : 0;
 
  228 static float ConstantExtension(
const float *Src, 
int Stride, 
int N, 
int n)
 
  230     return Src[(n < 0) ? 0 : ((n >= N) ? Stride*(N - 1) : n)];
 
  234 static float LinearExtension(
const float *Src, 
int Stride, 
int N, 
int n)
 
  239             return Src[Stride*n];
 
  244             Src += Stride*(N - 1);
 
  245             return Src[0] + (N - 1 - n)*(Src[-Stride] - Src[0]);
 
  251         return Src[0] + n*(Src[Stride] - Src[0]);
 
  255 static float PeriodicExtension(
const float *Src, 
int Stride, 
int N, 
int n)
 
  272     return Src[Stride*n];
 
  276 static float SymhExtension(
const float *Src, 
int Stride, 
int N, 
int n)
 
  288     return Src[Stride*n];
 
  292 static float SymwExtension(
const float *Src, 
int Stride, 
int N, 
int n)
 
  304     return Src[Stride*n];
 
  308 static float AsymhExtension(
const float *Src, 
int Stride, 
int N, 
int n)
 
  317             return Src[Stride*n];
 
  318         else if(n <= 2*N - 1)
 
  319             return 3*Src[Stride*(N - 1)] - Src[Stride*(N - 2)]
 
  320                 - Src[Stride*(2*N - 1 - n)];
 
  323         return 3*Src[0] - Src[Stride] - Src[Stride*(-1 - n)];
 
  330     Jump = 3*(Src[Stride*(N - 1)] - Src[0])
 
  331         - (Src[Stride*(N - 2)] - Src[Stride]);
 
  352         return Src[Stride*n] + Offset;
 
  354         return 3*Src[0] - Src[Stride] - Src[Stride*(-1 - n)] + Offset;
 
  358 static float AsymwExtension(
const float *Src, 
int Stride, 
int N, 
int n)
 
  367             return Src[Stride*n];
 
  369             return 2*Src[Stride*(N - 1)] - Src[Stride*(2*(N - 1) - n)];
 
  372         return 2*Src[0] - Src[Stride*(-n)];
 
  379     Jump = 2*(Src[Stride*(N - 1)] - Src[0]);
 
  400         return Src[Stride*n] + Offset;
 
  402         return 2*Src[0] - Src[Stride*(-n)] + Offset;
 
  423     if(!strcmp(Boundary, 
"zpd") || !strcmp(Boundary, 
"zero"))
 
  424         return ZeroPaddedExtension;
 
  425     else if(!strcmp(Boundary, 
"sp0") || !strcmp(Boundary, 
"const"))
 
  426         return ConstantExtension;
 
  427     else if(!strcmp(Boundary, 
"sp1") || !strcmp(Boundary, 
"linear"))
 
  428         return LinearExtension;
 
  429     else if(!strcmp(Boundary, 
"per") || !strcmp(Boundary, 
"periodic"))
 
  430         return PeriodicExtension;
 
  431     else if(!strcmp(Boundary, 
"sym")
 
  432         || !strcmp(Boundary, 
"symh") || !strcmp(Boundary, 
"hsym"))
 
  433         return SymhExtension;
 
  434     else if(!strcmp(Boundary, 
"symw") || !strcmp(Boundary, 
"wsym"))
 
  435         return SymwExtension;
 
  436     else if(!strcmp(Boundary, 
"asym")
 
  437         || !strcmp(Boundary, 
"asymh") || !strcmp(Boundary, 
"hasym"))
 
  438         return AsymhExtension;
 
  439     else if(!strcmp(Boundary, 
"asymw") || !strcmp(Boundary, 
"wasym"))
 
  440         return AsymwExtension;
 
  443         ErrorMessage(
"Unknown boundary extension \"%s\".\n", Boundary);