Ignore:
Timestamp:
Feb 22, 2009, 12:54:28 AM (15 years ago)
Author:
hamish
Message:

backport faster null check for G_is_c_null_value() (trac #392)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • grass/branches/develbranch_6/lib/gis/null_val.c

    r34888 r36024  
    2525#include <grass/glocale.h>
    2626
    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 
    4727static int EmbedGivenNulls(void *, char *, RASTER_MAP_TYPE, int);
    48 static void InitError(void);
    49 
    50 /*======================= Internal Static Functions ========================*/
    5128
    5229/****************************************************************************
     
    9774}
    9875
    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 
    12076/*========================== 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 *****************************************************************************/
    131 void G__init_null_patterns(void)
    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 }
    17277
    17378/****************************************************************************
     
    235140* RETURN VAL:   none
    236141*****************************************************************************/
    237 void G_set_c_null_value(CELL * cellVals, int numVals)
    238 {
    239     CELL *cellPtr;              /* pointer to CELL array to set to null */
     142void G_set_c_null_value(CELL *cellVals, int numVals)
     143{
    240144    int i;                      /* counter */
    241145
    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;
     146    for (i = 0; i < numVals; i++)
     147        cellVals[i] = (int) 0x80000000;
    256148}
    257149
     
    264156* RETURN VAL:   none
    265157*****************************************************************************/
    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;
     158void G_set_f_null_value(FCELL *fcellVals, int numVals)
     159{
     160    static const unsigned char null_bits[4] = {
     161        0xFF, 0xFF, 0xFF, 0xFF};
     162    int i;
     163
     164    for (i = 0; i < numVals; i++)
     165        memcpy(&fcellVals[i], null_bits, sizeof(null_bits));
    285166}
    286167
     
    293174* RETURN VAL:   none
    294175*****************************************************************************/
    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;
     176void G_set_d_null_value(DCELL *dcellVals, int numVals)
     177{
     178    static const unsigned char null_bits[8] = {
     179        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
     180    int i;
     181
     182    for (i = 0; i < numVals; i++)
     183        memcpy(&dcellVals[i], null_bits, sizeof(null_bits));
    314184}
    315185
     
    374244int G_is_c_null_value(const CELL * cellVal)
    375245{
    376     int i;                      /* counter */
    377 
    378     /* Check if the null patterns have been initialized */
    379     if (!initialized) {
    380         InitError();
    381     }
    382 
    383246    /* 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;
     247    return *cellVal == (CELL) 0x80000000;
    392248}
    393249
Note: See TracChangeset for help on using the changeset viewer.