1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8 /*
9 */
10
11 #include <dxconfig.h>
12
13
14 /***
15 MODULE:
16 AutoGrayScale
17 SHORTDESCRIPTION:
18 Adds color and opacity information to data, to prepare it for rendering.
19 CATEGORY:
20 Data Transformation
21 INPUTS:
22 data; scalar field; NULL; field to color
23 opacity; scalar; data dependent; opacity
24 hue; scalar; data dependent; color
25 start; scalar; 0.6666; starting color (default blue)
26 range; scalar; 0.6666; range of color (default blue -> red)
27 saturation; scalar; 1.00; saturation
28 min; scalar or scalar field; data dependent; minimum of data to map
29 max; scalar or scalar field; data dependent; maximum of data to map
30 delayed; flag; 0; delay application of color and opacity maps
31 OUTPUTS:
32 mapped; color field; NULL; color mapped input field
33 colormap; field; NULL; rgb color map used
34 FLAGS:
35 BUGS:
36 AUTHOR:
37 dl gresh
38 END:
39 ***/
40
41 #include <string.h>
42 #include <ctype.h>
43 #include <dx/dx.h>
44 #include "_autogray.h"
45 #include "_autocolor.h"
46 #include "_glyph.h"
47
48 int
m_AutoGrayScale(Object * in,Object * out)49 m_AutoGrayScale(Object *in, Object *out)
50 {
51 Group g_in;
52 Array onearray=NULL;
53 float opacity, hue, phase, range, saturation;
54 float inputmin, inputmax, r, g, b;
55 float *inputminp=(&inputmin), *inputmaxp=(&inputmax);
56 int used_object, delayed, i, count, one=1;
57 Object colormap;
58 char *colorstr, newstring[21];
59 RGBColor colorvecmin, colorvecmax;
60 RGBColor cv[2];
61
62
63 /* at this point it is assumed that the input group g_in is a composite
64 field (i.e. that all of the subfields are of a uniform type). */
65
66 if(!(g_in = (Group)in[0])) {
67 out[0] = NULL;
68 /* missing first parameter */
69 DXSetError(ERROR_MISSING_DATA, "#10000", "data");
70 return ERROR;
71 }
72
73 if (!(_dxfFieldWithInformation((Object)in[0]))) {
74 out[0] = in[0];
75 out[1] = (Object)DXNewField();
76 return OK;
77 }
78
79 if (!in[1])
80 opacity = -1.0;
81 else if (!DXExtractFloat((Object)in[1],&opacity)) {
82 /* bad opacity input; must be a float between 0 and 1 */
83 DXSetError(ERROR_BAD_PARAMETER,"#10110", "opacity", 0, 1);
84 return ERROR;
85 }
86 else if ((opacity < 0.0)||(opacity > 1.0)) {
87 /* bad opacity input; must be a float between 0 and 1 */
88 DXSetError(ERROR_BAD_PARAMETER,"#10110", "opacity", 0, 1);
89 return ERROR;
90 }
91 if (!in[2])
92 hue = 0.66666;
93 else if (!DXExtractFloat((Object)in[2],&hue)) {
94 /* bad hue input; must be a scalar value*/
95 DXSetError(ERROR_BAD_PARAMETER,"#10080","hue");
96 return ERROR;
97 }
98
99 if (!in[3])
100 phase = 0.0;
101 else if (!DXExtractFloat((Object)in[3],&phase)) {
102 /* bad phase, must be a float */
103 DXSetError(ERROR_BAD_PARAMETER,"#10090", "start");
104 return ERROR;
105 }
106 if (phase < 0.0) {
107 DXSetError(ERROR_BAD_PARAMETER,"#10090", "start");
108 return ERROR;
109 }
110
111 if (!in[4])
112 range = 1.0;
113 else if (!DXExtractFloat((Object)in[4],&range)) {
114 /* bad range, must be a float */
115 DXSetError(ERROR_BAD_PARAMETER,"#10080","range");
116 return ERROR;
117 }
118
119 if (phase+range < 0.0) {
120 DXSetError(ERROR_BAD_PARAMETER,"#10090", "start+range");
121 return ERROR;
122 }
123
124 if (!in[5])
125 saturation = 0.0;
126 else if (!DXExtractFloat((Object)in[5],&saturation)) {
127 /* bad saturation, must be a float between 0 and 1 */
128 DXSetError(ERROR_BAD_PARAMETER,"#10110","saturation", 0, 1);
129 return ERROR;
130 }
131 else if ((saturation < 0.0)||(saturation > 1.0)) {
132 /* bad saturation input; must be a float between 0 and 1 */
133 DXSetError(ERROR_BAD_PARAMETER,"#10110", "saturation", 0, 1);
134 return ERROR;
135 }
136
137 /* if in[6] is an object, and in[7] is null, then we want to
138 make inputmax be the max of the object, rather than the normal
139 default */
140
141 used_object = 0;
142
143
144 if (!in[6])
145 inputminp = NULL;
146 else if (!DXExtractFloat((Object)in[6],inputminp)) {
147 if (_dxfIsFieldorGroup((Object)in[6])) {
148 /* get max and min */
149 if (!DXStatistics((Object)in[6],"data",inputminp,inputmaxp,
150 NULL,NULL))
151 {
152 /* min must be a field or a scalar value */
153 DXAddMessage("min parameter");
154 return ERROR;
155 }
156 else
157 used_object++;
158 }
159 else {
160 /* min must be a field or a scalar value */
161 DXSetError(ERROR_BAD_PARAMETER,"#10520","min");
162 return ERROR;
163 }
164 }
165
166 if (!in[7]) {
167 if (!used_object)
168 inputmaxp = NULL;
169 /* implicit else, max was set above */
170 }
171 else if (!DXExtractFloat((Object)in[7],inputmaxp)) {
172 if (_dxfIsFieldorGroup((Object)in[7])) {
173 if (!DXStatistics((Object)in[7],"data",NULL,inputmaxp,NULL,
174 NULL)) {
175 /* max must be a field or a scalar value */
176 DXAddMessage("max parameter");
177 return ERROR;
178 }
179 }
180 else {
181 /* max must be a field or a scalar value */
182 DXSetError(ERROR_BAD_PARAMETER,"#10520", "max");
183 return ERROR;
184 }
185 }
186
187 if (!in[8])
188 delayed = 0;
189 else {
190 if (!(DXExtractInteger(in[8],&delayed))) {
191 DXSetError(ERROR_BAD_PARAMETER, "#10070", "delayed");
192 return ERROR;
193 }
194 if ((delayed != 0)&&(delayed != 1)) {
195 DXSetError(ERROR_BAD_PARAMETER, "#10070", "delayed");
196 return ERROR;
197 }
198 }
199
200
201 if (!in[9]) {
202 /* the default */
203 _dxfHSVtoRGB(hue, saturation, phase, &r, &g, &b);
204 colorvecmin = DXRGB(r, g, b);
205 _dxfHSVtoRGB(hue, saturation, phase+range, &r, &g, &b);
206 colorvecmax = DXRGB(r, g, b);
207 }
208 /* first try a string */
209 else if (DXExtractNthString(in[9], 0, &colorstr)) {
210 /* is it a valid color name? */
211 if (!(DXColorNameToRGB(colorstr, &colorvecmin))) {
212 /* if it's not a valid colorname, is it "min" or "max"? */
213 count = 0;
214 i=0;
215 while (i<20 && colorstr[i] != '\0') {
216 for (i=0; i< 20; i++) {
217 if (isalpha(colorstr[i])) {
218 newstring[count]=tolower(colorstr[i]);
219 count++;
220 }
221 else {
222 if (colorstr[i] != ' ') {
223 newstring[count] = colorstr[i];
224 count++;
225 }
226 }
227 }
228 }
229 if (!strcmp(newstring, "colorofmin")) {
230 DXResetError();
231 _dxfHSVtoRGB(hue, saturation, phase, &r, &g, &b);
232 colorvecmin = DXRGB(r,g,b);
233 }
234 else if (!strcmp(newstring,"colorofmax")) {
235 DXResetError();
236 _dxfHSVtoRGB(hue, saturation, phase+range, &r, &g, &b);
237 colorvecmin = DXRGB(r,g,b);
238 }
239 else goto error;
240 }
241 /* start by setting max = min */
242 colorvecmax=colorvecmin;
243 /* now look and see if there's a second string hanging around */
244 if (DXExtractNthString(in[9], 1, &colorstr)) {
245 /* is it a valid color name? */
246 if (!(DXColorNameToRGB(colorstr, &colorvecmax))) {
247 /* if it's not a valid colorname, is it "min" or "max"? */
248 count = 0;
249 i=0;
250 while (i<20 && colorstr[i] != '\0') {
251 for (i=0; i< 20; i++) {
252 if (isalpha(colorstr[i])) {
253 newstring[count]=tolower(colorstr[i]);
254 count++;
255 }
256 else {
257 if (colorstr[i] != ' ') {
258 newstring[count] = colorstr[i];
259 count++;
260 }
261 }
262 }
263 }
264 if (!strcmp(newstring, "colorofmin")) {
265 DXResetError();
266 _dxfHSVtoRGB(hue, saturation, phase, &r, &g, &b);
267 colorvecmax = DXRGB(r,g,b);
268 }
269 else if (!strcmp(newstring,"colorofmax")) {
270 DXResetError();
271 _dxfHSVtoRGB(hue, saturation, phase+range, &r, &g, &b);
272 colorvecmax = DXRGB(r,g,b);
273 }
274 else goto error;
275 }
276 }
277 }
278 else if ((DXExtractParameter(in[9], TYPE_FLOAT, 3, 1,
279 (Pointer)&colorvecmin))) {
280 colorvecmax = colorvecmin;
281 }
282 else if ((DXExtractParameter(in[9], TYPE_FLOAT, 3, 2, (Pointer)&cv))) {
283 colorvecmin = cv[0];
284 colorvecmax = cv[1];
285 }
286 else {
287 DXSetError(ERROR_BAD_PARAMETER,
288 "outofrange must be a color string or pair of color strings, \"color of min\" or \"color of max\", or a 3-vector or pair of 3 vectors");
289 goto error;
290 }
291
292
293 out[0] = (Object)_dxfAutoGrayScale((Object)g_in, opacity,
294 hue, phase, range, saturation,
295 inputminp, inputmaxp,
296 &colormap, delayed,
297 colorvecmin, colorvecmax);
298 if (out[0]) out[1] = (Object)colormap;
299
300 /* for delayed colors, add the direct color map attribute */
301 if (delayed) {
302 onearray = DXNewArray(TYPE_INT,CATEGORY_REAL, 0);
303 if (!DXAddArrayData(onearray, 0, 1, &one))
304 goto error;
305 if (!DXSetAttribute(out[0], "direct color map", (Object) onearray))
306 goto error;
307 onearray = NULL;
308 }
309
310
311
312
313 if ((!out[0])||(!(out[1])))
314 return ERROR;
315 else
316 return OK;
317
318 error:
319 DXDelete((Object)onearray);
320 return ERROR;
321 }
322
323
324
325
326