ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcond2.c
Revision: 3.7
Committed: Fri Jan 31 15:56:20 1997 UTC (27 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.6: +17 -2 lines
Log Message:
added gamut mapping for display devices (doesn't work w/ pcomb)

File Contents

# User Rev Content
1 greg 3.7 /* Copyright (c) 1997 Regents of the University of California */
2 greg 3.1
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * Input and output conditioning routines for pcond.
9     */
10    
11     #include "pcond.h"
12    
13    
14     RGBPRIMP inprims = stdprims; /* input primaries */
15     COLORMAT inrgb2xyz; /* convert input RGB to XYZ */
16     RGBPRIMP outprims = stdprims; /* output primaries */
17    
18     double (*lumf)() = rgblum; /* input luminance function */
19     double inpexp = 1.0; /* input exposure value */
20    
21     char *mbcalfile = NULL; /* macbethcal mapping file */
22    
23 greg 3.3 static struct mbc {
24 greg 3.7 COLORMAT cmat;
25 greg 3.3 float xa[3][6], ya[3][6];
26 greg 3.7 COLOR cmin, cmax;
27 greg 3.3 } mbcond; /* macbethcal conditioning struct */
28 greg 3.1
29     static COLOR *scanbuf; /* scanline processing buffer */
30     static int nread; /* number of scanlines processed */
31    
32    
33     double
34     rgblum(clr, scotopic) /* compute (scotopic) luminance of RGB color */
35     COLOR clr;
36     int scotopic;
37     {
38     if (scotopic) /* approximate */
39     return( WHTSEFFICACY * (colval(clr,RED)*.062 +
40     colval(clr,GRN)*.608 + colval(clr,BLU)*.330) );
41     return( WHTEFFICACY * (colval(clr,RED)*inrgb2xyz[1][0] +
42     colval(clr,GRN)*inrgb2xyz[1][1] +
43     colval(clr,BLU)*inrgb2xyz[1][2]) );
44     }
45    
46    
47     double
48     cielum(xyz, scotopic) /* compute (scotopic) luminance of CIE color */
49     COLOR xyz;
50     int scotopic;
51     {
52     if (scotopic) /* approximate */
53     return(colval(xyz,CIEY) *
54     (1.33*(1. + (colval(xyz,CIEY)+colval(xyz,CIEZ))/
55     colval(xyz,CIEX)) - 1.68));
56     return(colval(xyz,CIEY));
57     }
58    
59    
60     COLOR *
61     nextscan() /* read and condition next scanline */
62     {
63     if (nread >= numscans(&inpres)) {
64 greg 3.4 free((char *)scanbuf);
65     return(scanbuf = NULL);
66 greg 3.1 }
67 greg 3.2 if (what2do&DO_ACUITY)
68     acuscan(scanbuf, nread);
69     else if (freadscan(scanbuf, scanlen(&inpres), infp) < 0) {
70 greg 3.1 fprintf(stderr, "%s: %s: scanline read error\n",
71     progname, infn);
72     exit(1);
73     }
74     if (what2do&DO_VEIL) /* add veiling */
75 greg 3.2 addveil(scanbuf, nread);
76 greg 3.1 if (what2do&DO_COLOR) /* scotopic color loss */
77     scotscan(scanbuf, scanlen(&inpres));
78     if (what2do&DO_LINEAR) /* map luminances */
79     sfscan(scanbuf, scanlen(&inpres), scalef);
80     else
81     mapscan(scanbuf, scanlen(&inpres));
82     if (mbcalfile != NULL) /* device color correction */
83     mbscan(scanbuf, scanlen(&inpres), &mbcond);
84     else if (lumf == cielum | inprims != outprims)
85     matscan(scanbuf, scanlen(&inpres), mbcond.cmat);
86 greg 3.2 nread++;
87 greg 3.1 return(scanbuf);
88     }
89    
90    
91     COLOR *
92     firstscan() /* return first processed scanline */
93     {
94     if (mbcalfile != NULL) /* load macbethcal file */
95     getmbcalfile(mbcalfile, &mbcond);
96     else
97     if (lumf == rgblum)
98     comprgb2rgbmat(mbcond.cmat, inprims, outprims);
99     else
100     compxyz2rgbmat(mbcond.cmat, outprims);
101 greg 3.5 if (what2do&DO_ACUITY)
102 greg 3.2 initacuity();
103 greg 3.1 scanbuf = (COLOR *)malloc(scanlen(&inpres)*sizeof(COLOR));
104     if (scanbuf == NULL)
105     syserror("malloc");
106     nread = 0;
107     return(nextscan());
108     }
109    
110    
111     sfscan(sl, len, sf) /* apply scalefactor to scanline */
112     register COLOR *sl;
113     int len;
114     double sf;
115     {
116     while (len--) {
117     scalecolor(sl[0], sf);
118     sl++;
119     }
120     }
121    
122    
123     matscan(sl, len, mat) /* apply color matrix to scaline */
124     register COLOR *sl;
125     int len;
126     COLORMAT mat;
127     {
128     while (len--) {
129     colortrans(sl[0], mat, sl[0]);
130 greg 3.7 clipgamut(sl[0], bright(sl[0]), CGAMUT, cblack, cwhite);
131 greg 3.1 sl++;
132     }
133     }
134    
135    
136     mbscan(sl, len, mb) /* apply macbethcal adj. to scaline */
137     COLOR *sl;
138     int len;
139     register struct mbc *mb;
140     {
141     double d;
142     register int i, j;
143    
144     while (len--) {
145 greg 3.6 colortrans(sl[0], mb->cmat, sl[0]);
146 greg 3.7 clipgamut(sl[0], bright(sl[0]), CGAMUT, mb->cmin, mb->cmax);
147 greg 3.1 for (i = 0; i < 3; i++) {
148     d = colval(sl[0],i);
149     for (j = 0; j < 4 && mb->xa[i][j+1] <= d; j++)
150     ;
151     colval(sl[0],i) = ( (mb->xa[i][j+1] - d)*mb->ya[i][j] +
152     (d - mb->xa[i][j])*mb->ya[i][j+1] ) /
153     (mb->xa[i][j+1] - mb->xa[i][j]);
154     }
155     sl++;
156     }
157     }
158    
159    
160     getmbcalfile(fn, mb) /* load macbethcal file */
161     char *fn;
162     register struct mbc *mb;
163     {
164     extern char *fgets();
165     char buf[128];
166     FILE *fp;
167     int inpflags = 0;
168 greg 3.7 register int i;
169 greg 3.1
170     if ((fp = fopen(fn, "r")) == NULL)
171     syserror(fn);
172     while (fgets(buf, sizeof(buf), fp) != NULL) {
173     if (!(inpflags & 01) &&
174     sscanf(buf,
175     "rxa(i) : select(i,%f,%f,%f,%f,%f,%f)",
176     &mb->xa[0][0], &mb->xa[0][1],
177     &mb->xa[0][2], &mb->xa[0][3],
178     &mb->xa[0][4], &mb->xa[0][5]
179     ) == 6)
180     inpflags |= 01;
181     else if (!(inpflags & 02) &&
182     sscanf(buf,
183     "rya(i) : select(i,%f,%f,%f,%f,%f,%f)",
184     &mb->ya[0][0], &mb->ya[0][1],
185     &mb->ya[0][2], &mb->ya[0][3],
186     &mb->ya[0][4], &mb->ya[0][5]
187     ) == 6)
188     inpflags |= 02;
189     else if (!(inpflags & 04) &&
190     sscanf(buf,
191     "gxa(i) : select(i,%f,%f,%f,%f,%f,%f)",
192     &mb->xa[1][0], &mb->xa[1][1],
193     &mb->xa[1][2], &mb->xa[1][3],
194     &mb->xa[1][4], &mb->xa[1][5]
195     ) == 6)
196     inpflags |= 04;
197     else if (!(inpflags & 010) &&
198     sscanf(buf,
199     "gya(i) : select(i,%f,%f,%f,%f,%f,%f)",
200     &mb->ya[1][0], &mb->ya[1][1],
201     &mb->ya[1][2], &mb->ya[1][3],
202     &mb->ya[1][4], &mb->ya[1][5]
203     ) == 6)
204     inpflags |= 010;
205     else if (!(inpflags & 020) &&
206     sscanf(buf,
207     "bxa(i) : select(i,%f,%f,%f,%f,%f,%f)",
208     &mb->xa[2][0], &mb->xa[2][1],
209     &mb->xa[2][2], &mb->xa[2][3],
210     &mb->xa[2][4], &mb->xa[2][5]
211     ) == 6)
212     inpflags |= 020;
213     else if (!(inpflags & 040) &&
214     sscanf(buf,
215     "bya(i) : select(i,%f,%f,%f,%f,%f,%f)",
216     &mb->ya[2][0], &mb->ya[2][1],
217     &mb->ya[2][2], &mb->ya[2][3],
218     &mb->ya[2][4], &mb->ya[2][5]
219     ) == 6)
220     inpflags |= 040;
221     else if (!(inpflags & 0100) &&
222     sscanf(buf,
223 greg 3.6 "r = %f*r1 + %f*g1 + %f*b1",
224 greg 3.1 &mb->cmat[0][0], &mb->cmat[0][1],
225     &mb->cmat[0][2]) == 3)
226     inpflags |= 0100;
227     else if (!(inpflags & 0200) &&
228     sscanf(buf,
229 greg 3.6 "g = %f*r1 + %f*g1 + %f*b1",
230 greg 3.1 &mb->cmat[1][0], &mb->cmat[1][1],
231     &mb->cmat[1][2]) == 3)
232     inpflags |= 0200;
233     else if (!(inpflags & 0400) &&
234     sscanf(buf,
235 greg 3.6 "b = %f*r1 + %f*g1 + %f*b1",
236 greg 3.1 &mb->cmat[2][0], &mb->cmat[2][1],
237     &mb->cmat[2][2]) == 3)
238     inpflags |= 0400;
239     }
240     if (inpflags != 0777) {
241     fprintf(stderr,
242     "%s: cannot grok macbethcal file \"%s\" (inpflags==0%o)\n",
243     progname, fn, inpflags);
244     exit(1);
245     }
246     fclose(fp);
247 greg 3.7 /* compute gamut */
248     for (i = 0; i < 3; i++) {
249     colval(mb->cmin,i) = mb->xa[i][0] -
250     mb->ya[i][0] *
251     (mb->xa[i][1]-mb->xa[i][0]) /
252     (mb->ya[i][1]-mb->ya[i][0]);
253     colval(mb->cmax,i) = mb->xa[i][4] +
254     (1.-mb->ya[i][4]) *
255     (mb->xa[i][5] - mb->xa[i][4]) /
256     (mb->ya[i][5] - mb->ya[i][4]);
257     }
258 greg 3.1 }