color_look.c

Go to the documentation of this file.
00001 #include <math.h>
00002 #include <grass/gis.h>
00003 
00004 /* old 4.1 routine */
00005 
00038 int G_lookup_colors (
00039     CELL *cell,
00040     unsigned char *red,unsigned char *grn,unsigned char *blu,
00041     unsigned char *set,
00042     int n,
00043     struct Colors *colors)
00044 {
00045     G_lookup_c_raster_colors (cell, red, grn, blu, set, n, colors);
00046 
00047     return 0;
00048 }
00049 
00050 /* I don't think it should exist, because it requires openning
00051    of raster file every time Olga 
00052 int G_lookup_rgb_colors(map, mapset, r, g, b)
00053     char *name, *mapset;
00054     unsigned char *r, *g, *b;
00055 {
00056     RASTER_MAP_TYPE map_type;
00057     void *rast;
00058     ....
00059 }
00060 */
00061 
00062 
00078 int G_lookup_c_raster_colors (
00079     CELL *cell,
00080     unsigned char *red, unsigned char *grn, unsigned char *blu,
00081     unsigned char *set,
00082     int n,
00083     struct Colors *colors)
00084 {
00085     G__organize_colors (colors); /* make sure the lookup tables are in place */
00086 
00087     G_zero ((char *) set, n*sizeof(unsigned char));
00088 
00089 /* first lookup the fixed colors */
00090     G__lookup_colors ((void *)cell, red, grn, blu, set, n, colors, 0, 0, CELL_TYPE);
00091 
00092 /* now lookup unset colors using the modular rules */
00093     G__lookup_colors ((void *)cell, red, grn, blu, set, n, colors, 1, 0, CELL_TYPE);
00094 
00095     return 0;
00096 }
00097 
00098 
00120 int G_lookup_raster_colors (
00121     void *raster,
00122     unsigned char *red, unsigned char *grn, unsigned char *blu,
00123     unsigned char *set,
00124     int n,
00125     struct Colors *colors,
00126     RASTER_MAP_TYPE map_type)
00127 {
00128     G__organize_colors (colors); /* make sure the lookup tables are in place */
00129     /* in case of float color rules, fp_lookup table is created */
00130 
00131     G_zero ((char *) set, n*sizeof(unsigned char));
00132 
00133 /* first lookup the fixed colors */
00134     G__lookup_colors (raster, red, grn, blu, set, n, colors, 0, 0, map_type);
00135 
00136 /* now lookup unset colors using the modular rules */
00137     G__lookup_colors (raster, red, grn, blu, set, n, colors, 1, 0, map_type);
00138 
00139     return 0;
00140 }
00141 
00142 
00160 int G_lookup_f_raster_colors  (FCELL *fcell, unsigned char *red, unsigned char *grn, unsigned char *blu, unsigned char *set, int n, struct Colors *colors)
00161 
00162 {
00163     G__organize_colors (colors); /* make sure the lookup tables are in place */
00164     /* in case of float color rules, fp_lookup table is created */
00165 
00166     G_zero ((char *) set, n*sizeof(unsigned char));
00167 
00168 /* first lookup the fixed colors */
00169     G__lookup_colors ((void *) fcell, red, grn, blu, set, n, colors, 0, 0, FCELL_TYPE);
00170 
00171 /* now lookup unset colors using the modular rules */
00172     G__lookup_colors ((void *) fcell, red, grn, blu, set, n, colors, 1, 0, FCELL_TYPE);
00173 
00174     return 0;
00175 }
00176 
00177 
00195 int G_lookup_d_raster_colors  (DCELL *dcell, unsigned char *red, unsigned char *grn, unsigned char *blu, unsigned char *set, int n, struct Colors *colors)
00196 
00197 {
00198     G__organize_colors (colors); /* make sure the lookup tables are in place */
00199     /* in case of float color rules, fp_lookup table is created */
00200 
00201     G_zero ((char *) set, n*sizeof(unsigned char));
00202 
00203 /* first lookup the fixed colors */
00204     G__lookup_colors ((void *) dcell, red, grn, blu, set, n, colors, 0, 0, DCELL_TYPE);
00205 
00206 /* now lookup unset colors using the modular rules */
00207     G__lookup_colors ((void *) dcell, red, grn, blu, set, n, colors, 1, 0, DCELL_TYPE);
00208 
00209     return 0;
00210 }
00211 
00212 
00213 static int less_or_equal (double x, double y)
00214 
00215 {
00216    if(x<=y) return 1;
00217    else return 0;
00218 }
00219                 
00220 static int less (double x, double y)
00221 
00222 {
00223    if(x<y) return 1;
00224    else return 0;
00225 }
00226                 
00227 
00228 int G__lookup_colors  (void *raster, unsigned char *red, unsigned char *grn, unsigned char *blu, unsigned char *set, int n, struct Colors *colors, int  mod, int  rules_only, RASTER_MAP_TYPE data_type)
00229 
00230 {
00231     struct _Color_Info_ *cp;
00232     struct _Color_Rule_ *rule;
00233     DCELL dmin, dmax, val, dmod=0L, shift;
00234     CELL cat, min, max;
00235     register void *ptr, *last_ptr=NULL;
00236     int invert;
00237     int found, r, g, b;
00238     int cell_type;
00239     int lookup, max_ind, min_ind, try;
00240     int (*lower)();
00241     
00242     if (mod)
00243         cp = &colors->modular;
00244     else
00245         cp = &colors->fixed;
00246 
00247 /* rules_only will be true only when called by G__organize_colors()
00248  * when building the integer lookup talbes from the rules,
00249  * so do not shift, invert, use lookup table or modulate cats.
00250  * these operations will happen when lookup is called by user code
00251  */
00252     /* we want min, max for cp, not min, max overall */
00253     dmin = cp->min;
00254     dmax = cp->max;
00255     min = (CELL) dmin;
00256     max = (CELL) dmax + 1;
00257 
00258     cell_type = (data_type == CELL_TYPE);
00259 
00260     if (rules_only)
00261     {
00262         shift = invert = lookup = mod = 0;
00263     }
00264     else
00265     {
00266         if(mod)
00267         {
00268            dmod = dmax - dmin;
00269         /* for integers color table we make a gap of 1 in order
00270            to make the same colors as before */
00271            if(cell_type)
00272                dmod += 1;
00273         }
00274 
00275         shift  = colors->shift;
00276         invert = colors->invert;
00277         lookup = cp->lookup.active;
00278     }
00279 
00280     ptr = raster;
00281 
00282     for (; n-- > 0; ptr = G_incr_void_ptr(ptr, G_raster_size(data_type)), red++, grn++, blu++, *set++ = found)
00283     {
00284         /* if the cell is the same as last one, use the prev color values */  
00285         if(ptr != raster && G_raster_cmp(ptr, last_ptr, data_type) == 0)
00286         {
00287            *red = *(red-1);
00288            *blu = *(blu-1);
00289            *grn = *(grn-1);
00290            found = *(set-1);
00291            last_ptr = ptr;
00292            continue;
00293         }
00294         val = G_get_raster_value_d(ptr, data_type);
00295      /* DEBUG fprintf (stderr, "val: %.4lf\n", val); */
00296         last_ptr = ptr;
00297 
00298         if (*set)
00299         {
00300             found = 1;
00301             continue;
00302         }
00303 
00304         if (G_is_null_value(ptr, data_type))
00305         {
00306             /* returns integers, not unsigned chars */
00307             G_get_null_value_color(&r, &g, &b, colors);
00308             *red = r; *grn = g; *blu = b;
00309             found = 1;
00310             continue;
00311         }
00312 
00313         if (shift && val >= dmin && val <= dmax)
00314         {
00315             val += shift;
00316             while (val < dmin)
00317                 val += dmax - dmin + 1;
00318             while (val > dmax)
00319                 val -= dmax - dmin + 1;
00320         }
00321 
00322 /* invert non-null data around midpoint of range [min:max] */
00323         if (invert)
00324             val = dmin + dmax - val;
00325 
00326         if(mod)
00327         {
00328             if(dmod > 0)
00329             {
00330                 val -= dmin;
00331                 while (val < 0)
00332                      val += dmod;
00333                 val = val - dmod * floor(val/dmod);
00334                 val += dmin;
00335             }
00336             else
00337                 val = dmin;
00338         }
00339 
00340         cat = (CELL) val;
00341 
00342         found = 0;
00343 
00344         /* for non-null integers  try to look them up in lookup table */
00345         /* note: lookup table exists only for integer maps, and we also must
00346         check if val is really integer */
00347 
00348         if (lookup && ((double) cat - val == 0.))
00349         {
00350             if (cat >= min && cat <= max)
00351             {
00352                 cat -= min;
00353                 if (cp->lookup.set[cat])
00354                 {
00355                     *red = cp->lookup.red[cat];
00356                     *grn = cp->lookup.grn[cat];
00357                     *blu = cp->lookup.blu[cat];
00358                     found = 1;
00359 /*DEBUG
00360         fprintf (stderr, "lookup %d %.2lf %d %d %d\n\n", cat, val, *red, *grn, *blu);
00361         */
00362                 }
00363             }
00364         }
00365 
00366         if (found) 
00367            continue;
00368 
00369         /* if floating point lookup table is active, look up in there */
00370         if(cp->fp_lookup.active)
00371         {
00372            try = (cp->fp_lookup.nalloc-1)/2;
00373            min_ind = 0;
00374            max_ind = cp->fp_lookup.nalloc-2;
00375            while(1)
00376            {
00377            /* when the rule for the interval is NULL, we exclude the end points.
00378               when it exists, we include the end-points */
00379               if(cp->fp_lookup.rules[try])
00380                     lower = less;
00381               else
00382                     lower = less_or_equal;
00383               /* DEBUG
00384               fprintf (stderr, "%d %d %d %lf %lf %lf\n", min_ind, try, max_ind,
00385                                                cp->fp_lookup.vals[try-1],
00386                                                val,
00387                                                cp->fp_lookup.vals[try]);
00388               */
00389                         
00390               if (lower(cp->fp_lookup.vals[try+1], val))
00391               { /* recurse to the second half */
00392                  min_ind = try+1;
00393                 /* must be still < nalloc-1, since number is within the range */
00394                  try = (max_ind + min_ind)/2;
00395                  if(min_ind > max_ind)
00396                  {
00397                     rule = NULL;
00398                     break;
00399                  }
00400                  continue;
00401               }
00402               if (lower(val, cp->fp_lookup.vals[try]))
00403               { /* recurse to the second half */
00404                  max_ind = try-1;
00405                  /* must be still >= 0, since number is within the range */
00406                  try = (max_ind + min_ind)/2;
00407                  if(max_ind < min_ind)
00408                  {
00409                     rule = NULL;
00410                     break;
00411                  }
00412                  continue;
00413               }
00414               rule = cp->fp_lookup.rules[try];
00415               break;
00416            }
00417         }
00418         else     
00419         {
00420             /* find the [low:high] rule that applies */
00421             for (rule = cp->rules; rule; rule = rule->next)
00422             {
00423             /* DEBUG
00424                 fprintf (stderr, "%.2lf %.2lf %.2lf\n", 
00425                 val, rule->low.value, rule->high.value);
00426             */
00427                if (rule->low.value <= val && val <= rule->high.value)
00428                    break;
00429             }
00430         }
00431 
00432 /* if found, perform linear interpolation from low to high.
00433  * else set colors to colors->undef or white if undef not set
00434  */
00435 
00436         if (rule)
00437         {
00438             G__interpolate_color_rule (val, red, grn, blu, rule);
00439             found = 1;
00440         }
00441         if (!found)
00442         {
00443             /* otherwise use default color */
00444             G_get_default_color(&r, &g, &b, colors);
00445             *red = r; *grn = g; *blu = b;
00446         }
00447 /* DEBUG
00448         if (rule)
00449         fprintf (stderr, "%.2lf %d %d %d   %.2lf %d %d %d \n", rule->low.value , (int)rule->low.red, (int)rule->low.grn, (int)rule->low.blu, rule->high.value, (int)rule->high.red, (int)rule->high.grn, (int)rule->high.blu);
00450         fprintf (stderr, "rule found %d %.2lf %d %d %d\n\n", cat, val, *red, *grn, *blu);
00451 */
00452     }
00453 
00454     return 0;
00455 }
00456 
00457 int G__interpolate_color_rule  (DCELL val, unsigned char *red, unsigned char *grn, unsigned char *blu, struct _Color_Rule_ *rule)
00458 
00459 {
00460     DCELL delta;
00461 
00462     if((delta = rule->high.value - rule->low.value))
00463     {
00464         val -= rule->low.value;
00465 
00466         *red = (int) (val * (double) ((int)rule->high.red - (int)rule->low.red)/ delta)
00467                     + (int)rule->low.red;
00468         *grn = (int) (val * (double) ((int)rule->high.grn - (int)rule->low.grn)/ delta )
00469                     + (int)rule->low.grn;
00470         *blu = (int) (val * (double) ((int)rule->high.blu - (int)rule->low.blu)/ delta )
00471                     + (int)rule->low.blu;
00472     }
00473     else
00474     {
00475         *red = rule->low.red;
00476         *grn = rule->low.grn;
00477         *blu = rule->low.blu;
00478     }
00479 
00480     return 0;
00481 }
00482 

Generated on Fri Nov 21 11:02:17 2008 for GRASS by  doxygen 1.5.1