cellstats_eq.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #include <grass/gis.h>
  2. int G_cell_stats_histo_eq(struct Cell_stats *statf, CELL min1, CELL max1, /* input range to be rescaled */
  3. CELL min2, CELL max2, /* output range */
  4. int zero, /* include zero if min1 <= 0 <= min2 ? */
  5. void (*func) (CELL, CELL, CELL))
  6. {
  7. long count, total;
  8. CELL prev = 0;
  9. CELL cat;
  10. CELL x;
  11. CELL newcat = 0;
  12. int first;
  13. double span, sum;
  14. double range2;
  15. if (min1 > max1 || min2 > max2)
  16. return 0;
  17. total = 0;
  18. G_rewind_cell_stats(statf);
  19. while (G_next_cell_stat(&cat, &count, statf)) {
  20. if (cat < min1)
  21. continue;
  22. if (cat > max1)
  23. break;
  24. if (cat == 0 && !zero)
  25. continue;
  26. total += count;
  27. }
  28. if (total <= 0)
  29. return 0;
  30. range2 = max2 - min2 + 1;
  31. span = total / range2;
  32. first = 1;
  33. sum = 0;
  34. G_rewind_cell_stats(statf);
  35. while (G_next_cell_stat(&cat, &count, statf)) {
  36. if (cat < min1)
  37. continue;
  38. if (cat > max1)
  39. break;
  40. if (cat == 0 && !zero)
  41. continue;
  42. x = (sum + (count / 2.0)) / span;
  43. if (x < 0)
  44. x = 0;
  45. x += min2;
  46. sum += count;
  47. if (first) {
  48. prev = cat;
  49. newcat = x;
  50. first = 0;
  51. }
  52. else if (newcat != x) {
  53. func(prev, cat - 1, newcat);
  54. newcat = x;
  55. prev = cat;
  56. }
  57. }
  58. if (!first) {
  59. func(prev, cat, newcat);
  60. if (!zero && min1 <= 0 && max1 >= 0)
  61. func((CELL) 0, (CELL) 0, (CELL) 0);
  62. }
  63. return first == 0;
  64. }