~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to lib/raster/color_org.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdlib.h>
 
2
 
 
3
#include <grass/gis.h>
 
4
#include <grass/raster.h>
 
5
 
 
6
#define LOOKUP_COLORS 2048
 
7
 
 
8
static void organize_lookup(struct Colors *, int);
 
9
static int organize_fp_lookup(struct Colors *, int);
 
10
static int double_comp(const void *, const void *);
 
11
 
 
12
void Rast__organize_colors(struct Colors *colors)
 
13
{
 
14
    /* don't do anything if called recursively */
 
15
    if (!colors->organizing) {
 
16
        colors->organizing = 1;
 
17
 
 
18
        organize_lookup(colors, 0);
 
19
        organize_lookup(colors, 1);
 
20
 
 
21
        organize_fp_lookup(colors, 0);
 
22
        organize_fp_lookup(colors, 1);
 
23
 
 
24
        colors->organizing = 0;
 
25
    }
 
26
}
 
27
 
 
28
static int organize_fp_lookup(struct Colors *colors, int mod)
 
29
{
 
30
    int i;
 
31
    DCELL val;
 
32
    struct _Color_Info_ *cp;
 
33
    struct _Color_Rule_ *rule;
 
34
 
 
35
    if (mod)
 
36
        cp = &colors->modular;
 
37
    else
 
38
        cp = &colors->fixed;
 
39
 
 
40
    /* if one of the lookup tables exist, don't do anything */
 
41
    if (cp->lookup.active || cp->fp_lookup.active)
 
42
        return 1;
 
43
    if (cp->n_rules == 0)
 
44
        return 1;
 
45
 
 
46
    cp->fp_lookup.vals = (DCELL *)
 
47
        G_calloc(cp->n_rules * 2, sizeof(DCELL));
 
48
    /* 2 endpoints for each rule */
 
49
    cp->fp_lookup.rules = (struct _Color_Rule_ **)
 
50
        G_calloc(cp->n_rules * 2, sizeof(struct _Color_Rule_ *));
 
51
 
 
52
    /* get the list of DCELL values from set of all lows and highs
 
53
       of all rules */
 
54
    /* NOTE: if low==high in a rule, the value appears twice in a list
 
55
       but if low==high of the previous, rule the value appears only once */
 
56
 
 
57
    i = 0;
 
58
    /* go through the list of rules from end to beginning, 
 
59
       because rules are sored in reverse order of reading,
 
60
       and we want to read the in correct order, to ignore
 
61
       the same values in the end of rule and beginning of next rule */
 
62
 
 
63
    /* first go to the last rules */
 
64
    for (rule = cp->rules; rule->next; rule = rule->next) ;
 
65
    /* now traverse from the last to the first rule */
 
66
    for (; rule; rule = rule->prev) {
 
67
        /* check if the min is the same as previous maximum */
 
68
        if (i == 0 || rule->low.value != cp->fp_lookup.vals[i - 1])
 
69
            cp->fp_lookup.vals[i++] = rule->low.value;
 
70
        cp->fp_lookup.vals[i++] = rule->high.value;
 
71
    }
 
72
    cp->fp_lookup.nalloc = i;
 
73
 
 
74
    /* now sort the values */
 
75
    qsort((char *)cp->fp_lookup.vals, cp->fp_lookup.nalloc,
 
76
          sizeof(DCELL), &double_comp);
 
77
 
 
78
    /* now find the rule to apply inbetween each 2 values in a list */
 
79
    for (i = 0; i < cp->fp_lookup.nalloc - 1; i++) {
 
80
        val = (cp->fp_lookup.vals[i] + cp->fp_lookup.vals[i + 1]) / 2.;
 
81
        /* fprintf (stderr, "%lf %lf ", cp->fp_lookup.vals[i], cp->fp_lookup.vals[i+1]); */
 
82
 
 
83
        for (rule = cp->rules; rule; rule = rule->next)
 
84
            if (rule->low.value <= val && val <= rule->high.value)
 
85
                break;
 
86
        /* if(rule) fprintf (stderr, "%d %lf %lf %d\n", i, rule->low.value, rule->high.value, rule);
 
87
           else fprintf (stderr, "null\n");
 
88
         */
 
89
        cp->fp_lookup.rules[i] = rule;
 
90
    }
 
91
    cp->fp_lookup.active = 1;
 
92
 
 
93
    return 0;
 
94
}
 
95
 
 
96
static void organize_lookup(struct Colors *colors, int mod)
 
97
{
 
98
    int i, n;
 
99
    CELL x;
 
100
    CELL cat[LOOKUP_COLORS];
 
101
    struct _Color_Info_ *cp;
 
102
 
 
103
    /* don't do anything if the color structure is float */
 
104
    if (colors->is_float)
 
105
        return;
 
106
 
 
107
    if (mod)
 
108
        cp = &colors->modular;
 
109
    else
 
110
        cp = &colors->fixed;
 
111
 
 
112
    if (cp->lookup.active)
 
113
        return;
 
114
 
 
115
    n = (CELL) cp->max - (CELL) cp->min + 1;
 
116
    if (n >= LOOKUP_COLORS || n <= 0)
 
117
        return;
 
118
 
 
119
    x = (CELL) cp->min;
 
120
    for (i = 0; i < n; i++)
 
121
        cat[i] = x++;;
 
122
 
 
123
    cp->lookup.nalloc = n;
 
124
    cp->lookup.red = (unsigned char *)G_malloc(n);
 
125
    cp->lookup.grn = (unsigned char *)G_malloc(n);
 
126
    cp->lookup.blu = (unsigned char *)G_malloc(n);
 
127
    cp->lookup.set = (unsigned char *)G_malloc(n);
 
128
 
 
129
    G_zero(cp->lookup.set, n * sizeof(unsigned char));
 
130
    Rast__lookup_colors((void *)cat,
 
131
                        cp->lookup.red, cp->lookup.grn, cp->lookup.blu,
 
132
                        cp->lookup.set, n, colors, mod, 1, CELL_TYPE);
 
133
 
 
134
    cp->lookup.active = 1;
 
135
}
 
136
 
 
137
static int double_comp(const void *xx, const void *yy)
 
138
{
 
139
    const DCELL *x = xx, *y = yy;
 
140
 
 
141
    if (*x < *y)
 
142
        return -1;
 
143
    else if (*x == *y)
 
144
        return 0;
 
145
    else
 
146
        return 1;
 
147
}