ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/color.c
(Generate patch)

Comparing ray/src/common/color.c (file contents):
Revision 1.13 by greg, Fri Oct 19 11:13:02 1990 UTC vs.
Revision 2.9 by greg, Sat Feb 22 02:07:22 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1986 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  color.c - routines for color calculations.
6   *
7 < *     10/10/85
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 <        COLR  lastcolr;
105 <        int  rept;
104 >        register int  i, j, beg, cnt = 1;
105 >        int  c2;
106          
107 <        lastcolr[RED] = lastcolr[GRN] = lastcolr[BLU] = 1;
108 <        lastcolr[EXP] = 0;
109 <        rept = 0;
110 <        
111 <        while (len > 0) {
112 <                if (scanline[0][EXP] == lastcolr[EXP] &&
113 <                                scanline[0][RED] == lastcolr[RED] &&
114 <                                scanline[0][GRN] == lastcolr[GRN] &&
115 <                                scanline[0][BLU] == lastcolr[BLU])
116 <                        rept++;
117 <                else {
118 <                        while (rept) {          /* write out count */
119 <                                putc(1, fp);
120 <                                putc(1, fp);
121 <                                putc(1, fp);
122 <                                putc(rept & 255, fp);
123 <                                rept >>= 8;
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                          }
44                        putc(scanline[0][RED], fp);     /* new color */
45                        putc(scanline[0][GRN], fp);
46                        putc(scanline[0][BLU], fp);
47                        putc(scanline[0][EXP], fp);
48                        copycolr(lastcolr, scanline[0]);
49                        rept = 0;
133                  }
134 <                scanline++;
135 <                len--;
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          }
54        while (rept) {          /* write out count */
55                putc(1, fp);
56                putc(1, fp);
57                putc(1, fp);
58                putc(rept & 255, fp);
59                rept >>= 8;
60        }
147          return(ferror(fp) ? -1 : 0);
148   }
149  
150  
151 < freadcolrs(scanline, len, fp)           /* read in a colr scanline */
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;
# Line 98 | Line 185 | register FILE  *fp;
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 < register FILE  *fp;
242 > FILE  *fp;
243   {
244 <        COLR  lastcolr, thiscolr;
245 <        int  rept;
246 <        
247 <        lastcolr[RED] = lastcolr[GRN] = lastcolr[BLU] = 1;
248 <        lastcolr[EXP] = 0;
249 <        rept = 0;
250 <        
251 <        while (len > 0) {
252 <                setcolr(thiscolr, scanline[0][RED],
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]);
117                if (thiscolr[EXP] == lastcolr[EXP] &&
118                                thiscolr[RED] == lastcolr[RED] &&
119                                thiscolr[GRN] == lastcolr[GRN] &&
120                                thiscolr[BLU] == lastcolr[BLU])
121                        rept++;
122                else {
123                        while (rept) {          /* write out count */
124                                putc(1, fp);
125                                putc(1, fp);
126                                putc(1, fp);
127                                putc(rept & 255, fp);
128                                rept >>= 8;
129                        }
130                        putc(thiscolr[RED], fp);        /* new color */
131                        putc(thiscolr[GRN], fp);
132                        putc(thiscolr[BLU], fp);
133                        putc(thiscolr[EXP], fp);
134                        copycolr(lastcolr, thiscolr);
135                        rept = 0;
136                }
257                  scanline++;
258 <                len--;
258 >                sp++;
259          }
260 <        while (rept) {          /* write out count */
141 <                putc(1, fp);
142 <                putc(1, fp);
143 <                putc(1, fp);
144 <                putc(rept & 255, fp);
145 <                rept >>= 8;
146 <        }
147 <        return(ferror(fp) ? -1 : 0);
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 < register FILE  *fp;
268 > FILE  *fp;
269   {
270 <        COLR  thiscolr;
271 <        int  rshift;
272 <        register int  i;
273 <        
274 <        rshift = 0;
275 <        
276 <        while (len > 0) {
277 <                thiscolr[RED] = getc(fp);
278 <                thiscolr[GRN] = getc(fp);
279 <                thiscolr[BLU] = getc(fp);
280 <                thiscolr[EXP] = getc(fp);
281 <                if (feof(fp) || ferror(fp))
282 <                        return(-1);
283 <                if (thiscolr[RED] == 1 &&
284 <                                thiscolr[GRN] == 1 &&
285 <                                thiscolr[BLU] == 1) {
286 <                        for (i = thiscolr[EXP] << rshift; i > 0; i--) {
173 <                                copycolor(scanline[0], scanline[-1]);
174 <                                scanline++;
175 <                                len--;
176 <                        }
177 <                        rshift += 8;
178 <                } else {
179 <                        colr_color(scanline[0], thiscolr);
180 <                        scanline++;
181 <                        len--;
182 <                        rshift = 0;
183 <                }
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   {
193        double  frexp();
297          double  d;
298          int  e;
299          
# Line 203 | Line 306 | double  r, g, b;
306                  return;
307          }
308  
309 <        d = frexp(d, &e) * 256.0 / d;
309 >        d = frexp(d, &e) * 255.9999 / d;
310  
311          clr[RED] = r * d;
312          clr[GRN] = g * d;
# Line 212 | Line 315 | double  r, g, b;
315   }
316  
317  
318 + void
319   colr_color(col, clr)            /* convert short to float color */
320   register COLOR  col;
321   register COLR  clr;
# Line 229 | Line 333 | register COLR  clr;
333   }
334  
335  
336 + int
337   bigdiff(c1, c2, md)                     /* c1 delta c2 > md? */
338   register COLOR  c1, c2;
339   double  md;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines