GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
Loading...
Searching...
No Matches
address.c
Go to the documentation of this file.
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
14#include "local_proto.h"
15
16#define SEG_N_ROW_NONZERO(SEG, row, col) \
17 (((row) >> (SEG)->srowbits) * (SEG)->spr + ((col) >> (SEG)->scolbits))
18
19#define SEG_INDEX_ROW_NONZERO(SEG, row, col) \
20 ((((row) & ((SEG)->srows - 1)) << (SEG)->scolbits) + \
21 ((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) +
48 (col & (SEG->scols - 1));
49
50 /* slower version for testing */
51 /*
52 off_t seg_r = row >> SEG->srowbits;
53 off_t seg_c = col >> SEG->scolbits;
54
55 *n = seg_r * SEG->spr + seg_c;
56
57 *index = ((row - (seg_r << SEG->srowbits)) << SEG->scolbits) +
58 col - (seg_c << SEG->scolbits);
59 */
60 }
61 /* for simple arrays */
62 else {
63 *n = col >> SEG->scolbits;
64 *index = col - ((*n) << SEG->scolbits);
65 }
66
67 *index = SEG->fast_seek ? (*index << SEG->lenbits) : (*index * SEG->len);
68
69#endif
70
71 return 0;
72}
73
74int seg_address_slow(const SEGMENT *SEG, off_t row, off_t col, int *n,
75 int *index)
76{
77 if (row) {
78 off_t seg_r = row / SEG->srows;
79 off_t seg_c = col / SEG->scols;
80
81 *n = seg_r * SEG->spr + seg_c;
82 *index =
83 (row - seg_r * SEG->srows) * SEG->scols + col - seg_c * SEG->scols;
84 }
85 /* for simple arrays */
86 else {
87 *n = col / SEG->scols;
88 *index = col - *n * SEG->scols;
89 }
90 *index *= SEG->len;
91
92 return 0;
93}
94
95/**
96 * \brief Internal use only
97 *
98 * Gets segment address and sets<b>n</b> and <b>index</b>.
99 *
100 * \param[in] SEG segment
101 * \param[in] row
102 * \param[in] col
103 * \param[in,out] n
104 * \param[in,out] index
105 * \return always returns 0
106 */
107
108int seg_address(const SEGMENT *SEG, off_t row, off_t col, int *n, int *index)
109{
110 /* old code
111 *n = row / SEG->srows * SEG->spr + col / SEG->scols;
112 *index = (row % SEG->srows * SEG->scols + col % SEG->scols) * SEG->len;
113 */
114
115 /* this function is called at least once every time data are accessed in SEG
116 * avoid very slow modulus and divisions, modulus was the main time killer
117 */
118
119 return SEG->address(SEG, row, col, n, index);
120}
#define SEG_INDEX_ROW_NONZERO(SEG, row, col)
Definition address.c:19
int seg_address_slow(const SEGMENT *SEG, off_t row, off_t col, int *n, int *index)
Definition address.c:74
#define SEG_N_ROW_NONZERO(SEG, row, col)
Definition address.c:16
int seg_address(const SEGMENT *SEG, off_t row, off_t col, int *n, int *index)
Internal use only.
Definition address.c:108
#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