ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/colrops.c
Revision: 2.6
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.5: +66 -8 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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.6 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4     /*
5     * Integer operations on COLR scanlines
6     */
7    
8 greg 2.6 /* ====================================================================
9     * The Radiance Software License, Version 1.0
10     *
11     * Copyright (c) 1990 - 2002 The Regents of the University of California,
12     * through Lawrence Berkeley National Laboratory. All rights reserved.
13     *
14     * Redistribution and use in source and binary forms, with or without
15     * modification, are permitted provided that the following conditions
16     * are met:
17     *
18     * 1. Redistributions of source code must retain the above copyright
19     * notice, this list of conditions and the following disclaimer.
20     *
21     * 2. Redistributions in binary form must reproduce the above copyright
22     * notice, this list of conditions and the following disclaimer in
23     * the documentation and/or other materials provided with the
24     * distribution.
25     *
26     * 3. The end-user documentation included with the redistribution,
27     * if any, must include the following acknowledgment:
28     * "This product includes Radiance software
29     * (http://radsite.lbl.gov/)
30     * developed by the Lawrence Berkeley National Laboratory
31     * (http://www.lbl.gov/)."
32     * Alternately, this acknowledgment may appear in the software itself,
33     * if and wherever such third-party acknowledgments normally appear.
34     *
35     * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
36     * and "The Regents of the University of California" must
37     * not be used to endorse or promote products derived from this
38     * software without prior written permission. For written
39     * permission, please contact [email protected].
40     *
41     * 5. Products derived from this software may not be called "Radiance",
42     * nor may "Radiance" appear in their name, without prior written
43     * permission of Lawrence Berkeley National Laboratory.
44     *
45     * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48     * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
49     * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52     * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54     * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56     * SUCH DAMAGE.
57     * ====================================================================
58     *
59     * This software consists of voluntary contributions made by many
60     * individuals on behalf of Lawrence Berkeley National Laboratory. For more
61     * information on Lawrence Berkeley National Laboratory, please see
62     * <http://www.lbl.gov/>.
63     */
64    
65     #include <math.h>
66 greg 1.1 #include "color.h"
67    
68 greg 2.3 #define NULL 0
69 greg 1.1
70 greg 2.3 extern char *bmalloc();
71 greg 1.1
72 greg 2.3 #define MAXGSHIFT 31 /* maximum shift for gamma table */
73 greg 1.1
74 greg 2.3 static BYTE *g_mant = NULL, *g_nexp = NULL;
75 greg 1.1
76 greg 2.3 static BYTE (*g_bval)[256] = NULL;
77    
78    
79 greg 2.6 int
80 greg 2.3 setcolrcor(f, a2) /* set brightness correction */
81     double (*f)();
82     double a2;
83 greg 1.1 {
84     double mult;
85     register int i, j;
86 greg 2.3 /* allocate tables */
87     if (g_bval == NULL && (g_bval =
88     (BYTE (*)[256])bmalloc((MAXGSHIFT+1)*256)) == NULL)
89     return(-1);
90 greg 1.1 /* compute colr -> gamb mapping */
91 greg 2.3 mult = 1.0/256.0;
92 greg 1.1 for (i = 0; i <= MAXGSHIFT; i++) {
93     for (j = 0; j < 256; j++)
94 greg 2.3 g_bval[i][j] = 256.0 * (*f)((j+.5)*mult, a2);
95     mult *= 0.5;
96 greg 1.1 }
97 greg 2.3 return(0);
98     }
99    
100    
101 greg 2.6 int
102 greg 2.3 setcolrinv(f, a2) /* set inverse brightness correction */
103     double (*f)();
104     double a2;
105     {
106     double mult;
107     register int i, j;
108     /* allocate tables */
109     if (g_mant == NULL && (g_mant = (BYTE *)bmalloc(256)) == NULL)
110     return(-1);
111     if (g_nexp == NULL && (g_nexp = (BYTE *)bmalloc(256)) == NULL)
112     return(-1);
113 greg 1.1 /* compute gamb -> colr mapping */
114     i = 0;
115     mult = 256.0;
116 gregl 2.5 for (j = 256; j--; ) {
117     while ((g_mant[j] = mult * (*f)((j+.5)/256.0, a2)) < 128) {
118 greg 1.1 i++;
119     mult *= 2.0;
120     }
121     g_nexp[j] = i;
122     }
123 greg 2.3 return(0);
124 greg 1.1 }
125    
126    
127 greg 2.6 int
128 greg 2.3 setcolrgam(g) /* set gamma conversion */
129     double g;
130     {
131     if (setcolrcor(pow, 1.0/g) < 0)
132     return(-1);
133     return(setcolrinv(pow, g));
134     }
135    
136    
137 greg 2.6 int
138 greg 1.1 colrs_gambs(scan, len) /* convert scanline of colrs to gamma bytes */
139     register COLR *scan;
140     int len;
141     {
142     register int i, expo;
143    
144 greg 2.3 if (g_bval == NULL)
145     return(-1);
146 greg 1.1 while (len-- > 0) {
147     expo = scan[0][EXP] - COLXS;
148     if (expo < -MAXGSHIFT) {
149     if (expo < -MAXGSHIFT-8) {
150     scan[0][RED] =
151     scan[0][GRN] =
152     scan[0][BLU] = 0;
153     } else {
154     i = (-MAXGSHIFT-1) - expo;
155     scan[0][RED] =
156     g_bval[MAXGSHIFT][((scan[0][RED]>>i)+1)>>1];
157     scan[0][GRN] =
158     g_bval[MAXGSHIFT][((scan[0][GRN]>>i)+1)>>1];
159     scan[0][BLU] =
160     g_bval[MAXGSHIFT][((scan[0][BLU]>>i)+1)>>1];
161     }
162     } else if (expo > 0) {
163     if (expo > 8) {
164     scan[0][RED] =
165     scan[0][GRN] =
166     scan[0][BLU] = 255;
167     } else {
168     i = (scan[0][RED]<<1 | 1) << (expo-1);
169     scan[0][RED] = i > 255 ? 255 : g_bval[0][i];
170     i = (scan[0][GRN]<<1 | 1) << (expo-1);
171     scan[0][GRN] = i > 255 ? 255 : g_bval[0][i];
172     i = (scan[0][BLU]<<1 | 1) << (expo-1);
173     scan[0][BLU] = i > 255 ? 255 : g_bval[0][i];
174     }
175     } else {
176     scan[0][RED] = g_bval[-expo][scan[0][RED]];
177     scan[0][GRN] = g_bval[-expo][scan[0][GRN]];
178     scan[0][BLU] = g_bval[-expo][scan[0][BLU]];
179     }
180     scan[0][EXP] = COLXS;
181     scan++;
182     }
183 greg 2.3 return(0);
184 greg 1.1 }
185    
186    
187 greg 2.6 int
188 greg 1.1 gambs_colrs(scan, len) /* convert gamma bytes to colr scanline */
189     register COLR *scan;
190     int len;
191     {
192     register int nexpo;
193    
194 greg 2.3 if (g_mant == NULL | g_nexp == NULL)
195     return(-1);
196 greg 1.1 while (len-- > 0) {
197     nexpo = g_nexp[scan[0][RED]];
198     if (g_nexp[scan[0][GRN]] < nexpo)
199     nexpo = g_nexp[scan[0][GRN]];
200     if (g_nexp[scan[0][BLU]] < nexpo)
201     nexpo = g_nexp[scan[0][BLU]];
202     if (nexpo < g_nexp[scan[0][RED]])
203     scan[0][RED] = g_mant[scan[0][RED]]
204     >> (g_nexp[scan[0][RED]]-nexpo);
205     else
206     scan[0][RED] = g_mant[scan[0][RED]];
207     if (nexpo < g_nexp[scan[0][GRN]])
208     scan[0][GRN] = g_mant[scan[0][GRN]]
209     >> (g_nexp[scan[0][GRN]]-nexpo);
210     else
211     scan[0][GRN] = g_mant[scan[0][GRN]];
212     if (nexpo < g_nexp[scan[0][BLU]])
213     scan[0][BLU] = g_mant[scan[0][BLU]]
214     >> (g_nexp[scan[0][BLU]]-nexpo);
215     else
216     scan[0][BLU] = g_mant[scan[0][BLU]];
217     scan[0][EXP] = COLXS - nexpo;
218     scan++;
219     }
220 greg 2.3 return(0);
221 greg 1.1 }
222    
223    
224 greg 2.6 void
225 greg 1.1 shiftcolrs(scan, len, adjust) /* shift a scanline of colors by 2^adjust */
226     register COLR *scan;
227     register int len;
228     register int adjust;
229     {
230 greg 2.2 int minexp;
231    
232     if (adjust == 0)
233     return;
234     minexp = adjust < 0 ? -adjust : 0;
235 greg 1.1 while (len-- > 0) {
236 greg 2.2 if (scan[0][EXP] <= minexp)
237     scan[0][RED] = scan[0][GRN] = scan[0][BLU] =
238     scan[0][EXP] = 0;
239     else
240     scan[0][EXP] += adjust;
241 greg 1.1 scan++;
242     }
243     }
244    
245    
246 greg 2.6 void
247 greg 1.1 normcolrs(scan, len, adjust) /* normalize a scanline of colrs */
248     register COLR *scan;
249     int len;
250     int adjust;
251     {
252     register int c;
253     register int shift;
254    
255     while (len-- > 0) {
256     shift = scan[0][EXP] + adjust - COLXS;
257     if (shift > 0) {
258     if (shift > 8) {
259     scan[0][RED] =
260     scan[0][GRN] =
261     scan[0][BLU] = 255;
262     } else {
263     shift--;
264     c = (scan[0][RED]<<1 | 1) << shift;
265     scan[0][RED] = c > 255 ? 255 : c;
266     c = (scan[0][GRN]<<1 | 1) << shift;
267     scan[0][GRN] = c > 255 ? 255 : c;
268     c = (scan[0][BLU]<<1 | 1) << shift;
269     scan[0][BLU] = c > 255 ? 255 : c;
270     }
271     } else if (shift < 0) {
272     if (shift < -8) {
273     scan[0][RED] =
274     scan[0][GRN] =
275     scan[0][BLU] = 0;
276     } else {
277     shift = -1-shift;
278     scan[0][RED] = ((scan[0][RED]>>shift)+1)>>1;
279     scan[0][GRN] = ((scan[0][GRN]>>shift)+1)>>1;
280     scan[0][BLU] = ((scan[0][BLU]>>shift)+1)>>1;
281     }
282     }
283     scan[0][EXP] = COLXS - adjust;
284     scan++;
285     }
286     }