GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
address.c
Go to the documentation of this file.
1 
2 /**
3  * \file address.c
4  *
5  * \brief Address routines.
6  *
7  * This program is free software under the GNU General Public License
8  * (>=v2). Read the file COPYING that comes with GRASS for details.
9  *
10  * \author GRASS GIS Development Team
11  *
12  * \date 2005-2009
13  */
14 
15 #include "local_proto.h"
16 
17 #define SEG_N_ROW_NONZERO(SEG, row, col) \
18  (((row) >> (SEG)->srowbits) * (SEG)->spr + ((col) >> (SEG)->scolbits))
19 
20 #define SEG_INDEX_ROW_NONZERO(SEG, row, col) \
21  ((((row) & ((SEG)->srows - 1)) << (SEG)->scolbits) + ((col) & ((SEG)->scols - 1)))
22 
23 #define SEG_N_ROW_ZERO(SEG, col) ((col) >> (SEG)->scolbits)
24 
25 #define SEG_INDEX_ROW_ZERO(SEG, col) ((col) & ((SEG)->scols - 1))
26 
27 #define INDEX_ADJ(SEG, i) \
28  ((SEG)->fast_seek ? ((i) << (SEG)->lenbits) : ((i) * (SEG)->len))
29 
30 int seg_address_fast(const SEGMENT * SEG, off_t row, off_t col, int *n,
31  int *index)
32 {
33 
34 #if 1
35  if (row) {
36  *n = SEG_N_ROW_NONZERO(SEG, row, col);
37  *index = INDEX_ADJ(SEG, SEG_INDEX_ROW_NONZERO(SEG, row, col));
38  }
39  /* for simple arrays */
40  else {
41  *n = SEG_N_ROW_ZERO(SEG, col);
42  *index = INDEX_ADJ(SEG, SEG_INDEX_ROW_ZERO(SEG, col));
43  }
44 #else
45  if (row) {
46  *n = (row >> SEG->srowbits) * SEG->spr + (col >> SEG->scolbits);
47  *index = ((row & (SEG->srows - 1)) << SEG->scolbits) + (col & (SEG->scols - 1));
48 
49  /* slower version for testing */
50  /*
51  off_t seg_r = row >> SEG->srowbits;
52  off_t seg_c = col >> SEG->scolbits;
53 
54  *n = seg_r * SEG->spr + seg_c;
55 
56  *index = ((row - (seg_r << SEG->srowbits)) << SEG->scolbits) +
57  col - (seg_c << SEG->scolbits);
58  */
59  }
60  /* for simple arrays */
61  else {
62  *n = col >> SEG->scolbits;
63  *index = col - ((*n) << SEG->scolbits);
64  }
65 
66  *index = SEG->fast_seek ? (*index << SEG->lenbits) : (*index * SEG->len);
67 
68 #endif
69 
70  return 0;
71 }
72 
73 int seg_address_slow(const SEGMENT * SEG, off_t row, off_t col, int *n,
74  int *index)
75 {
76  if (row) {
77  off_t seg_r = row / SEG->srows;
78  off_t seg_c = col / SEG->scols;
79 
80  *n = seg_r * SEG->spr + seg_c;
81  *index = (row - seg_r * SEG->srows) * SEG->scols + col -
82  seg_c * SEG->scols;
83  }
84  /* for simple arrays */
85  else {
86  *n = col / SEG->scols;
87  *index = col - *n * SEG->scols;
88  }
89  *index *= SEG->len;
90 
91  return 0;
92 }
93 
94 /**
95  * \brief Internal use only
96  *
97  * Gets segment address and sets<b>n</b> and <b>index</b>.
98  *
99  * \param[in] SEG segment
100  * \param[in] row
101  * \param[in] col
102  * \param[in,out] n
103  * \param[in,out] index
104  * \return always returns 0
105  */
106 
107 int seg_address(const SEGMENT * SEG, off_t row, off_t col, int *n, int *index)
108 {
109  /* old code
110  *n = row / SEG->srows * SEG->spr + col / SEG->scols;
111  *index = (row % SEG->srows * SEG->scols + col % SEG->scols) * SEG->len;
112  */
113 
114  /* this function is called at least once every time data are accessed in SEG
115  * avoid very slow modulus and divisions, modulus was the main time killer */
116 
117  return SEG->address(SEG, row, col, n, index);
118 }
#define SEG_INDEX_ROW_NONZERO(SEG, row, col)
Definition: address.c:20
#define SEG_INDEX_ROW_ZERO(SEG, col)
Definition: address.c:25
int(* address)()
Definition: segment.h:40
off_t srowbits
Definition: segment.h:35
off_t scolbits
Definition: segment.h:34
int seg_address_slow(const SEGMENT *SEG, off_t row, off_t col, int *n, int *index)
Definition: address.c:73
int len
Definition: segment.h:24
int seg_address_fast(const SEGMENT *SEG, off_t row, off_t col, int *n, int *index)
Definition: address.c:30
#define SEG_N_ROW_NONZERO(SEG, row, col)
Definition: address.c:17
int lenbits
Definition: segment.h:38
#define INDEX_ADJ(SEG, i)
Definition: address.c:27
int seg_address(const SEGMENT *SEG, off_t row, off_t col, int *n, int *index)
Internal use only.
Definition: address.c:107
int srows
Definition: segment.h:25
int spr
Definition: segment.h:29
int scols
Definition: segment.h:26
#define SEG_N_ROW_ZERO(SEG, col)
Definition: address.c:23
int fast_seek
Definition: segment.h:37