lanczos.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Name
  3. * lanczos.c -- use lanczos interpolation for given row, col
  4. *
  5. * Description
  6. * lanczos returns the value in the buffer that is the result of
  7. * lanczos 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_lanczos(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, k;
  29. double t, u; /* intermediate slope */
  30. FCELL result; /* result of interpolation */
  31. DCELL c[25];
  32. /* cut indices to integer */
  33. row = (int)floor(row_idx);
  34. col = (int)floor(col_idx);
  35. /* check for out of bounds of map - if out of bounds set NULL value */
  36. if (row - 2 < 0 || row + 2 >= cellhd->rows ||
  37. col - 2 < 0 || col + 2 >= cellhd->cols) {
  38. Rast_set_null_value(obufptr, 1, cell_type);
  39. return;
  40. }
  41. k = 0;
  42. for (i = 0; i < 5; i++) {
  43. for (j = 0; j < 5; j++) {
  44. const FCELL cell = CVAL(ibuffer, row - 2 + i, col - 2 + j);
  45. if (Rast_is_f_null_value(&cell)) {
  46. Rast_set_null_value(obufptr, 1, cell_type);
  47. return;
  48. }
  49. c[k++] = cell;
  50. }
  51. }
  52. /* do the interpolation */
  53. t = col_idx - 0.5 - col;
  54. u = row_idx - 0.5 - row;
  55. result = Rast_interp_lanczos(t, u, c);
  56. Rast_set_f_value(obufptr, result, cell_type);
  57. }
  58. void p_lanczos_f(struct cache *ibuffer, /* input buffer */
  59. void *obufptr, /* ptr in output buffer */
  60. int cell_type, /* raster map type of obufptr */
  61. double col_idx, /* column index (decimal) */
  62. double row_idx, /* row index (decimal) */
  63. struct Cell_head *cellhd /* information of output map */
  64. )
  65. {
  66. int row; /* row indices for interp */
  67. int col; /* column indices for interp */
  68. FCELL cell;
  69. /* cut indices to integer */
  70. row = (int)floor(row_idx);
  71. col = (int)floor(col_idx);
  72. /* check for out of bounds - if out of bounds set NULL value */
  73. if (row < 0 || row >= cellhd->rows || col < 0 || col >= cellhd->cols) {
  74. Rast_set_null_value(obufptr, 1, cell_type);
  75. return;
  76. }
  77. cell = CVAL(ibuffer, row, col);
  78. /* if nearest is null, all the other interps will be null */
  79. if (Rast_is_f_null_value(&cell)) {
  80. Rast_set_null_value(obufptr, 1, cell_type);
  81. return;
  82. }
  83. p_lanczos(ibuffer, obufptr, cell_type, col_idx, row_idx, cellhd);
  84. /* fallback to bicubic if lanczos is null */
  85. if (Rast_is_f_null_value(obufptr)) {
  86. p_cubic(ibuffer, obufptr, cell_type, col_idx, row_idx, cellhd);
  87. /* fallback to bilinear if cubic is null */
  88. if (Rast_is_f_null_value(obufptr)) {
  89. p_bilinear(ibuffer, obufptr, cell_type, col_idx, row_idx, cellhd);
  90. /* fallback to nearest if bilinear is null */
  91. if (Rast_is_f_null_value(obufptr))
  92. Rast_set_f_value(obufptr, cell, cell_type);
  93. }
  94. }
  95. }