1 /*!
2  * \file lib/raster/raster.c
3  *
4  * \brief Raster Library - Raster cell value routines.
5  *
6  * (C) 2001-2009 by the GRASS Development Team
7  *
8  * This program is free software under the GNU General Public License
9  * (>=v2). Read the file COPYING that comes with GRASS for details.
10  *
11  * \author Original author CERL
12  */
13 
14 #include <stdlib.h>
15 #include <string.h>
16 #include <grass/gis.h>
17 #include <grass/raster.h>
18 
19 /*!
20  * \brief Compares raster values.
21  *
22  * \param v1,v2 values to be compared
23  * \param data_type raster type (CELL, FCELL, DCELL)
24  *
25  * \return  1 if p > q or only q is null value
26  * \return -1 if p < q or only p is null value
27  * \return  0 if p == q or p==q==null value
28  */
Rast_raster_cmp(const void * v1,const void * v2,RASTER_MAP_TYPE data_type)29 int Rast_raster_cmp(const void *v1, const void *v2, RASTER_MAP_TYPE data_type)
30 {
31     if (Rast_is_null_value(v1, data_type)) {
32 	if (Rast_is_null_value(v2, data_type))
33 	    return 0;
34 	else
35 	    return -1;
36     }
37     else if (Rast_is_null_value(v2, data_type))
38 	return 1;
39 
40     switch (data_type) {
41     case CELL_TYPE:
42 	if (*((const CELL *)v1) > *((const CELL *)v2))
43 	    return 1;
44 	else if (*((const CELL *)v1) == *((const CELL *)v2))
45 	    return 0;
46 	else
47 	    return -1;
48     case FCELL_TYPE:
49 	if (*((const FCELL *)v1) > *((const FCELL *)v2))
50 	    return 1;
51 	else if (*((const FCELL *)v1) == *((const FCELL *)v2))
52 	    return 0;
53 	else
54 	    return -1;
55     case DCELL_TYPE:
56 	if (*((const DCELL *)v1) > *((const DCELL *)v2))
57 	    return 1;
58 	else if (*((const DCELL *)v1) == *((const DCELL *)v2))
59 	    return 0;
60 	else
61 	    return -1;
62     }
63 
64     return 0;
65 }
66 
67 /*!
68  * \brief Copies raster values.
69  *
70  * If \p v2 is null value, sets \p v2 to null value.
71  * \p n is typically size of the destination array
72  * and the source array is at least that large.
73  *
74  * \param v1 destination array for raster values
75  * \param v2 source array with raster values
76  * \param n number of values to copy
77  * \param data_type raster type (CELL, FCELL, DCELL)
78  */
Rast_raster_cpy(void * v1,const void * v2,int n,RASTER_MAP_TYPE data_type)79 void Rast_raster_cpy(void *v1, const void *v2, int n,
80 		     RASTER_MAP_TYPE data_type)
81 {
82     memcpy(v1, v2, n * Rast_cell_size(data_type));
83 }
84 
85 /*!
86  * \brief Places a CELL raster value
87  *
88  * If Rast_is_c_null_value() is true, sets p to null value. Converts CELL
89  * val to data_type (type of p) and stores result in p. Used for
90  * assigning CELL values to raster cells of any type.
91  *
92  * \param rast pointer to raster cell value
93  * \param cval value to set
94  * \param data_type raster type (CELL, FCELL, DCELL)
95  */
Rast_set_c_value(void * rast,CELL cval,RASTER_MAP_TYPE data_type)96 void Rast_set_c_value(void *rast, CELL cval, RASTER_MAP_TYPE data_type)
97 {
98     CELL c;
99 
100     c = cval;
101     if (Rast_is_c_null_value(&c)) {
102 	Rast_set_null_value(rast, 1, data_type);
103 	return;
104     }
105     switch (data_type) {
106     case CELL_TYPE:
107 	*((CELL *) rast) = cval;
108 	break;
109     case FCELL_TYPE:
110 	*((FCELL *) rast) = (FCELL) cval;
111 	break;
112     case DCELL_TYPE:
113 	*((DCELL *) rast) = (DCELL) cval;
114 	break;
115     }
116 }
117 
118 /*!
119  * \brief Places a FCELL raster value
120  *
121  * If Rast_is_f_null_value() is true, sets p to null value. Converts
122  * FCELL val to data_type (type of p) and stores result in p. Used for
123  * assigning FCELL values to raster cells of any type.
124  *
125  * \param rast pointer to raster cell value
126  * \param fval value to set
127  * \param data_type raster type (CELL, FCELL, DCELL)
128  */
Rast_set_f_value(void * rast,FCELL fval,RASTER_MAP_TYPE data_type)129 void Rast_set_f_value(void *rast, FCELL fval, RASTER_MAP_TYPE data_type)
130 {
131     FCELL f;
132 
133     f = fval;
134     if (Rast_is_f_null_value(&f)) {
135 	Rast_set_null_value(rast, 1, data_type);
136 	return;
137     }
138     switch (data_type) {
139     case CELL_TYPE:
140 	*((CELL *) rast) = (CELL) fval;
141 	break;
142     case FCELL_TYPE:
143 	*((FCELL *) rast) = fval;
144 	break;
145     case DCELL_TYPE:
146 	*((DCELL *) rast) = (DCELL) fval;
147 	break;
148     }
149 }
150 
151 
152 /*!
153  * \brief  Places a DCELL raster value
154  *
155  * If Rast_is_d_null_value() is true, sets p to null value. Converts
156  * DCELL val to data_type (type of p) and stores result in p. Used for
157  * assigning DCELL values to raster cells of any type.
158  *
159  * \param rast pointer to raster cell value
160  * \param fval value to set
161  * \param data_type raster type (CELL, FCELL, DCELL)
162  */
Rast_set_d_value(void * rast,DCELL dval,RASTER_MAP_TYPE data_type)163 void Rast_set_d_value(void *rast, DCELL dval, RASTER_MAP_TYPE data_type)
164 {
165     DCELL d;
166 
167     d = dval;
168     if (Rast_is_d_null_value(&d)) {
169 	Rast_set_null_value(rast, 1, data_type);
170 	return;
171     }
172     switch (data_type) {
173     case CELL_TYPE:
174 	*((CELL *) rast) = (CELL) dval;
175 	break;
176     case FCELL_TYPE:
177 	*((FCELL *) rast) = (FCELL) dval;
178 	break;
179     case DCELL_TYPE:
180 	*((DCELL *) rast) = dval;
181 	break;
182     }
183 }
184 
185 /*!
186  * \brief Retrieves the value of give type from pointer p
187  *
188  * Retrieves the value of type data_type from pointer p, converts it
189  * to CELL type and returns the result. If null value is stored in p,
190  * returns CELL null value.
191  *
192  * Used for retrieving CELL values from raster cells of any type.
193  *
194  * Note: when data_type != CELL_TYPE, no quantization is used, only
195  * type conversion.
196  *
197  * \param rast pointer to raster cell value
198  * \param data_type raster type (CELL, FCELL, DCELL)
199  *
200  * \return raster value
201  */
Rast_get_c_value(const void * rast,RASTER_MAP_TYPE data_type)202 CELL Rast_get_c_value(const void *rast, RASTER_MAP_TYPE data_type)
203 {
204     CELL c;
205 
206     if (Rast_is_null_value(rast, data_type)) {
207 	Rast_set_c_null_value(&c, 1);
208 	return c;
209     }
210     switch (data_type) {
211     case CELL_TYPE:
212 	return *((const CELL *)rast);
213     case FCELL_TYPE:
214 	return (CELL) * ((const FCELL *)rast);
215     case DCELL_TYPE:
216 	return (CELL) * ((const DCELL *)rast);
217     }
218 
219     return 0;
220 }
221 
222 /*!
223  * \brief Retrieves the value of given raster type from pointer p (FCELL)
224  *
225  * Retrieves the value of type data_type from pointer p, converts it
226  * to FCELL type and returns the result. If null value is stored in p,
227  * returns FCELL null value.
228  *
229  * Used for retrieving FCELL values from raster cells of any type.
230  *
231  * \param rast pointer to raster cell value
232  * \param data_type raster type (CELL, FCELL, DCELL)
233  *
234  * \return raster value
235  */
Rast_get_f_value(const void * rast,RASTER_MAP_TYPE data_type)236 FCELL Rast_get_f_value(const void *rast, RASTER_MAP_TYPE data_type)
237 {
238     FCELL f;
239 
240     if (Rast_is_null_value(rast, data_type)) {
241 	Rast_set_f_null_value(&f, 1);
242 	return f;
243     }
244     switch (data_type) {
245     case CELL_TYPE:
246 	return (FCELL) * ((const CELL *)rast);
247     case FCELL_TYPE:
248 	return *((const FCELL *)rast);
249     case DCELL_TYPE:
250 	return (FCELL) * ((const DCELL *)rast);
251     }
252 
253     return 0;
254 }
255 
256 
257 /*!
258  * \brief Retrieves the value of given type from pointer p (DCELL)
259  *
260  * Retrieves the value of type data_type from pointer p, converts it
261  * to DCELL type and returns the result. If null value is stored in p,
262  * returns DCELL null value.
263 
264  * Used for retrieving DCELL values from raster cells of any type.
265  *
266  * \param rast pointer to raster cell value
267  * \param data_type raster type (CELL, FCELL, DCELL)
268  *
269  * \return raster value
270  */
Rast_get_d_value(const void * rast,RASTER_MAP_TYPE data_type)271 DCELL Rast_get_d_value(const void *rast, RASTER_MAP_TYPE data_type)
272 {
273     DCELL d;
274 
275     if (Rast_is_null_value(rast, data_type)) {
276 	Rast_set_d_null_value(&d, 1);
277 	return d;
278     }
279     switch (data_type) {
280     case CELL_TYPE:
281 	return (DCELL) * ((const CELL *)rast);
282     case FCELL_TYPE:
283 	return (DCELL) * ((const FCELL *)rast);
284     case DCELL_TYPE:
285 	return *((const DCELL *)rast);
286     }
287 
288     return 0;
289 }
290