address.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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)
  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 = (row - seg_r * SEG->srows) * SEG->scols + col -
  47. seg_c * SEG->scols;
  48. }
  49. /* for simple arrays */
  50. else {
  51. *n = col / SEG->scols;
  52. *index = col - *n * SEG->scols;
  53. }
  54. *index *= SEG->len;
  55. return 0;
  56. }
  57. /**
  58. * \fn int segment_address (SEGMENT *SEG, int row, int col, int *n, int *index)
  59. *
  60. * \brief Gets segment address and returns <b>n</b> and <b>index</b>.
  61. *
  62. * \param[in] SEG segment
  63. * \param[in] row
  64. * \param[in] col
  65. * \param[in,out] n
  66. * \param[in,out] index
  67. * \return always returns 0
  68. */
  69. int segment_address(const SEGMENT * SEG, int row, int col, int *n, int *index)
  70. {
  71. /* old code
  72. *n = row / SEG->srows * SEG->spr + col / SEG->scols;
  73. *index = (row % SEG->srows * SEG->scols + col % SEG->scols) * SEG->len;
  74. */
  75. /* this function is called at least once every time data are accessed in SEG
  76. * avoid very slow modulus and divisions, modulus was the main time killer */
  77. return SEG->segment_address(SEG, row, col, n, index);
  78. }