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 "gis.h"
00025 #include "glocale.h"
00026 
00027 /*======================= Internal Constants/Defines =======================*/
00028 
00029 /* none */
00030 
00031 /*========================== Internal Typedefs =============================*/
00032 
00033 /* none */
00034 
00035 /*====================== Static Variable Declaration =======================*/
00036 
00037 /* Null pattern variables */
00038 static CELL     cellNullPattern;
00039 static FCELL    fcellNullPattern;
00040 static DCELL    dcellNullPattern;
00041 
00042 /* Flag to indicate null patterns are initialized */
00043 static int      initialized = FALSE;
00044 
00045 /*============================== Prototypes ================================*/
00046 
00047 static int EmbedGivenNulls (void *, char *, RASTER_MAP_TYPE, int);
00048 static void InitError (void);
00049 
00050 /*======================= Internal Static Functions ========================*/
00051 
00052 /****************************************************************************
00053 * int EmbedGivenNulls (void *cell, char *nulls, RASTER_MAP_TYPE map_type,
00054 *   int ncols)
00055 *
00056 * PURPOSE:      To insert null values into a map. Needs more.....
00057 * INPUT VARS:   cell        =>  ??
00058 *               nulls       =>  ??
00059 *               map_type    =>  type of raster - CELL, FCELL, DCELL
00060 *               ncols       =>  ??
00061 * RETURN VAL:   ??
00062 *****************************************************************************/
00063 static int EmbedGivenNulls (void *cell, char *nulls, RASTER_MAP_TYPE map_type,
00064     int ncols)
00065 {
00066     CELL    *c;
00067     FCELL   *f;
00068     DCELL   *d;
00069     int     i;
00070 
00071     c = (CELL *) cell;
00072     f = (FCELL *) cell;
00073     d = (DCELL *) cell;
00074 
00075     for(i = 0; i < ncols; i++)
00076     {
00077         if(nulls[i])
00078         {
00079             switch (map_type)
00080             {
00081                 case CELL_TYPE:
00082                     G_set_c_null_value((CELL *) (c + i), 1);
00083                     break;
00084             
00085                 case FCELL_TYPE:
00086                     G_set_f_null_value((FCELL *) (f + i), 1);
00087                     break;
00088             
00089                 case DCELL_TYPE:
00090                     G_set_d_null_value((DCELL *) (d + i), 1);
00091                     break;
00092                 
00093                 default:
00094                     G_warning(_("EmbedGivenNulls: wrong data type!"));
00095             }
00096         }
00097     }
00098     
00099     return 1;
00100 }
00101 
00102 /****************************************************************************
00103 * void InitError (void)
00104 *
00105 * PURPOSE:      To print an error message and exit the program. This function
00106 *               is called if something tries to access a null pattern before
00107 *               it is initialized.
00108 * INPUT VARS:   none
00109 * RETURN VAL:   none
00110 *****************************************************************************/
00111 static void InitError (void)
00112 {
00113     char    errMsg[512];    /* array to hold error message */
00114     
00115     strcpy(errMsg, _("Null values have not been initialized. "));
00116     strcat(errMsg, _("G_gisinit() must be called first. "));
00117     strcat(errMsg, _("Please advise GRASS developers of this error.\n"));
00118     G_fatal_error(errMsg);
00119 
00120     return;
00121 } 
00122 
00123 /*========================== Library Functions =============================*/
00124 
00125 /****************************************************************************
00126 * void G__init_null_patterns (void)
00127 *
00128 * PURPOSE:      To initialize the three null patterns for CELL, FCELL, and
00129 *               DCELL data types. It also sets the initialized flag to TRUE.
00130 *               This function is called by G_gisinit()
00131 * INPUT VARS:   none
00132 * RETURN VAL:   none
00133 *****************************************************************************/
00134 void G__init_null_patterns (void)
00135 {
00136     unsigned char   *bytePtr;       /* pointer to traverse FCELL and DCELL */
00137     int             numBits;        /* number of bits for CELL type */
00138     int             i;              /* counter */
00139     
00140     if (!initialized)
00141     {
00142         /* Create the null pattern for the CELL data type - set the left */
00143         /* most bit to 1 and the rest to 0, basically INT_MIN. Since CELL is */
00144         /* some type of integer the bytes are not split into exponent and */
00145         /* mantissa. Thus a simple left shift can be used */
00146         numBits = sizeof(CELL) * 8;
00147     
00148         cellNullPattern = 1 << (numBits - 1);
00149 
00150         /* Create the null pattern for the FCELL data type - set all bits */
00151         /* to 1, basically NaN. Need to use a byte pointer since bytes */
00152         /* represent the exponent and mantissa */
00153         bytePtr = (unsigned char *) &fcellNullPattern;
00154 
00155         for (i = 0; i < sizeof(FCELL); i++)
00156         {
00157             *bytePtr = (unsigned char) 255;
00158             bytePtr++;
00159         }
00160 
00161         /* Create the null pattern for the DCELL data type - set all bits */
00162         /* to 1, basically NaN. Need to use a byte pointer since bytes */
00163         /* represent the exponent and mantissa */
00164         bytePtr = (unsigned char *) &dcellNullPattern;
00165     
00166         for (i = 0; i < sizeof(DCELL); i++)
00167         {
00168             *bytePtr = (unsigned char) 255;
00169             bytePtr++;
00170         }
00171 
00172         /* Set the initialized flag to TRUE */
00173         initialized = TRUE;
00174     }
00175     
00176     return;
00177 }
00178 
00179 /****************************************************************************
00180 * void G__set_null_value (void *rast, int numVals, int null_is_zero,
00181 *   RASTER_MAP_TYPE data_type)
00182 *
00183 * PURPOSE:      To set one or more raster values to null. It also sets null
00184 *               to zero if null_is_zero is TRUE.
00185 * INPUT VARS:   rast            =>  pointer to values to set to null
00186 *               numVals         =>  number of values to set to null
00187 *               null_is_zero    =>  flag to indicate if NULL = 0
00188 *               data_type       =>  type of raster - CELL, FCELL, DCELL
00189 * RETURN VAL:   none
00190 *****************************************************************************/
00191 void G__set_null_value (void *rast, int numVals, int null_is_zero,
00192     RASTER_MAP_TYPE data_type)
00193 {
00194     if (null_is_zero)
00195     {
00196         G_zero((char *) rast, numVals * G_raster_size(data_type));
00197         return;
00198     }
00199     
00200     G_set_null_value(rast, numVals, data_type);
00201 
00202     return;
00203 } 
00204 
00205 /****************************************************************************
00206 * void G_set_null_value (void *buf, int numVals, RASTER_MAP_TYPE data_type)
00207 *
00208 * PURPOSE:      To set one or more raster values to null.
00209 * INPUT VARS:   rast        =>  pointer to values to set to null
00210 *               numVals     =>  number of values to set to null
00211 *               data_type   =>  type of raster - CELL, FCELL, DCELL
00212 * RETURN VAL:   none
00213 *****************************************************************************/
00214 void G_set_null_value (void *buf, int numVals, RASTER_MAP_TYPE data_type)
00215 {
00216     switch (data_type)
00217     {
00218         case CELL_TYPE:
00219             G_set_c_null_value((CELL *) buf, numVals);
00220             break;
00221             
00222         case FCELL_TYPE:
00223             G_set_f_null_value((FCELL *) buf, numVals);
00224             break;
00225             
00226         case DCELL_TYPE:
00227             G_set_d_null_value((DCELL *) buf, numVals);
00228             break;
00229                 
00230         default:
00231             G_warning(_("G_set_null_value: wrong data type!"));
00232     }
00233 
00234     return;
00235 } 
00236 
00237 /****************************************************************************
00238 * void G_set_c_null_value (CELL *cellVals, int numVals)
00239 *
00240 * PURPOSE:      To set a number of CELL raster values to NULL.
00241 * INPUT VARS:   cellVals    =>  pointer to CELL values to set to null
00242 *               numVals     =>  number of values to set to null
00243 * RETURN VAL:   none
00244 *****************************************************************************/
00245 void G_set_c_null_value (CELL *cellVals, int numVals)
00246 {
00247     CELL    *cellPtr;       /* pointer to CELL array to set to null */
00248     int     i;              /* counter */
00249     
00250     /* Check if the null patterns have been initialized */
00251     if (!initialized)
00252     {
00253         InitError();
00254     }
00255     
00256     /* Set numVals consecutive CELL values to null */
00257     cellPtr = cellVals;
00258     
00259     for (i = 0; i < numVals; i++)
00260     {
00261         *cellPtr = cellNullPattern;
00262         cellPtr++;
00263     }
00264     
00265     return;
00266 } 
00267 
00268 /****************************************************************************
00269 * void G_set_f_null_value (FCELL *fcellVals, int numVals)
00270 *
00271 * PURPOSE:      To set a number of FCELL raster values to NULL.
00272 * INPUT VARS:   fcellVals   =>  pointer to FCELL values to set to null
00273 *               numVals     =>  number of values to set to null
00274 * RETURN VAL:   none
00275 *****************************************************************************/
00276 void G_set_f_null_value (FCELL *fcellVals, int numVals)
00277 {
00278     FCELL   *fcellPtr;      /* pointer to FCELL array to set to null */
00279     int     i;              /* counter */
00280     
00281     /* Check if the null patterns have been initialized */
00282     if (!initialized)
00283     {
00284         InitError();
00285     }
00286     
00287     /* Set numVals consecutive FCELL values to null */
00288     fcellPtr = fcellVals;
00289     
00290     for (i = 0; i < numVals; i++)
00291     {
00292         *fcellPtr = fcellNullPattern;
00293         fcellPtr++;
00294     }
00295 
00296     return;
00297 } 
00298 
00299 /****************************************************************************
00300 * void G_set_d_null_value (DCELL *dcellVals, int numVals)
00301 *
00302 * PURPOSE:      To set a number of DCELL raster values to NULL.
00303 * INPUT VARS:   dcellVals   =>  pointer to DCELL values to set to null
00304 *               numVals     =>  number of values to set to null
00305 * RETURN VAL:   none
00306 *****************************************************************************/
00307 void G_set_d_null_value (DCELL *dcellVals, int numVals)
00308 {
00309     DCELL   *dcellPtr;      /* pointer to DCELL array to set to null */
00310     int     i;              /* counter */
00311     
00312     /* Check if the null patterns have been initialized */
00313     if (!initialized)
00314     {
00315         InitError();
00316     }
00317     
00318     /* Set numVals consecutive DCELL values to null */
00319     dcellPtr = dcellVals;
00320     
00321     for (i = 0; i < numVals; i++)
00322     {
00323         *dcellPtr = dcellNullPattern;
00324         dcellPtr++;
00325     }
00326     
00327     return;
00328 } 
00329 
00330 /****************************************************************************
00331 * int G_is_null_value (void *rast, RASTER_MAP_TYPE data_type)
00332 *
00333 * PURPOSE:      To check if a raster value is set to NULL
00334 * INPUT VARS:   rast        =>  raster value to check 
00335 *               data_type   =>  type of raster - CELL, FCELL, DCELL
00336 * RETURN VAL:   TRUE if raster value is NULL FALSE otherwise
00337 *****************************************************************************/
00338 
00354 int G_is_null_value (const void *rast, RASTER_MAP_TYPE data_type)
00355 {
00356     switch(data_type)
00357     {
00358         case CELL_TYPE:
00359             return (G_is_c_null_value((CELL *) rast));
00360         
00361         case FCELL_TYPE:
00362             return (G_is_f_null_value((FCELL *) rast));
00363         
00364         case DCELL_TYPE:
00365             return (G_is_d_null_value((DCELL *) rast));
00366         
00367         default:
00368             G_warning("G_is_null_value: wrong data type!");
00369             return FALSE;
00370     }
00371 }
00372 
00373 /****************************************************************************
00374 * 
00375 * int G_is_c_null_value (CELL *cellVal)
00376 *
00377 * PURPOSE:      To check if a CELL raster value is set to NULL
00378 * INPUT VARS:   cellVal    =>   CELL raster value to check
00379 * RETURN VAL:   TRUE if CELL raster value is NULL FALSE otherwise
00380 *****************************************************************************/
00381 
00392 int G_is_c_null_value (const CELL *cellVal)
00393 {
00394     int     i;      /* counter */
00395 
00396     /* Check if the null patterns have been initialized */
00397     if (!initialized)
00398     {
00399         InitError();
00400     }
00401     
00402     /* Check if the CELL value matches the null pattern */
00403     for(i = 0; i < sizeof (CELL); i++)
00404     {
00405         if(((unsigned char *) cellVal)[i] !=
00406             ((unsigned char *) &cellNullPattern)[i])
00407         {
00408             return FALSE;
00409         }
00410     }
00411     
00412     return TRUE;
00413 }
00414 
00415 /****************************************************************************
00416 * 
00417 * int G_is_f_null_value (FCELL *fcellVal)
00418 *
00419 * PURPOSE:      To check if a FCELL raster value is set to NULL
00420 * INPUT VARS:   fcellVal    =>  FCELL raster value to check
00421 * RETURN VAL:   TRUE if FCELL raster value is NULL FALSE otherwise
00422 *****************************************************************************/
00423 
00446 int G_is_f_null_value (const FCELL *fcellVal)
00447 {
00448     int     i;      /* counter */
00449 
00450     /* Check if the null patterns have been initialized */
00451     if (!initialized)
00452     {
00453         InitError();
00454     }
00455     
00456     /* Check if the FCELL value matches the null pattern */
00457     for(i = 0; i < sizeof (FCELL); i++)
00458     {
00459         if(((unsigned char *) fcellVal)[i] != 
00460             ((unsigned char *) &fcellNullPattern)[i])
00461         {
00462             return FALSE;
00463         }
00464     }
00465     
00466     return TRUE;
00467 }
00468 
00469 /****************************************************************************
00470 * 
00471 * int G_is_d_null_value (DCELL *dcellVal)
00472 *
00473 * PURPOSE:      To check if a DCELL raster value is set to NULL
00474 * INPUT VARS:   dcellVal    =>  DCELL raster value to check
00475 * RETURN VAL:   TRUE if DCELL raster value is NULL FALSE otherwise
00476 *****************************************************************************/
00477 
00489 int G_is_d_null_value (const DCELL *dcellVal)
00490 {
00491     int     i;      /* counter */
00492 
00493     /* Check if the null patterns have been initialized */
00494     if (!initialized)
00495     {
00496         InitError();
00497     }
00498     
00499     /* Check if the DCELL value matches the null pattern */
00500     for(i = 0; i < sizeof (DCELL); i++)
00501     {
00502         if(((unsigned char *) dcellVal)[i] != 
00503             ((unsigned char *) &dcellNullPattern)[i])
00504         {
00505             return FALSE;
00506         }
00507     }
00508     
00509     return TRUE;
00510 }
00511 
00512 /****************************************************************************
00513 * 
00514 * int G_insert_null_values (void *rast, char *null_row, int ncols,
00515 *   RASTER_MAP_TYPE data_type)
00516 *
00517 * PURPOSE:      To insert null values into a map. Needs more.....
00518 * INPUT VARS:   rast        =>  ??
00519 *               null_row    =>  ??
00520 *               ncols       =>  ??
00521 *               data_type   =>  type of raster - CELL, FCELL, DCELL
00522 * RETURN VAL:   ??
00523 *****************************************************************************/
00524 
00542 int G_insert_null_values (void *rast, char *null_row, int ncols,
00543     RASTER_MAP_TYPE data_type)
00544 {
00545     return (EmbedGivenNulls(rast, null_row, data_type, ncols));
00546 }
00547 
00548 /****************************************************************************
00549 * 
00550 * int G_insert_c_null_values (CELL *cellVal, char *null_row, int ncols)
00551 *
00552 * PURPOSE:      To insert null values into a CELL map. Needs more.....
00553 * INPUT VARS:   cellVal     =>  ??
00554 *               null_row    =>  ??
00555 *               ncols       =>  ??
00556 * RETURN VAL:   ??
00557 *****************************************************************************/
00558 
00571 int G_insert_c_null_values (CELL *cellVal, char *null_row, int ncols)
00572 {
00573     return (EmbedGivenNulls((void *) cellVal, null_row, CELL_TYPE, ncols));
00574 }
00575 
00576 /****************************************************************************
00577 * 
00578 * int G_insert_f_null_values (FCELL *fcellVal, char *null_row, int ncols)
00579 *
00580 * PURPOSE:      To insert null values into a FCELL map. Needs more.....
00581 * INPUT VARS:   fcellVal    =>  ??
00582 *               null_row    =>  ??
00583 *               ncols       =>  ??
00584 * RETURN VAL:   ??
00585 *****************************************************************************/
00586 
00599 int G_insert_f_null_values (FCELL *fcellVal, char *null_row, int ncols)
00600 {
00601     return (EmbedGivenNulls((void *) fcellVal, null_row, FCELL_TYPE, ncols));
00602 }
00603 
00604 /****************************************************************************
00605 * 
00606 * int G_insert_d_null_values (DCELL *dcellVal, char *null_row, int ncols)
00607 *
00608 * PURPOSE:      To insert null values into a DCELL map. Needs more.....
00609 * INPUT VARS:   dcellVal    =>  ??
00610 *               null_row    =>  ??
00611 *               ncols       =>  ??
00612 * RETURN VAL:   ??
00613 *****************************************************************************/
00614 
00627 int G_insert_d_null_values (DCELL *dcellVal, char *null_row, int ncols)
00628 {
00629     return (EmbedGivenNulls((void *) dcellVal, null_row, DCELL_TYPE, ncols));
00630 }
00631 
00632 /****************************************************************************
00633 * int G__check_null_bit (unsigned char *flags, int bit_num, int n)
00634 *
00635 * PURPOSE:      To...
00636 * INPUT VARS:   flags   =>  ??
00637 *               bit_num =>  ??
00638 *               n       =>  ??
00639 * RETURN VAL:   ??
00640 *****************************************************************************/
00641 int G__check_null_bit (unsigned char *flags, int bit_num, int n)
00642 {
00643     int ind;
00644     int offset;
00645 
00646     /* find the index of the unsigned char in which this bit appears */
00647     ind = G__null_bitstream_size(bit_num + 1) - 1;
00648 
00649     /* find how many unsigned chars the buffer with bit_num+1 (counting from 0
00650       has and subtract 1 to get unsigned char index */
00651     if (ind > G__null_bitstream_size(n) - 1 )
00652     {
00653         G_warning("G__check_null_bit: can't access index %d. Size of flags is %d (bit # is %d", ind, G__null_bitstream_size(n) - 1, bit_num);
00654         return -1;
00655     }
00656    
00657     offset = (ind+1)*8 - bit_num - 1;
00658 
00659     return ((flags[ind] & ( (unsigned char) 1 << offset)) != 0);
00660 }
00661 
00662 /****************************************************************************
00663 * int G__set_flags_from_01_random (char *zero_ones, unsigned char *flags, 
00664 *   int col, int n, int ncols)
00665 *
00666 * PURPOSE:      given array of 0/1 of length n starting from column col
00667 *               set the corresponding  bits of flags; total number of bits
00668 *               in flags is ncols
00669 * INPUT VARS:   zero_ones   =>  ??
00670 *               flags       =>  ??
00671 *               col         =>  ??
00672 *               n           =>  ??
00673 *               ncols       =>  ??
00674 * RETURN VAL:   ??
00675 *****************************************************************************/
00676 int G__set_flags_from_01_random (char *zero_ones, unsigned char *flags, 
00677     int col, int n, int ncols)
00678 {
00679     unsigned char   v;
00680     int             count;
00681     int             size;
00682     int             i, k;
00683 
00684     if (col==0 && n == ncols)
00685     {
00686         G__convert_01_flags(zero_ones, flags, n);
00687         return 0;
00688     }
00689    
00690     count = 0;
00691     size = G__null_bitstream_size(ncols);
00692    
00693     for (i = 0; i < size; i++)
00694     {
00695         v = 0;
00696         k = 8;
00697         
00698         while (k-- > 0)
00699         {
00700             if (count >= col && count < (col+ n))
00701             {  
00702                 v = v | ((unsigned char) zero_ones[count - col] << k);
00703             }
00704             else if(count < ncols)
00705             {
00706                 v = v | 
00707                     ((unsigned char) G__check_null_bit(flags, count, ncols) << k);
00708             }
00709             
00710             /* otherwise  keep this bit the same as it was */
00711             count++;
00712         }
00713         
00714         flags[i] = v;
00715     }
00716     
00717     return 1;
00718 }
00719 
00720 /****************************************************************************
00721 * int G__convert_01_flags (char *zero_ones, unsigned char *flags, int n)
00722 *
00723 * PURPOSE:      To...
00724 * INPUT VARS:   zero_ones   =>  ??
00725 *               flags       =>  ??
00726 *               n           =>  ??
00727 * RETURN VAL:   ??
00728 *****************************************************************************/
00729 int G__convert_01_flags (char *zero_ones, unsigned char *flags, int n)
00730 {
00731     unsigned char   *v;
00732     int             count;
00733     int             size;
00734     int             i, k;
00735 
00736     /* pad the flags with 0's to make size multiple of 8 */
00737     v = flags;
00738     size = G__null_bitstream_size(n);
00739     count = 0;
00740    
00741     for (i = 0; i < size; i++)
00742     {
00743         *v = 0;
00744         k = 8;
00745         
00746         while (k-- > 0)
00747         {
00748             if (count < n)
00749             {
00750                 *v = *v | ((unsigned char) zero_ones[count] << k);
00751             }
00752             
00753             count++;
00754         }
00755       
00756         v++;
00757     }
00758 
00759     return 0;
00760 }
00761 
00762 /****************************************************************************
00763 * int G__convert_flags_01 (char *zero_ones, unsigned char *flags, int n)
00764 *
00765 * PURPOSE:      To...
00766 * INPUT VARS:   zero_ones   =>  ??
00767 *               flags       =>  ??
00768 *               n           =>  ??
00769 * RETURN VAL:   ??
00770 *****************************************************************************/
00771 int G__convert_flags_01 (char *zero_ones, unsigned char *flags, int n)
00772 {
00773     unsigned char   *v;
00774     int             count;
00775     int             size;
00776     int             i, k;
00777 
00778     count = 0;
00779     v = flags;
00780     size = G__null_bitstream_size(n);
00781    
00782     for (i = 0; i < size; i++)
00783     {
00784         k = 8;
00785       
00786         while (k-- > 0)
00787         {
00788             if (count < n) 
00789             {
00790                 zero_ones[count] = ((*v & ( (unsigned char) 1 << k)) != 0);
00791                 count++;
00792             }
00793         }
00794         
00795         v++;
00796     }
00797 
00798     return 0;
00799 }
00800 
00801 /****************************************************************************
00802 * int G__init_null_bits (unsigned char *flags, int cols)
00803 *
00804 * PURPOSE:      To...
00805 * INPUT VARS:   flags   =>  ??
00806 *               cols    =>  ??
00807 * RETURN VAL:   ??
00808 *****************************************************************************/
00809 int G__init_null_bits (unsigned char *flags, int cols)
00810 {
00811     unsigned char   *v;
00812     int             size;
00813     int             i;
00814 
00815     /* pad the flags with 0's to make size multiple of 8 */
00816     v = flags;
00817     size = G__null_bitstream_size(cols);
00818     
00819     for (i = 0; i < size; i++)
00820     {
00821         if((i+1) * 8 <= cols)
00822         {
00823             *v = (unsigned char) 255;
00824         }
00825         else
00826         {
00827             *v = (unsigned char) 255 << ((i+1) * 8 - cols);
00828         }
00829         
00830         v++;
00831     }
00832 
00833     return 0;
00834 }
00835 

Generated on Wed Aug 23 17:49:22 2006 for GRASS by  doxygen 1.4.7