123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- #ifndef INCLUDED_IMF_RGBA_YCA_H
- #define INCLUDED_IMF_RGBA_YCA_H
- //////////////////////////////////////////////////////////////////////////////
- //
- // Copyright (c) 2004, Industrial Light & Magic, a division of Lucasfilm
- // Entertainment Company Ltd. Portions contributed and copyright held by
- // others as indicated. All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above
- // copyright notice, this list of conditions and the following
- // disclaimer.
- //
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following
- // disclaimer in the documentation and/or other materials provided with
- // the distribution.
- //
- // * Neither the name of Industrial Light & Magic nor the names of
- // any other contributors to this software may be used to endorse or
- // promote products derived from this software without specific prior
- // written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- //
- //////////////////////////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------------
- //
- // Conversion between RGBA (red, green, blue alpha)
- // and YCA (luminance, subsampled chroma, alpha) data:
- //
- // Luminance, Y, is computed as a weighted sum of R, G, and B:
- //
- // Y = yw.x * R + yw.y * G + yw.z * B
- //
- // Function computeYw() computes a set of RGB-to-Y weights, yw,
- // from a set of primary and white point chromaticities.
- //
- // Chroma, C, consists of two components, RY and BY:
- //
- // RY = (R - Y) / Y
- // BY = (B - Y) / Y
- //
- // For efficiency, the x and y subsampling rates for chroma are
- // hardwired to 2, and the chroma subsampling and reconstruction
- // filters are fixed 27-pixel wide windowed sinc functions.
- //
- // Starting with an image that has RGBA data for all pixels,
- //
- // RGBA RGBA RGBA RGBA ... RGBA RGBA
- // RGBA RGBA RGBA RGBA ... RGBA RGBA
- // RGBA RGBA RGBA RGBA ... RGBA RGBA
- // RGBA RGBA RGBA RGBA ... RGBA RGBA
- // ...
- // RGBA RGBA RGBA RGBA ... RGBA RGBA
- // RGBA RGBA RGBA RGBA ... RGBA RGBA
- //
- // function RGBAtoYCA() converts the pixels to YCA format:
- //
- // YCA YCA YCA YCA ... YCA YCA
- // YCA YCA YCA YCA ... YCA YCA
- // YCA YCA YCA YCA ... YCA YCA
- // YCA YCA YCA YCA ... YCA YCA
- // ...
- // YCA YCA YCA YCA ... YCA YCA
- // YCA YCA YCA YCA ... YCA YCA
- //
- // Next, decimateChomaHoriz() eliminates the chroma values from
- // the odd-numbered pixels in every scan line:
- //
- // YCA YA YCA YA ... YCA YA
- // YCA YA YCA YA ... YCA YA
- // YCA YA YCA YA ... YCA YA
- // YCA YA YCA YA ... YCA YA
- // ...
- // YCA YA YCA YA ... YCA YA
- // YCA YA YCA YA ... YCA YA
- //
- // decimateChromaVert() eliminates all chroma values from the
- // odd-numbered scan lines:
- //
- // YCA YA YCA YA ... YCA YA
- // YA YA YA YA ... YA YA
- // YCA YA YCA YA ... YCA YA
- // YA YA YA YA ... YA YA
- // ...
- // YCA YA YCA YA ... YCA YA
- // YA YA YA YA ... YA YA
- //
- // Finally, roundYCA() reduces the precision of the luminance
- // and chroma values so that the pixel data shrink more when
- // they are saved in a compressed file.
- //
- // The output of roundYCA() can be converted back to a set
- // of RGBA pixel data that is visually very similar to the
- // original RGBA image, by calling reconstructChromaHoriz(),
- // reconstructChromaVert(), YCAtoRGBA(), and finally
- // fixSaturation().
- //
- //-----------------------------------------------------------------------------
- #include "ImfRgba.h"
- #include "ImfChromaticities.h"
- #include "ImfNamespace.h"
- OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
- namespace RgbaYca {
- //
- // Width of the chroma subsampling and reconstruction filters
- //
- static const int N = 27;
- static const int N2 = N / 2;
- //
- // Convert a set of primary chromaticities into a set of weighting
- // factors for computing a pixels's luminance, Y, from R, G and B
- //
-
- IMF_EXPORT
- IMATH_NAMESPACE::V3f computeYw (const Chromaticities &cr);
- //
- // Convert an array of n RGBA pixels, rgbaIn, to YCA (luminance/chroma/alpha):
- //
- // ycaOut[i].g = Y (rgbaIn[i]);
- // ycaOut[i].r = RY (rgbaIn[i]);
- // ycaOut[i].b = BY (rgbaIn[i]);
- // ycaOut[i].a = aIsValid? rgbaIn[i].a: 1
- //
- // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
- //
- IMF_EXPORT
- void RGBAtoYCA (const IMATH_NAMESPACE::V3f &yw,
- int n,
- bool aIsValid,
- const Rgba rgbaIn[/*n*/],
- Rgba ycaOut[/*n*/]);
- //
- // Perform horizontal low-pass filtering and subsampling of
- // the chroma channels of an array of n pixels. In order
- // to avoid indexing off the ends of the input array during
- // low-pass filtering, ycaIn must have N2 extra pixels at
- // both ends. Before calling decimateChromaHoriz(), the extra
- // pixels should be filled with copies of the first and last
- // "real" input pixel.
- //
- IMF_EXPORT
- void decimateChromaHoriz (int n,
- const Rgba ycaIn[/*n+N-1*/],
- Rgba ycaOut[/*n*/]);
- //
- // Perform vertical chroma channel low-pass filtering and subsampling.
- // N scan lines of input pixels are combined into a single scan line
- // of output pixels.
- //
- IMF_EXPORT
- void decimateChromaVert (int n,
- const Rgba * const ycaIn[N],
- Rgba ycaOut[/*n*/]);
- //
- // Round the luminance and chroma channels of an array of YCA
- // pixels that has already been filtered and subsampled.
- // The signifcands of the pixels' luminance and chroma values
- // are rounded to roundY and roundC bits respectively.
- //
- IMF_EXPORT
- void roundYCA (int n,
- unsigned int roundY,
- unsigned int roundC,
- const Rgba ycaIn[/*n*/],
- Rgba ycaOut[/*n*/]);
- //
- // For a scan line that has valid chroma data only for every other pixel,
- // reconstruct the missing chroma values.
- //
- IMF_EXPORT
- void reconstructChromaHoriz (int n,
- const Rgba ycaIn[/*n+N-1*/],
- Rgba ycaOut[/*n*/]);
- //
- // For a scan line that has only luminance and no valid chroma data,
- // reconstruct chroma from the surronding N scan lines.
- //
- IMF_EXPORT
- void reconstructChromaVert (int n,
- const Rgba * const ycaIn[N],
- Rgba ycaOut[/*n*/]);
-
- //
- // Convert an array of n YCA (luminance/chroma/alpha) pixels to RGBA.
- // This function is the inverse of RGBAtoYCA().
- // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
- //
- IMF_EXPORT
- void YCAtoRGBA (const IMATH_NAMESPACE::V3f &yw,
- int n,
- const Rgba ycaIn[/*n*/],
- Rgba rgbaOut[/*n*/]);
-
- //
- // Eliminate super-saturated pixels:
- //
- // Converting an image from RGBA to YCA, low-pass filtering chroma,
- // and converting the result back to RGBA can produce pixels with
- // super-saturated colors, where one or two of the RGB components
- // become zero or negative. (The low-pass and reconstruction filters
- // introduce some amount of ringing into the chroma components.
- // This can lead to negative RGB values near high-contrast edges.)
- //
- // The fixSaturation() function finds super-saturated pixels and
- // corrects them by desaturating their colors while maintaining
- // their luminance. fixSaturation() takes three adjacent input
- // scan lines, rgbaIn[0], rgbaIn[1], rgbaIn[2], adjusts the
- // saturation of rgbaIn[1], and stores the result in rgbaOut.
- //
- IMF_EXPORT
- void fixSaturation (const IMATH_NAMESPACE::V3f &yw,
- int n,
- const Rgba * const rgbaIn[3],
- Rgba rgbaOut[/*n*/]);
- } // namespace RgbaYca
- OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
- #endif
|