Home | History | Annotate | Download | only in IlmImf
      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
    249