00001 #include <math.h>
00002 #include <grass/gis.h>
00003
00004
00005
00038 int G_lookup_colors(const CELL * cell,
00039 unsigned char *red, unsigned char *grn,
00040 unsigned char *blu, unsigned char *set, int n,
00041 struct Colors *colors)
00042 {
00043 G_lookup_c_raster_colors(cell, red, grn, blu, set, n, colors);
00044
00045 return 0;
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00076 int G_lookup_c_raster_colors(const CELL * cell,
00077 unsigned char *red, unsigned char *grn,
00078 unsigned char *blu, unsigned char *set, int n,
00079 struct Colors *colors)
00080 {
00081 G__organize_colors(colors);
00082
00083 G_zero((char *)set, n * sizeof(unsigned char));
00084
00085
00086 G__lookup_colors((void *)cell, red, grn, blu, set, n, colors, 0, 0,
00087 CELL_TYPE);
00088
00089
00090 G__lookup_colors((void *)cell, red, grn, blu, set, n, colors, 1, 0,
00091 CELL_TYPE);
00092
00093 return 0;
00094 }
00095
00096
00118 int G_lookup_raster_colors(const void *raster,
00119 unsigned char *red, unsigned char *grn,
00120 unsigned char *blu, unsigned char *set, int n,
00121 struct Colors *colors, RASTER_MAP_TYPE map_type)
00122 {
00123 G__organize_colors(colors);
00124
00125
00126 G_zero((char *)set, n * sizeof(unsigned char));
00127
00128
00129 G__lookup_colors(raster, red, grn, blu, set, n, colors, 0, 0, map_type);
00130
00131
00132 G__lookup_colors(raster, red, grn, blu, set, n, colors, 1, 0, map_type);
00133
00134 return 0;
00135 }
00136
00137
00155 int G_lookup_f_raster_colors(const FCELL * fcell, unsigned char *red,
00156 unsigned char *grn, unsigned char *blu,
00157 unsigned char *set, int n, struct Colors *colors)
00158 {
00159 G__organize_colors(colors);
00160
00161
00162 G_zero((char *)set, n * sizeof(unsigned char));
00163
00164
00165 G__lookup_colors((void *)fcell, red, grn, blu, set, n, colors, 0, 0,
00166 FCELL_TYPE);
00167
00168
00169 G__lookup_colors((void *)fcell, red, grn, blu, set, n, colors, 1, 0,
00170 FCELL_TYPE);
00171
00172 return 0;
00173 }
00174
00175
00193 int G_lookup_d_raster_colors(const DCELL * dcell, unsigned char *red,
00194 unsigned char *grn, unsigned char *blu,
00195 unsigned char *set, int n, struct Colors *colors)
00196 {
00197 G__organize_colors(colors);
00198
00199
00200 G_zero((char *)set, n * sizeof(unsigned char));
00201
00202
00203 G__lookup_colors((void *)dcell, red, grn, blu, set, n, colors, 0, 0,
00204 DCELL_TYPE);
00205
00206
00207 G__lookup_colors((void *)dcell, red, grn, blu, set, n, colors, 1, 0,
00208 DCELL_TYPE);
00209
00210 return 0;
00211 }
00212
00213
00214 static int less_or_equal(double x, double y)
00215 {
00216 if (x <= y)
00217 return 1;
00218 else
00219 return 0;
00220 }
00221
00222 static int less(double x, double y)
00223 {
00224 if (x < y)
00225 return 1;
00226 else
00227 return 0;
00228 }
00229
00230
00231 int G__lookup_colors(const void *raster, unsigned char *red,
00232 unsigned char *grn, unsigned char *blu,
00233 unsigned char *set, int n, struct Colors *colors,
00234 int mod, int rules_only, RASTER_MAP_TYPE data_type)
00235 {
00236 struct _Color_Info_ *cp;
00237 struct _Color_Rule_ *rule;
00238 DCELL dmin, dmax, val, dmod = 0L, shift;
00239 CELL cat, min, max;
00240 register const void *ptr, *last_ptr = NULL;
00241 int invert;
00242 int found, r, g, b;
00243 int cell_type;
00244 int lookup, max_ind, min_ind, try;
00245 int (*lower) ();
00246
00247 if (mod)
00248 cp = &colors->modular;
00249 else
00250 cp = &colors->fixed;
00251
00252
00253
00254
00255
00256
00257
00258 dmin = cp->min;
00259 dmax = cp->max;
00260 min = (CELL) dmin;
00261 max = (CELL) dmax + 1;
00262
00263 cell_type = (data_type == CELL_TYPE);
00264
00265 if (rules_only) {
00266 shift = invert = lookup = mod = 0;
00267 }
00268 else {
00269 if (mod) {
00270 dmod = dmax - dmin;
00271
00272
00273 if (cell_type)
00274 dmod += 1;
00275 }
00276
00277 shift = colors->shift;
00278 invert = colors->invert;
00279 lookup = cp->lookup.active;
00280 }
00281
00282 ptr = raster;
00283
00284 for (; n-- > 0;
00285 ptr =
00286 G_incr_void_ptr(ptr, G_raster_size(data_type)), red++, grn++, blu++,
00287 *set++ = found) {
00288
00289 if (ptr != raster && G_raster_cmp(ptr, last_ptr, data_type) == 0) {
00290 *red = *(red - 1);
00291 *blu = *(blu - 1);
00292 *grn = *(grn - 1);
00293 found = *(set - 1);
00294 last_ptr = ptr;
00295 continue;
00296 }
00297 val = G_get_raster_value_d(ptr, data_type);
00298
00299 last_ptr = ptr;
00300
00301 if (*set) {
00302 found = 1;
00303 continue;
00304 }
00305
00306 if (G_is_null_value(ptr, data_type)) {
00307
00308 G_get_null_value_color(&r, &g, &b, colors);
00309 *red = r;
00310 *grn = g;
00311 *blu = b;
00312 found = 1;
00313 continue;
00314 }
00315
00316 if (shift && val >= dmin && val <= dmax) {
00317 val += shift;
00318 while (val < dmin)
00319 val += dmax - dmin + 1;
00320 while (val > dmax)
00321 val -= dmax - dmin + 1;
00322 }
00323
00324
00325 if (invert)
00326 val = dmin + dmax - val;
00327
00328 if (mod) {
00329 if (dmod > 0) {
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
00345
00346
00347
00348 if (lookup && ((double)cat - val == 0.)) {
00349 if (cat >= min && cat <= max) {
00350 cat -= min;
00351 if (cp->lookup.set[cat]) {
00352 *red = cp->lookup.red[cat];
00353 *grn = cp->lookup.grn[cat];
00354 *blu = cp->lookup.blu[cat];
00355 found = 1;
00356
00357
00358
00359 }
00360 }
00361 }
00362
00363 if (found)
00364 continue;
00365
00366
00367 if (cp->fp_lookup.active) {
00368 try = (cp->fp_lookup.nalloc - 1) / 2;
00369 min_ind = 0;
00370 max_ind = cp->fp_lookup.nalloc - 2;
00371 while (1) {
00372
00373
00374 if (cp->fp_lookup.rules[try])
00375 lower = less;
00376 else
00377 lower = less_or_equal;
00378
00379
00380
00381
00382
00383
00384
00385 if (lower(cp->fp_lookup.vals[try + 1], val)) {
00386 min_ind = try + 1;
00387
00388 try = (max_ind + min_ind) / 2;
00389 if (min_ind > max_ind) {
00390 rule = NULL;
00391 break;
00392 }
00393 continue;
00394 }
00395 if (lower(val, cp->fp_lookup.vals[try])) {
00396 max_ind = try - 1;
00397
00398 try = (max_ind + min_ind) / 2;
00399 if (max_ind < min_ind) {
00400 rule = NULL;
00401 break;
00402 }
00403 continue;
00404 }
00405 rule = cp->fp_lookup.rules[try];
00406 break;
00407 }
00408 }
00409 else {
00410
00411 for (rule = cp->rules; rule; rule = rule->next) {
00412
00413
00414
00415
00416 if (rule->low.value <= val && val <= rule->high.value)
00417 break;
00418 }
00419 }
00420
00421
00422
00423
00424
00425 if (rule) {
00426 G__interpolate_color_rule(val, red, grn, blu, rule);
00427 found = 1;
00428 }
00429 if (!found) {
00430
00431 G_get_default_color(&r, &g, &b, colors);
00432 *red = r;
00433 *grn = g;
00434 *blu = b;
00435 }
00436
00437
00438
00439
00440
00441 }
00442
00443 return 0;
00444 }
00445
00446 int G__interpolate_color_rule(DCELL val, unsigned char *red,
00447 unsigned char *grn, unsigned char *blu,
00448 const struct _Color_Rule_ *rule)
00449 {
00450 DCELL delta;
00451
00452 if ((delta = rule->high.value - rule->low.value)) {
00453 val -= rule->low.value;
00454
00455 *red =
00456 (int)(val * (double)((int)rule->high.red - (int)rule->low.red) /
00457 delta)
00458 + (int)rule->low.red;
00459 *grn =
00460 (int)(val * (double)((int)rule->high.grn - (int)rule->low.grn) /
00461 delta)
00462 + (int)rule->low.grn;
00463 *blu =
00464 (int)(val * (double)((int)rule->high.blu - (int)rule->low.blu) /
00465 delta)
00466 + (int)rule->low.blu;
00467 }
00468 else {
00469 *red = rule->low.red;
00470 *grn = rule->low.grn;
00471 *blu = rule->low.blu;
00472 }
00473
00474 return 0;
00475 }