HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImfRgbaYca.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright (c) Contributors to the OpenEXR Project.
4 //
5 
6 #ifndef INCLUDED_IMF_RGBA_YCA_H
7 #define INCLUDED_IMF_RGBA_YCA_H
8 
9 //-----------------------------------------------------------------------------
10 //
11 // Conversion between RGBA (red, green, blue alpha)
12 // and YCA (luminance, subsampled chroma, alpha) data:
13 //
14 // Luminance, Y, is computed as a weighted sum of R, G, and B:
15 //
16 // Y = yw.x * R + yw.y * G + yw.z * B
17 //
18 // Function computeYw() computes a set of RGB-to-Y weights, yw,
19 // from a set of primary and white point chromaticities.
20 //
21 // Chroma, C, consists of two components, RY and BY:
22 //
23 // RY = (R - Y) / Y
24 // BY = (B - Y) / Y
25 //
26 // For efficiency, the x and y subsampling rates for chroma are
27 // hardwired to 2, and the chroma subsampling and reconstruction
28 // filters are fixed 27-pixel wide windowed sinc functions.
29 //
30 // Starting with an image that has RGBA data for all pixels,
31 //
32 // RGBA RGBA RGBA RGBA ... RGBA RGBA
33 // RGBA RGBA RGBA RGBA ... RGBA RGBA
34 // RGBA RGBA RGBA RGBA ... RGBA RGBA
35 // RGBA RGBA RGBA RGBA ... RGBA RGBA
36 // ...
37 // RGBA RGBA RGBA RGBA ... RGBA RGBA
38 // RGBA RGBA RGBA RGBA ... RGBA RGBA
39 //
40 // function RGBAtoYCA() converts the pixels to YCA format:
41 //
42 // YCA YCA YCA YCA ... YCA YCA
43 // YCA YCA YCA YCA ... YCA YCA
44 // YCA YCA YCA YCA ... YCA YCA
45 // YCA YCA YCA YCA ... YCA YCA
46 // ...
47 // YCA YCA YCA YCA ... YCA YCA
48 // YCA YCA YCA YCA ... YCA YCA
49 //
50 // Next, decimateChomaHoriz() eliminates the chroma values from
51 // the odd-numbered pixels in every scan line:
52 //
53 // YCA YA YCA YA ... YCA YA
54 // YCA YA YCA YA ... YCA YA
55 // YCA YA YCA YA ... YCA YA
56 // YCA YA YCA YA ... YCA YA
57 // ...
58 // YCA YA YCA YA ... YCA YA
59 // YCA YA YCA YA ... YCA YA
60 //
61 // decimateChromaVert() eliminates all chroma values from the
62 // odd-numbered scan lines:
63 //
64 // YCA YA YCA YA ... YCA YA
65 // YA YA YA YA ... YA YA
66 // YCA YA YCA YA ... YCA YA
67 // YA YA YA YA ... YA YA
68 // ...
69 // YCA YA YCA YA ... YCA YA
70 // YA YA YA YA ... YA YA
71 //
72 // Finally, roundYCA() reduces the precision of the luminance
73 // and chroma values so that the pixel data shrink more when
74 // they are saved in a compressed file.
75 //
76 // The output of roundYCA() can be converted back to a set
77 // of RGBA pixel data that is visually very similar to the
78 // original RGBA image, by calling reconstructChromaHoriz(),
79 // reconstructChromaVert(), YCAtoRGBA(), and finally
80 // fixSaturation().
81 //
82 //-----------------------------------------------------------------------------
83 
84 #include "ImfExport.h"
85 #include "ImfNamespace.h"
86 
87 #include "ImfRgba.h"
88 #include "ImfChromaticities.h"
89 
91 
92 namespace RgbaYca {
93 
94 
95 //
96 // Width of the chroma subsampling and reconstruction filters
97 //
98 
99 static const int N = 27;
100 static const int N2 = N / 2;
101 
102 
103 //
104 // Convert a set of primary chromaticities into a set of weighting
105 // factors for computing a pixels's luminance, Y, from R, G and B
106 //
107 
110 
111 
112 //
113 // Convert an array of n RGBA pixels, rgbaIn, to YCA (luminance/chroma/alpha):
114 //
115 // ycaOut[i].g = Y (rgbaIn[i]);
116 // ycaOut[i].r = RY (rgbaIn[i]);
117 // ycaOut[i].b = BY (rgbaIn[i]);
118 // ycaOut[i].a = aIsValid? rgbaIn[i].a: 1
119 //
120 // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
121 //
122 
124 void RGBAtoYCA (const IMATH_NAMESPACE::V3f &yw,
125  int n,
126  bool aIsValid,
127  const Rgba rgbaIn[/*n*/],
128  Rgba ycaOut[/*n*/]);
129 
130 //
131 // Perform horizontal low-pass filtering and subsampling of
132 // the chroma channels of an array of n pixels. In order
133 // to avoid indexing off the ends of the input array during
134 // low-pass filtering, ycaIn must have N2 extra pixels at
135 // both ends. Before calling decimateChromaHoriz(), the extra
136 // pixels should be filled with copies of the first and last
137 // "real" input pixel.
138 //
139 
141 void decimateChromaHoriz (int n,
142  const Rgba ycaIn[/*n+N-1*/],
143  Rgba ycaOut[/*n*/]);
144 
145 //
146 // Perform vertical chroma channel low-pass filtering and subsampling.
147 // N scan lines of input pixels are combined into a single scan line
148 // of output pixels.
149 //
150 
152 void decimateChromaVert (int n,
153  const Rgba * const ycaIn[N],
154  Rgba ycaOut[/*n*/]);
155 
156 //
157 // Round the luminance and chroma channels of an array of YCA
158 // pixels that has already been filtered and subsampled.
159 // The signifcands of the pixels' luminance and chroma values
160 // are rounded to roundY and roundC bits respectively.
161 //
162 
164 void roundYCA (int n,
165  unsigned int roundY,
166  unsigned int roundC,
167  const Rgba ycaIn[/*n*/],
168  Rgba ycaOut[/*n*/]);
169 
170 //
171 // For a scan line that has valid chroma data only for every other pixel,
172 // reconstruct the missing chroma values.
173 //
174 
176 void reconstructChromaHoriz (int n,
177  const Rgba ycaIn[/*n+N-1*/],
178  Rgba ycaOut[/*n*/]);
179 
180 //
181 // For a scan line that has only luminance and no valid chroma data,
182 // reconstruct chroma from the surronding N scan lines.
183 //
184 
186 void reconstructChromaVert (int n,
187  const Rgba * const ycaIn[N],
188  Rgba ycaOut[/*n*/]);
189 
190 //
191 // Convert an array of n YCA (luminance/chroma/alpha) pixels to RGBA.
192 // This function is the inverse of RGBAtoYCA().
193 // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
194 //
195 
197 void YCAtoRGBA (const IMATH_NAMESPACE::V3f &yw,
198  int n,
199  const Rgba ycaIn[/*n*/],
200  Rgba rgbaOut[/*n*/]);
201 
202 //
203 // Eliminate super-saturated pixels:
204 //
205 // Converting an image from RGBA to YCA, low-pass filtering chroma,
206 // and converting the result back to RGBA can produce pixels with
207 // super-saturated colors, where one or two of the RGB components
208 // become zero or negative. (The low-pass and reconstruction filters
209 // introduce some amount of ringing into the chroma components.
210 // This can lead to negative RGB values near high-contrast edges.)
211 //
212 // The fixSaturation() function finds super-saturated pixels and
213 // corrects them by desaturating their colors while maintaining
214 // their luminance. fixSaturation() takes three adjacent input
215 // scan lines, rgbaIn[0], rgbaIn[1], rgbaIn[2], adjusts the
216 // saturation of rgbaIn[1], and stores the result in rgbaOut.
217 //
218 
220 void fixSaturation (const IMATH_NAMESPACE::V3f &yw,
221  int n,
222  const Rgba * const rgbaIn[3],
223  Rgba rgbaOut[/*n*/]);
224 
225 } // namespace RgbaYca
227 
228 #endif
IMF_EXPORT void decimateChromaVert(int n, const Rgba *const ycaIn[N], Rgba ycaOut[])
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
Definition: ImfNamespace.h:80
IMF_EXPORT void decimateChromaHoriz(int n, const Rgba ycaIn[], Rgba ycaOut[])
GLdouble n
Definition: glcorearb.h:2008
IMF_EXPORT void RGBAtoYCA(const IMATH_NAMESPACE::V3f &yw, int n, bool aIsValid, const Rgba rgbaIn[], Rgba ycaOut[])
IMF_EXPORT void fixSaturation(const IMATH_NAMESPACE::V3f &yw, int n, const Rgba *const rgbaIn[3], Rgba rgbaOut[])
#define IMF_EXPORT
Definition: ImfExport.h:54
IMF_EXPORT void reconstructChromaHoriz(int n, const Rgba ycaIn[], Rgba ycaOut[])
Vec3< float > V3f
Vec3 of float.
Definition: ImathVec.h:849
IMF_EXPORT void YCAtoRGBA(const IMATH_NAMESPACE::V3f &yw, int n, const Rgba ycaIn[], Rgba rgbaOut[])
IMF_EXPORT IMATH_NAMESPACE::V3f computeYw(const Chromaticities &cr)
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
Definition: ImfNamespace.h:79
Definition: ImfRgba.h:27
IMF_EXPORT void reconstructChromaVert(int n, const Rgba *const ycaIn[N], Rgba ycaOut[])
IMF_EXPORT void roundYCA(int n, unsigned int roundY, unsigned int roundC, const Rgba ycaIn[], Rgba ycaOut[])