GRASS GIS 8 Programmer's Manual 8.2.0(2022)-exported
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
30int 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
73int 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
107int 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
int seg_address_slow(const SEGMENT *SEG, off_t row, off_t col, int *n, int *index)
Definition: address.c:73
#define SEG_N_ROW_NONZERO(SEG, row, col)
Definition: address.c:17
int seg_address(const SEGMENT *SEG, off_t row, off_t col, int *n, int *index)
Internal use only.
Definition: address.c:107
#define SEG_INDEX_ROW_ZERO(SEG, col)
Definition: address.c:25
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_ZERO(SEG, col)
Definition: address.c:23
#define INDEX_ADJ(SEG, i)
Definition: address.c:27