cubic.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * Name
  3. * cubic.c -- use cubic convolution interpolation for given row, col
  4. *
  5. * Description
  6. * cubic returns the value in the buffer that is the result of cubic
  7. * convolution interpolation for the given row, column indices.
  8. * If the given row or column is outside the bounds of the input map,
  9. * the corresponding point in the output map is set to NULL.
  10. *
  11. * If single surrounding points in the interpolation matrix are
  12. * NULL they where filled with their neighbor
  13. */
  14. #include <grass/gis.h>
  15. #include <grass/raster.h>
  16. #include <math.h>
  17. #include "r.proj.h"
  18. void p_cubic(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 (decimal) */
  22. double row_idx, /* row index (decimal) */
  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 val[4]; /* buffer for temporary values */
  32. FCELL c[4][4];
  33. /* cut indices to integer */
  34. row = (int)floor(row_idx - 0.5);
  35. col = (int)floor(col_idx - 0.5);
  36. /* check for out of bounds of map - if out of bounds set NULL value */
  37. if (row - 1 < 0 || row + 2 >= cellhd->rows ||
  38. col - 1 < 0 || col + 2 >= cellhd->cols) {
  39. Rast_set_null_value(obufptr, 1, cell_type);
  40. return;
  41. }
  42. for (i = 0; i < 4; i++)
  43. for (j = 0; j < 4; j++) {
  44. const FCELL cell = CVAL(ibuffer, row - 1 + i, col - 1 + j);
  45. if (Rast_is_f_null_value(&cell)) {
  46. Rast_set_null_value(obufptr, 1, cell_type);
  47. return;
  48. }
  49. c[i][j] = cell;
  50. }
  51. /* do the interpolation */
  52. t = col_idx - 0.5 - col;
  53. u = row_idx - 0.5 - row;
  54. for (i = 0; i < 4; i++) {
  55. const FCELL *tmp = c[i];
  56. val[i] = Rast_interp_cubic(t, tmp[0], tmp[1], tmp[2], tmp[3]);
  57. }
  58. result = Rast_interp_cubic(u, val[0], val[1], val[2], val[3]);
  59. Rast_set_f_value(obufptr, result, cell_type);
  60. }