• Main Page
  • Related Pages
  • Data Structures
  • Files
  • File List
  • Globals

color_rule.c

Go to the documentation of this file.
00001 
00017 #include <grass/gis.h>
00018 
00019 #define LIMIT(x) if (x < 0) x = 0; else if (x > 255) x = 255;
00020 
00021 static int add_color_rule(const void *, int, int, int,
00022                           const void *, int, int, int,
00023                           struct _Color_Info_ *, int,
00024                           DCELL *, DCELL *, RASTER_MAP_TYPE);
00025 
00026 
00040 int
00041 G_add_d_raster_color_rule(const DCELL * val1, int r1, int g1, int b1,
00042                           const DCELL * val2, int r2, int g2, int b2,
00043                           struct Colors *colors)
00044 {
00045     add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->fixed,
00046                    colors->version, &colors->cmin, &colors->cmax, DCELL_TYPE);
00047     return 1;
00048 }
00049 
00050 
00064 int
00065 G_add_f_raster_color_rule(const FCELL * cat1, int r1, int g1, int b1,
00066                           const FCELL * cat2, int r2, int g2, int b2,
00067                           struct Colors *colors)
00068 {
00069     add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
00070                    colors->version, &colors->cmin, &colors->cmax, FCELL_TYPE);
00071     return 1;
00072 }
00073 
00074 
00088 int
00089 G_add_c_raster_color_rule(const CELL * cat1, int r1, int g1, int b1,
00090                           const CELL * cat2, int r2, int g2, int b2,
00091                           struct Colors *colors)
00092 {
00093     add_color_rule(cat1, r1, g1, b1, cat2, r2, g2, b2, &colors->fixed,
00094                    colors->version, &colors->cmin, &colors->cmax, CELL_TYPE);
00095     return 1;
00096 }
00097 
00098 
00121 int
00122 G_add_raster_color_rule(const void *val1, int r1, int g1, int b1,
00123                         const void *val2, int r2, int g2, int b2,
00124                         struct Colors *colors, RASTER_MAP_TYPE data_type)
00125 {
00126     add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->fixed,
00127                    colors->version, &colors->cmin, &colors->cmax, data_type);
00128     return 1;
00129 }
00130 
00131 
00164 int
00165 G_add_color_rule(CELL cat1, int r1, int g1, int b1, CELL cat2, int r2, int g2,
00166                  int b2, struct Colors *colors)
00167 {
00168     add_color_rule((void *)&cat1, r1, g1, b1, (void *)&cat2, r2, g2, b2,
00169                    &colors->fixed, colors->version, &colors->cmin,
00170                    &colors->cmax, CELL_TYPE);
00171     return 1;
00172 }
00173 
00186 int
00187 G_add_modular_d_raster_color_rule(const DCELL * val1, int r1, int g1, int b1,
00188                                   const DCELL * val2, int r2, int g2, int b2,
00189                                   struct Colors *colors)
00190 {
00191     DCELL min, max;
00192 
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(val1, r1, g1, b1, val2, r2, g2, b2, &colors->modular, 0,
00198                    &colors->cmin, &colors->cmax, DCELL_TYPE);
00199     colors->cmin = min;         /* don't reset these */
00200     colors->cmax = max;
00201 
00202     return 1;
00203 }
00204 
00217 int
00218 G_add_modular_f_raster_color_rule(const FCELL * val1, int r1, int g1, int b1,
00219                                   const FCELL * val2, int r2, int g2, int b2,
00220                                   struct Colors *colors)
00221 {
00222     DCELL min, max;
00223 
00224     if (colors->version < 0)
00225         return -1;              /* can;t use this on 3.0 colors */
00226     min = colors->cmin;
00227     max = colors->cmax;
00228     add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->modular, 0,
00229                    &colors->cmin, &colors->cmax, FCELL_TYPE);
00230     colors->cmin = min;         /* don't reset these */
00231     colors->cmax = max;
00232 
00233     return 1;
00234 }
00235 
00248 int
00249 G_add_modular_c_raster_color_rule(const CELL * val1, int r1, int g1, int b1,
00250                                   const CELL * val2, int r2, int g2, int b2,
00251                                   struct Colors *colors)
00252 {
00253     return G_add_modular_color_rule(*val1, r1, g1, b1, *val2, r2, g2, b2,
00254                                     colors);
00255 }
00256 
00273 int
00274 G_add_modular_raster_color_rule(const void *val1, int r1, int g1, int b1,
00275                                 const void *val2, int r2, int g2, int b2,
00276                                 struct Colors *colors,
00277                                 RASTER_MAP_TYPE data_type)
00278 {
00279     CELL min, max;
00280 
00281     if (colors->version < 0)
00282         return -1;              /* can't use this on 3.0 colors */
00283     min = colors->cmin;
00284     max = colors->cmax;
00285     add_color_rule(val1, r1, g1, b1, val2, r2, g2, b2, &colors->modular, 0,
00286                    &colors->cmin, &colors->cmax, data_type);
00287     colors->cmin = min;         /* don't reset these */
00288     colors->cmax = max;
00289 
00290     return 1;
00291 }
00292 
00309 int
00310 G_add_modular_color_rule(CELL cat1, int r1, int g1, int b1, CELL cat2, int r2,
00311                          int g2, int b2, struct Colors *colors)
00312 {
00313     CELL min, max;
00314 
00315     if (colors->version < 0)
00316         return -1;              /* can;t use this on 3.0 colors */
00317     min = colors->cmin;
00318     max = colors->cmax;
00319     add_color_rule((void *)&cat1, r1, g1, b1, (void *)&cat2, r2, g2, b2,
00320                    &colors->modular, 0, &colors->cmin, &colors->cmax,
00321                    CELL_TYPE);
00322     colors->cmin = min;         /* don't reset these */
00323     colors->cmax = max;
00324 
00325     return 1;
00326 }
00327 
00328 static int add_color_rule(const void *pt1, int r1, int g1, int b1,
00329                           const void *pt2, int r2, int g2, int b2,
00330                           struct _Color_Info_ *cp, int version, DCELL * cmin,
00331                           DCELL * cmax, RASTER_MAP_TYPE data_type)
00332 {
00333     struct _Color_Rule_ *rule, *next;
00334     unsigned char red, grn, blu;
00335     DCELL min, max, val1, val2;
00336     CELL cat;
00337 
00338     val1 = G_get_raster_value_d(pt1, data_type);
00339     val2 = G_get_raster_value_d(pt2, data_type);
00340     /* allocate a low:high rule */
00341     rule = (struct _Color_Rule_ *)G_malloc(sizeof(*rule));
00342     rule->next = rule->prev = NULL;
00343 
00344     /* make sure colors are in the range [0,255] */
00345     LIMIT(r1);
00346     LIMIT(g1);
00347     LIMIT(b1);
00348     LIMIT(r2);
00349     LIMIT(g2);
00350     LIMIT(b2);
00351 
00352     /* val1==val2, use average color */
00353     /* otherwise make sure low < high */
00354     if (val1 == val2) {
00355         rule->low.value = rule->high.value = val1;
00356         rule->low.red = rule->high.red = (r1 + r2) / 2;
00357         rule->low.grn = rule->high.grn = (g1 + g2) / 2;
00358         rule->low.blu = rule->high.blu = (b1 + b2) / 2;
00359     }
00360     else if (val1 < val2) {
00361         rule->low.value = val1;
00362         rule->low.red = r1;
00363         rule->low.grn = g1;
00364         rule->low.blu = b1;
00365 
00366         rule->high.value = val2;
00367         rule->high.red = r2;
00368         rule->high.grn = g2;
00369         rule->high.blu = b2;
00370     }
00371     else {
00372         rule->low.value = val2;
00373         rule->low.red = r2;
00374         rule->low.grn = g2;
00375         rule->low.blu = b2;
00376 
00377         rule->high.value = val1;
00378         rule->high.red = r1;
00379         rule->high.grn = g1;
00380         rule->high.blu = b1;
00381     }
00382 
00383     /* keep track of the overall min and max, excluding null */
00384     if (G_is_d_null_value(&(rule->low.value)))
00385         return 0;
00386     if (G_is_d_null_value(&(rule->high.value)))
00387         return 0;
00388     min = rule->low.value;
00389     max = rule->high.value;
00390     if (min <= max) {
00391         if (cp->min > cp->max) {
00392             cp->min = min;
00393             cp->max = max;
00394         }
00395         else {
00396             if (cp->min > min)
00397                 cp->min = min;
00398             if (cp->max < max)
00399                 cp->max = max;
00400         }
00401     }
00402     if (*cmin > *cmax) {
00403         *cmin = cp->min;
00404         *cmax = cp->max;
00405     }
00406     else {
00407         if (*cmin > cp->min)
00408             *cmin = cp->min;
00409         if (*cmax < cp->max)
00410             *cmax = cp->max;
00411     }
00412 
00413     /* If version is old style (i.e., pre 4.0),
00414      *     interpolate this rule from min to max
00415      *     and insert each cat into the lookup table.
00416      *     Then free the rule.
00417      * Otherwise, free the lookup table, if active.
00418      *     G_organize_colors() will regenerate it
00419      *     Link this rule into the list of rules
00420      */
00421 
00422     if (version < 0) {
00423         for (cat = (CELL) min; cat <= (CELL) max; cat++) {
00424             G__interpolate_color_rule((DCELL) cat, &red, &grn, &blu, rule);
00425             G__insert_color_into_lookup(cat, (int)red, (int)grn, (int)blu,
00426                                         cp);
00427         }
00428         G_free(rule);
00429     }
00430     else {
00431         if (cp->rules)
00432             cp->rules->prev = rule;
00433         rule->next = cp->rules;
00434         cp->rules = rule;
00435 
00436         /* prune the rules:
00437          * remove all rules that are contained by this rule 
00438          */
00439         min = rule->low.value;  /* mod 4.1 */
00440         max = rule->high.value; /* mod 4.1 */
00441         cp->n_rules++;
00442         for (rule = rule->next; rule; rule = next) {
00443             next = rule->next;  /* has to be done here, not in for stmt */
00444             if (min <= rule->low.value && max >= rule->high.value) {
00445                 if ((rule->prev->next = next))  /* remove from the list */
00446                     next->prev = rule->prev;
00447                 G_free(rule);
00448                 cp->n_rules--;
00449             }
00450         }
00451 
00452         /* free lookup array, if allocated */
00453         G__color_free_lookup(cp);
00454         G__color_free_fp_lookup(cp);
00455     }
00456 
00457     return 0;
00458 }

Generated on Wed Oct 13 2010 12:09:29 for GRASS Programmer's Manual by  doxygen 1.7.1