GRASS Programmer's Manual  6.4.4(2014)-r
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
null_val.c
Go to the documentation of this file.
1 /*
2  *
3  *****************************************************************************
4  *
5  * MODULE: GRASS gis library
6  * AUTHOR(S): Original author unknown - probably CERL
7  * Justin Hickey - Thailand - jhickey@hpcc.nectec.or.th
8  * PURPOSE: To provide functionality to handle NULL values for data types
9  * CELL, FCELL, and DCELL. May need more...
10  * COPYRIGHT: (C) 2000 by the GRASS Development Team
11  *
12  * This program is free software under the GNU General Public
13  * License (>=v2). Read the file COPYING that comes with GRASS
14  * for details.
15  *
16  *****************************************************************************/
17 
18 /*============================= Include Files ==============================*/
19 
20 /* System include files */
21 #include <string.h>
22 
23 /* Grass and local include files */
24 #include <grass/gis.h>
25 #include <grass/glocale.h>
26 
27 /*======================= Internal Constants/Defines =======================*/
28 
29 /* none */
30 
31 /*========================== Internal Typedefs =============================*/
32 
33 /* none */
34 
35 /*====================== Static Variable Declaration =======================*/
36 
37 /* Null pattern variables */
38 static CELL cellNullPattern;
39 static FCELL fcellNullPattern;
40 static DCELL dcellNullPattern;
41 
42 /* Flag to indicate null patterns are initialized */
43 static int initialized = FALSE;
44 
45 /*============================== Prototypes ================================*/
46 
47 static int EmbedGivenNulls(void *, char *, RASTER_MAP_TYPE, int);
48 static void InitError(void);
49 
50 /*======================= Internal Static Functions ========================*/
51 
52 /****************************************************************************
53 * int EmbedGivenNulls (void *cell, char *nulls, RASTER_MAP_TYPE map_type,
54 * int ncols)
55 *
56 * PURPOSE: To insert null values into a map. Needs more.....
57 * INPUT VARS: cell => ??
58 * nulls => ??
59 * map_type => type of raster - CELL, FCELL, DCELL
60 * ncols => ??
61 * RETURN VAL: ??
62 *****************************************************************************/
63 static int EmbedGivenNulls(void *cell, char *nulls, RASTER_MAP_TYPE map_type,
64  int ncols)
65 {
66  CELL *c;
67  FCELL *f;
68  DCELL *d;
69  int i;
70 
71  c = (CELL *) cell;
72  f = (FCELL *) cell;
73  d = (DCELL *) cell;
74 
75  for (i = 0; i < ncols; i++) {
76  if (nulls[i]) {
77  switch (map_type) {
78  case CELL_TYPE:
79  G_set_c_null_value((CELL *) (c + i), 1);
80  break;
81 
82  case FCELL_TYPE:
83  G_set_f_null_value((FCELL *) (f + i), 1);
84  break;
85 
86  case DCELL_TYPE:
87  G_set_d_null_value((DCELL *) (d + i), 1);
88  break;
89 
90  default:
91  G_warning(_("EmbedGivenNulls: wrong data type!"));
92  }
93  }
94  }
95 
96  return 1;
97 }
98 
99 /****************************************************************************
100 * void InitError (void)
101 *
102 * PURPOSE: To print an error message and exit the program. This function
103 * is called if something tries to access a null pattern before
104 * it is initialized.
105 * INPUT VARS: none
106 * RETURN VAL: none
107 *****************************************************************************/
108 static void InitError(void)
109 {
110  char errMsg[512]; /* array to hold error message */
111 
112  strcpy(errMsg, _("Null values have not been initialized. "));
113  strcat(errMsg, _("G_gisinit() must be called first. "));
114  strcat(errMsg, _("Please advise GRASS developers of this error.\n"));
115  G_fatal_error(errMsg);
116 
117  return;
118 }
119 
120 /*========================== Library Functions =============================*/
121 
122 /****************************************************************************
123 * void G__init_null_patterns (void)
124 *
125 * PURPOSE: To initialize the three null patterns for CELL, FCELL, and
126 * DCELL data types. It also sets the initialized flag to TRUE.
127 * This function is called by G_gisinit()
128 * INPUT VARS: none
129 * RETURN VAL: none
130 *****************************************************************************/
132 {
133  unsigned char *bytePtr; /* pointer to traverse FCELL and DCELL */
134  int numBits; /* number of bits for CELL type */
135  int i; /* counter */
136 
137  if (!initialized) {
138  /* Create the null pattern for the CELL data type - set the left */
139  /* most bit to 1 and the rest to 0, basically INT_MIN. Since CELL is */
140  /* some type of integer the bytes are not split into exponent and */
141  /* mantissa. Thus a simple left shift can be used */
142  numBits = sizeof(CELL) * 8;
143 
144  cellNullPattern = 1 << (numBits - 1);
145 
146  /* Create the null pattern for the FCELL data type - set all bits */
147  /* to 1, basically NaN. Need to use a byte pointer since bytes */
148  /* represent the exponent and mantissa */
149  bytePtr = (unsigned char *)&fcellNullPattern;
150 
151  for (i = 0; i < sizeof(FCELL); i++) {
152  *bytePtr = (unsigned char)255;
153  bytePtr++;
154  }
155 
156  /* Create the null pattern for the DCELL data type - set all bits */
157  /* to 1, basically NaN. Need to use a byte pointer since bytes */
158  /* represent the exponent and mantissa */
159  bytePtr = (unsigned char *)&dcellNullPattern;
160 
161  for (i = 0; i < sizeof(DCELL); i++) {
162  *bytePtr = (unsigned char)255;
163  bytePtr++;
164  }
165 
166  /* Set the initialized flag to TRUE */
167  initialized = TRUE;
168  }
169 
170  return;
171 }
172 
173 /****************************************************************************
174 * void G__set_null_value (void *rast, int numVals, int null_is_zero,
175 * RASTER_MAP_TYPE data_type)
176 *
177 * PURPOSE: To set one or more raster values to null. It also sets null
178 * to zero if null_is_zero is TRUE.
179 * INPUT VARS: rast => pointer to values to set to null
180 * numVals => number of values to set to null
181 * null_is_zero => flag to indicate if NULL = 0
182 * data_type => type of raster - CELL, FCELL, DCELL
183 * RETURN VAL: none
184 *****************************************************************************/
185 void G__set_null_value(void *rast, int numVals, int null_is_zero,
186  RASTER_MAP_TYPE data_type)
187 {
188  if (null_is_zero) {
189  G_zero((char *)rast, numVals * G_raster_size(data_type));
190  return;
191  }
192 
193  G_set_null_value(rast, numVals, data_type);
194 
195  return;
196 }
197 
198 /****************************************************************************
199 * void G_set_null_value (void *buf, int numVals, RASTER_MAP_TYPE data_type)
200 *
201 * PURPOSE: To set one or more raster values to null.
202 * INPUT VARS: buf => pointer to values to set to null
203 * numVals => number of values to set to null
204 * data_type => type of raster - CELL, FCELL, DCELL
205 * RETURN VAL: none
206 *****************************************************************************/
207 void G_set_null_value(void *buf, int numVals, RASTER_MAP_TYPE data_type)
208 {
209  switch (data_type) {
210  case CELL_TYPE:
211  G_set_c_null_value((CELL *) buf, numVals);
212  break;
213 
214  case FCELL_TYPE:
215  G_set_f_null_value((FCELL *) buf, numVals);
216  break;
217 
218  case DCELL_TYPE:
219  G_set_d_null_value((DCELL *) buf, numVals);
220  break;
221 
222  default:
223  G_warning(_("G_set_null_value: wrong data type!"));
224  }
225 
226  return;
227 }
228 
229 /****************************************************************************
230 * void G_set_c_null_value (CELL *cellVals, int numVals)
231 *
232 * PURPOSE: To set a number of CELL raster values to NULL.
233 * INPUT VARS: cellVals => pointer to CELL values to set to null
234 * numVals => number of values to set to null
235 * RETURN VAL: none
236 *****************************************************************************/
237 void G_set_c_null_value(CELL * cellVals, int numVals)
238 {
239  CELL *cellPtr; /* pointer to CELL array to set to null */
240  int i; /* counter */
241 
242  /* Check if the null patterns have been initialized */
243  if (!initialized) {
244  InitError();
245  }
246 
247  /* Set numVals consecutive CELL values to null */
248  cellPtr = cellVals;
249 
250  for (i = 0; i < numVals; i++) {
251  *cellPtr = cellNullPattern;
252  cellPtr++;
253  }
254 
255  return;
256 }
257 
258 /****************************************************************************
259 * void G_set_f_null_value (FCELL *fcellVals, int numVals)
260 *
261 * PURPOSE: To set a number of FCELL raster values to NULL.
262 * INPUT VARS: fcellVals => pointer to FCELL values to set to null
263 * numVals => number of values to set to null
264 * RETURN VAL: none
265 *****************************************************************************/
266 void G_set_f_null_value(FCELL * fcellVals, int numVals)
267 {
268  FCELL *fcellPtr; /* pointer to FCELL array to set to null */
269  int i; /* counter */
270 
271  /* Check if the null patterns have been initialized */
272  if (!initialized) {
273  InitError();
274  }
275 
276  /* Set numVals consecutive FCELL values to null */
277  fcellPtr = fcellVals;
278 
279  for (i = 0; i < numVals; i++) {
280  *fcellPtr = fcellNullPattern;
281  fcellPtr++;
282  }
283 
284  return;
285 }
286 
287 /****************************************************************************
288 * void G_set_d_null_value (DCELL *dcellVals, int numVals)
289 *
290 * PURPOSE: To set a number of DCELL raster values to NULL.
291 * INPUT VARS: dcellVals => pointer to DCELL values to set to null
292 * numVals => number of values to set to null
293 * RETURN VAL: none
294 *****************************************************************************/
295 void G_set_d_null_value(DCELL * dcellVals, int numVals)
296 {
297  DCELL *dcellPtr; /* pointer to DCELL array to set to null */
298  int i; /* counter */
299 
300  /* Check if the null patterns have been initialized */
301  if (!initialized) {
302  InitError();
303  }
304 
305  /* Set numVals consecutive DCELL values to null */
306  dcellPtr = dcellVals;
307 
308  for (i = 0; i < numVals; i++) {
309  *dcellPtr = dcellNullPattern;
310  dcellPtr++;
311  }
312 
313  return;
314 }
315 
316 /****************************************************************************
317 * int G_is_null_value (void *rast, RASTER_MAP_TYPE data_type)
318 *
319 * PURPOSE: To check if a raster value is set to NULL
320 * INPUT VARS: rast => raster value to check
321 * data_type => type of raster - CELL, FCELL, DCELL
322 * RETURN VAL: TRUE if raster value is NULL FALSE otherwise
323 *****************************************************************************/
324 
337 int G_is_null_value(const void *rast, RASTER_MAP_TYPE data_type)
338 {
339  switch (data_type) {
340  case CELL_TYPE:
341  return (G_is_c_null_value((CELL *) rast));
342 
343  case FCELL_TYPE:
344  return (G_is_f_null_value((FCELL *) rast));
345 
346  case DCELL_TYPE:
347  return (G_is_d_null_value((DCELL *) rast));
348 
349  default:
350  G_warning("G_is_null_value: wrong data type!");
351  return FALSE;
352  }
353 }
354 
355 /****************************************************************************
356 *
357 * int G_is_c_null_value (CELL *cellVal)
358 *
359 * PURPOSE: To check if a CELL raster value is set to NULL
360 * INPUT VARS: cellVal => CELL raster value to check
361 * RETURN VAL: TRUE if CELL raster value is NULL FALSE otherwise
362 *****************************************************************************/
363 
374 int G_is_c_null_value(const CELL * cellVal)
375 {
376  int i; /* counter */
377 
378  /* Check if the null patterns have been initialized */
379  if (!initialized) {
380  InitError();
381  }
382 
383  /* Check if the CELL value matches the null pattern */
384  for (i = 0; i < sizeof(CELL); i++) {
385  if (((unsigned char *)cellVal)[i] !=
386  ((unsigned char *)&cellNullPattern)[i]) {
387  return FALSE;
388  }
389  }
390 
391  return TRUE;
392 }
393 
394 /****************************************************************************
395 *
396 * int G_is_f_null_value (FCELL *fcellVal)
397 *
398 * PURPOSE: To check if a FCELL raster value is set to NULL
399 * INPUT VARS: fcellVal => FCELL raster value to check
400 * RETURN VAL: TRUE if FCELL raster value is NULL FALSE otherwise
401 *****************************************************************************/
402 
425 int G_is_f_null_value(const FCELL * fcellVal)
426 {
427  return *fcellVal != *fcellVal;
428 }
429 
430 /****************************************************************************
431 *
432 * int G_is_d_null_value (DCELL *dcellVal)
433 *
434 * PURPOSE: To check if a DCELL raster value is set to NULL
435 * INPUT VARS: dcellVal => DCELL raster value to check
436 * RETURN VAL: TRUE if DCELL raster value is NULL FALSE otherwise
437 *****************************************************************************/
438 
450 int G_is_d_null_value(const DCELL * dcellVal)
451 {
452  return *dcellVal != *dcellVal;
453 }
454 
455 /****************************************************************************
456 *
457 * int G_insert_null_values (void *rast, char *null_row, int ncols,
458 * RASTER_MAP_TYPE data_type)
459 *
460 * PURPOSE: To insert null values into a map. Needs more.....
461 * INPUT VARS: rast => ??
462 * null_row => ??
463 * ncols => ??
464 * data_type => type of raster - CELL, FCELL, DCELL
465 * RETURN VAL: ??
466 *****************************************************************************/
467 
485 int G_insert_null_values(void *rast, char *null_row, int ncols,
486  RASTER_MAP_TYPE data_type)
487 {
488  return (EmbedGivenNulls(rast, null_row, data_type, ncols));
489 }
490 
491 /****************************************************************************
492 *
493 * int G_insert_c_null_values (CELL *cellVal, char *null_row, int ncols)
494 *
495 * PURPOSE: To insert null values into a CELL map. Needs more.....
496 * INPUT VARS: cellVal => ??
497 * null_row => ??
498 * ncols => ??
499 * RETURN VAL: ??
500 *****************************************************************************/
501 
514 int G_insert_c_null_values(CELL * cellVal, char *null_row, int ncols)
515 {
516  return (EmbedGivenNulls((void *)cellVal, null_row, CELL_TYPE, ncols));
517 }
518 
519 /****************************************************************************
520 *
521 * int G_insert_f_null_values (FCELL *fcellVal, char *null_row, int ncols)
522 *
523 * PURPOSE: To insert null values into a FCELL map. Needs more.....
524 * INPUT VARS: fcellVal => ??
525 * null_row => ??
526 * ncols => ??
527 * RETURN VAL: ??
528 *****************************************************************************/
529 
542 int G_insert_f_null_values(FCELL * fcellVal, char *null_row, int ncols)
543 {
544  return (EmbedGivenNulls((void *)fcellVal, null_row, FCELL_TYPE, ncols));
545 }
546 
547 /****************************************************************************
548 *
549 * int G_insert_d_null_values (DCELL *dcellVal, char *null_row, int ncols)
550 *
551 * PURPOSE: To insert null values into a DCELL map. Needs more.....
552 * INPUT VARS: dcellVal => ??
553 * null_row => ??
554 * ncols => ??
555 * RETURN VAL: ??
556 *****************************************************************************/
557 
570 int G_insert_d_null_values(DCELL * dcellVal, char *null_row, int ncols)
571 {
572  return (EmbedGivenNulls((void *)dcellVal, null_row, DCELL_TYPE, ncols));
573 }
574 
575 /****************************************************************************
576 * int G__check_null_bit (unsigned char *flags, int bit_num, int n)
577 *
578 * PURPOSE: To...
579 * INPUT VARS: flags => ??
580 * bit_num => ??
581 * n => ??
582 * RETURN VAL: ??
583 *****************************************************************************/
584 int G__check_null_bit(const unsigned char *flags, int bit_num, int n)
585 {
586  int ind;
587  int offset;
588 
589  /* find the index of the unsigned char in which this bit appears */
590  ind = G__null_bitstream_size(bit_num + 1) - 1;
591 
592  /* find how many unsigned chars the buffer with bit_num+1 (counting from 0
593  has and subtract 1 to get unsigned char index */
594  if (ind > G__null_bitstream_size(n) - 1) {
595  G_warning("G__check_null_bit: can't access index %d. "
596  "Size of flags is %d (bit # is %d",
597  ind, G__null_bitstream_size(n) - 1, bit_num);
598  return -1;
599  }
600 
601  offset = (ind + 1) * 8 - bit_num - 1;
602 
603  return ((flags[ind] & ((unsigned char)1 << offset)) != 0);
604 }
605 
606 /****************************************************************************
607 * int G__set_flags_from_01_random (char *zero_ones, unsigned char *flags,
608 * int col, int n, int ncols)
609 *
610 * PURPOSE: given array of 0/1 of length n starting from column col
611 * set the corresponding bits of flags; total number of bits
612 * in flags is ncols
613 * INPUT VARS: zero_ones => ??
614 * flags => ??
615 * col => ??
616 * n => ??
617 * ncols => ??
618 * RETURN VAL: ??
619 *****************************************************************************/
620 int G__set_flags_from_01_random(const char *zero_ones, unsigned char *flags,
621  int col, int n, int ncols)
622 {
623  unsigned char v;
624  int count;
625  int size;
626  int i, k;
627 
628  if (col == 0 && n == ncols) {
629  G__convert_01_flags(zero_ones, flags, n);
630  return 0;
631  }
632 
633  count = 0;
634  size = G__null_bitstream_size(ncols);
635 
636  for (i = 0; i < size; i++) {
637  v = 0;
638  k = 8;
639 
640  while (k-- > 0) {
641  if (count >= col && count < (col + n)) {
642  v = v | ((unsigned char)zero_ones[count - col] << k);
643  }
644  else if (count < ncols) {
645  v = v |
646  ((unsigned char)G__check_null_bit(flags, count, ncols) << k);
647  }
648 
649  /* otherwise keep this bit the same as it was */
650  count++;
651  }
652 
653  flags[i] = v;
654  }
655 
656  return 1;
657 }
658 
659 /****************************************************************************
660 * int G__convert_01_flags (char *zero_ones, unsigned char *flags, int n)
661 *
662 * PURPOSE: To...
663 * INPUT VARS: zero_ones => ??
664 * flags => ??
665 * n => ??
666 * RETURN VAL: ??
667 *****************************************************************************/
668 int G__convert_01_flags(const char *zero_ones, unsigned char *flags, int n)
669 {
670  unsigned char *v;
671  int count;
672  int size;
673  int i, k;
674 
675  /* pad the flags with 0's to make size multiple of 8 */
676  v = flags;
677  size = G__null_bitstream_size(n);
678  count = 0;
679 
680  for (i = 0; i < size; i++) {
681  *v = 0;
682  k = 8;
683 
684  while (k-- > 0) {
685  if (count < n) {
686  *v = *v | ((unsigned char)zero_ones[count] << k);
687  }
688 
689  count++;
690  }
691 
692  v++;
693  }
694 
695  return 0;
696 }
697 
698 /****************************************************************************
699 * int G__convert_flags_01 (char *zero_ones, unsigned char *flags, int n)
700 *
701 * PURPOSE: To...
702 * INPUT VARS: zero_ones => ??
703 * flags => ??
704 * n => ??
705 * RETURN VAL: ??
706 *****************************************************************************/
707 int G__convert_flags_01(char *zero_ones, const unsigned char *flags, int n)
708 {
709  const unsigned char *v;
710  int count;
711  int size;
712  int i, k;
713 
714  count = 0;
715  v = flags;
716  size = G__null_bitstream_size(n);
717 
718  for (i = 0; i < size; i++) {
719  k = 8;
720 
721  while (k-- > 0) {
722  if (count < n) {
723  zero_ones[count] = ((*v & ((unsigned char)1 << k)) != 0);
724  count++;
725  }
726  }
727 
728  v++;
729  }
730 
731  return 0;
732 }
733 
734 /****************************************************************************
735 * int G__init_null_bits (unsigned char *flags, int cols)
736 *
737 * PURPOSE: To...
738 * INPUT VARS: flags => ??
739 * cols => ??
740 * RETURN VAL: ??
741 *****************************************************************************/
742 int G__init_null_bits(unsigned char *flags, int cols)
743 {
744  unsigned char *v;
745  int size;
746  int i;
747 
748  /* pad the flags with 0's to make size multiple of 8 */
749  v = flags;
750  size = G__null_bitstream_size(cols);
751 
752  for (i = 0; i < size; i++) {
753  if ((i + 1) * 8 <= cols) {
754  *v = (unsigned char)255;
755  }
756  else {
757  *v = (unsigned char)255 << ((i + 1) * 8 - cols);
758  }
759 
760  v++;
761  }
762 
763  return 0;
764 }
int G_is_c_null_value(const CELL *cellVal)
Returns 1 if cell is NULL, 0 otherwise. This will test if the value cell is the largest int...
Definition: null_val.c:374
void G__set_null_value(void *rast, int numVals, int null_is_zero, RASTER_MAP_TYPE data_type)
Definition: null_val.c:185
#define FALSE
Definition: dbfopen.c:117
void G_set_d_null_value(DCELL *dcellVals, int numVals)
Definition: null_val.c:295
int count
int G__set_flags_from_01_random(const char *zero_ones, unsigned char *flags, int col, int n, int ncols)
Definition: null_val.c:620
int G_warning(const char *msg,...)
Print a warning message to stderr.
tuple size
value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
Definition: tools.py:2334
int G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition: gis/zero.c:29
void G__init_null_patterns(void)
Definition: null_val.c:131
int G_is_d_null_value(const DCELL *dcellVal)
Returns 1 if dcell is NULL, 0 otherwise. This will test if the value dcell is a NaN. Same test as in G_is_f_null_value().
Definition: null_val.c:450
int G_is_f_null_value(const FCELL *fcellVal)
Returns 1 if fcell is NULL, 0 otherwise. This will test if the value fcell is a NaN. It isn't good enough to test for a particular NaN bit pattern since the machine code may change this bit pattern to a different NaN. The test will be.
Definition: null_val.c:425
#define TRUE
Definition: dbfopen.c:118
int G_insert_null_values(void *rast, char *null_row, int ncols, RASTER_MAP_TYPE data_type)
Insert NULL value.
Definition: null_val.c:485
size_t G_raster_size(RASTER_MAP_TYPE data_type)
Returns size of a raster CELL in bytes.
Definition: alloc_cell.c:38
int G__convert_01_flags(const char *zero_ones, unsigned char *flags, int n)
Definition: null_val.c:668
int G__init_null_bits(unsigned char *flags, int cols)
Definition: null_val.c:742
int G_insert_d_null_values(DCELL *dcellVal, char *null_row, int ncols)
Insert DCELL NULL value.
Definition: null_val.c:570
int G__convert_flags_01(char *zero_ones, const unsigned char *flags, int n)
Definition: null_val.c:707
int G_insert_f_null_values(FCELL *fcellVal, char *null_row, int ncols)
Insert FCELL NULL value.
Definition: null_val.c:542
void G_set_f_null_value(FCELL *fcellVals, int numVals)
Definition: null_val.c:266
int G__null_bitstream_size(int cols)
Determines null bitstream size.
Definition: alloc_cell.c:171
void G_set_null_value(void *buf, int numVals, RASTER_MAP_TYPE data_type)
Definition: null_val.c:207
tuple cols
void G_set_c_null_value(CELL *cellVals, int numVals)
Definition: null_val.c:237
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int G__check_null_bit(const unsigned char *flags, int bit_num, int n)
Definition: null_val.c:584
int G_is_null_value(const void *rast, RASTER_MAP_TYPE data_type)
If the data_type is CELL_TYPE, calls G_is_c_null_value ((CELL *) rast); If the data_type is FCELL_TYP...
Definition: null_val.c:337
int G_insert_c_null_values(CELL *cellVal, char *null_row, int ncols)
Insert CELL NULL value.
Definition: null_val.c:514