void bicubic_interpolation_boundary(float *result, float *img, int w, int h, int pd, float x, float y, int boundary) { x -= 1; y -= 1; getsample_operator p; switch(boundary) { default: case 0: p = getsample_0; break; case 1: p = getsample_1; break; case 2: p = getsample_2; break; case -1: p = getsample_error; break; } int ix = floor(x); int iy = floor(y); for (int l = 0; l < pd; l++) { float c[4][4]; for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) c[i][j] = p(img, w, h, pd, ix + i, iy + j, l); float r = bicubic_interpolation_cell(c, x - ix, y - iy); result[l] = r; } }
static void tiff_cache_interpolate_float(float *result, struct tiff_tile_cache *t, float x, float y) { int pd = t->i->spp; x -= 1; y -= 1; int ix = floor(x); int iy = floor(y); float c[4][4][pd]; for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) { void *p = tiff_tile_cache_getpixel(t, ix + i, iy + j); convert_pixel_to_float(c[i][j], t->i, p); } for (int l = 0; l < pd; l++) { float C[4][4]; for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) C[i][j] = c[i][j][l]; float r = bicubic_interpolation_cell(C, x - ix, y - iy); result[l] = r; } }
// instance of "interpolator_t" for bicubic interpolation static float bicubic_interpolation_at(float *img, int w, int h, int pd, float x, float y, int l, extrapolator_t p) { x -= 1; y -= 1; int ix = floor(x); int iy = floor(y); float c[4][4]; for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) c[i][j] = p(img, w, h, pd, ix + i, iy + j, l); return bicubic_interpolation_cell(c, x - ix, y - iy); }
float bicubic_interpolation(float *img, int w, int h, float x, float y) { x -= 1; y -= 1; getpixel_operator p = getpixel_0; int ix = floor(x); int iy = floor(y); float c[4][4]; for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) c[i][j] = p(img, w, h, ix + i, iy + j); return bicubic_interpolation_cell(c, x - ix, y - iy); }
void bicubic_interpolation_boundary2(float *result, float *img, int w, int h, int pd, float x, float y, getsample_operator p) { x -= 1; y -= 1; int ix = floor(x); int iy = floor(y); for (int l = 0; l < pd; l++) { float c[4][4]; for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) c[i][j] = p(img, w, h, pd, ix + i, iy + j, l); float r = bicubic_interpolation_cell(c, x - ix, y - iy); result[l] = r; } }
/** * * Compute the bicubic interpolation of a point in an image. * Detect if the point goes outside the image domain. * **/ static float bicubic_interpolation_at( const float *input, //image to be interpolated const float uu, //x component of the vector field const float vv, //y component of the vector field const int nx, //image width const int ny, //image height bool border_out //if true, return zero outside the region ) { const int boundary_condition = DEFAULT_BICUBIC_BOUNDARY_CONDITION; const int sx = (uu < 0) ? -1: 1; const int sy = (vv < 0) ? -1: 1; int x, y, mx, my, dx, dy, ddx, ddy; bool out[1] = {false}; //apply the corresponding boundary conditions switch(boundary_condition) { case BICUBIC_BOUNDARY_NEUMANN: x = neumann_bc((int) uu, nx, out); y = neumann_bc((int) vv, ny, out); mx = neumann_bc((int) uu - sx, nx, out); my = neumann_bc((int) vv - sx, ny, out); dx = neumann_bc((int) uu + sx, nx, out); dy = neumann_bc((int) vv + sy, ny, out); ddx = neumann_bc((int) uu + 2*sx, nx, out); ddy = neumann_bc((int) vv + 2*sy, ny, out); break; case BICUBIC_BOUNDARY_PERIODIC: x = periodic_bc((int) uu, nx, out); y = periodic_bc((int) vv, ny, out); mx = periodic_bc((int) uu - sx, nx, out); my = periodic_bc((int) vv - sx, ny, out); dx = periodic_bc((int) uu + sx, nx, out); dy = periodic_bc((int) vv + sy, ny, out); ddx = periodic_bc((int) uu + 2*sx, nx, out); ddy = periodic_bc((int) vv + 2*sy, ny, out); break; case BICUBIC_BOUNDARY_SYMMETRIC: x = symmetric_bc((int) uu, nx, out); y = symmetric_bc((int) vv, ny, out); mx = symmetric_bc((int) uu - sx, nx, out); my = symmetric_bc((int) vv - sx, ny, out); dx = symmetric_bc((int) uu + sx, nx, out); dy = symmetric_bc((int) vv + sy, ny, out); ddx = symmetric_bc((int) uu + 2*sx, nx, out); ddy = symmetric_bc((int) vv + 2*sy, ny, out); break; } if(*out && border_out) return 0.0; else { //obtain the interpolation points of the image const float p11 = input[mx + nx * my]; const float p12 = input[x + nx * my]; const float p13 = input[dx + nx * my]; const float p14 = input[ddx + nx * my]; const float p21 = input[mx + nx * y]; const float p22 = input[x + nx * y]; const float p23 = input[dx + nx * y]; const float p24 = input[ddx + nx * y]; const float p31 = input[mx + nx * dy]; const float p32 = input[x + nx * dy]; const float p33 = input[dx + nx * dy]; const float p34 = input[ddx + nx * dy]; const float p41 = input[mx + nx * ddy]; const float p42 = input[x + nx * ddy]; const float p43 = input[dx + nx * ddy]; const float p44 = input[ddx + nx * ddy]; //create array double pol[4][4] = { {p11, p21, p31, p41}, {p12, p22, p32, p42}, {p13, p23, p33, p43}, {p14, p24, p34, p44} }; //return interpolation return bicubic_interpolation_cell(pol, uu-x, vv-y); } }