ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/color.c
Revision: 2.9
Committed: Sat Feb 22 02:07:22 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.8: +117 -50 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 /*
5 * color.c - routines for color calculations.
6 *
7 * Externals declared in color.h
8 */
9
10 /* ====================================================================
11 * The Radiance Software License, Version 1.0
12 *
13 * Copyright (c) 1990 - 2002 The Regents of the University of California,
14 * through Lawrence Berkeley National Laboratory. All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 *
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 *
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in
25 * the documentation and/or other materials provided with the
26 * distribution.
27 *
28 * 3. The end-user documentation included with the redistribution,
29 * if any, must include the following acknowledgment:
30 * "This product includes Radiance software
31 * (http://radsite.lbl.gov/)
32 * developed by the Lawrence Berkeley National Laboratory
33 * (http://www.lbl.gov/)."
34 * Alternately, this acknowledgment may appear in the software itself,
35 * if and wherever such third-party acknowledgments normally appear.
36 *
37 * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
38 * and "The Regents of the University of California" must
39 * not be used to endorse or promote products derived from this
40 * software without prior written permission. For written
41 * permission, please contact [email protected].
42 *
43 * 5. Products derived from this software may not be called "Radiance",
44 * nor may "Radiance" appear in their name, without prior written
45 * permission of Lawrence Berkeley National Laboratory.
46 *
47 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
48 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50 * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
51 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
53 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
54 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
56 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 * ====================================================================
60 *
61 * This software consists of voluntary contributions made by many
62 * individuals on behalf of Lawrence Berkeley National Laboratory. For more
63 * information on Lawrence Berkeley National Laboratory, please see
64 * <http://www.lbl.gov/>.
65 */
66
67 #include <stdio.h>
68
69 #include <stdlib.h>
70
71 #include <math.h>
72
73 #include "color.h"
74
75 #define MINELEN 8 /* minimum scanline length for encoding */
76 #define MAXELEN 0x7fff /* maximum scanline length for encoding */
77 #define MINRUN 4 /* minimum run length */
78
79
80 char *
81 tempbuffer(len) /* get a temporary buffer */
82 unsigned int len;
83 {
84 static char *tempbuf = NULL;
85 static unsigned tempbuflen = 0;
86
87 if (len > tempbuflen) {
88 if (tempbuflen > 0)
89 tempbuf = (char *)realloc(tempbuf, len);
90 else
91 tempbuf = (char *)malloc(len);
92 tempbuflen = tempbuf==NULL ? 0 : len;
93 }
94 return(tempbuf);
95 }
96
97
98 int
99 fwritecolrs(scanline, len, fp) /* write out a colr scanline */
100 register COLR *scanline;
101 int len;
102 register FILE *fp;
103 {
104 register int i, j, beg, cnt = 1;
105 int c2;
106
107 if (len < MINELEN | len > MAXELEN) /* OOBs, write out flat */
108 return(fwrite((char *)scanline,sizeof(COLR),len,fp) - len);
109 /* put magic header */
110 putc(2, fp);
111 putc(2, fp);
112 putc(len>>8, fp);
113 putc(len&255, fp);
114 /* put components seperately */
115 for (i = 0; i < 4; i++) {
116 for (j = 0; j < len; j += cnt) { /* find next run */
117 for (beg = j; beg < len; beg += cnt) {
118 for (cnt = 1; cnt < 127 && beg+cnt < len &&
119 scanline[beg+cnt][i] == scanline[beg][i]; cnt++)
120 ;
121 if (cnt >= MINRUN)
122 break; /* long enough */
123 }
124 if (beg-j > 1 && beg-j < MINRUN) {
125 c2 = j+1;
126 while (scanline[c2++][i] == scanline[j][i])
127 if (c2 == beg) { /* short run */
128 putc(128+beg-j, fp);
129 putc(scanline[j][i], fp);
130 j = beg;
131 break;
132 }
133 }
134 while (j < beg) { /* write out non-run */
135 if ((c2 = beg-j) > 128) c2 = 128;
136 putc(c2, fp);
137 while (c2--)
138 putc(scanline[j++][i], fp);
139 }
140 if (cnt >= MINRUN) { /* write out run */
141 putc(128+cnt, fp);
142 putc(scanline[beg][i], fp);
143 } else
144 cnt = 0;
145 }
146 }
147 return(ferror(fp) ? -1 : 0);
148 }
149
150
151 static int
152 oldreadcolrs(scanline, len, fp) /* read in an old colr scanline */
153 register COLR *scanline;
154 int len;
155 register FILE *fp;
156 {
157 int rshift;
158 register int i;
159
160 rshift = 0;
161
162 while (len > 0) {
163 scanline[0][RED] = getc(fp);
164 scanline[0][GRN] = getc(fp);
165 scanline[0][BLU] = getc(fp);
166 scanline[0][EXP] = getc(fp);
167 if (feof(fp) || ferror(fp))
168 return(-1);
169 if (scanline[0][RED] == 1 &&
170 scanline[0][GRN] == 1 &&
171 scanline[0][BLU] == 1) {
172 for (i = scanline[0][EXP] << rshift; i > 0; i--) {
173 copycolr(scanline[0], scanline[-1]);
174 scanline++;
175 len--;
176 }
177 rshift += 8;
178 } else {
179 scanline++;
180 len--;
181 rshift = 0;
182 }
183 }
184 return(0);
185 }
186
187
188 int
189 freadcolrs(scanline, len, fp) /* read in an encoded colr scanline */
190 register COLR *scanline;
191 int len;
192 register FILE *fp;
193 {
194 register int i, j;
195 int code, val;
196 /* determine scanline type */
197 if (len < MINELEN | len > MAXELEN)
198 return(oldreadcolrs(scanline, len, fp));
199 if ((i = getc(fp)) == EOF)
200 return(-1);
201 if (i != 2) {
202 ungetc(i, fp);
203 return(oldreadcolrs(scanline, len, fp));
204 }
205 scanline[0][GRN] = getc(fp);
206 scanline[0][BLU] = getc(fp);
207 if ((i = getc(fp)) == EOF)
208 return(-1);
209 if (scanline[0][GRN] != 2 || scanline[0][BLU] & 128) {
210 scanline[0][RED] = 2;
211 scanline[0][EXP] = i;
212 return(oldreadcolrs(scanline+1, len-1, fp));
213 }
214 if ((scanline[0][BLU]<<8 | i) != len)
215 return(-1); /* length mismatch! */
216 /* read each component */
217 for (i = 0; i < 4; i++)
218 for (j = 0; j < len; ) {
219 if ((code = getc(fp)) == EOF)
220 return(-1);
221 if (code > 128) { /* run */
222 code &= 127;
223 if ((val = getc(fp)) == EOF)
224 return -1;
225 while (code--)
226 scanline[j++][i] = val;
227 } else /* non-run */
228 while (code--) {
229 if ((val = getc(fp)) == EOF)
230 return -1;
231 scanline[j++][i] = val;
232 }
233 }
234 return(0);
235 }
236
237
238 int
239 fwritescan(scanline, len, fp) /* write out a scanline */
240 register COLOR *scanline;
241 int len;
242 FILE *fp;
243 {
244 COLR *clrscan;
245 int n;
246 register COLR *sp;
247 /* get scanline buffer */
248 if ((sp = (COLR *)tempbuffer(len*sizeof(COLR))) == NULL)
249 return(-1);
250 clrscan = sp;
251 /* convert scanline */
252 n = len;
253 while (n-- > 0) {
254 setcolr(sp[0], scanline[0][RED],
255 scanline[0][GRN],
256 scanline[0][BLU]);
257 scanline++;
258 sp++;
259 }
260 return(fwritecolrs(clrscan, len, fp));
261 }
262
263
264 int
265 freadscan(scanline, len, fp) /* read in a scanline */
266 register COLOR *scanline;
267 int len;
268 FILE *fp;
269 {
270 register COLR *clrscan;
271
272 if ((clrscan = (COLR *)tempbuffer(len*sizeof(COLR))) == NULL)
273 return(-1);
274 if (freadcolrs(clrscan, len, fp) < 0)
275 return(-1);
276 /* convert scanline */
277 colr_color(scanline[0], clrscan[0]);
278 while (--len > 0) {
279 scanline++; clrscan++;
280 if (clrscan[0][RED] == clrscan[-1][RED] &&
281 clrscan[0][GRN] == clrscan[-1][GRN] &&
282 clrscan[0][BLU] == clrscan[-1][BLU] &&
283 clrscan[0][EXP] == clrscan[-1][EXP])
284 copycolor(scanline[0], scanline[-1]);
285 else
286 colr_color(scanline[0], clrscan[0]);
287 }
288 return(0);
289 }
290
291
292 void
293 setcolr(clr, r, g, b) /* assign a short color value */
294 register COLR clr;
295 double r, g, b;
296 {
297 double d;
298 int e;
299
300 d = r > g ? r : g;
301 if (b > d) d = b;
302
303 if (d <= 1e-32) {
304 clr[RED] = clr[GRN] = clr[BLU] = 0;
305 clr[EXP] = 0;
306 return;
307 }
308
309 d = frexp(d, &e) * 255.9999 / d;
310
311 clr[RED] = r * d;
312 clr[GRN] = g * d;
313 clr[BLU] = b * d;
314 clr[EXP] = e + COLXS;
315 }
316
317
318 void
319 colr_color(col, clr) /* convert short to float color */
320 register COLOR col;
321 register COLR clr;
322 {
323 double f;
324
325 if (clr[EXP] == 0)
326 col[RED] = col[GRN] = col[BLU] = 0.0;
327 else {
328 f = ldexp(1.0, (int)clr[EXP]-(COLXS+8));
329 col[RED] = (clr[RED] + 0.5)*f;
330 col[GRN] = (clr[GRN] + 0.5)*f;
331 col[BLU] = (clr[BLU] + 0.5)*f;
332 }
333 }
334
335
336 int
337 bigdiff(c1, c2, md) /* c1 delta c2 > md? */
338 register COLOR c1, c2;
339 double md;
340 {
341 register int i;
342
343 for (i = 0; i < 3; i++)
344 if (colval(c1,i)-colval(c2,i) > md*colval(c2,i) ||
345 colval(c2,i)-colval(c1,i) > md*colval(c1,i))
346 return(1);
347 return(0);
348 }