1 /*
2 * Name
3 * bilinear.c -- use bilinear interpolation for given row, col
4 *
5 * Description
6 * bilinear interpolation for the given row, column indices.
7 * If the given row or column is outside the bounds of the input map,
8 * the point in the output map is set to NULL.
9 * If any of the 4 surrounding points to be used in the interpolation
10 * is NULL it is filled with is neighbor value
11 */
12
13 #include <math.h>
14 #include <grass/gis.h>
15 #include <grass/raster.h>
16 #include "r.proj.h"
17
p_bilinear(struct cache * ibuffer,void * obufptr,int cell_type,double col_idx,double row_idx,struct Cell_head * cellhd)18 void p_bilinear(struct cache *ibuffer, /* input buffer */
19 void *obufptr, /* ptr in output buffer */
20 int cell_type, /* raster map type of obufptr */
21 double col_idx, /* column index */
22 double row_idx, /* row index */
23 struct Cell_head *cellhd /* information of output map */
24 )
25 {
26 int row; /* row indices for interp */
27 int col; /* column indices for interp */
28 int i, j;
29 FCELL t, u; /* intermediate slope */
30 FCELL result; /* result of interpolation */
31 FCELL c[2][2];
32
33 /* cut indices to integer */
34 row = (int)floor(row_idx - 0.5);
35 col = (int)floor(col_idx - 0.5);
36
37 /* check for out of bounds - if out of bounds set NULL value and return */
38 if (row < 0 || row + 1 >= cellhd->rows || col < 0 || col + 1 >= cellhd->cols) {
39 Rast_set_null_value(obufptr, 1, cell_type);
40 return;
41 }
42
43 for (i = 0; i < 2; i++)
44 for (j = 0; j < 2; j++) {
45 const FCELL cell = CVAL(ibuffer, row + i, col + j);
46 if (Rast_is_f_null_value(&cell)) {
47 Rast_set_null_value(obufptr, 1, cell_type);
48 return;
49 }
50 c[i][j] = cell;
51 }
52
53 /* do the interpolation */
54 t = col_idx - 0.5 - col;
55 u = row_idx - 0.5 - row;
56
57 result = Rast_interp_bilinear(t, u, c[0][0], c[0][1], c[1][0], c[1][1]);
58
59 Rast_set_f_value(obufptr, result, cell_type);
60 }
61