1 |
/* Copyright (c) 1990 Regents of the University of California */ |
2 |
|
3 |
#ifndef lint |
4 |
static char SCCSid[] = "$SunId$ LBL"; |
5 |
#endif |
6 |
|
7 |
/* |
8 |
* Load lamp data. |
9 |
*/ |
10 |
|
11 |
#include <stdio.h> |
12 |
#include <ctype.h> |
13 |
|
14 |
extern char *eindex(), *expsave(), *malloc(); |
15 |
extern FILE *fropen(); |
16 |
|
17 |
typedef struct lamp { |
18 |
char *pattern; /* search pattern */ |
19 |
float *color; /* pointer to lamp value */ |
20 |
struct lamp *next; /* next lamp in list */ |
21 |
} LAMP; /* a lamp entry */ |
22 |
|
23 |
static LAMP *lamps = NULL; /* lamp list */ |
24 |
|
25 |
|
26 |
float * |
27 |
matchlamp(s) /* see if string matches any lamp */ |
28 |
char *s; |
29 |
{ |
30 |
register LAMP *lp; |
31 |
|
32 |
for (lp = lamps; lp != NULL; lp = lp->next) { |
33 |
expset(lp->pattern); |
34 |
if (eindex(s) != NULL) |
35 |
return(lp->color); |
36 |
} |
37 |
return(NULL); |
38 |
} |
39 |
|
40 |
|
41 |
loadlamps(file) /* load lamp type file */ |
42 |
char *file; |
43 |
{ |
44 |
LAMP *lastp; |
45 |
register LAMP *lp; |
46 |
FILE *fp; |
47 |
float xyz[3]; |
48 |
char buf[128], str[128]; |
49 |
register char *cp1, *cp2; |
50 |
|
51 |
if ((fp = fropen(file)) == NULL) |
52 |
return(0); |
53 |
lastp = NULL; |
54 |
while (fgets(buf, sizeof(buf), fp) != NULL) { |
55 |
/* work on a copy of buffer */ |
56 |
strcpy(str, buf); |
57 |
/* get pattern for this entry */ |
58 |
for (cp1 = str; isspace(*cp1); cp1++) |
59 |
; |
60 |
if (!*cp1 || *cp1 == '#') |
61 |
continue; |
62 |
for (cp2 = cp1+1; *cp2; cp2++) |
63 |
if (*cp2 == *cp1 && cp2[-1] != '\\') |
64 |
break; |
65 |
if (!*cp2) { |
66 |
cp1 = "unclosed pattern"; |
67 |
goto fmterr; |
68 |
} |
69 |
cp1++; *cp2++ = '\0'; |
70 |
if (ecompile(cp1, 1, 0) < 0) { |
71 |
cp1 = "bad regular expression"; |
72 |
goto fmterr; |
73 |
} |
74 |
if ((lp = (LAMP *)malloc(sizeof(LAMP))) == NULL) |
75 |
goto memerr; |
76 |
if ((lp->pattern = expsave()) == NULL) |
77 |
goto memerr; |
78 |
/* get specification */ |
79 |
for (cp1 = cp2; isspace(*cp1); cp1++) |
80 |
; |
81 |
if (!isdigit(*cp1) && *cp1 != '.' && *cp1 != '(') { |
82 |
cp1 = "missing lamp specification"; |
83 |
goto fmterr; |
84 |
} |
85 |
if (*cp1 == '(') { /* find alias */ |
86 |
for (cp2 = ++cp1; *cp2; cp2++) |
87 |
if (*cp2 == ')' && cp2[-1] != '\\') |
88 |
break; |
89 |
*cp2 = '\0'; |
90 |
if ((lp->color = matchlamp(cp1)) == NULL) { |
91 |
cp1 = "unmatched alias"; |
92 |
goto fmterr; |
93 |
} |
94 |
} else { /* or read specificaion */ |
95 |
if ((lp->color=(float *)malloc(3*sizeof(float)))==NULL) |
96 |
goto memerr; |
97 |
if (sscanf(cp1, "%f %f %f", &lp->color[0], & |
98 |
lp->color[1], &lp->color[2]) != 3) { |
99 |
cp1 = "bad lamp data"; |
100 |
goto fmterr; |
101 |
} |
102 |
/* convert xyY to XYZ */ |
103 |
xyz[1] = lp->color[2]; |
104 |
xyz[0] = lp->color[0]/lp->color[1] * xyz[1]; |
105 |
xyz[2] = xyz[1]*(1./lp->color[1] - 1.) - xyz[0]; |
106 |
/* XYZ to RGB */ |
107 |
cie_rgb(lp->color, xyz); |
108 |
} |
109 |
if (lastp == NULL) |
110 |
lamps = lp; |
111 |
else |
112 |
lastp->next = lp; |
113 |
lp->next = NULL; |
114 |
lastp = lp; |
115 |
} |
116 |
fclose(fp); |
117 |
return(1); |
118 |
memerr: |
119 |
fputs("Out of memory in loadlamps\n", stderr); |
120 |
return(-1); |
121 |
fmterr: |
122 |
fputs(buf, stderr); |
123 |
fprintf(stderr, "%s: %s\n", file, cp1); |
124 |
return(-1); |
125 |
} |
126 |
|
127 |
|
128 |
freelamps() /* free our lamps list */ |
129 |
{ |
130 |
register LAMP *lp1, *lp2; |
131 |
|
132 |
for (lp1 = lamps; lp1 != NULL; lp1 = lp1->next) { |
133 |
free(lp1->pattern); |
134 |
if (lp1->color != NULL) { |
135 |
for (lp2 = lp1->next; lp2 != NULL; lp2 = lp2->next) |
136 |
if (lp2->color == lp1->color) |
137 |
lp2->color = NULL; |
138 |
free((char *)lp1->color); |
139 |
} |
140 |
free((char *)lp1); |
141 |
} |
142 |
lamps = NULL; |
143 |
} |