color_look.c

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

Generated on Sat Jul 22 22:06:14 2006 for GRASS by  doxygen 1.4.7