1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
11 // *       Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // *       Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // *       Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 ///////////////////////////////////////////////////////////////////////////
34 
35 
36 
37 //-----------------------------------------------------------------------------
38 //
39 //	Lookup tables for efficient application
40 //	of half --> half functions to pixel data,
41 //	and some commonly applied functions.
42 //
43 //-----------------------------------------------------------------------------
44 
45 #include <ImfLut.h>
46 #include <math.h>
47 #include <assert.h>
48 #include "ImfNamespace.h"
49 
50 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
51 
52 
53 void
apply(half * data,int nData,int stride) const54 HalfLut::apply (half *data, int nData, int stride) const
55 {
56     while (nData)
57     {
58 	*data = _lut (*data);
59 	data += stride;
60 	nData -= 1;
61     }
62 }
63 
64 
65 void
apply(const Slice & data,const IMATH_NAMESPACE::Box2i & dataWindow) const66 HalfLut::apply (const Slice &data, const IMATH_NAMESPACE::Box2i &dataWindow) const
67 {
68     assert (data.type == HALF);
69     assert (dataWindow.min.x % data.xSampling == 0);
70     assert (dataWindow.min.y % data.ySampling == 0);
71     assert ((dataWindow.max.x - dataWindow.min.x + 1) % data.xSampling == 0);
72     assert ((dataWindow.max.y - dataWindow.min.y + 1) % data.ySampling == 0);
73 
74     char *base = data.base + data.yStride *
75 		 (dataWindow.min.y / data.ySampling);
76 
77     for (int y = dataWindow.min.y;
78 	 y <= dataWindow.max.y;
79 	 y += data.ySampling)
80     {
81 	char *pixel = base + data.xStride *
82 		      (dataWindow.min.x / data.xSampling);
83 
84 	for (int x = dataWindow.min.x;
85 	     x <= dataWindow.max.x;
86 	     x += data.xSampling)
87 	{
88 	    *(half *)pixel = _lut (*(half *)pixel);
89 	    pixel += data.xStride;
90 	}
91 
92 	base += data.yStride;
93     }
94 }
95 
96 
97 void
apply(Rgba * data,int nData,int stride) const98 RgbaLut::apply (Rgba *data, int nData, int stride) const
99 {
100     while (nData)
101     {
102 	if (_chn & WRITE_R)
103 	    data->r = _lut (data->r);
104 
105 	if (_chn & WRITE_G)
106 	    data->g = _lut (data->g);
107 
108 	if (_chn & WRITE_B)
109 	    data->b = _lut (data->b);
110 
111 	if (_chn & WRITE_A)
112 	    data->a = _lut (data->a);
113 
114 	data += stride;
115 	nData -= 1;
116     }
117 }
118 
119 
120 void
apply(Rgba * base,int xStride,int yStride,const IMATH_NAMESPACE::Box2i & dataWindow) const121 RgbaLut::apply (Rgba *base,
122 		int xStride, int yStride,
123 		const IMATH_NAMESPACE::Box2i &dataWindow) const
124 {
125     base += dataWindow.min.y * yStride;
126 
127     for (int y = dataWindow.min.y; y <= dataWindow.max.y; ++y)
128     {
129 	Rgba *pixel = base + dataWindow.min.x * xStride;
130 
131 	for (int x = dataWindow.min.x; x <= dataWindow.max.x; ++x)
132 	{
133 	    if (_chn & WRITE_R)
134 		pixel->r = _lut (pixel->r);
135 
136 	    if (_chn & WRITE_G)
137 		pixel->g = _lut (pixel->g);
138 
139 	    if (_chn & WRITE_B)
140 		pixel->b = _lut (pixel->b);
141 
142 	    if (_chn & WRITE_A)
143 		pixel->a = _lut (pixel->a);
144 
145 	    pixel += xStride;
146 	}
147 
148 	base += yStride;
149     }
150 }
151 
152 
153 half
round12log(half x)154 round12log (half x)
155 {
156     const float middleval = pow (2.0, -2.5);
157     int int12log;
158 
159     if (x <= 0)
160     {
161 	return 0;
162     }
163     else
164     {
165 	int12log = int (2000.5 + 200.0 * log (x / middleval) / log (2.0));
166 
167 	if (int12log > 4095)
168 	    int12log = 4095;
169 
170 	if (int12log < 1)
171 	    int12log = 1;
172     }
173 
174     return middleval * pow (2.0, (int12log - 2000.0) / 200.0);
175 }
176 
177 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
178 
179