address.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /**
  2. * \file address.c
  3. *
  4. * \brief Address routines.
  5. *
  6. * This program is free software under the GNU General Public License
  7. * (>=v2). Read the file COPYING that comes with GRASS for details.
  8. *
  9. * \author GRASS GIS Development Team
  10. *
  11. * \date 2005-2009
  12. */
  13. #include <grass/segment.h>
  14. int segment_address_fast(const SEGMENT * SEG, int row, int col, int *n,
  15. int *index)
  16. {
  17. if (row) {
  18. int seg_r = row >> SEG->srowbits;
  19. int seg_c = col >> SEG->scolbits;
  20. *n = seg_r * SEG->spr + seg_c;
  21. *index = ((row - (seg_r << SEG->srowbits)) << SEG->scolbits) +
  22. col - (seg_c << SEG->scolbits);
  23. /*
  24. *n = (row >> SEG->srowbits) * SEG->spr + (col >> SEG->scolbits);
  25. *index = ((row & (SEG->srows - 1)) << SEG->scolbits) + (col & (SEG->scols - 1));
  26. */
  27. }
  28. /* for simple arrays */
  29. else {
  30. *n = col >> SEG->scolbits;
  31. *index = col - ((*n) << SEG->scolbits);
  32. }
  33. if (SEG->slow_seek == 0)
  34. *index = *index << SEG->lenbits;
  35. else
  36. *index *= SEG->len;
  37. return 0;
  38. }
  39. int segment_address_slow(const SEGMENT * SEG, int row, int col, int *n,
  40. int *index)
  41. {
  42. if (row) {
  43. int seg_r = row / SEG->srows;
  44. int seg_c = col / SEG->scols;
  45. *n = seg_r * SEG->spr + seg_c;
  46. *index =
  47. (row - seg_r * SEG->srows) * SEG->scols + col -
  48. seg_c * SEG->scols;
  49. }
  50. /* for simple arrays */
  51. else {
  52. *n = col / SEG->scols;
  53. *index = col - *n * SEG->scols;
  54. }
  55. *index *= SEG->len;
  56. return 0;
  57. }
  58. static int (*segment_adrs[2]) () = {
  59. segment_address_fast, segment_address_slow};
  60. /**
  61. * \fn int segment_address (SEGMENT *SEG, int row, int col, int *n, int *index)
  62. *
  63. * \brief Gets segment address and returns <b>n</b> and <b>index</b>.
  64. *
  65. * \param[in] SEG segment
  66. * \param[in] row
  67. * \param[in] col
  68. * \param[in,out] n
  69. * \param[in,out] index
  70. * \return always returns 0
  71. */
  72. int segment_address(const SEGMENT * SEG, int row, int col, int *n, int *index)
  73. {
  74. /* old code
  75. *n = row / SEG->srows * SEG->spr + col / SEG->scols;
  76. *index = (row % SEG->srows * SEG->scols + col % SEG->scols) * SEG->len;
  77. */
  78. /* this function is called at least once every time data are accessed in SEG
  79. * avoid very slow modulus and divisions, modulus was the main time killer */
  80. return (*segment_adrs[SEG->slow_adrs]) (SEG, row, col, n, index);
  81. }