Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / include / OpenEXR / ImfRgbaYca.h
1 #ifndef INCLUDED_IMF_RGBA_YCA_H
2 #define INCLUDED_IMF_RGBA_YCA_H
3
4 //////////////////////////////////////////////////////////////////////////////
5 //
6 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucasfilm
7 // Entertainment Company Ltd.  Portions contributed and copyright held by
8 // others as indicated.  All rights reserved.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 //     * Redistributions of source code must retain the above
15 //       copyright notice, this list of conditions and the following
16 //       disclaimer.
17 //
18 //     * Redistributions in binary form must reproduce the above
19 //       copyright notice, this list of conditions and the following
20 //       disclaimer in the documentation and/or other materials provided with
21 //       the distribution.
22 //
23 //     * Neither the name of Industrial Light & Magic nor the names of
24 //       any other contributors to this software may be used to endorse or
25 //       promote products derived from this software without specific prior
26 //       written permission.
27 //
28 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
29 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
30 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
32 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
35 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
37 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 //
40 //////////////////////////////////////////////////////////////////////////////
41
42 //-----------------------------------------------------------------------------
43 //
44 //      Conversion between RGBA (red, green, blue alpha)
45 //      and YCA (luminance, subsampled chroma, alpha) data:
46 //
47 //      Luminance, Y, is computed as a weighted sum of R, G, and B:
48 //
49 //              Y = yw.x * R + yw.y * G + yw.z * B
50 //
51 //      Function computeYw() computes a set of RGB-to-Y weights, yw,
52 //      from a set of primary and white point chromaticities.
53 //
54 //      Chroma, C, consists of two components, RY and BY:
55 //
56 //              RY = (R - Y) / Y
57 //              BY = (B - Y) / Y
58 //
59 //      For efficiency, the x and y subsampling rates for chroma are
60 //      hardwired to 2, and the chroma subsampling and reconstruction
61 //      filters are fixed 27-pixel wide windowed sinc functions.
62 //
63 //      Starting with an image that has RGBA data for all pixels,
64 //
65 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
66 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
67 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
68 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
69 //              ...
70 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
71 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
72 //
73 //      function RGBAtoYCA() converts the pixels to YCA format:
74 //
75 //              YCA  YCA  YCA  YCA  ... YCA  YCA
76 //              YCA  YCA  YCA  YCA  ... YCA  YCA
77 //              YCA  YCA  YCA  YCA  ... YCA  YCA
78 //              YCA  YCA  YCA  YCA  ... YCA  YCA
79 //              ...
80 //              YCA  YCA  YCA  YCA  ... YCA  YCA
81 //              YCA  YCA  YCA  YCA  ... YCA  YCA
82 //
83 //      Next, decimateChomaHoriz() eliminates the chroma values from
84 //      the odd-numbered pixels in every scan line:
85 //
86 //              YCA  YA   YCA  YA   ... YCA  YA  
87 //              YCA  YA   YCA  YA   ... YCA  YA  
88 //              YCA  YA   YCA  YA   ... YCA  YA  
89 //              YCA  YA   YCA  YA   ... YCA  YA  
90 //              ...
91 //              YCA  YA   YCA  YA   ... YCA  YA  
92 //              YCA  YA   YCA  YA   ... YCA  YA  
93 //
94 //      decimateChromaVert() eliminates all chroma values from the
95 //      odd-numbered scan lines:
96 //
97 //              YCA  YA   YCA  YA   ... YCA  YA  
98 //              YA   YA   YA   YA   ... YA   YA  
99 //              YCA  YA   YCA  YA   ... YCA  YA  
100 //              YA   YA   YA   YA   ... YA   YA  
101 //              ...
102 //              YCA  YA   YCA  YA   ... YCA  YA  
103 //              YA   YA   YA   YA   ... YA   YA  
104 //
105 //      Finally, roundYCA() reduces the precision of the luminance
106 //      and chroma values so that the pixel data shrink more when
107 //      they are saved in a compressed file.
108 //
109 //      The output of roundYCA() can be converted back to a set
110 //      of RGBA pixel data that is visually very similar to the
111 //      original RGBA image, by calling reconstructChromaHoriz(),
112 //      reconstructChromaVert(), YCAtoRGBA(), and finally
113 //      fixSaturation().
114 //
115 //-----------------------------------------------------------------------------
116
117 #include <ImfRgba.h>
118 #include <ImfChromaticities.h>
119
120 namespace Imf {
121 namespace RgbaYca {
122
123
124 //
125 // Width of the chroma subsampling and reconstruction filters
126 //
127
128 static const int N = 27;
129 static const int N2 = N / 2;
130
131
132 //
133 // Convert a set of primary chromaticities into a set of weighting
134 // factors for computing a pixels's luminance, Y, from R, G and B
135 // 
136
137 Imath::V3f computeYw (const Chromaticities &cr);
138
139
140 //
141 // Convert an array of n RGBA pixels, rgbaIn, to YCA (luminance/chroma/alpha):
142 //
143 //      ycaOut[i].g = Y (rgbaIn[i]);
144 //      ycaOut[i].r = RY (rgbaIn[i]);
145 //      ycaOut[i].b = BY (rgbaIn[i]);
146 //      ycaOut[i].a = aIsValid? rgbaIn[i].a: 1
147 //
148 // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
149 //
150
151 void RGBAtoYCA (const Imath::V3f &yw,
152                 int n,
153                 bool aIsValid,
154                 const Rgba rgbaIn[/*n*/],
155                 Rgba ycaOut[/*n*/]);
156
157 //
158 // Perform horizontal low-pass filtering and subsampling of
159 // the chroma channels of an array of n pixels.  In order
160 // to avoid indexing off the ends of the input array during
161 // low-pass filtering, ycaIn must have N2 extra pixels at
162 // both ends.  Before calling decimateChromaHoriz(), the extra
163 // pixels should be filled with copies of the first and last
164 // "real" input pixel.
165 //
166
167 void decimateChromaHoriz (int n,
168                           const Rgba ycaIn[/*n+N-1*/],
169                           Rgba ycaOut[/*n*/]);
170
171 //
172 // Perform vertical chroma channel low-pass filtering and subsampling.
173 // N scan lines of input pixels are combined into a single scan line
174 // of output pixels.
175 //
176
177 void decimateChromaVert (int n,
178                          const Rgba * const ycaIn[N],
179                          Rgba ycaOut[/*n*/]);
180
181 //
182 // Round the luminance and chroma channels of an array of YCA
183 // pixels that has already been filtered and subsampled.
184 // The signifcands of the pixels' luminance and chroma values
185 // are rounded to roundY and roundC bits respectively.
186 //
187
188 void roundYCA (int n,
189                unsigned int roundY,
190                unsigned int roundC,
191                const Rgba ycaIn[/*n*/],
192                Rgba ycaOut[/*n*/]);
193
194 //
195 // For a scan line that has valid chroma data only for every other pixel,
196 // reconstruct the missing chroma values.
197 //
198
199 void reconstructChromaHoriz (int n,
200                              const Rgba ycaIn[/*n+N-1*/],
201                              Rgba ycaOut[/*n*/]);
202
203 //
204 // For a scan line that has only luminance and no valid chroma data,
205 // reconstruct chroma from the surronding N scan lines.
206 //
207
208 void reconstructChromaVert (int n,
209                             const Rgba * const ycaIn[N],
210                             Rgba ycaOut[/*n*/]);
211                          
212 //
213 // Convert an array of n YCA (luminance/chroma/alpha) pixels to RGBA.
214 // This function is the inverse of RGBAtoYCA().
215 // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
216 //
217
218 void YCAtoRGBA (const Imath::V3f &yw,
219                 int n,
220                 const Rgba ycaIn[/*n*/],
221                 Rgba rgbaOut[/*n*/]);
222                          
223 //
224 // Eliminate super-saturated pixels:
225 //
226 // Converting an image from RGBA to YCA, low-pass filtering chroma,
227 // and converting the result back to RGBA can produce pixels with
228 // super-saturated colors, where one or two of the RGB components
229 // become zero or negative.  (The low-pass and reconstruction filters
230 // introduce some amount of ringing into the chroma components.
231 // This can lead to negative RGB values near high-contrast edges.)
232 //
233 // The fixSaturation() function finds super-saturated pixels and
234 // corrects them by desaturating their colors while maintaining
235 // their luminance.  fixSaturation() takes three adjacent input
236 // scan lines, rgbaIn[0], rgbaIn[1], rgbaIn[2], adjusts the
237 // saturation of rgbaIn[1], and stores the result in rgbaOut.
238 //
239
240 void fixSaturation (const Imath::V3f &yw,
241                     int n,
242                     const Rgba * const rgbaIn[3],
243                     Rgba rgbaOut[/*n*/]);
244
245 } // namespace RgbaYca
246 } // namespace Imf
247
248 #endif