PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/openexr-1.7.0/ImfRgbaYca.h
00001 #ifndef INCLUDED_IMF_RGBA_YCA_H
00002 #define INCLUDED_IMF_RGBA_YCA_H
00003 
00005 //
00006 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucasfilm
00007 // Entertainment Company Ltd.  Portions contributed and copyright held by
00008 // others as indicated.  All rights reserved.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 //     * Redistributions of source code must retain the above
00015 //       copyright notice, this list of conditions and the following
00016 //       disclaimer.
00017 //
00018 //     * Redistributions in binary form must reproduce the above
00019 //       copyright notice, this list of conditions and the following
00020 //       disclaimer in the documentation and/or other materials provided with
00021 //       the distribution.
00022 //
00023 //     * Neither the name of Industrial Light & Magic nor the names of
00024 //       any other contributors to this software may be used to endorse or
00025 //       promote products derived from this software without specific prior
00026 //       written permission.
00027 //
00028 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00029 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
00030 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00031 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00032 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00033 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00034 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00035 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00036 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00037 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00038 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039 //
00041 
00042 //-----------------------------------------------------------------------------
00043 //
00044 //      Conversion between RGBA (red, green, blue alpha)
00045 //      and YCA (luminance, subsampled chroma, alpha) data:
00046 //
00047 //      Luminance, Y, is computed as a weighted sum of R, G, and B:
00048 //
00049 //              Y = yw.x * R + yw.y * G + yw.z * B
00050 //
00051 //      Function computeYw() computes a set of RGB-to-Y weights, yw,
00052 //      from a set of primary and white point chromaticities.
00053 //
00054 //      Chroma, C, consists of two components, RY and BY:
00055 //
00056 //              RY = (R - Y) / Y
00057 //              BY = (B - Y) / Y
00058 //
00059 //      For efficiency, the x and y subsampling rates for chroma are
00060 //      hardwired to 2, and the chroma subsampling and reconstruction
00061 //      filters are fixed 27-pixel wide windowed sinc functions.
00062 //
00063 //      Starting with an image that has RGBA data for all pixels,
00064 //
00065 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
00066 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
00067 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
00068 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
00069 //              ...
00070 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
00071 //              RGBA RGBA RGBA RGBA ... RGBA RGBA
00072 //
00073 //      function RGBAtoYCA() converts the pixels to YCA format:
00074 //
00075 //              YCA  YCA  YCA  YCA  ... YCA  YCA
00076 //              YCA  YCA  YCA  YCA  ... YCA  YCA
00077 //              YCA  YCA  YCA  YCA  ... YCA  YCA
00078 //              YCA  YCA  YCA  YCA  ... YCA  YCA
00079 //              ...
00080 //              YCA  YCA  YCA  YCA  ... YCA  YCA
00081 //              YCA  YCA  YCA  YCA  ... YCA  YCA
00082 //
00083 //      Next, decimateChomaHoriz() eliminates the chroma values from
00084 //      the odd-numbered pixels in every scan line:
00085 //
00086 //              YCA  YA   YCA  YA   ... YCA  YA  
00087 //              YCA  YA   YCA  YA   ... YCA  YA  
00088 //              YCA  YA   YCA  YA   ... YCA  YA  
00089 //              YCA  YA   YCA  YA   ... YCA  YA  
00090 //              ...
00091 //              YCA  YA   YCA  YA   ... YCA  YA  
00092 //              YCA  YA   YCA  YA   ... YCA  YA  
00093 //
00094 //      decimateChromaVert() eliminates all chroma values from the
00095 //      odd-numbered scan lines:
00096 //
00097 //              YCA  YA   YCA  YA   ... YCA  YA  
00098 //              YA   YA   YA   YA   ... YA   YA  
00099 //              YCA  YA   YCA  YA   ... YCA  YA  
00100 //              YA   YA   YA   YA   ... YA   YA  
00101 //              ...
00102 //              YCA  YA   YCA  YA   ... YCA  YA  
00103 //              YA   YA   YA   YA   ... YA   YA  
00104 //
00105 //      Finally, roundYCA() reduces the precision of the luminance
00106 //      and chroma values so that the pixel data shrink more when
00107 //      they are saved in a compressed file.
00108 //
00109 //      The output of roundYCA() can be converted back to a set
00110 //      of RGBA pixel data that is visually very similar to the
00111 //      original RGBA image, by calling reconstructChromaHoriz(),
00112 //      reconstructChromaVert(), YCAtoRGBA(), and finally
00113 //      fixSaturation().
00114 //
00115 //-----------------------------------------------------------------------------
00116 
00117 #include <ImfRgba.h>
00118 #include <ImfChromaticities.h>
00119 
00120 namespace Imf {
00121 namespace RgbaYca {
00122 
00123 
00124 //
00125 // Width of the chroma subsampling and reconstruction filters
00126 //
00127 
00128 static const int N = 27;
00129 static const int N2 = N / 2;
00130 
00131 
00132 //
00133 // Convert a set of primary chromaticities into a set of weighting
00134 // factors for computing a pixels's luminance, Y, from R, G and B
00135 // 
00136 
00137 Imath::V3f computeYw (const Chromaticities &cr);
00138 
00139 
00140 //
00141 // Convert an array of n RGBA pixels, rgbaIn, to YCA (luminance/chroma/alpha):
00142 //
00143 //      ycaOut[i].g = Y (rgbaIn[i]);
00144 //      ycaOut[i].r = RY (rgbaIn[i]);
00145 //      ycaOut[i].b = BY (rgbaIn[i]);
00146 //      ycaOut[i].a = aIsValid? rgbaIn[i].a: 1
00147 //
00148 // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
00149 //
00150 
00151 void RGBAtoYCA (const Imath::V3f &yw,
00152                 int n,
00153                 bool aIsValid,
00154                 const Rgba rgbaIn[/*n*/],
00155                 Rgba ycaOut[/*n*/]);
00156 
00157 //
00158 // Perform horizontal low-pass filtering and subsampling of
00159 // the chroma channels of an array of n pixels.  In order
00160 // to avoid indexing off the ends of the input array during
00161 // low-pass filtering, ycaIn must have N2 extra pixels at
00162 // both ends.  Before calling decimateChromaHoriz(), the extra
00163 // pixels should be filled with copies of the first and last
00164 // "real" input pixel.
00165 //
00166 
00167 void decimateChromaHoriz (int n,
00168                           const Rgba ycaIn[/*n+N-1*/],
00169                           Rgba ycaOut[/*n*/]);
00170 
00171 //
00172 // Perform vertical chroma channel low-pass filtering and subsampling.
00173 // N scan lines of input pixels are combined into a single scan line
00174 // of output pixels.
00175 //
00176 
00177 void decimateChromaVert (int n,
00178                          const Rgba * const ycaIn[N],
00179                          Rgba ycaOut[/*n*/]);
00180 
00181 //
00182 // Round the luminance and chroma channels of an array of YCA
00183 // pixels that has already been filtered and subsampled.
00184 // The signifcands of the pixels' luminance and chroma values
00185 // are rounded to roundY and roundC bits respectively.
00186 //
00187 
00188 void roundYCA (int n,
00189                unsigned int roundY,
00190                unsigned int roundC,
00191                const Rgba ycaIn[/*n*/],
00192                Rgba ycaOut[/*n*/]);
00193 
00194 //
00195 // For a scan line that has valid chroma data only for every other pixel,
00196 // reconstruct the missing chroma values.
00197 //
00198 
00199 void reconstructChromaHoriz (int n,
00200                              const Rgba ycaIn[/*n+N-1*/],
00201                              Rgba ycaOut[/*n*/]);
00202 
00203 //
00204 // For a scan line that has only luminance and no valid chroma data,
00205 // reconstruct chroma from the surronding N scan lines.
00206 //
00207 
00208 void reconstructChromaVert (int n,
00209                             const Rgba * const ycaIn[N],
00210                             Rgba ycaOut[/*n*/]);
00211                          
00212 //
00213 // Convert an array of n YCA (luminance/chroma/alpha) pixels to RGBA.
00214 // This function is the inverse of RGBAtoYCA().
00215 // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
00216 //
00217 
00218 void YCAtoRGBA (const Imath::V3f &yw,
00219                 int n,
00220                 const Rgba ycaIn[/*n*/],
00221                 Rgba rgbaOut[/*n*/]);
00222                          
00223 //
00224 // Eliminate super-saturated pixels:
00225 //
00226 // Converting an image from RGBA to YCA, low-pass filtering chroma,
00227 // and converting the result back to RGBA can produce pixels with
00228 // super-saturated colors, where one or two of the RGB components
00229 // become zero or negative.  (The low-pass and reconstruction filters
00230 // introduce some amount of ringing into the chroma components.
00231 // This can lead to negative RGB values near high-contrast edges.)
00232 //
00233 // The fixSaturation() function finds super-saturated pixels and
00234 // corrects them by desaturating their colors while maintaining
00235 // their luminance.  fixSaturation() takes three adjacent input
00236 // scan lines, rgbaIn[0], rgbaIn[1], rgbaIn[2], adjusts the
00237 // saturation of rgbaIn[1], and stores the result in rgbaOut.
00238 //
00239 
00240 void fixSaturation (const Imath::V3f &yw,
00241                     int n,
00242                     const Rgba * const rgbaIn[3],
00243                     Rgba rgbaOut[/*n*/]);
00244 
00245 } // namespace RgbaYca
00246 } // namespace Imf
00247 
00248 #endif