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