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