GRASS Programmer's Manual 6.4.1(2011)
|
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 }