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