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