GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
null_val.c
Go to the documentation of this file.
1/*!
2 * \file lib/raster/null_val.c
3 *
4 * \brief Raster Library - NULL value management
5 *
6 * To provide functionality to handle NULL values for data types CELL,
7 * FCELL, and DCELL. May need more...
8 *
9 * (C) 2001-2009 GRASS Development Team
10 *
11 * This program is free software under the GNU General Public License
12 * (>=v2). Read the file COPYING that comes with GRASS for details.
13 *
14 * \author Original author unknown - probably CERL
15 * \author Justin Hickey - Thailand - jhickey@hpcc.nectec.or.th
16 */
17
18/* System include files */
19#include <string.h>
20
21/* Grass and local include files */
22#include <grass/gis.h>
23#include <grass/raster.h>
24#include <grass/glocale.h>
25
26static void EmbedGivenNulls(void *, char *, RASTER_MAP_TYPE, int);
27
28/*!
29 \brief To insert null values into a map. Needs more.....
30
31 \param cell raster values
32 \param nulls raster null values
33 \param map_type type of raster - CELL, FCELL, DCELL
34 \param ncols number of columns
35 */
36void EmbedGivenNulls(void *cell, char *nulls, RASTER_MAP_TYPE map_type,
37 int ncols)
38{
39 CELL *c;
40 FCELL *f;
41 DCELL *d;
42 int i;
43
44 c = (CELL *)cell;
45 f = (FCELL *)cell;
46 d = (DCELL *)cell;
47
48 for (i = 0; i < ncols; i++) {
49 if (nulls[i]) {
50 switch (map_type) {
51 case CELL_TYPE:
52 Rast_set_c_null_value((CELL *)(c + i), 1);
53 break;
54
55 case FCELL_TYPE:
56 Rast_set_f_null_value((FCELL *)(f + i), 1);
57 break;
58
59 case DCELL_TYPE:
60 Rast_set_d_null_value((DCELL *)(d + i), 1);
61 break;
62
63 default:
64 G_warning(_("EmbedGivenNulls: wrong data type"));
65 }
66 }
67 }
68}
69
70/*!
71 \brief To set one or more raster values to null.
72
73 It also sets null to zero if null_is_zero is TRUE.
74
75 \param rast pointer to values to set to null
76 \param numVals number of values to set to null
77 \param null_is_zero flag to indicate if NULL = 0
78 \param data_type type of raster - CELL, FCELL, DCELL
79 */
81 RASTER_MAP_TYPE data_type)
82{
83 if (null_is_zero) {
84 G_zero((char *)rast, numVals * Rast_cell_size(data_type));
85 return;
86 }
87
88 Rast_set_null_value(rast, numVals, data_type);
89}
90
91/*!
92 \brief To set one or more raster values to null.
93
94 \param buf pointer to values to set to null
95 \param numVals number of values to set to null
96 \param data_type type of raster - CELL, FCELL, DCELL
97 */
98void Rast_set_null_value(void *buf, int numVals, RASTER_MAP_TYPE data_type)
99{
100 switch (data_type) {
101 case CELL_TYPE:
103 break;
104
105 case FCELL_TYPE:
107 break;
108
109 case DCELL_TYPE:
111 break;
112
113 default:
114 G_warning(_("Rast_set_null_value: wrong data type!"));
115 }
116}
117
118/*!
119 \brief To set a number of CELL raster values to NULL.
120
121 \param cellVals pointer to CELL values to set to null
122 \param numVals number of values to set to null
123 */
125{
126 int i; /* counter */
127
128 for (i = 0; i < numVals; i++)
129 cellVals[i] = (int)0x80000000;
130}
131
132/*!
133 \brief To set a number of FCELL raster values to NULL.
134
135 \param fcellVals pointer to FCELL values to set to null
136 \param numVals number of values to set to null
137 */
139{
140 static const unsigned char null_bits[4] = {0xFF, 0xFF, 0xFF, 0xFF};
141 int i;
142
143 for (i = 0; i < numVals; i++)
144 memcpy(&fcellVals[i], null_bits, sizeof(null_bits));
145}
146
147/*!
148 \brief To set a number of DCELL raster values to NULL.
149
150 \param dcellVals pointer to DCELL values to set to null
151 \param numVals number of values to set to null
152 */
154{
155 static const unsigned char null_bits[8] = {0xFF, 0xFF, 0xFF, 0xFF,
156 0xFF, 0xFF, 0xFF, 0xFF};
157 int i;
158
159 for (i = 0; i < numVals; i++)
160 memcpy(&dcellVals[i], null_bits, sizeof(null_bits));
161}
162
163/*!
164 \brief To check if a raster value is set to NULL
165
166 - If the <em>data_type</em> is CELL_TYPE, calls Rast_is_c_null_value()
167 - If the <em>data_type</em> is FCELL_TYPE, calls Rast_is_f_null_value()
168 - If the <em>data_type</em> is DCELL_TYPE, calls Rast_is_d_null_value()
169
170 \param rast raster value to check
171 \param data_type type of raster - CELL, FCELL, DCELL
172
173 \return TRUE if raster value is NULL
174 \return FALSE otherwise
175 */
176int Rast_is_null_value(const void *rast, RASTER_MAP_TYPE data_type)
177{
178 switch (data_type) {
179 case CELL_TYPE:
180 return (Rast_is_c_null_value((CELL *)rast));
181
182 case FCELL_TYPE:
183 return (Rast_is_f_null_value((FCELL *)rast));
184
185 case DCELL_TYPE:
186 return (Rast_is_d_null_value((DCELL *)rast));
187
188 default:
189 G_warning("Rast_is_null_value: wrong data type!");
190 return FALSE;
191 }
192}
193
194/*!
195 \brief To check if a CELL raster value is set to NULL
196
197 Returns 1 if <em>cell</em> is NULL, 0 otherwise. This will test if the
198 value <em>cell</em> is the largest <tt>int</tt>.
199
200 \param cellVal CELL raster value to check
201
202 \return TRUE if CELL raster value is NULL
203 \return FALSE otherwise
204 */
205#ifndef Rast_is_c_null_value
207{
208 /* Check if the CELL value matches the null pattern */
209 return *cellVal == (CELL)0x80000000;
210}
211#endif
212
213/*!
214 \brief To check if a FCELL raster value is set to NULL
215
216 Returns 1 if <em>fcell</em> is NULL, 0 otherwise. This will test if
217 the value <em>fcell</em> is a NaN. It isn't good enough to test for
218 a particular NaN bit pattern since the machine code may change this
219 bit pattern to a different NaN. The test will be
220
221 \code
222 if(fcell==0.0) return 0;
223 if(fcell>0.0) return 0;
224 if(fcell<0.0) return 0;
225 return 1;
226 \endcode
227
228 or (as suggested by Mark Line)
229 \code
230 return (fcell != fcell);
231 \endcode
232
233 \param fcellVal FCELL raster value to check
234
235 \return TRUE if FCELL raster value is NULL
236 \return FALSE otherwise
237 */
238#ifndef Rast_is_f_null_value
240{
241 return *fcellVal != *fcellVal;
242}
243#endif
244
245/*!
246 \brief To check if a DCELL raster value is set to NULL
247
248 Returns 1 if <em>dcell</em> is NULL, 0 otherwise. This will test if
249 the value <em>dcell</em> is a NaN. Same test as in
250 Rast_is_f_null_value().
251
252 \param dcellVal DCELL raster value to check
253
254 \return TRUE if DCELL raster value is NULL
255 \return FALSE otherwise
256 */
257#ifndef Rast_is_d_null_value
259{
260 return *dcellVal != *dcellVal;
261}
262#endif
263
264/*!
265 \brief To insert null values into a map.
266
267 - If the <em>data_type</em> is CELL_TYPE, calls Rast_insert_c_null_values()
268 - If the <em>data_type</em> is FCELL_TYPE, calls Rast_insert_f_null_values()
269 - If the <em>data_type</em> is DCELL_TYPE, calls Rast_insert_d_null_values()
270
271 \param rast pointer raster values
272 \param null_row null row
273 \param ncols number of columns
274 \param data_type type of raster - CELL, FCELL, DCELL
275 */
276void Rast_insert_null_values(void *rast, char *null_row, int ncols,
277 RASTER_MAP_TYPE data_type)
278{
279 EmbedGivenNulls(rast, null_row, data_type, ncols);
280}
281
282/*!
283 \brief To insert null values into an integer raster map (CELL)
284
285 For each of the <em>count</em> <em>flags</em> which is true(!=0),
286 set the corresponding <em>cell</em> to the NULL value.
287
288 \param rast pointer raster values
289 \param null_row null row
290 \param ncols number of columns
291 */
292void Rast_insert_c_null_values(CELL *cellVal, char *null_row, int ncols)
293{
294 EmbedGivenNulls((void *)cellVal, null_row, CELL_TYPE, ncols);
295}
296
297/*!
298 \brief To insert null values into an floating-point raster map (FCELL)
299
300 \param fcellVal pointer raster values
301 \param null_row null row
302 \param ncols number of columns
303 */
304void Rast_insert_f_null_values(FCELL *fcellVal, char *null_row, int ncols)
305{
306 EmbedGivenNulls((void *)fcellVal, null_row, FCELL_TYPE, ncols);
307}
308
309/*!
310 \brief To insert null values into an floating-point raster map (FCELL)
311
312 For each for the <em>count</em> <em>flag</em> which is true(!=0), set
313 the corresponding <em>dcell</em> to the NULL value.
314
315 \param dcellVal pointer raster values
316 \param null_row null row
317 \param ncols number of columns
318 */
319void Rast_insert_d_null_values(DCELL *dcellVal, char *null_row, int ncols)
320{
321 EmbedGivenNulls((void *)dcellVal, null_row, DCELL_TYPE, ncols);
322}
323
324/*!
325 \brief Check NULL
326
327 Note: Only for internal use.
328
329 \param flags null bitmap
330 \param bit_num index of bit to check
331 \param n size of null bitmap (in bits)
332
333 \return 1 if set, 0 if unset
334 */
335int Rast__check_null_bit(const unsigned char *flags, int bit_num, int n)
336{
337 int ind;
338 int offset;
339
340 /* check that bit_num is in range */
343 "Rast__check_null_bit: index %d out of range (size = %d).", bit_num,
344 n);
345
346 /* find the index of the unsigned char in which this bit appears */
347 ind = bit_num / 8;
348
349 offset = bit_num & 7;
350
351 return ((flags[ind] & ((unsigned char)0x80 >> offset)) != 0);
352}
353
354/*!
355 \brief Given array of 0/1 of length n starting from column.
356
357 Note: Only for internal use.
358
359 Given array of 0/1 of length n starting from column set the
360 corresponding bits of flags; total number of bits in flags is ncols.
361
362 \param zero_ones
363 \param flags
364 \param col
365 \param n
366 \param ncols
367
368 \return 0
369 \return 1
370 */
371int G__set_flags_from_01_random(const char *zero_ones, unsigned char *flags,
372 int col, int n, int ncols)
373{
374 unsigned char v;
375 int count;
376 int size;
377 int i, k;
378
379 if (col == 0 && n == ncols) {
381 return 0;
382 }
383
384 count = 0;
385 size = Rast__null_bitstream_size(ncols);
386
387 for (i = 0; i < size; i++) {
388 v = 0;
389 k = 8;
390
391 while (k-- > 0) {
392 if (count >= col && count < (col + n)) {
393 v = v | ((unsigned char)zero_ones[count - col] << k);
394 }
395 else if (count < ncols) {
396 v = v |
397 ((unsigned char)Rast__check_null_bit(flags, count, ncols)
398 << k);
399 }
400
401 /* otherwise keep this bit the same as it was */
402 count++;
403 }
404
405 flags[i] = v;
406 }
407
408 return 1;
409}
410
411/*!
412 \brief ?
413
414 Note: Only for internal use.
415
416 \param zero_ones
417 \param flags
418 \param n
419 */
420void Rast__convert_01_flags(const char *zero_ones, unsigned char *flags, int n)
421{
422 unsigned char *v;
423 int count;
424 int size;
425 int i, k;
426
427 /* pad the flags with 0's to make size multiple of 8 */
428 v = flags;
430 count = 0;
431
432 for (i = 0; i < size; i++) {
433 *v = 0;
434 k = 8;
435
436 while (k-- > 0) {
437 if (count < n) {
438 *v = *v | ((unsigned char)zero_ones[count] << k);
439 }
440
441 count++;
442 }
443
444 v++;
445 }
446}
447
448/*!
449 \brief ?
450
451 Note: Only for internal use.
452
453 \param zero_ones
454 \param flags
455 \param n
456 */
457void Rast__convert_flags_01(char *zero_ones, const unsigned char *flags, int n)
458{
459 const unsigned char *v;
460 int count;
461 int size;
462 int i, k;
463
464 count = 0;
465 v = flags;
467
468 for (i = 0; i < size; i++) {
469 k = 8;
470
471 while (k-- > 0) {
472 if (count < n) {
473 zero_ones[count] = ((*v & ((unsigned char)1 << k)) != 0);
474 count++;
475 }
476 }
477
478 v++;
479 }
480}
481
482/*!
483 \brief ?
484
485 Note: Only for internal use.
486
487 \param flags
488 \param cols
489 */
490void Rast__init_null_bits(unsigned char *flags, int cols)
491{
492 unsigned char *v;
493 int size;
494 int i;
495
496 /* pad the flags with 0's to make size multiple of 8 */
497 v = flags;
498 size = Rast__null_bitstream_size(cols);
499
500 for (i = 0; i < size; i++) {
501 if ((i + 1) * 8 <= cols) {
502 *v = (unsigned char)255;
503 }
504 else {
505 *v = (unsigned char)255 << ((i + 1) * 8 - cols);
506 }
507
508 v++;
509 }
510}
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition gis/zero.c:23
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
int Rast__null_bitstream_size(int)
Determines null bitstream size.
Definition alloc_cell.c:146
#define Rast_is_f_null_value(fcellVal)
size_t Rast_cell_size(RASTER_MAP_TYPE)
Returns size of a raster cell in bytes.
Definition alloc_cell.c:37
#define Rast_is_d_null_value(dcellVal)
#define Rast_is_c_null_value(cellVal)
float FCELL
Definition gis.h:636
#define FALSE
Definition gis.h:82
double DCELL
Definition gis.h:635
int CELL
Definition gis.h:634
#define _(str)
Definition glocale.h:10
int count
void Rast_set_d_null_value(DCELL *dcellVals, int numVals)
To set a number of DCELL raster values to NULL.
Definition null_val.c:153
int G__set_flags_from_01_random(const char *zero_ones, unsigned char *flags, int col, int n, int ncols)
Given array of 0/1 of length n starting from column.
Definition null_val.c:371
void Rast_set_null_value(void *buf, int numVals, RASTER_MAP_TYPE data_type)
To set one or more raster values to null.
Definition null_val.c:98
int Rast__check_null_bit(const unsigned char *flags, int bit_num, int n)
Check NULL.
Definition null_val.c:335
void Rast__init_null_bits(unsigned char *flags, int cols)
?
Definition null_val.c:490
void Rast__convert_flags_01(char *zero_ones, const unsigned char *flags, int n)
?
Definition null_val.c:457
void Rast_insert_null_values(void *rast, char *null_row, int ncols, RASTER_MAP_TYPE data_type)
To check if a CELL raster value is set to NULL.
Definition null_val.c:276
int Rast_is_null_value(const void *rast, RASTER_MAP_TYPE data_type)
To check if a raster value is set to NULL.
Definition null_val.c:176
void Rast_set_c_null_value(CELL *cellVals, int numVals)
To set a number of CELL raster values to NULL.
Definition null_val.c:124
void Rast_set_f_null_value(FCELL *fcellVals, int numVals)
To set a number of FCELL raster values to NULL.
Definition null_val.c:138
void Rast__set_null_value(void *rast, int numVals, int null_is_zero, RASTER_MAP_TYPE data_type)
To set one or more raster values to null.
Definition null_val.c:80
void Rast_insert_f_null_values(FCELL *fcellVal, char *null_row, int ncols)
To insert null values into an floating-point raster map (FCELL)
Definition null_val.c:304
void Rast__convert_01_flags(const char *zero_ones, unsigned char *flags, int n)
?
Definition null_val.c:420
void Rast_insert_d_null_values(DCELL *dcellVal, char *null_row, int ncols)
To insert null values into an floating-point raster map (FCELL)
Definition null_val.c:319
void Rast_insert_c_null_values(CELL *cellVal, char *null_row, int ncols)
To insert null values into an integer raster map (CELL)
Definition null_val.c:292
#define FCELL_TYPE
Definition raster.h:12
#define DCELL_TYPE
Definition raster.h:13
#define CELL_TYPE
Definition raster.h:11
int RASTER_MAP_TYPE
Definition raster.h:25