00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <math.h>
00004 #include <assert.h>
00005 #include "interpolate.h"
00006
00007
00008
00009
00010 #ifdef __GNUC__
00011 #define likely(a) __builtin_expect((a), 1)
00012 #define unlikely(a) __builtin_expect((a), 0)
00013 #else
00014 #define likely(a) (a)
00015 #define unlikely(a) (a)
00016 #endif
00017
00018
00019 static inline void dc3kernel (double u[4], double s);
00020 static inline void fc3kernel (float u[4], float s);
00021 static inline void dc4kernel (double u[6], double s);
00022 static inline void fc4kernel (float u[6], float s);
00023 static inline float fc3convolve(int ix, int iy, int nx, int ny, float *f,
00024 float *ux, float *uy, float fillvalue);
00025 static inline double dc3convolve(int ix, int iy, int nx, int ny, double *f,
00026 double *ux, double *uy, double fillvalue);
00027 static inline double dc4convolve(int ix, int iy, int nx, int ny, double *f,
00028 double *ux, double *uy, double fillvalue);
00029 static inline float fc4convolve(int ix, int iy, int nx, int ny, float *f,
00030 float *ux, float *uy, float fillvalue);
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 float fcint(int order, int nx, int ny, float *f,
00042 float x, float y, float fillvalue)
00043 {
00044 float ux[6], uy[6];
00045 int ix, iy;
00046
00047 if ( unlikely(x < 0.0f || x > (float)(nx-1) ||
00048 y < 0.0f || y > (float)(ny-1)) )
00049 return fillvalue;
00050 else
00051 {
00052 iy = (int)y;
00053 ix = (int)x;
00054 switch(order)
00055 {
00056 case 3:
00057 fc3kernel (uy, y - (float)iy);
00058 fc3kernel (ux, x - (float)ix);
00059 return fc3convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00060 break;
00061 case 4:
00062 fc4kernel (uy, y - (float)iy);
00063 fc4kernel (ux, x - (float)ix);
00064 return fc4convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00065 break;
00066 default:
00067 abort();
00068 }
00069 }
00070 }
00071
00072
00073
00074
00075
00076
00077
00078 double dcint(int order, int nx, int ny, double *f,
00079 double x, double y, double fillvalue)
00080 {
00081 double ux[6], uy[6];
00082 int ix, iy;
00083
00084 if ( unlikely(x < 0.0 || x > (double)(nx-1) ||
00085 y < 0.0 || y > (double)(ny-1)) )
00086 return fillvalue;
00087 else
00088 {
00089 iy = (int)y;
00090 ix = (int)x;
00091 switch(order)
00092 {
00093 case 3:
00094 dc3kernel (uy, y - (double)iy);
00095 dc3kernel (ux, x - (double)ix);
00096 return dc3convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00097 break;
00098 case 4:
00099 dc4kernel (uy, y - (double)iy);
00100 dc4kernel (ux, x - (double)ix);
00101 return dc4convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00102 break;
00103 default:
00104 abort();
00105 }
00106 }
00107 }
00108
00109
00110
00111
00112
00113
00114 void fcint_vect(int order, int nx, int ny, float *f, float *g,
00115 int N, float *X, float *Y, float fillvalue)
00116 {
00117 int i;
00118 float x, y;
00119 float ux[6], uy[6];
00120 int ix, iy;
00121
00122 for (i=0; i<N; i++)
00123 {
00124 x = X[i];
00125 y = Y[i];
00126
00127 if ( unlikely(x < 0.0f || x > (float)(nx-1) ||
00128 y < 0.0f || y > (float)(ny-1)) )
00129 g[i] = fillvalue;
00130 else
00131 {
00132 iy = (int)y;
00133 ix = (int)x;
00134 switch(order)
00135 {
00136 case 3:
00137 fc3kernel (uy, y - (float)iy);
00138 fc3kernel (ux, x - (float)ix);
00139 g[i] = fc3convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00140 break;
00141 case 4:
00142 fc4kernel (uy, y - (float)iy);
00143 fc4kernel (ux, x - (float)ix);
00144 g[i] = fc4convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00145 break;
00146 default:
00147 abort();
00148 }
00149 }
00150 }
00151 }
00152
00153
00154
00155
00156
00157 void dcint_vect(int order, int nx, int ny, double *f, double *g,
00158 int N, double *X, double *Y, double fillvalue)
00159 {
00160 int i;
00161 double x, y;
00162 double ux[6], uy[6];
00163 int ix, iy;
00164
00165 for (i=0; i<N; i++)
00166 {
00167 x = X[i];
00168 y = Y[i];
00169
00170 if ( unlikely(x < 0.0 || x > (double)(nx-1) ||
00171 y < 0.0 || y > (double)(ny-1)) )
00172 g[i] = fillvalue;
00173 else
00174 {
00175 iy = (int)y;
00176 ix = (int)x;
00177 switch(order)
00178 {
00179 case 3:
00180 dc3kernel (uy, y - (double)iy);
00181 dc3kernel (ux, x - (double)ix);
00182 g[i] = dc3convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00183 break;
00184 case 4:
00185 dc4kernel (uy, y - (double)iy);
00186 dc4kernel (ux, x - (double)ix);
00187 g[i] = dc4convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00188 break;
00189 default:
00190 abort();
00191 }
00192 }
00193 }
00194 }
00195
00196
00197
00198
00199
00200 void fshift(int order, int nx, int ny, float *f, float *g,
00201 float dx, float dy, float fillvalue)
00202 {
00203 int i,j;
00204 float x, y;
00205 float ux[6], uy[6];
00206 int ix, iy;
00207
00208
00209 y = dy;
00210 iy = (int)y;
00211 x = dx;
00212 ix = (int)x;
00213 switch(order)
00214 {
00215 case 3:
00216 fc3kernel (uy, dy - iy);
00217 fc3kernel (ux, dx - ix);
00218 break;
00219 case 4:
00220 fc4kernel (uy, dy - iy);
00221 fc4kernel (ux, dx - ix);
00222 break;
00223 default:
00224 abort();
00225 }
00226
00227 y = dy;
00228 iy = (int)y;
00229 for (i=0; i<ny; i++)
00230 {
00231 x = dx;
00232 ix = (int)x;
00233 if ( unlikely( y < 0.0f || y > (float)(ny-1)) )
00234 for (j=0; j<nx; j++)
00235 g[i*nx+j] = fillvalue;
00236
00237 for (j=0; j<nx; j++)
00238 {
00239 if ( unlikely(x < 0.0f || x > (float)(nx-1)) )
00240 g[i*nx+j] = fillvalue;
00241 else
00242 {
00243 switch(order)
00244 {
00245 case 3:
00246 g[i*nx+j] = fc3convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00247 break;
00248 case 4:
00249 g[i*nx+j] = fc4convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00250 break;
00251 default:
00252 abort();
00253 }
00254 }
00255 x += 1.0f;
00256 ix++;
00257 }
00258 y += 1.0f;
00259 iy++;
00260 }
00261 }
00262
00263
00264
00265
00266 void dshift(int order, int nx, int ny, double *f, double *g,
00267 double dx, double dy, double fillvalue)
00268 {
00269 int i,j;
00270 double x, y;
00271 double ux[6], uy[6];
00272 int ix, iy;
00273
00274
00275 switch(order)
00276 {
00277 case 3:
00278 dc3kernel (uy, dy);
00279 dc3kernel (ux, dx);
00280 break;
00281 case 4:
00282 dc4kernel (uy, dy);
00283 dc4kernel (ux, dx);
00284 break;
00285 default:
00286 abort();
00287 }
00288
00289 y = dy;
00290 iy = (int)y;
00291 for (i=0; i<ny; i++)
00292 {
00293 x = dx;
00294 ix = (int)x;
00295 if ( unlikely( y < 0.0f || y > (double)(ny-1)) )
00296 for (j=0; j<nx; j++)
00297 g[i*nx+j] = fillvalue;
00298
00299 for (j=0; j<nx; j++)
00300 {
00301 if ( unlikely(x < 0.0f || x > (double)(nx-1)) )
00302 g[i*nx+j] = fillvalue;
00303 else
00304 {
00305 switch(order)
00306 {
00307 case 3:
00308 g[i*nx+j] = dc3convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00309 break;
00310 case 4:
00311 g[i*nx+j] = dc4convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00312 break;
00313 default:
00314 abort();
00315 }
00316 }
00317 x += 1.0;
00318 ix++;
00319 }
00320 y += 1.0;
00321 iy++;
00322 }
00323 }
00324
00325
00326
00327
00328 void fscale(int order, int nx, int ny, float *f,
00329 int new_nx, int new_ny, float *g)
00330 {
00331 int i,j;
00332 float x, y;
00333 float ux[6], uy[6], stepx, stepy;
00334 int ix, iy;
00335
00336 stepx = ((float) (nx-1))/(new_nx-1);
00337 stepy = ((float) (ny-1))/(new_ny-1);
00338 for (i=0; i<new_ny; i++)
00339 {
00340 y = stepy*i;
00341 for (j=0; j<new_nx; j++)
00342 {
00343 x = stepx*j;
00344 iy = (int)y;
00345 ix = (int)x;
00346 switch(order)
00347 {
00348 case 3:
00349 fc3kernel (uy, y - (float)iy);
00350 fc3kernel (ux, x - (float)ix);
00351 g[i*new_nx+j] = fc3convolve(ix,iy,nx,ny,f,ux,uy,0.0f);
00352 break;
00353 case 4:
00354 fc4kernel (uy, y - (float)iy);
00355 fc4kernel (ux, x - (float)ix);
00356 g[i*new_nx+j] = fc4convolve(ix,iy,nx,ny,f,ux,uy,0.0f);
00357 break;
00358 default:
00359 abort();
00360 }
00361 }
00362 }
00363 }
00364
00365
00366
00367
00368
00369
00370 void dscale(int order, int nx, int ny, double *f,
00371 int new_nx, int new_ny, double *g)
00372 {
00373 int i,j;
00374 double x, y;
00375 double ux[6], uy[6], stepx, stepy;
00376 int ix, iy;
00377
00378 stepx = ((double) (nx-1))/(new_nx-1);
00379 stepy = ((double) (ny-1))/(new_ny-1);
00380 for (i=0; i<new_ny; i++)
00381 {
00382 y = stepy*i;
00383 for (j=0; j<new_nx; j++)
00384 {
00385 x = stepx*j;
00386 iy = (int)y;
00387 ix = (int)x;
00388 switch(order)
00389 {
00390 case 3:
00391 dc3kernel (uy, y - (double)iy);
00392 dc3kernel (ux, x - (double)ix);
00393 g[i*new_nx+j] = dc3convolve(ix,iy,nx,ny,f,ux,uy,0.0);
00394 break;
00395 case 4:
00396 dc4kernel (uy, y - (double)iy);
00397 dc4kernel (ux, x - (double)ix);
00398 g[i*new_nx+j] = dc4convolve(ix,iy,nx,ny,f,ux,uy,0.0);
00399 break;
00400 default:
00401 abort();
00402 }
00403 }
00404 }
00405 }
00406
00407
00408
00409 void faffine(int order, int nx, int ny, float *f, float *g,
00410 float a11, float a12, float a21, float a22,
00411 float dx, float dy, float fillvalue)
00412 {
00413 int i,j;
00414 float x0 ,y0, x, y;
00415 float ux[6], uy[6];
00416 int ix, iy;
00417
00418
00419 x0 = dx;
00420 y0 = dy;
00421 for (i=0; i<ny; i++)
00422 {
00423
00424
00425 x = x0;
00426 y = y0;
00427 for (j=0; j<nx; j++)
00428 {
00429 x = x0 + a11*(float)j;
00430 y = y0 + a21*(float)j;
00431
00432 if ( unlikely(x < 0.0f || x > (float)(nx-1) ||
00433 y < 0.0f || y > (float)(ny-1)) )
00434 g[i*nx+j] = fillvalue;
00435 else
00436 {
00437 iy = (int)y;
00438 ix = (int)x;
00439 switch(order)
00440 {
00441 case 3:
00442 fc3kernel (uy, y - (float)iy);
00443 fc3kernel (ux, x - (float)ix);
00444 g[i*nx+j] = fc3convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00445 break;
00446 case 4:
00447 fc4kernel (uy, y - (float)iy);
00448 fc4kernel (ux, x - (float)ix);
00449 g[i*nx+j] = fc4convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00450 break;
00451 default:
00452 abort();
00453 }
00454 }
00455 x += a11;
00456 y += a21;
00457 }
00458 x0 += a12;
00459 y0 += a22;
00460 }
00461 }
00462
00463
00464 void daffine(int order, int nx, int ny, double *f, double *g,
00465 double a11, double a12, double a21, double a22,
00466 double dx, double dy, double fillvalue)
00467 {
00468 int i,j;
00469 double x0 ,y0, x, y;
00470 double ux[6], uy[6];
00471 int ix, iy;
00472
00473 for (i=0; i<ny; i++)
00474 {
00475 x0 = a12*(double)i + dx;
00476 y0 = a22*(double)i + dy;
00477 for (j=0; j<nx; j++)
00478 {
00479 x = x0 + a11*(double)j;
00480 y = y0 + a21*(double)j;
00481
00482 if ( unlikely(x < 0.0 || x > (double)(nx-1) ||
00483 y < 0.0 || y > (double)(ny-1)) )
00484 g[i*nx+j] = fillvalue;
00485 else
00486 {
00487 iy = (int)y;
00488 ix = (int)x;
00489 switch(order)
00490 {
00491 case 3:
00492 dc3kernel (uy, y - (double)iy);
00493 dc3kernel (ux, x - (double)ix);
00494 g[i*nx+j] = dc3convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00495 break;
00496 case 4:
00497 dc4kernel (uy, y - (double)iy);
00498 dc4kernel (ux, x - (double)ix);
00499 g[i*nx+j] = dc4convolve(ix,iy,nx,ny,f,ux,uy,fillvalue);
00500 break;
00501 default:
00502 abort();
00503 }
00504 }
00505 }
00506 }
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 static inline void dc3kernel (double u[4], double s)
00519 {
00520 double s2;
00521 s2 = s*s;
00522 u[0] = -s*(1.0 - s*(2.0 - s));
00523 u[1] = 2.0 - s2*(5.0 - 3.0*s);
00524 u[2] = s*(1.0 + s*(4.0 - 3.0*s));
00525 u[3] = -s2*(1.0-s);
00526 }
00527
00528 static inline void fc3kernel (float u[4], float s)
00529 {
00530 float s2;
00531 s2 = s*s;
00532 u[0] = -s*(1.0f - s*(2.0f - s));
00533 u[1] = 2.0f - s2*(5.0f - 3.0f*s);
00534 u[2] = s*(1.0f + s*(4.0f - 3.0f*s));
00535 u[3] = -s2*(1.0f-s);
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 static inline void dc4kernel (double u[6], double s)
00547 {
00548 double s2;
00549
00550 s2 = s * s;
00551 u[0] = s*(1.0 + s*(-2.0 + s));
00552 u[1] = s*(-8.0 + s*(15.0 -7.0*s));
00553 u[2] = 12.0 + s2*(-28.0 + 16.0*s);
00554 u[3] = s*(8.0 + s*(20.0 - 16.0*s));
00555 u[4] = s*(-1.0 + s*(-6.0 + 7.0*s));
00556 u[5] = s2*(1.0 - s);
00557 }
00558
00559 static inline void fc4kernel (float u[6], float s)
00560 {
00561 float s2;
00562
00563 s2 = s * s;
00564 u[0] = s*(1.0f + s*(-2.0f + s));
00565 u[1] = s*(-8.0f + s*(15.0f -7.0f*s));
00566 u[2] = 12.0f + s2*(-28.0f + 16.0f*s);
00567 u[3] = s*(8.0f + s*(20.0f - 16.0f*s));
00568 u[4] = s*(-1.0f + s*(-6.0f + 7.0f*s));
00569 u[5] = s2*(1.0f - s);
00570 }
00571
00572
00573
00574
00575
00576
00577 static inline float fc3convolve(int ix, int iy, int nx, int ny, float *f,
00578 float *ux, float *uy, float fillvalue)
00579 {
00580 float *fc;
00581 float t1,t2,t3;
00582
00583 fc = &f[iy*nx + ix];
00584 if ( unlikely(ix == 0) )
00585 {
00586 if ( unlikely(iy == 0) )
00587 {
00588 t1 = (3.0f*fc[0] - 3.0f*fc[nx] + fc[2*nx]);
00589 t2 = (3.0f*fc[1] - 3.0f*fc[nx+1] + fc[2*nx+1]);
00590 t3 = (3.0f*fc[2] - 3.0f*fc[nx+2] + fc[2*nx+2]);
00591 return
00592 0.25f*(
00593 (t1*ux[1] + t2*ux[2] +
00594 t3*ux[3] + (3.0f*t1 - 3.0f*t2 + t3)*ux[0]) * uy[0] +
00595 ((3.0f*fc[0] - 3.0f*fc[1] + fc[2])*ux[0] + fc[0]*ux[1] +
00596 fc[1]*ux[2] + fc[2]*ux[3]) * uy[1] +
00597 ((3.0f*fc[nx] - 3.0f*fc[nx+1] + fc[nx+2])*ux[0] + fc[nx]*ux[1] +
00598 fc[nx+1]*ux[2] + fc[nx+2]*ux[3]) * uy[2] +
00599 ((3.0f*fc[2*nx] - 3.0f*fc[2*nx+1] + fc[2*nx+2])*ux[0] + fc[2*nx]*ux[1] +
00600 fc[2*nx+1]*ux[2] + fc[2*nx+2]*ux[3]) * uy[3]
00601 );
00602 }
00603 else if ( unlikely(iy >= ny-2) )
00604 {
00605 if (iy == ny-1)
00606 {
00607 fc = &fc[-nx];
00608 uy[0] = 0.0f;
00609 uy[1] = 0.0f;
00610 uy[2] = 2.0f;
00611 uy[3] = 0.0f;
00612 }
00613
00614 t1 = (fc[ -nx] - 3.0f*fc[0] + 3.0f*fc[nx]);
00615 t2 = (fc[-nx+1] - 3.0f*fc[1] + 3.0f*fc[nx+1]);
00616 t3 = (fc[-nx+2] - 3.0f*fc[2] + 3.0f*fc[nx+2]);
00617 return
00618 0.25f*(
00619 ((3.0f*fc[-nx] - 3.0f*fc[-nx+1] + fc[-nx+2])*ux[0] + fc[-nx]*ux[1] +
00620 fc[-nx+1]*ux[2] + fc[-nx+2]*ux[3]) * uy[0] +
00621 ((3.0f*fc[ 0] - 3.0f*fc[ 1] + fc[ 2])*ux[0] + fc[ 0]*ux[1] +
00622 fc[ 1]*ux[2] + fc[ 2]*ux[3]) * uy[1] +
00623 ((3.0f*fc[ nx] - 3.0f*fc[ nx+1] + fc[ nx+2])*ux[0] + fc[ nx]*ux[1] +
00624 fc[ nx+1]*ux[2] + fc[ nx+2]*ux[3]) * uy[2] +
00625 ((3.0f*t1-3.0f*t2+t3) *ux[0] + t1*ux[1] +
00626 t2 *ux[2] + t3 *ux[3]) * uy[3]
00627 );
00628 }
00629 else
00630 {
00631 return
00632 0.25f*(
00633 ((3.0f*fc[-nx] - 3.0f*fc[-nx+1] + fc[-nx+2])*ux[0] + fc[-nx ]*ux[1] +
00634 fc[-nx+1]*ux[2] + fc[-nx+2]*ux[3]) * uy[0] +
00635 ((3.0f*fc[0] - 3.0f*fc[1] + fc[2])*ux[0] + fc[0]*ux[1] +
00636 fc[1]*ux[2] + fc[2]*ux[3]) * uy[1] +
00637 ((3.0f*fc[nx] - 3.0f*fc[nx+1] + fc[nx+2])*ux[0] + fc[nx ]*ux[1] +
00638 fc[nx+1]*ux[2] + fc[nx+2]*ux[3]) * uy[2] +
00639 ((3.0f*fc[2*nx] - 3.0f*fc[2*nx+1] + fc[2*nx+2])*ux[0] + fc[2*nx ]*ux[1] +
00640 fc[2*nx+1]*ux[2] + fc[2*nx+2]*ux[3]) * uy[3]
00641 );
00642 }
00643 }
00644 else if ( unlikely(ix >= nx-2) )
00645 {
00646 if (ix == nx-1)
00647 {
00648 fc = &fc[-1];
00649 ux[0] = 0.0f;
00650 ux[1] = 0.0f;
00651 ux[2] = 2.0f;
00652 ux[3] = 0.0f;
00653 }
00654 if ( unlikely(iy == 0) )
00655 {
00656 t1 = (3.0f*fc[-1] - 3.0f*fc[nx-1] + fc[2*nx-1]);
00657 t2 = (3.0f*fc[ 0] - 3.0f*fc[nx] + fc[2*nx]);
00658 t3 = (3.0f*fc[ 1] - 3.0f*fc[nx+1] + fc[2*nx+1]);
00659 return
00660 0.25f*(
00661 (t1*ux[0] + t2*ux[1] +
00662 t3*ux[2] + (3.0f*t3 - 3.0f*t2 + t1)*ux[3]) * uy[0] +
00663 (fc[ -1]*ux[0] + fc[0]*ux[1] +
00664 fc[ 1]*ux[2] + (3.0f*fc[1] - 3.0f*fc[0] + fc[-1])*ux[3]) * uy[1] +
00665 (fc[ nx-1]*ux[0] + fc[nx]*ux[1] +
00666 fc[ nx+1]*ux[2] + (3.0f*fc[nx+1] - 3.0f*fc[nx] + fc[nx-1])*ux[3]) * uy[2] +
00667 (fc[2*nx-1]*ux[0] + fc[2*nx]*ux[1] +
00668 fc[2*nx+1]*ux[2] + (3.0f*fc[2*nx+1]-3.0f*fc[2*nx] + fc[2*nx-1])*ux[3]) * uy[3]
00669 );
00670 }
00671 else if ( unlikely(iy >= ny-2) )
00672 {
00673 if (iy == ny-1)
00674 {
00675 fc = &fc[-nx];
00676 uy[0] = 0.0f;
00677 uy[1] = 0.0f;
00678 uy[2] = 2.0f;
00679 uy[3] = 0.0f;
00680 }
00681 t1 = (fc[-nx-1] - 3.0f*fc[-1] + 3.0f*fc[nx-1]);
00682 t2 = (fc[-nx] - 3.0f*fc[0] + 3.0f*fc[nx]);
00683 t3 = (fc[-nx+1] - 3.0f*fc[1] + 3.0f*fc[nx+1]);
00684 return
00685 0.25f*(
00686 (fc[-nx-1]*ux[0] + fc[-nx ]*ux[1] +
00687 fc[-nx+1]*ux[2] + (3.0f*fc[-nx+1] - 3.0f*fc[-nx] + fc[-nx-1])*ux[3]) * uy[0] +
00688 (fc[-1]*ux[0] + fc[0]*ux[1] +
00689 fc[1]*ux[2] + (3.0f*fc[1] - 3.0f*fc[0] + fc[-1])*ux[3]) * uy[1] +
00690 (fc[nx-1]*ux[0] + fc[nx]*ux[1] +
00691 fc[nx+1]*ux[2] + (3.0f*fc[nx+1] - 3.0f*fc[nx] + fc[nx-1])*ux[3]) * uy[2] +
00692 (t1*ux[0] + t2*ux[1] +
00693 t3*ux[2] + (3.0f*t3 - 3.0f*t2 + t1)*ux[3])*uy[3]
00694 );
00695 }
00696 else
00697 {
00698 return
00699 0.25f*(
00700 (fc[-nx-1]*ux[0] + fc[-nx]*ux[1] +
00701 fc[-nx+1]*ux[2] + (3.0f*fc[-nx+1] - 3.0f*fc[-nx] + fc[-nx-1])*ux[3]) * uy[0] +
00702 (fc[-1]*ux[0] + fc[0 ]*ux[1] +
00703 fc[1 ]*ux[2] + (3.0f*fc[1] - 3.0f*fc[0] + fc[-1])*ux[3]) * uy[1] +
00704 (fc[nx-1]*ux[0] + fc[nx ]*ux[1] +
00705 fc[nx+1]*ux[2] + (3.0f*fc[nx+1] - 3.0f*fc[nx] + fc[nx-1])*ux[3]) * uy[2] +
00706 (fc[2*nx-1]*ux[0] + fc[2*nx ]*ux[1] +
00707 fc[2*nx+1]*ux[2] + (3.0f*fc[2*nx+1]-3.0f*fc[2*nx] + fc[2*nx-1])*ux[3]) * uy[3]
00708 );
00709 }
00710 }
00711 else
00712 {
00713 if ( unlikely(iy == 0) )
00714 {
00715 return
00716 0.25f*(
00717 ((3.0f*fc[-1] - 3.0f*fc[nx-1] + fc[2*nx-1])*ux[0] +
00718 (3.0f*fc[0] - 3.0f*fc[nx] + fc[2*nx])*ux[1] +
00719 (3.0f*fc[1] - 3.0f*fc[nx+1] + fc[2*nx+1])*ux[2] +
00720 (3.0f*fc[2] - 3.0f*fc[nx+2] + fc[2*nx+2])*ux[3] ) * uy[0] +
00721 (fc[-1]*ux[0] + fc[0 ]*ux[1] +
00722 fc[1 ]*ux[2] + fc[2 ]*ux[3]) * uy[1] +
00723 (fc[nx-1]*ux[0] + fc[nx ]*ux[1] +
00724 fc[nx+1]*ux[2] + fc[nx+2]*ux[3]) * uy[2] +
00725 (fc[2*nx-1]*ux[0] + fc[2*nx ]*ux[1] +
00726 fc[2*nx+1]*ux[2] + fc[2*nx+2]*ux[3]) * uy[3]
00727 );
00728 }
00729 else if ( unlikely(iy >= ny-2) )
00730 {
00731 if (iy == ny-1)
00732 {
00733 fc = &fc[-nx];
00734 uy[0] = 0.0f;
00735 uy[1] = 0.0f;
00736 uy[2] = 2.0f;
00737 uy[3] = 0.0f;
00738 }
00739 return
00740 0.25f*(
00741 (fc[-nx-1]*ux[0] + fc[-nx ]*ux[1] +
00742 fc[-nx+1]*ux[2] + fc[-nx+2]*ux[3]) * uy[0] +
00743 (fc[-1]*ux[0] + fc[0 ]*ux[1] +
00744 fc[1 ]*ux[2] + fc[2 ]*ux[3]) * uy[1] +
00745 (fc[nx-1]*ux[0] + fc[nx ]*ux[1] +
00746 fc[nx+1]*ux[2] + fc[nx+2]*ux[3]) * uy[2] +
00747 ((fc[-nx-1] - 3.0f*fc[-1] + 3.0f*fc[nx-1])*ux[0] +
00748 (fc[-nx] - 3.0f*fc[0] + 3.0f*fc[nx])*ux[1] +
00749 (fc[-nx+1] - 3.0f*fc[1] + 3.0f*fc[nx+1])*ux[2] +
00750 (fc[-nx+2] - 3.0f*fc[2] + 3.0f*fc[nx+2])*ux[3])*uy[3]
00751 );
00752 }
00753 else
00754 {
00755 return
00756 0.25f*(
00757 (fc[ -nx-1]*ux[0] + fc[ -nx ]*ux[1] +
00758 fc[ -nx+1]*ux[2] + fc[ -nx+2]*ux[3])*uy[0] +
00759 (fc[ -1]*ux[0] + fc[ 0]*ux[1]+
00760 fc[ 1]*ux[2] + fc[ 2]*ux[3])*uy[1] +
00761 (fc[ nx-1]*ux[0] + fc[ nx ]*ux[1] +
00762 fc[ nx+1]*ux[2] + fc[ nx+2]*ux[3])*uy[2] +
00763 (fc[2*nx-1]*ux[0] + fc[2*nx ]*ux[1] +
00764 fc[2*nx+1]*ux[2] + fc[2*nx+2]*ux[3])*uy[3]
00765 );
00766 }
00767 }
00768 }
00769
00770
00771
00772
00773
00774 static inline double dc3convolve(int ix, int iy, int nx, int ny, double *f,
00775 double *ux, double *uy, double fillvalue)
00776 {
00777 double *fc;
00778 double t1,t2,t3;
00779
00780 fc = &f[iy*nx + ix];
00781 if ( unlikely(ix == 0) )
00782 {
00783 if ( unlikely(iy == 0) )
00784 {
00785 t1 = (3.0*fc[0] - 3.0*fc[nx] + fc[2*nx]);
00786 t2 = (3.0*fc[1] - 3.0*fc[nx+1] + fc[2*nx+1]);
00787 t3 = (3.0*fc[2] - 3.0*fc[nx+2] + fc[2*nx+2]);
00788 return
00789 0.25*(
00790 (t1*ux[1] + t2*ux[2] +
00791 t3*ux[3] + (3.0*t1 - 3.0*t2 + t3)*ux[0]) * uy[0] +
00792 ((3.0*fc[0] - 3.0*fc[1] + fc[2])*ux[0] + fc[0]*ux[1] +
00793 fc[1]*ux[2] + fc[2]*ux[3]) * uy[1] +
00794 ((3.0*fc[nx] - 3.0*fc[nx+1] + fc[nx+2])*ux[0] + fc[nx]*ux[1] +
00795 fc[nx+1]*ux[2] + fc[nx+2]*ux[3]) * uy[2] +
00796 ((3.0*fc[2*nx] - 3.0*fc[2*nx+1] + fc[2*nx+2])*ux[0] + fc[2*nx]*ux[1] +
00797 fc[2*nx+1]*ux[2] + fc[2*nx+2]*ux[3]) * uy[3]
00798 );
00799 }
00800 else if ( unlikely(iy >= ny-2) )
00801 {
00802 if (iy == ny-1)
00803 {
00804 fc = &fc[-nx];
00805 uy[0] = 0.0;
00806 uy[1] = 0.0;
00807 uy[2] = 2.0;
00808 uy[3] = 0.0;
00809 }
00810
00811 t1 = (fc[ -nx] - 3.0*fc[0] + 3.0*fc[nx]);
00812 t2 = (fc[-nx+1] - 3.0*fc[1] + 3.0*fc[nx+1]);
00813 t3 = (fc[-nx+2] - 3.0*fc[2] + 3.0*fc[nx+2]);
00814 return
00815 0.25*(
00816 ((3.0*fc[-nx] - 3.0*fc[-nx+1] + fc[-nx+2])*ux[0] + fc[-nx]*ux[1] +
00817 fc[-nx+1]*ux[2] + fc[-nx+2]*ux[3]) * uy[0] +
00818 ((3.0*fc[0] - 3.0*fc[1] + fc[2])*ux[0] + fc[0]*ux[1] +
00819 fc[1]*ux[2] + fc[2]*ux[3]) * uy[1] +
00820 ((3.0*fc[nx] - 3.0*fc[nx+1] + fc[nx+2])*ux[0] + fc[nx]*ux[1] +
00821 fc[nx+1]*ux[2] + fc[nx+2]*ux[3]) * uy[2] +
00822 (t1*ux[1] + t2*ux[2] +
00823 t3*ux[3] + (3.0*t1-3.0*t2+t3)*ux[0]) * uy[3]
00824 );
00825 }
00826 else
00827 {
00828 return
00829 0.25*(
00830 ((3.0*fc[-nx] - 3.0*fc[-nx+1] + fc[-nx+2])*ux[0] + fc[-nx ]*ux[1] +
00831 fc[-nx+1]*ux[2] + fc[-nx+2]*ux[3]) * uy[0] +
00832 ((3.0*fc[0] - 3.0*fc[1] + fc[2])*ux[0] + fc[0]*ux[1] +
00833 fc[1]*ux[2] + fc[2]*ux[3]) * uy[1] +
00834 ((3.0*fc[nx] - 3.0*fc[nx+1] + fc[nx+2])*ux[0] + fc[nx ]*ux[1] +
00835 fc[nx+1]*ux[2] + fc[nx+2]*ux[3]) * uy[2] +
00836 ((3.0*fc[2*nx] - 3.0*fc[2*nx+1] + fc[2*nx+2])*ux[0] + fc[2*nx ]*ux[1] +
00837 fc[2*nx+1]*ux[2] + fc[2*nx+2]*ux[3]) * uy[3]
00838 );
00839 }
00840 }
00841 else if ( unlikely(ix >= nx-2) )
00842 {
00843 if (ix == nx-1)
00844 {
00845 fc = &fc[-1];
00846 ux[0] = 0.0;
00847 ux[1] = 0.0;
00848 ux[2] = 2.0;
00849 ux[3] = 0.0;
00850 }
00851 if ( unlikely(iy == 0) )
00852 {
00853 t1 = (3.0*fc[-1] - 3.0*fc[nx-1] + fc[2*nx-1]);
00854 t2 = (3.0*fc[0] - 3.0*fc[nx] + fc[2*nx]);
00855 t3 = (3.0*fc[1] - 3.0*fc[nx+1] + fc[2*nx+1]);
00856 return
00857 0.25*(
00858 (t1*ux[0] + t2*ux[1] +
00859 t3*ux[2] + (3.0*t3 - 3.0*t2 + t1)*ux[3]) * uy[0] +
00860 (fc[-1]*ux[0] + fc[0]*ux[1] +
00861 fc[1]*ux[2] + (3.0*fc[1] - 3.0*fc[0] + fc[-1])*ux[3]) * uy[1] +
00862 (fc[nx-1]*ux[0] + fc[nx]*ux[1] +
00863 fc[nx+1]*ux[2] + (3.0*fc[nx+1] - 3.0*fc[nx] + fc[nx-1])*ux[3]) * uy[2] +
00864 (fc[2*nx-1]*ux[0] + fc[2*nx]*ux[1] +
00865 fc[2*nx+1]*ux[2] + (3.0*fc[2*nx+1]-3.0*fc[2*nx] + fc[2*nx-1])*ux[3]) * uy[3]
00866 );
00867 }
00868 else if ( unlikely(iy >= ny-2) )
00869 {
00870 if (iy == ny-1)
00871 {
00872 fc = &fc[-nx];
00873 uy[0] = 0.0;
00874 uy[1] = 0.0;
00875 uy[2] = 2.0;
00876 uy[3] = 0.0;
00877 }
00878
00879 t1 = (fc[-nx-1] - 3.0*fc[-1] + 3.0*fc[nx-1]);
00880 t2 = (fc[-nx] - 3.0*fc[0] + 3.0*fc[nx]);
00881 t3 = (fc[-nx+1] - 3.0*fc[1] + 3.0*fc[nx+1]);
00882 return
00883 0.25*(
00884 (fc[-nx-1]*ux[0] + fc[-nx ]*ux[1] +
00885 fc[-nx+1]*ux[2] + (3.0*fc[-nx+1] - 3.0*fc[-nx] + fc[-nx-1])*ux[3]) * uy[0] +
00886 (fc[-1]*ux[0] + fc[0]*ux[1] +
00887 fc[1]*ux[2] + (3.0*fc[1] - 3.0*fc[0] + fc[-1])*ux[3]) * uy[1] +
00888 (fc[nx-1]*ux[0] + fc[nx]*ux[1] +
00889 fc[nx+1]*ux[2] + (3.0*fc[nx+1] - 3.0*fc[nx] + fc[nx-1])*ux[3]) * uy[2] +
00890 (t1*ux[0] + t2*ux[1] +
00891 t3*ux[2] + (3.0*t3 - 3.0*t2 + t1)*ux[3])*uy[3]
00892 );
00893 }
00894 else
00895 {
00896 return
00897 0.25*(
00898 (fc[-nx-1]*ux[0] + fc[-nx]*ux[1] +
00899 fc[-nx+1]*ux[2] + (3.0*fc[-nx+1] - 3.0*fc[-nx] + fc[-nx-1])*ux[3]) * uy[0] +
00900 (fc[-1]*ux[0] + fc[0 ]*ux[1] +
00901 fc[1 ]*ux[2] + (3.0*fc[1] - 3.0*fc[0] + fc[-1])*ux[3]) * uy[1] +
00902 (fc[nx-1]*ux[0] + fc[nx ]*ux[1] +
00903 fc[nx+1]*ux[2] + (3.0*fc[nx+1] - 3.0*fc[nx] + fc[nx-1])*ux[3]) * uy[2] +
00904 (fc[2*nx-1]*ux[0] + fc[2*nx ]*ux[1] +
00905 fc[2*nx+1]*ux[2] + (3.0*fc[2*nx+1]-3.0*fc[2*nx] + fc[2*nx-1])*ux[3]) * uy[3]
00906 );
00907 }
00908 }
00909 else
00910 {
00911 if ( unlikely(iy == 0) )
00912 {
00913 return
00914 0.25*(
00915 ((3.0*fc[-1] - 3.0*fc[nx-1] + fc[2*nx-1])*ux[0] +
00916 (3.0*fc[0] - 3.0*fc[nx] + fc[2*nx])*ux[1] +
00917 (3.0*fc[1] - 3.0*fc[nx+1] + fc[2*nx+1])*ux[2] +
00918 (3.0*fc[2] - 3.0*fc[nx+2] + fc[2*nx+2])*ux[3] ) * uy[0] +
00919 (fc[-1]*ux[0] + fc[0 ]*ux[1] +
00920 fc[1 ]*ux[2] + fc[2 ]*ux[3]) * uy[1] +
00921 (fc[nx-1]*ux[0] + fc[nx ]*ux[1] +
00922 fc[nx+1]*ux[2] + fc[nx+2]*ux[3]) * uy[2] +
00923 (fc[2*nx-1]*ux[0] + fc[2*nx ]*ux[1] +
00924 fc[2*nx+1]*ux[2] + fc[2*nx+2]*ux[3]) * uy[3]
00925 );
00926 }
00927 else if ( unlikely(iy >= ny-2) )
00928 {
00929 if (iy == ny-1)
00930 {
00931 fc = &fc[-nx];
00932 uy[0] = 0.0;
00933 uy[1] = 0.0;
00934 uy[2] = 2.0;
00935 uy[3] = 0.0;
00936 }
00937 return
00938 0.25*(
00939 (fc[-nx-1]*ux[0] + fc[-nx ]*ux[1] +
00940 fc[-nx+1]*ux[2] + fc[-nx+2]*ux[3]) * uy[0] +
00941 (fc[-1]*ux[0] + fc[0 ]*ux[1] +
00942 fc[1 ]*ux[2] + fc[2 ]*ux[3]) * uy[1] +
00943 (fc[nx-1]*ux[0] + fc[nx ]*ux[1] +
00944 fc[nx+1]*ux[2] + fc[nx+2]*ux[3]) * uy[2] +
00945 ((fc[-nx-1] - 3.0*fc[-1] + 3.0*fc[nx-1])*ux[0] +
00946 (fc[-nx] - 3.0*fc[0] + 3.0*fc[nx])*ux[1] +
00947 (fc[-nx+1] - 3.0*fc[1] + 3.0*fc[nx+1])*ux[2] +
00948 (fc[-nx+2] - 3.0*fc[2] + 3.0*fc[nx+2])*ux[3])*uy[3]
00949 );
00950 }
00951 else
00952 {
00953 return
00954 0.25*(
00955 (fc[ -nx-1]*ux[0] + fc[ -nx ]*ux[1] +
00956 fc[ -nx+1]*ux[2] + fc[ -nx+2]*ux[3])*uy[0] +
00957 (fc[ -1]*ux[0] + fc[ 0]*ux[1]+
00958 fc[ 1]*ux[2] + fc[ 2]*ux[3])*uy[1] +
00959 (fc[ nx-1]*ux[0] + fc[ nx ]*ux[1] +
00960 fc[ nx+1]*ux[2] + fc[ nx+2]*ux[3])*uy[2] +
00961 (fc[2*nx-1]*ux[0] + fc[2*nx ]*ux[1] +
00962 fc[2*nx+1]*ux[2] + fc[2*nx+2]*ux[3])*uy[3]
00963 );
00964 }
00965 }
00966 }
00967
00968
00969
00970
00971
00972
00973
00974 static inline double dc4convolve(int ix, int iy, int nx, int ny, double *f,
00975 double *ux, double *uy, double fillvalue)
00976 {
00977 double *fc;
00978
00979 if ( unlikely(ix < 2 || ix >= (nx-3) ||
00980 iy < 2 || iy >= (ny-3)) )
00981 return fillvalue;
00982 else
00983 {
00984 fc = &f[iy*nx + ix];
00985 return
00986 (1.0/144.0)*(
00987 (fc[-2*nx-2]*ux[0] + fc[-2*nx-1]*ux[1] +
00988 fc[-2*nx ]*ux[2] + fc[-2*nx+1]*ux[3] +
00989 fc[-2*nx+2]*ux[4] + fc[-2*nx+3]*ux[5]) * uy[0] +
00990 (fc[ -nx-2]*ux[0] + fc[ -nx-1]*ux[1] +
00991 fc[ -nx ]*ux[2] + fc[ -nx+1]*ux[3] +
00992 fc[ -nx+2]*ux[4] + fc[ -nx+3]*ux[5]) * uy[1] +
00993 (fc[ -2]*ux[0] + fc[ -1]*ux[1] +
00994 fc[ 0]*ux[2] + fc[ 1]*ux[3] +
00995 fc[ 2]*ux[4] + fc[ 3]*ux[5]) * uy[2] +
00996 (fc[ nx-2]*ux[0] + fc[ nx-1]*ux[1] +
00997 fc[ nx ]*ux[2] + fc[ nx+1]*ux[3] +
00998 fc[ nx+2]*ux[4] + fc[ nx+3]*ux[5]) * uy[3] +
00999 (fc[ 2*nx-2]*ux[0] + fc[ 2*nx-1]*ux[1] +
01000 fc[ 2*nx ]*ux[2] + fc[ 2*nx+1]*ux[3] +
01001 fc[ 2*nx+2]*ux[4] + fc[ 2*nx+3]*ux[5]) * uy[4] +
01002 (fc[ 3*nx-2]*ux[0] + fc[ 3*nx-1]*ux[1] +
01003 fc[ 3*nx ]*ux[2] + fc[ 3*nx+1]*ux[3] +
01004 fc[ 3*nx+2]*ux[4] + fc[ 3*nx+3]*ux[5]) * uy[5]
01005 );
01006 }
01007 }
01008
01009
01010 static inline float fc4convolve(int ix, int iy, int nx, int ny, float *f,
01011 float *ux, float *uy, float fillvalue)
01012 {
01013 float *fc;
01014
01015 if ( unlikely(ix < 2 || ix >= (nx-3) ||
01016 iy < 2 || iy >= (ny-3)) )
01017 return fillvalue;
01018 else
01019 {
01020 fc = &f[iy*nx + ix];
01021 return
01022 (1.0f/144.0f)*(
01023 (fc[-2*nx-2]*ux[0] + fc[-2*nx-1]*ux[1] +
01024 fc[-2*nx ]*ux[2] + fc[-2*nx+1]*ux[3] +
01025 fc[-2*nx+2]*ux[4] + fc[-2*nx+3]*ux[5]) * uy[0] +
01026 (fc[ -nx-2]*ux[0] + fc[ -nx-1]*ux[1] +
01027 fc[ -nx ]*ux[2] + fc[ -nx+1]*ux[3] +
01028 fc[ -nx+2]*ux[4] + fc[ -nx+3]*ux[5]) * uy[1] +
01029 (fc[ -2]*ux[0] + fc[ -1]*ux[1] +
01030 fc[ 0]*ux[2] + fc[ 1]*ux[3] +
01031 fc[ 2]*ux[4] + fc[ 3]*ux[5]) * uy[2] +
01032 (fc[ nx-2]*ux[0] + fc[ nx-1]*ux[1] +
01033 fc[ nx ]*ux[2] + fc[ nx+1]*ux[3] +
01034 fc[ nx+2]*ux[4] + fc[ nx+3]*ux[5]) * uy[3] +
01035 (fc[ 2*nx-2]*ux[0] + fc[ 2*nx-1]*ux[1] +
01036 fc[ 2*nx ]*ux[2] + fc[ 2*nx+1]*ux[3] +
01037 fc[ 2*nx+2]*ux[4] + fc[ 2*nx+3]*ux[5]) * uy[4] +
01038 (fc[ 3*nx-2]*ux[0] + fc[ 3*nx-1]*ux[1] +
01039 fc[ 3*nx ]*ux[2] + fc[ 3*nx+1]*ux[3] +
01040 fc[ 3*nx+2]*ux[4] + fc[ 3*nx+3]*ux[5]) * uy[5]
01041 );
01042 }
01043 }
01044
01045
01046
01047