GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
null_val.c
Go to the documentation of this file.
00001 /*
00002  *
00003  *****************************************************************************
00004  *
00005  * MODULE:      GRASS gis library
00006  * AUTHOR(S):   Original author unknown - probably CERL
00007  *              Justin Hickey - Thailand - jhickey@hpcc.nectec.or.th
00008  * PURPOSE:     To provide functionality to handle NULL values for data types
00009  *              CELL, FCELL, and DCELL. May need more...
00010  * COPYRIGHT:    (C) 2000 by the GRASS Development Team
00011  *
00012  *               This program is free software under the GNU General Public
00013  *              License (>=v2). Read the file COPYING that comes with GRASS
00014  *              for details.
00015  *
00016  *****************************************************************************/
00017 
00018 /*============================= Include Files ==============================*/
00019 
00020 /* System include files */
00021 #include <string.h>
00022 
00023 /* Grass and local include files */
00024 #include <grass/gis.h>
00025 #include <grass/glocale.h>
00026 
00027 static int EmbedGivenNulls(void *, char *, RASTER_MAP_TYPE, int);
00028 
00029 /****************************************************************************
00030 * int EmbedGivenNulls (void *cell, char *nulls, RASTER_MAP_TYPE map_type,
00031 *   int ncols)
00032 *
00033 * PURPOSE:      To insert null values into a map. Needs more.....
00034 * INPUT VARS:   cell        =>  ??
00035 *               nulls       =>  ??
00036 *               map_type    =>  type of raster - CELL, FCELL, DCELL
00037 *               ncols       =>  ??
00038 * RETURN VAL:   ??
00039 *****************************************************************************/
00040 static int EmbedGivenNulls(void *cell, char *nulls, RASTER_MAP_TYPE map_type,
00041                            int ncols)
00042 {
00043     CELL *c;
00044     FCELL *f;
00045     DCELL *d;
00046     int i;
00047 
00048     c = (CELL *) cell;
00049     f = (FCELL *) cell;
00050     d = (DCELL *) cell;
00051 
00052     for (i = 0; i < ncols; i++) {
00053         if (nulls[i]) {
00054             switch (map_type) {
00055             case CELL_TYPE:
00056                 G_set_c_null_value((CELL *) (c + i), 1);
00057                 break;
00058 
00059             case FCELL_TYPE:
00060                 G_set_f_null_value((FCELL *) (f + i), 1);
00061                 break;
00062 
00063             case DCELL_TYPE:
00064                 G_set_d_null_value((DCELL *) (d + i), 1);
00065                 break;
00066 
00067             default:
00068                 G_warning(_("EmbedGivenNulls: wrong data type!"));
00069             }
00070         }
00071     }
00072 
00073     return 1;
00074 }
00075 
00076 /*========================== Library Functions =============================*/
00077 
00078 /****************************************************************************
00079 * void G__set_null_value (void *rast, int numVals, int null_is_zero,
00080 *   RASTER_MAP_TYPE data_type)
00081 *
00082 * PURPOSE:      To set one or more raster values to null. It also sets null
00083 *               to zero if null_is_zero is TRUE.
00084 * INPUT VARS:   rast            =>  pointer to values to set to null
00085 *               numVals         =>  number of values to set to null
00086 *               null_is_zero    =>  flag to indicate if NULL = 0
00087 *               data_type       =>  type of raster - CELL, FCELL, DCELL
00088 * RETURN VAL:   none
00089 *****************************************************************************/
00090 void G__set_null_value(void *rast, int numVals, int null_is_zero,
00091                        RASTER_MAP_TYPE data_type)
00092 {
00093     if (null_is_zero) {
00094         G_zero((char *)rast, numVals * G_raster_size(data_type));
00095         return;
00096     }
00097 
00098     G_set_null_value(rast, numVals, data_type);
00099 
00100     return;
00101 }
00102 
00103 /****************************************************************************
00104 * void G_set_null_value (void *buf, int numVals, RASTER_MAP_TYPE data_type)
00105 *
00106 * PURPOSE:      To set one or more raster values to null.
00107 * INPUT VARS:   buf         =>  pointer to values to set to null
00108 *               numVals     =>  number of values to set to null
00109 *               data_type   =>  type of raster - CELL, FCELL, DCELL
00110 * RETURN VAL:   none
00111 *****************************************************************************/
00112 void G_set_null_value(void *buf, int numVals, RASTER_MAP_TYPE data_type)
00113 {
00114     switch (data_type) {
00115     case CELL_TYPE:
00116         G_set_c_null_value((CELL *) buf, numVals);
00117         break;
00118 
00119     case FCELL_TYPE:
00120         G_set_f_null_value((FCELL *) buf, numVals);
00121         break;
00122 
00123     case DCELL_TYPE:
00124         G_set_d_null_value((DCELL *) buf, numVals);
00125         break;
00126 
00127     default:
00128         G_warning(_("G_set_null_value: wrong data type!"));
00129     }
00130 
00131     return;
00132 }
00133 
00134 /****************************************************************************
00135 * void G_set_c_null_value (CELL *cellVals, int numVals)
00136 *
00137 * PURPOSE:      To set a number of CELL raster values to NULL.
00138 * INPUT VARS:   cellVals    =>  pointer to CELL values to set to null
00139 *               numVals     =>  number of values to set to null
00140 * RETURN VAL:   none
00141 *****************************************************************************/
00142 void G_set_c_null_value(CELL *cellVals, int numVals)
00143 {
00144     int i;                      /* counter */
00145 
00146     for (i = 0; i < numVals; i++)
00147         cellVals[i] = (int) 0x80000000;
00148 }
00149 
00150 /****************************************************************************
00151 * void G_set_f_null_value (FCELL *fcellVals, int numVals)
00152 *
00153 * PURPOSE:      To set a number of FCELL raster values to NULL.
00154 * INPUT VARS:   fcellVals   =>  pointer to FCELL values to set to null
00155 *               numVals     =>  number of values to set to null
00156 * RETURN VAL:   none
00157 *****************************************************************************/
00158 void G_set_f_null_value(FCELL *fcellVals, int numVals)
00159 {
00160     static const unsigned char null_bits[4] = {
00161         0xFF, 0xFF, 0xFF, 0xFF};
00162     int i;
00163 
00164     for (i = 0; i < numVals; i++)
00165         memcpy(&fcellVals[i], null_bits, sizeof(null_bits));
00166 }
00167 
00168 /****************************************************************************
00169 * void G_set_d_null_value (DCELL *dcellVals, int numVals)
00170 *
00171 * PURPOSE:      To set a number of DCELL raster values to NULL.
00172 * INPUT VARS:   dcellVals   =>  pointer to DCELL values to set to null
00173 *               numVals     =>  number of values to set to null
00174 * RETURN VAL:   none
00175 *****************************************************************************/
00176 void G_set_d_null_value(DCELL *dcellVals, int numVals)
00177 {
00178     static const unsigned char null_bits[8] = {
00179         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
00180     int i;
00181 
00182     for (i = 0; i < numVals; i++)
00183         memcpy(&dcellVals[i], null_bits, sizeof(null_bits));
00184 }
00185 
00186 /****************************************************************************
00187 * int G_is_null_value (void *rast, RASTER_MAP_TYPE data_type)
00188 *
00189 * PURPOSE:      To check if a raster value is set to NULL
00190 * INPUT VARS:   rast        =>  raster value to check 
00191 *               data_type   =>  type of raster - CELL, FCELL, DCELL
00192 * RETURN VAL:   TRUE if raster value is NULL FALSE otherwise
00193 *****************************************************************************/
00194 
00207 int G_is_null_value(const void *rast, RASTER_MAP_TYPE data_type)
00208 {
00209     switch (data_type) {
00210     case CELL_TYPE:
00211         return (G_is_c_null_value((CELL *) rast));
00212 
00213     case FCELL_TYPE:
00214         return (G_is_f_null_value((FCELL *) rast));
00215 
00216     case DCELL_TYPE:
00217         return (G_is_d_null_value((DCELL *) rast));
00218 
00219     default:
00220         G_warning("G_is_null_value: wrong data type!");
00221         return FALSE;
00222     }
00223 }
00224 
00225 /****************************************************************************
00226 * 
00227 * int G_is_c_null_value (CELL *cellVal)
00228 *
00229 * PURPOSE:      To check if a CELL raster value is set to NULL
00230 * INPUT VARS:   cellVal    =>   CELL raster value to check
00231 * RETURN VAL:   TRUE if CELL raster value is NULL FALSE otherwise
00232 *****************************************************************************/
00233 
00244 int G_is_c_null_value(const CELL * cellVal)
00245 {
00246     /* Check if the CELL value matches the null pattern */
00247     return *cellVal == (CELL) 0x80000000;
00248 }
00249 
00250 /****************************************************************************
00251 * 
00252 * int G_is_f_null_value (FCELL *fcellVal)
00253 *
00254 * PURPOSE:      To check if a FCELL raster value is set to NULL
00255 * INPUT VARS:   fcellVal    =>  FCELL raster value to check
00256 * RETURN VAL:   TRUE if FCELL raster value is NULL FALSE otherwise
00257 *****************************************************************************/
00258 
00281 int G_is_f_null_value(const FCELL * fcellVal)
00282 {
00283     return *fcellVal != *fcellVal;
00284 }
00285 
00286 /****************************************************************************
00287 * 
00288 * int G_is_d_null_value (DCELL *dcellVal)
00289 *
00290 * PURPOSE:      To check if a DCELL raster value is set to NULL
00291 * INPUT VARS:   dcellVal    =>  DCELL raster value to check
00292 * RETURN VAL:   TRUE if DCELL raster value is NULL FALSE otherwise
00293 *****************************************************************************/
00294 
00306 int G_is_d_null_value(const DCELL * dcellVal)
00307 {
00308     return *dcellVal != *dcellVal;
00309 }
00310 
00311 /****************************************************************************
00312 * 
00313 * int G_insert_null_values (void *rast, char *null_row, int ncols,
00314 *   RASTER_MAP_TYPE data_type)
00315 *
00316 * PURPOSE:      To insert null values into a map. Needs more.....
00317 * INPUT VARS:   rast        =>  ??
00318 *               null_row    =>  ??
00319 *               ncols       =>  ??
00320 *               data_type   =>  type of raster - CELL, FCELL, DCELL
00321 * RETURN VAL:   ??
00322 *****************************************************************************/
00323 
00341 int G_insert_null_values(void *rast, char *null_row, int ncols,
00342                          RASTER_MAP_TYPE data_type)
00343 {
00344     return (EmbedGivenNulls(rast, null_row, data_type, ncols));
00345 }
00346 
00347 /****************************************************************************
00348 * 
00349 * int G_insert_c_null_values (CELL *cellVal, char *null_row, int ncols)
00350 *
00351 * PURPOSE:      To insert null values into a CELL map. Needs more.....
00352 * INPUT VARS:   cellVal     =>  ??
00353 *               null_row    =>  ??
00354 *               ncols       =>  ??
00355 * RETURN VAL:   ??
00356 *****************************************************************************/
00357 
00370 int G_insert_c_null_values(CELL * cellVal, char *null_row, int ncols)
00371 {
00372     return (EmbedGivenNulls((void *)cellVal, null_row, CELL_TYPE, ncols));
00373 }
00374 
00375 /****************************************************************************
00376 * 
00377 * int G_insert_f_null_values (FCELL *fcellVal, char *null_row, int ncols)
00378 *
00379 * PURPOSE:      To insert null values into a FCELL map. Needs more.....
00380 * INPUT VARS:   fcellVal    =>  ??
00381 *               null_row    =>  ??
00382 *               ncols       =>  ??
00383 * RETURN VAL:   ??
00384 *****************************************************************************/
00385 
00398 int G_insert_f_null_values(FCELL * fcellVal, char *null_row, int ncols)
00399 {
00400     return (EmbedGivenNulls((void *)fcellVal, null_row, FCELL_TYPE, ncols));
00401 }
00402 
00403 /****************************************************************************
00404 * 
00405 * int G_insert_d_null_values (DCELL *dcellVal, char *null_row, int ncols)
00406 *
00407 * PURPOSE:      To insert null values into a DCELL map. Needs more.....
00408 * INPUT VARS:   dcellVal    =>  ??
00409 *               null_row    =>  ??
00410 *               ncols       =>  ??
00411 * RETURN VAL:   ??
00412 *****************************************************************************/
00413 
00426 int G_insert_d_null_values(DCELL * dcellVal, char *null_row, int ncols)
00427 {
00428     return (EmbedGivenNulls((void *)dcellVal, null_row, DCELL_TYPE, ncols));
00429 }
00430 
00431 /****************************************************************************
00432 * int G__check_null_bit (unsigned char *flags, int bit_num, int n)
00433 *
00434 * PURPOSE:      To...
00435 * INPUT VARS:   flags   =>  ??
00436 *               bit_num =>  ??
00437 *               n       =>  ??
00438 * RETURN VAL:   ??
00439 *****************************************************************************/
00440 int G__check_null_bit(const unsigned char *flags, int bit_num, int n)
00441 {
00442     int ind;
00443     int offset;
00444 
00445     /* find the index of the unsigned char in which this bit appears */
00446     ind = G__null_bitstream_size(bit_num + 1) - 1;
00447 
00448     /* find how many unsigned chars the buffer with bit_num+1 (counting from 0
00449        has and subtract 1 to get unsigned char index */
00450     if (ind > G__null_bitstream_size(n) - 1) {
00451         G_warning("G__check_null_bit: can't access index %d. "
00452                   "Size of flags is %d (bit # is %d",
00453              ind, G__null_bitstream_size(n) - 1, bit_num);
00454         return -1;
00455     }
00456 
00457     offset = (ind + 1) * 8 - bit_num - 1;
00458 
00459     return ((flags[ind] & ((unsigned char)1 << offset)) != 0);
00460 }
00461 
00462 /****************************************************************************
00463 * int G__set_flags_from_01_random (char *zero_ones, unsigned char *flags, 
00464 *   int col, int n, int ncols)
00465 *
00466 * PURPOSE:      given array of 0/1 of length n starting from column col
00467 *               set the corresponding  bits of flags; total number of bits
00468 *               in flags is ncols
00469 * INPUT VARS:   zero_ones   =>  ??
00470 *               flags       =>  ??
00471 *               col         =>  ??
00472 *               n           =>  ??
00473 *               ncols       =>  ??
00474 * RETURN VAL:   ??
00475 *****************************************************************************/
00476 int G__set_flags_from_01_random(const char *zero_ones, unsigned char *flags,
00477                                 int col, int n, int ncols)
00478 {
00479     unsigned char v;
00480     int count;
00481     int size;
00482     int i, k;
00483 
00484     if (col == 0 && n == ncols) {
00485         G__convert_01_flags(zero_ones, flags, n);
00486         return 0;
00487     }
00488 
00489     count = 0;
00490     size = G__null_bitstream_size(ncols);
00491 
00492     for (i = 0; i < size; i++) {
00493         v = 0;
00494         k = 8;
00495 
00496         while (k-- > 0) {
00497             if (count >= col && count < (col + n)) {
00498                 v = v | ((unsigned char)zero_ones[count - col] << k);
00499             }
00500             else if (count < ncols) {
00501                 v = v |
00502                     ((unsigned char)G__check_null_bit(flags, count, ncols) << k);
00503             }
00504 
00505             /* otherwise  keep this bit the same as it was */
00506             count++;
00507         }
00508 
00509         flags[i] = v;
00510     }
00511 
00512     return 1;
00513 }
00514 
00515 /****************************************************************************
00516 * int G__convert_01_flags (char *zero_ones, unsigned char *flags, int n)
00517 *
00518 * PURPOSE:      To...
00519 * INPUT VARS:   zero_ones   =>  ??
00520 *               flags       =>  ??
00521 *               n           =>  ??
00522 * RETURN VAL:   ??
00523 *****************************************************************************/
00524 int G__convert_01_flags(const char *zero_ones, unsigned char *flags, int n)
00525 {
00526     unsigned char *v;
00527     int count;
00528     int size;
00529     int i, k;
00530 
00531     /* pad the flags with 0's to make size multiple of 8 */
00532     v = flags;
00533     size = G__null_bitstream_size(n);
00534     count = 0;
00535 
00536     for (i = 0; i < size; i++) {
00537         *v = 0;
00538         k = 8;
00539 
00540         while (k-- > 0) {
00541             if (count < n) {
00542                 *v = *v | ((unsigned char)zero_ones[count] << k);
00543             }
00544 
00545             count++;
00546         }
00547 
00548         v++;
00549     }
00550 
00551     return 0;
00552 }
00553 
00554 /****************************************************************************
00555 * int G__convert_flags_01 (char *zero_ones, unsigned char *flags, int n)
00556 *
00557 * PURPOSE:      To...
00558 * INPUT VARS:   zero_ones   =>  ??
00559 *               flags       =>  ??
00560 *               n           =>  ??
00561 * RETURN VAL:   ??
00562 *****************************************************************************/
00563 int G__convert_flags_01(char *zero_ones, const unsigned char *flags, int n)
00564 {
00565     const unsigned char *v;
00566     int count;
00567     int size;
00568     int i, k;
00569 
00570     count = 0;
00571     v = flags;
00572     size = G__null_bitstream_size(n);
00573 
00574     for (i = 0; i < size; i++) {
00575         k = 8;
00576 
00577         while (k-- > 0) {
00578             if (count < n) {
00579                 zero_ones[count] = ((*v & ((unsigned char)1 << k)) != 0);
00580                 count++;
00581             }
00582         }
00583 
00584         v++;
00585     }
00586 
00587     return 0;
00588 }
00589 
00590 /****************************************************************************
00591 * int G__init_null_bits (unsigned char *flags, int cols)
00592 *
00593 * PURPOSE:      To...
00594 * INPUT VARS:   flags   =>  ??
00595 *               cols    =>  ??
00596 * RETURN VAL:   ??
00597 *****************************************************************************/
00598 int G__init_null_bits(unsigned char *flags, int cols)
00599 {
00600     unsigned char *v;
00601     int size;
00602     int i;
00603 
00604     /* pad the flags with 0's to make size multiple of 8 */
00605     v = flags;
00606     size = G__null_bitstream_size(cols);
00607 
00608     for (i = 0; i < size; i++) {
00609         if ((i + 1) * 8 <= cols) {
00610             *v = (unsigned char)255;
00611         }
00612         else {
00613             *v = (unsigned char)255 << ((i + 1) * 8 - cols);
00614         }
00615 
00616         v++;
00617     }
00618 
00619     return 0;
00620 }