color_rule.c

Go to the documentation of this file.
00001 #include "gis.h"
00002 
00003 #define LIMIT(x) if (x < 0) x = 0; else if (x > 255) x = 255;
00004 
00005 static int add_color_rule (void *,int,int,int,
00006            void *,int,int,int,
00007            struct _Color_Info_ *,int,
00008            DCELL *,DCELL *,RASTER_MAP_TYPE);
00009 
00010 
00032 int 
00033 G_add_d_raster_color_rule (DCELL *val1, int r1, int g1, int b1, DCELL *val2, int r2, int g2, int b2, struct Colors *colors)
00034 {
00035     add_color_rule ( (void *) val1, r1,g1,b1,  (void *) val2, r2,g2,b2, &colors->fixed, colors->version,
00036         &colors->cmin, &colors->cmax, DCELL_TYPE);
00037     return 1;
00038 }
00039 
00040 
00062 int 
00063 G_add_f_raster_color_rule (FCELL *cat1, int r1, int g1, int b1, FCELL *cat2, int r2, int g2, int b2, struct Colors *colors)
00064 {
00065     add_color_rule ((void *) cat1, r1,g1,b1, (void *) cat2, r2,g2,b2, &colors->fixed, colors->version,
00066         &colors->cmin, &colors->cmax, FCELL_TYPE);
00067     return 1;
00068 }
00069 
00070 
00088 int 
00089 G_add_c_raster_color_rule (CELL *cat1, int r1, int g1, int b1, CELL *cat2, int r2, int g2, int b2, struct Colors *colors)
00090 {
00091     add_color_rule ((void *) cat1, r1,g1,b1, (void *) cat2, r2,g2,b2, &colors->fixed, colors->version,
00092         &colors->cmin, &colors->cmax, CELL_TYPE);
00093     return 1;
00094 }
00095 
00096 
00120 int 
00121 G_add_raster_color_rule (void *val1, int r1, int g1, int b1, void *val2, int r2, int g2, int b2, struct Colors *colors, RASTER_MAP_TYPE data_type)
00122 {
00123     add_color_rule (val1, r1,g1,b1, val2, r2,g2,b2, &colors->fixed, colors->version,
00124         &colors->cmin, &colors->cmax, data_type);
00125     return 1;
00126 }
00127 
00128 
00165 int 
00166 G_add_color_rule (CELL cat1, int r1, int g1, int b1, CELL cat2, int r2, int g2, int b2, struct Colors *colors)
00167 {
00168     add_color_rule ((void *) &cat1, r1,g1,b1, (void *) &cat2, r2,g2,b2, &colors->fixed, colors->version,
00169         &colors->cmin, &colors->cmax, CELL_TYPE);
00170     return 1;
00171 }
00172 
00173 int 
00174 G_add_modular_d_raster_color_rule (DCELL *val1, int r1, int g1, int b1, DCELL *val2, int r2, int g2, int b2, struct Colors *colors)
00175 {
00176     DCELL min, max;
00177     if (colors->version < 0)
00178         return -1; /* can;t use this on 3.0 colors */
00179     min = colors->cmin;
00180     max = colors->cmax;
00181     add_color_rule ((void *) val1, r1,g1,b1, (void *) val2, r2,g2,b2, &colors->modular, 0,
00182         &colors->cmin, &colors->cmax, DCELL_TYPE);
00183     colors->cmin = min; /* don't reset these */
00184     colors->cmax = max;
00185         
00186     return 1;
00187 }
00188 
00189 int 
00190 G_add_modular_f_raster_color_rule (FCELL *val1, int r1, int g1, int b1, FCELL *val2, int r2, int g2, int b2, struct Colors *colors)
00191 {
00192     DCELL min, max;
00193     if (colors->version < 0)
00194         return -1; /* can;t use this on 3.0 colors */
00195     min = colors->cmin;
00196     max = colors->cmax;
00197     add_color_rule ((void *) val1, r1,g1,b1, (void *) val2, r2,g2,b2, &colors->modular, 0,
00198         &colors->cmin, &colors->cmax, FCELL_TYPE);
00199     colors->cmin = min; /* don't reset these */
00200     colors->cmax = max;
00201         
00202     return 1;
00203 }
00204 
00205 int 
00206 G_add_modular_c_raster_color_rule (CELL *val1, int r1, int g1, int b1, CELL *val2, int r2, int g2, int b2, struct Colors *colors)
00207 {
00208     return G_add_modular_color_rule (*val1, r1,g1,b1, *val2, r2,g2,b2, colors);
00209 }
00210 
00211 int 
00212 G_add_modular_raster_color_rule (void *val1, int r1, int g1, int b1, void *val2, int r2, int g2, int b2, struct Colors *colors, RASTER_MAP_TYPE data_type)
00213 {
00214     CELL min, max;
00215     if (colors->version < 0)
00216         return -1; /* can't use this on 3.0 colors */
00217     min = colors->cmin;
00218     max = colors->cmax;
00219     add_color_rule (val1, r1,g1,b1, val2, r2,g2,b2, &colors->modular, 0,
00220         &colors->cmin, &colors->cmax, data_type);
00221     colors->cmin = min; /* don't reset these */
00222     colors->cmax = max;
00223         
00224     return 1;
00225 }
00226 
00227 int 
00228 G_add_modular_color_rule (CELL cat1, int r1, int g1, int b1, CELL cat2, int r2, int g2, int b2, struct Colors *colors)
00229 {
00230     CELL min, max;
00231     if (colors->version < 0)
00232         return -1; /* can;t use this on 3.0 colors */
00233     min = colors->cmin;
00234     max = colors->cmax;
00235     add_color_rule ((void *) &cat1, r1,g1,b1, (void *) &cat2, r2,g2,b2, &colors->modular, 0,
00236         &colors->cmin, &colors->cmax, CELL_TYPE);
00237     colors->cmin = min; /* don't reset these */
00238     colors->cmax = max;
00239         
00240     return 1;
00241 }
00242 
00243 static int add_color_rule (void *pt1, int r1, int g1, int b1, void *pt2, int r2, int g2, int b2, struct _Color_Info_ *cp, int version, DCELL *cmin, DCELL *cmax, RASTER_MAP_TYPE data_type)
00244 {
00245     struct _Color_Rule_ *rule, *next;
00246     unsigned char red, grn, blu;
00247     DCELL min,max, val1, val2;
00248     CELL cat;
00249 
00250     val1 = G_get_raster_value_d(pt1, data_type);
00251     val2 = G_get_raster_value_d(pt2, data_type);
00252 /* allocate a low:high rule */
00253     rule = (struct _Color_Rule_ *) G_malloc (sizeof(*rule));
00254     rule->next = rule->prev = NULL;
00255 
00256 /* make sure colors are in the range [0,255] */
00257     LIMIT(r1);
00258     LIMIT(g1);
00259     LIMIT(b1);
00260     LIMIT(r2);
00261     LIMIT(g2);
00262     LIMIT(b2);
00263 
00264 /* val1==val2, use average color */
00265 /* otherwise make sure low < high */
00266     if (val1 == val2)
00267     {
00268         rule->low.value = rule->high.value = val1;
00269         rule->low.red = rule->high.red = (r1+r2)/2;
00270         rule->low.grn = rule->high.grn = (g1+g2)/2;
00271         rule->low.blu = rule->high.blu = (b1+b2)/2;
00272     }
00273     else if (val1 < val2)
00274     {
00275         rule->low.value = val1;
00276         rule->low.red = r1;
00277         rule->low.grn = g1;
00278         rule->low.blu = b1;
00279 
00280         rule->high.value = val2;
00281         rule->high.red = r2;
00282         rule->high.grn = g2;
00283         rule->high.blu = b2;
00284     }
00285     else
00286     {
00287         rule->low.value = val2;
00288         rule->low.red = r2;
00289         rule->low.grn = g2;
00290         rule->low.blu = b2;
00291 
00292         rule->high.value = val1;
00293         rule->high.red = r1;
00294         rule->high.grn = g1;
00295         rule->high.blu = b1;
00296     }
00297 
00298 /* keep track of the overall min and max, excluding null */
00299     if (G_is_d_null_value(&(rule->low.value)))
00300         return 0;
00301     if (G_is_d_null_value(&(rule->high.value)))
00302         return 0;
00303     min = rule->low.value;
00304     max = rule->high.value;
00305     if (min <= max)
00306     {
00307         if (cp->min > cp->max)
00308         {
00309             cp->min = min;
00310             cp->max = max;
00311         }
00312         else
00313         {
00314             if(cp->min > min)
00315                 cp->min = min;
00316             if(cp->max < max)
00317                 cp->max = max;
00318         }
00319     }
00320     if (*cmin > *cmax)
00321     {
00322         *cmin = cp->min;
00323         *cmax = cp->max;
00324     }
00325     else
00326     {
00327         if(*cmin > cp->min)
00328             *cmin = cp->min;
00329         if(*cmax < cp->max)
00330             *cmax = cp->max;
00331     }
00332 
00333 /* If version is old style (i.e., pre 4.0),
00334  *     interpolate this rule from min to max
00335  *     and insert each cat into the lookup table.
00336  *     Then free the rule.
00337  * Otherwise, free the lookup table, if active.
00338  *     G_organize_colors() will regenerate it
00339  *     Link this rule into the list of rules
00340  */
00341 
00342     if (version < 0)
00343     {
00344         for (cat = (CELL) min; cat <= (CELL) max; cat++)
00345         {
00346             G__interpolate_color_rule ((DCELL) cat, &red, &grn, &blu, rule);
00347             G__insert_color_into_lookup (cat, (int)red, (int)grn, (int)blu, cp);
00348         }
00349         G_free (rule);
00350     }
00351     else
00352     {
00353         if (cp->rules)
00354             cp->rules->prev = rule;
00355         rule->next = cp->rules;
00356         cp->rules = rule;
00357 
00358     /* prune the rules:
00359      * remove all rules that are contained by this rule 
00360      */
00361         min = rule->low.value;  /* mod 4.1 */
00362         max = rule->high.value; /* mod 4.1 */
00363         cp->n_rules++;
00364         for (rule = rule->next; rule; rule = next)
00365         {
00366             next = rule->next; /* has to be done here, not in for stmt */
00367             if (min <= rule->low.value && max >= rule->high.value)
00368             {
00369                 if (rule->prev->next = next) /* remove from the list */
00370                     next->prev = rule->prev;
00371                 G_free(rule);
00372                 cp->n_rules--;
00373             }
00374         }
00375 
00376     /* free lookup array, if allocated */
00377         G__color_free_lookup(cp);
00378         G__color_free_fp_lookup(cp);
00379     }
00380 
00381     return 0;
00382 }

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