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
49 namespace Imf {
50
51
52 void
apply(half * data,int nData,int stride) const53 HalfLut::apply (half *data, int nData, int stride) const
54 {
55 while (nData)
56 {
57 *data = _lut (*data);
58 data += stride;
59 nData -= 1;
60 }
61 }
62
63
64 void
apply(const Slice & data,const Imath::Box2i & dataWindow) const65 HalfLut::apply (const Slice &data, const Imath::Box2i &dataWindow) const
66 {
67 assert (data.type == HALF);
68 assert (dataWindow.min.x % data.xSampling == 0);
69 assert (dataWindow.min.y % data.ySampling == 0);
70 assert ((dataWindow.max.x - dataWindow.min.x + 1) % data.xSampling == 0);
71 assert ((dataWindow.max.y - dataWindow.min.y + 1) % data.ySampling == 0);
72
73 char *base = data.base + data.yStride *
74 (dataWindow.min.y / data.ySampling);
75
76 for (int y = dataWindow.min.y;
77 y <= dataWindow.max.y;
78 y += data.ySampling)
79 {
80 char *pixel = base + data.xStride *
81 (dataWindow.min.x / data.xSampling);
82
83 for (int x = dataWindow.min.x;
84 x <= dataWindow.max.x;
85 x += data.xSampling)
86 {
87 *(half *)pixel = _lut (*(half *)pixel);
88 pixel += data.xStride;
89 }
90
91 base += data.yStride;
92 }
93 }
94
95
96 void
apply(Rgba * data,int nData,int stride) const97 RgbaLut::apply (Rgba *data, int nData, int stride) const
98 {
99 while (nData)
100 {
101 if (_chn & WRITE_R)
102 data->r = _lut (data->r);
103
104 if (_chn & WRITE_G)
105 data->g = _lut (data->g);
106
107 if (_chn & WRITE_B)
108 data->b = _lut (data->b);
109
110 if (_chn & WRITE_A)
111 data->a = _lut (data->a);
112
113 data += stride;
114 nData -= 1;
115 }
116 }
117
118
119 void
apply(Rgba * base,int xStride,int yStride,const Imath::Box2i & dataWindow) const120 RgbaLut::apply (Rgba *base,
121 int xStride, int yStride,
122 const Imath::Box2i &dataWindow) const
123 {
124 base += dataWindow.min.y * yStride;
125
126 for (int y = dataWindow.min.y; y <= dataWindow.max.y; ++y)
127 {
128 Rgba *pixel = base + dataWindow.min.x * xStride;
129
130 for (int x = dataWindow.min.x; x <= dataWindow.max.x; ++x)
131 {
132 if (_chn & WRITE_R)
133 pixel->r = _lut (pixel->r);
134
135 if (_chn & WRITE_G)
136 pixel->g = _lut (pixel->g);
137
138 if (_chn & WRITE_B)
139 pixel->b = _lut (pixel->b);
140
141 if (_chn & WRITE_A)
142 pixel->a = _lut (pixel->a);
143
144 pixel += xStride;
145 }
146
147 base += yStride;
148 }
149 }
150
151
152 half
round12log(half x)153 round12log (half x)
154 {
155 const float middleval = pow (2.0, -2.5);
156 int int12log;
157
158 if (x <= 0)
159 {
160 return 0;
161 }
162 else
163 {
164 int12log = int (2000.5 + 200.0 * log (x / middleval) / log (2.0));
165
166 if (int12log > 4095)
167 int12log = 4095;
168
169 if (int12log < 1)
170 int12log = 1;
171 }
172
173 return middleval * pow (2.0, (int12log - 2000.0) / 200.0);
174 }
175
176 } // namespace Imf
177