Blame IlmImf/ImfRgbaYca.cpp

Packit Service 6754ca
//////////////////////////////////////////////////////////////////////////////
Packit Service 6754ca
//
Packit Service 6754ca
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucasfilm
Packit Service 6754ca
// Entertainment Company Ltd.  Portions contributed and copyright held by
Packit Service 6754ca
// others as indicated.  All rights reserved.
Packit Service 6754ca
//
Packit Service 6754ca
// Redistribution and use in source and binary forms, with or without
Packit Service 6754ca
// modification, are permitted provided that the following conditions are
Packit Service 6754ca
// met:
Packit Service 6754ca
//
Packit Service 6754ca
//     * Redistributions of source code must retain the above
Packit Service 6754ca
//       copyright notice, this list of conditions and the following
Packit Service 6754ca
//       disclaimer.
Packit Service 6754ca
//
Packit Service 6754ca
//     * Redistributions in binary form must reproduce the above
Packit Service 6754ca
//       copyright notice, this list of conditions and the following
Packit Service 6754ca
//       disclaimer in the documentation and/or other materials provided with
Packit Service 6754ca
//       the distribution.
Packit Service 6754ca
//
Packit Service 6754ca
//     * Neither the name of Industrial Light & Magic nor the names of
Packit Service 6754ca
//       any other contributors to this software may be used to endorse or
Packit Service 6754ca
//       promote products derived from this software without specific prior
Packit Service 6754ca
//       written permission.
Packit Service 6754ca
//
Packit Service 6754ca
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
Packit Service 6754ca
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
Packit Service 6754ca
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
Packit Service 6754ca
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
Packit Service 6754ca
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Packit Service 6754ca
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Packit Service 6754ca
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit Service 6754ca
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit Service 6754ca
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Packit Service 6754ca
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Packit Service 6754ca
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 6754ca
//
Packit Service 6754ca
//////////////////////////////////////////////////////////////////////////////
Packit Service 6754ca
Packit Service 6754ca
//-----------------------------------------------------------------------------
Packit Service 6754ca
//
Packit Service 6754ca
//	Conversion between RGBA and YCA data.
Packit Service 6754ca
//
Packit Service 6754ca
//-----------------------------------------------------------------------------
Packit Service 6754ca
Packit Service 6754ca
#include <ImfRgbaYca.h>
Packit Service 6754ca
#include <assert.h>
Packit Service 6754ca
#include <algorithm>
Packit Service 6754ca
Packit Service 6754ca
using namespace IMATH_NAMESPACE;
Packit Service 6754ca
using namespace std;
Packit Service 6754ca
#include "ImfNamespace.h"
Packit Service 6754ca
Packit Service 6754ca
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
Packit Service 6754ca
Packit Service 6754ca
namespace RgbaYca {
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
V3f
Packit Service 6754ca
computeYw (const Chromaticities &cr)
Packit Service 6754ca
{
Packit Service 6754ca
    M44f m = RGBtoXYZ (cr, 1);
Packit Service 6754ca
    return V3f (m[0][1], m[1][1], m[2][1]) / (m[0][1] + m[1][1] + m[2][1]);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
RGBAtoYCA (const V3f &yw,
Packit Service 6754ca
	   int n,
Packit Service 6754ca
	   bool aIsValid,
Packit Service 6754ca
	   const Rgba rgbaIn[/*n*/],
Packit Service 6754ca
	   Rgba ycaOut[/*n*/])
Packit Service 6754ca
{
Packit Service 6754ca
    for (int i = 0; i < n; ++i)
Packit Service 6754ca
    {
Packit Service 6754ca
	Rgba in = rgbaIn[i];
Packit Service 6754ca
	Rgba &out = ycaOut[i];
Packit Service 6754ca
Packit Service 6754ca
	//
Packit Service 6754ca
	// Conversion to YCA and subsequent chroma subsampling
Packit Service 6754ca
	// work only if R, G and B are finite and non-negative.
Packit Service 6754ca
	//
Packit Service 6754ca
Packit Service 6754ca
	if (!in.r.isFinite() || in.r < 0)
Packit Service 6754ca
	    in.r = 0;
Packit Service 6754ca
Packit Service 6754ca
	if (!in.g.isFinite() || in.g < 0)
Packit Service 6754ca
	    in.g = 0;
Packit Service 6754ca
Packit Service 6754ca
	if (!in.b.isFinite() || in.b < 0)
Packit Service 6754ca
	    in.b = 0;
Packit Service 6754ca
Packit Service 6754ca
	if (in.r == in.g && in.g == in.b)
Packit Service 6754ca
	{
Packit Service 6754ca
	    //
Packit Service 6754ca
	    // Special case -- R, G and B are equal. To avoid rounding
Packit Service 6754ca
	    // errors, we explicitly set the output luminance channel
Packit Service 6754ca
	    // to G, and the chroma channels to 0.
Packit Service 6754ca
	    //
Packit Service 6754ca
	    // The special cases here and in YCAtoRGBA() ensure that
Packit Service 6754ca
	    // converting black-and white images from RGBA to YCA and
Packit Service 6754ca
	    // back is lossless.
Packit Service 6754ca
	    //
Packit Service 6754ca
Packit Service 6754ca
	    out.r = 0;
Packit Service 6754ca
	    out.g = in.g;
Packit Service 6754ca
	    out.b = 0;
Packit Service 6754ca
	}
Packit Service 6754ca
	else
Packit Service 6754ca
	{
Packit Service 6754ca
	    out.g = in.r * yw.x + in.g * yw.y + in.b * yw.z;
Packit Service 6754ca
Packit Service 6754ca
	    float Y = out.g;
Packit Service 6754ca
Packit Service 6754ca
	    if (abs (in.r - Y) < HALF_MAX * Y)
Packit Service 6754ca
		out.r = (in.r - Y) / Y;
Packit Service 6754ca
	    else
Packit Service 6754ca
		out.r = 0;
Packit Service 6754ca
Packit Service 6754ca
	    if (abs (in.b - Y) < HALF_MAX * Y)
Packit Service 6754ca
		out.b = (in.b - Y) / Y;
Packit Service 6754ca
	    else
Packit Service 6754ca
		out.b = 0;
Packit Service 6754ca
	}
Packit Service 6754ca
Packit Service 6754ca
	if (aIsValid)
Packit Service 6754ca
	    out.a = in.a;
Packit Service 6754ca
	else
Packit Service 6754ca
	    out.a = 1;
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
decimateChromaHoriz (int n,
Packit Service 6754ca
		     const Rgba ycaIn[/*n+N-1*/],
Packit Service 6754ca
		     Rgba ycaOut[/*n*/])
Packit Service 6754ca
{
Packit Service 6754ca
    #ifdef DEBUG
Packit Service 6754ca
	assert (ycaIn != ycaOut);
Packit Service 6754ca
    #endif
Packit Service 6754ca
Packit Service 6754ca
    int begin = N2;
Packit Service 6754ca
    int end = begin + n;
Packit Service 6754ca
Packit Service 6754ca
    for (int i = begin, j = 0; i < end; ++i, ++j)
Packit Service 6754ca
    {
Packit Service 6754ca
	if ((j & 1) == 0)
Packit Service 6754ca
	{
Packit Service 6754ca
	    ycaOut[j].r = ycaIn[i - 13].r *  0.001064f +
Packit Service 6754ca
			  ycaIn[i - 11].r * -0.003771f +
Packit Service 6754ca
			  ycaIn[i -  9].r *  0.009801f +
Packit Service 6754ca
			  ycaIn[i -  7].r * -0.021586f +
Packit Service 6754ca
			  ycaIn[i -  5].r *  0.043978f +
Packit Service 6754ca
			  ycaIn[i -  3].r * -0.093067f +
Packit Service 6754ca
			  ycaIn[i -  1].r *  0.313659f +
Packit Service 6754ca
			  ycaIn[i     ].r *  0.499846f +
Packit Service 6754ca
			  ycaIn[i +  1].r *  0.313659f +
Packit Service 6754ca
			  ycaIn[i +  3].r * -0.093067f +
Packit Service 6754ca
			  ycaIn[i +  5].r *  0.043978f +
Packit Service 6754ca
			  ycaIn[i +  7].r * -0.021586f +
Packit Service 6754ca
			  ycaIn[i +  9].r *  0.009801f +
Packit Service 6754ca
			  ycaIn[i + 11].r * -0.003771f +
Packit Service 6754ca
			  ycaIn[i + 13].r *  0.001064f;
Packit Service 6754ca
Packit Service 6754ca
	    ycaOut[j].b = ycaIn[i - 13].b *  0.001064f +
Packit Service 6754ca
			  ycaIn[i - 11].b * -0.003771f +
Packit Service 6754ca
			  ycaIn[i -  9].b *  0.009801f +
Packit Service 6754ca
			  ycaIn[i -  7].b * -0.021586f +
Packit Service 6754ca
			  ycaIn[i -  5].b *  0.043978f +
Packit Service 6754ca
			  ycaIn[i -  3].b * -0.093067f +
Packit Service 6754ca
			  ycaIn[i -  1].b *  0.313659f +
Packit Service 6754ca
			  ycaIn[i     ].b *  0.499846f +
Packit Service 6754ca
			  ycaIn[i +  1].b *  0.313659f +
Packit Service 6754ca
			  ycaIn[i +  3].b * -0.093067f +
Packit Service 6754ca
			  ycaIn[i +  5].b *  0.043978f +
Packit Service 6754ca
			  ycaIn[i +  7].b * -0.021586f +
Packit Service 6754ca
			  ycaIn[i +  9].b *  0.009801f +
Packit Service 6754ca
			  ycaIn[i + 11].b * -0.003771f +
Packit Service 6754ca
			  ycaIn[i + 13].b *  0.001064f;
Packit Service 6754ca
	}
Packit Service 6754ca
Packit Service 6754ca
	ycaOut[j].g = ycaIn[i].g;
Packit Service 6754ca
	ycaOut[j].a = ycaIn[i].a;
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
decimateChromaVert (int n,
Packit Service 6754ca
		    const Rgba * const ycaIn[N],
Packit Service 6754ca
		    Rgba ycaOut[/*n*/])
Packit Service 6754ca
{
Packit Service 6754ca
    for (int i = 0; i < n; ++i)
Packit Service 6754ca
    {
Packit Service 6754ca
	if ((i & 1) == 0)
Packit Service 6754ca
	{
Packit Service 6754ca
	    ycaOut[i].r = ycaIn[ 0][i].r *  0.001064f +
Packit Service 6754ca
			  ycaIn[ 2][i].r * -0.003771f +
Packit Service 6754ca
			  ycaIn[ 4][i].r *  0.009801f +
Packit Service 6754ca
			  ycaIn[ 6][i].r * -0.021586f +
Packit Service 6754ca
			  ycaIn[ 8][i].r *  0.043978f +
Packit Service 6754ca
			  ycaIn[10][i].r * -0.093067f +
Packit Service 6754ca
			  ycaIn[12][i].r *  0.313659f +
Packit Service 6754ca
			  ycaIn[13][i].r *  0.499846f +
Packit Service 6754ca
			  ycaIn[14][i].r *  0.313659f +
Packit Service 6754ca
			  ycaIn[16][i].r * -0.093067f +
Packit Service 6754ca
			  ycaIn[18][i].r *  0.043978f +
Packit Service 6754ca
			  ycaIn[20][i].r * -0.021586f +
Packit Service 6754ca
			  ycaIn[22][i].r *  0.009801f +
Packit Service 6754ca
			  ycaIn[24][i].r * -0.003771f +
Packit Service 6754ca
			  ycaIn[26][i].r *  0.001064f;
Packit Service 6754ca
Packit Service 6754ca
	    ycaOut[i].b = ycaIn[ 0][i].b *  0.001064f +
Packit Service 6754ca
			  ycaIn[ 2][i].b * -0.003771f +
Packit Service 6754ca
			  ycaIn[ 4][i].b *  0.009801f +
Packit Service 6754ca
			  ycaIn[ 6][i].b * -0.021586f +
Packit Service 6754ca
			  ycaIn[ 8][i].b *  0.043978f +
Packit Service 6754ca
			  ycaIn[10][i].b * -0.093067f +
Packit Service 6754ca
			  ycaIn[12][i].b *  0.313659f +
Packit Service 6754ca
			  ycaIn[13][i].b *  0.499846f +
Packit Service 6754ca
			  ycaIn[14][i].b *  0.313659f +
Packit Service 6754ca
			  ycaIn[16][i].b * -0.093067f +
Packit Service 6754ca
			  ycaIn[18][i].b *  0.043978f +
Packit Service 6754ca
			  ycaIn[20][i].b * -0.021586f +
Packit Service 6754ca
			  ycaIn[22][i].b *  0.009801f +
Packit Service 6754ca
			  ycaIn[24][i].b * -0.003771f +
Packit Service 6754ca
			  ycaIn[26][i].b *  0.001064f;
Packit Service 6754ca
	}
Packit Service 6754ca
Packit Service 6754ca
	ycaOut[i].g = ycaIn[13][i].g;
Packit Service 6754ca
	ycaOut[i].a = ycaIn[13][i].a;
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
roundYCA (int n,
Packit Service 6754ca
	  unsigned int roundY,
Packit Service 6754ca
	  unsigned int roundC,
Packit Service 6754ca
	  const Rgba ycaIn[/*n*/],
Packit Service 6754ca
	  Rgba ycaOut[/*n*/])
Packit Service 6754ca
{
Packit Service 6754ca
    for (int i = 0; i < n; ++i)
Packit Service 6754ca
    {
Packit Service 6754ca
	ycaOut[i].g = ycaIn[i].g.round (roundY);
Packit Service 6754ca
	ycaOut[i].a = ycaIn[i].a;
Packit Service 6754ca
Packit Service 6754ca
	if ((i & 1) == 0)
Packit Service 6754ca
	{
Packit Service 6754ca
	    ycaOut[i].r = ycaIn[i].r.round (roundC);
Packit Service 6754ca
	    ycaOut[i].b = ycaIn[i].b.round (roundC);
Packit Service 6754ca
	}
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
reconstructChromaHoriz (int n,
Packit Service 6754ca
			const Rgba ycaIn[/*n+N-1*/],
Packit Service 6754ca
			Rgba ycaOut[/*n*/])
Packit Service 6754ca
{
Packit Service 6754ca
    #ifdef DEBUG
Packit Service 6754ca
	assert (ycaIn != ycaOut);
Packit Service 6754ca
    #endif
Packit Service 6754ca
Packit Service 6754ca
    int begin = N2;
Packit Service 6754ca
    int end = begin + n;
Packit Service 6754ca
Packit Service 6754ca
    for (int i = begin, j = 0; i < end; ++i, ++j)
Packit Service 6754ca
    {
Packit Service 6754ca
	if (j & 1)
Packit Service 6754ca
	{
Packit Service 6754ca
	    ycaOut[j].r = ycaIn[i - 13].r *  0.002128f +
Packit Service 6754ca
			  ycaIn[i - 11].r * -0.007540f +
Packit Service 6754ca
			  ycaIn[i -  9].r *  0.019597f +
Packit Service 6754ca
			  ycaIn[i -  7].r * -0.043159f +
Packit Service 6754ca
			  ycaIn[i -  5].r *  0.087929f +
Packit Service 6754ca
			  ycaIn[i -  3].r * -0.186077f +
Packit Service 6754ca
			  ycaIn[i -  1].r *  0.627123f +
Packit Service 6754ca
			  ycaIn[i +  1].r *  0.627123f +
Packit Service 6754ca
			  ycaIn[i +  3].r * -0.186077f +
Packit Service 6754ca
			  ycaIn[i +  5].r *  0.087929f +
Packit Service 6754ca
			  ycaIn[i +  7].r * -0.043159f +
Packit Service 6754ca
			  ycaIn[i +  9].r *  0.019597f +
Packit Service 6754ca
			  ycaIn[i + 11].r * -0.007540f +
Packit Service 6754ca
			  ycaIn[i + 13].r *  0.002128f;
Packit Service 6754ca
Packit Service 6754ca
	    ycaOut[j].b = ycaIn[i - 13].b *  0.002128f +
Packit Service 6754ca
			  ycaIn[i - 11].b * -0.007540f +
Packit Service 6754ca
			  ycaIn[i -  9].b *  0.019597f +
Packit Service 6754ca
			  ycaIn[i -  7].b * -0.043159f +
Packit Service 6754ca
			  ycaIn[i -  5].b *  0.087929f +
Packit Service 6754ca
			  ycaIn[i -  3].b * -0.186077f +
Packit Service 6754ca
			  ycaIn[i -  1].b *  0.627123f +
Packit Service 6754ca
			  ycaIn[i +  1].b *  0.627123f +
Packit Service 6754ca
			  ycaIn[i +  3].b * -0.186077f +
Packit Service 6754ca
			  ycaIn[i +  5].b *  0.087929f +
Packit Service 6754ca
			  ycaIn[i +  7].b * -0.043159f +
Packit Service 6754ca
			  ycaIn[i +  9].b *  0.019597f +
Packit Service 6754ca
			  ycaIn[i + 11].b * -0.007540f +
Packit Service 6754ca
			  ycaIn[i + 13].b *  0.002128f;
Packit Service 6754ca
	}
Packit Service 6754ca
	else
Packit Service 6754ca
	{
Packit Service 6754ca
	    ycaOut[j].r = ycaIn[i].r;
Packit Service 6754ca
	    ycaOut[j].b = ycaIn[i].b;
Packit Service 6754ca
	}
Packit Service 6754ca
Packit Service 6754ca
	ycaOut[j].g = ycaIn[i].g;
Packit Service 6754ca
	ycaOut[j].a = ycaIn[i].a;
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
reconstructChromaVert (int n,
Packit Service 6754ca
		       const Rgba * const ycaIn[N],
Packit Service 6754ca
		       Rgba ycaOut[/*n*/])
Packit Service 6754ca
{
Packit Service 6754ca
    for (int i = 0; i < n; ++i)
Packit Service 6754ca
    {
Packit Service 6754ca
	ycaOut[i].r = ycaIn[ 0][i].r *  0.002128f +
Packit Service 6754ca
		      ycaIn[ 2][i].r * -0.007540f +
Packit Service 6754ca
		      ycaIn[ 4][i].r *  0.019597f +
Packit Service 6754ca
		      ycaIn[ 6][i].r * -0.043159f +
Packit Service 6754ca
		      ycaIn[ 8][i].r *  0.087929f +
Packit Service 6754ca
		      ycaIn[10][i].r * -0.186077f +
Packit Service 6754ca
		      ycaIn[12][i].r *  0.627123f +
Packit Service 6754ca
		      ycaIn[14][i].r *  0.627123f +
Packit Service 6754ca
		      ycaIn[16][i].r * -0.186077f +
Packit Service 6754ca
		      ycaIn[18][i].r *  0.087929f +
Packit Service 6754ca
		      ycaIn[20][i].r * -0.043159f +
Packit Service 6754ca
		      ycaIn[22][i].r *  0.019597f +
Packit Service 6754ca
		      ycaIn[24][i].r * -0.007540f +
Packit Service 6754ca
		      ycaIn[26][i].r *  0.002128f;
Packit Service 6754ca
Packit Service 6754ca
	ycaOut[i].b = ycaIn[ 0][i].b *  0.002128f +
Packit Service 6754ca
		      ycaIn[ 2][i].b * -0.007540f +
Packit Service 6754ca
		      ycaIn[ 4][i].b *  0.019597f +
Packit Service 6754ca
		      ycaIn[ 6][i].b * -0.043159f +
Packit Service 6754ca
		      ycaIn[ 8][i].b *  0.087929f +
Packit Service 6754ca
		      ycaIn[10][i].b * -0.186077f +
Packit Service 6754ca
		      ycaIn[12][i].b *  0.627123f +
Packit Service 6754ca
		      ycaIn[14][i].b *  0.627123f +
Packit Service 6754ca
		      ycaIn[16][i].b * -0.186077f +
Packit Service 6754ca
		      ycaIn[18][i].b *  0.087929f +
Packit Service 6754ca
		      ycaIn[20][i].b * -0.043159f +
Packit Service 6754ca
		      ycaIn[22][i].b *  0.019597f +
Packit Service 6754ca
		      ycaIn[24][i].b * -0.007540f +
Packit Service 6754ca
		      ycaIn[26][i].b *  0.002128f;
Packit Service 6754ca
Packit Service 6754ca
	ycaOut[i].g = ycaIn[13][i].g;
Packit Service 6754ca
	ycaOut[i].a = ycaIn[13][i].a;
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
			 
Packit Service 6754ca
void
Packit Service 6754ca
YCAtoRGBA (const IMATH_NAMESPACE::V3f &yw,
Packit Service 6754ca
	   int n,
Packit Service 6754ca
	   const Rgba ycaIn[/*n*/],
Packit Service 6754ca
	   Rgba rgbaOut[/*n*/])
Packit Service 6754ca
{
Packit Service 6754ca
    for (int i = 0; i < n; ++i)
Packit Service 6754ca
    {
Packit Service 6754ca
	const Rgba &in = ycaIn[i];
Packit Service 6754ca
	Rgba &out = rgbaOut[i];
Packit Service 6754ca
Packit Service 6754ca
	if (in.r == 0 && in.b == 0)
Packit Service 6754ca
	{
Packit Service 6754ca
	    //
Packit Service 6754ca
	    // Special case -- both chroma channels are 0.  To avoid
Packit Service 6754ca
	    // rounding errors, we explicitly set the output R, G and B
Packit Service 6754ca
	    // channels equal to the input luminance.
Packit Service 6754ca
	    //
Packit Service 6754ca
	    // The special cases here and in RGBAtoYCA() ensure that
Packit Service 6754ca
	    // converting black-and white images from RGBA to YCA and
Packit Service 6754ca
	    // back is lossless.
Packit Service 6754ca
	    //
Packit Service 6754ca
Packit Service 6754ca
	    out.r = in.g;
Packit Service 6754ca
	    out.g = in.g;
Packit Service 6754ca
	    out.b = in.g;
Packit Service 6754ca
	    out.a = in.a;
Packit Service 6754ca
	}
Packit Service 6754ca
	else
Packit Service 6754ca
	{
Packit Service 6754ca
	    float Y =  in.g;
Packit Service 6754ca
	    float r = (in.r + 1) * Y;
Packit Service 6754ca
	    float b = (in.b + 1) * Y;
Packit Service 6754ca
	    float g = (Y - r * yw.x - b * yw.z) / yw.y;
Packit Service 6754ca
Packit Service 6754ca
	    out.r = r;
Packit Service 6754ca
	    out.g = g;
Packit Service 6754ca
	    out.b = b;
Packit Service 6754ca
	    out.a = in.a;
Packit Service 6754ca
	}
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
namespace {
Packit Service 6754ca
Packit Service 6754ca
inline float
Packit Service 6754ca
saturation (const Rgba &in)
Packit Service 6754ca
{
Packit Service 6754ca
    float rgbMax = max (in.r, max (in.g, in.b));
Packit Service 6754ca
    float rgbMin = min (in.r, min (in.g, in.b));
Packit Service 6754ca
Packit Service 6754ca
    if (rgbMax > 0)
Packit Service 6754ca
	return 1 - rgbMin / rgbMax;
Packit Service 6754ca
    else
Packit Service 6754ca
	return 0;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
desaturate (const Rgba &in, float f, const V3f &yw, Rgba &out)
Packit Service 6754ca
{
Packit Service 6754ca
    float rgbMax = max (in.r, max (in.g, in.b));
Packit Service 6754ca
Packit Service 6754ca
    out.r = max (float (rgbMax - (rgbMax - in.r) * f), 0.0f);
Packit Service 6754ca
    out.g = max (float (rgbMax - (rgbMax - in.g) * f), 0.0f);
Packit Service 6754ca
    out.b = max (float (rgbMax - (rgbMax - in.b) * f), 0.0f);
Packit Service 6754ca
    out.a = in.a;
Packit Service 6754ca
Packit Service 6754ca
    float Yin  = in.r  * yw.x + in.g  * yw.y + in.b  * yw.z;
Packit Service 6754ca
    float Yout = out.r * yw.x + out.g * yw.y + out.b * yw.z;
Packit Service 6754ca
Packit Service 6754ca
    if (Yout > 0)
Packit Service 6754ca
    {
Packit Service 6754ca
	out.r *= Yin / Yout;
Packit Service 6754ca
	out.g *= Yin / Yout;
Packit Service 6754ca
	out.b *= Yin / Yout;
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
} // namespace
Packit Service 6754ca
Packit Service 6754ca
			 
Packit Service 6754ca
void
Packit Service 6754ca
fixSaturation (const IMATH_NAMESPACE::V3f &yw,
Packit Service 6754ca
	       int n,
Packit Service 6754ca
	       const Rgba * const rgbaIn[3],
Packit Service 6754ca
	       Rgba rgbaOut[/*n*/])
Packit Service 6754ca
{
Packit Service 6754ca
    float neighborA2 = saturation (rgbaIn[0][0]);
Packit Service 6754ca
    float neighborA1 = neighborA2;
Packit Service 6754ca
Packit Service 6754ca
    float neighborB2 = saturation (rgbaIn[2][0]);
Packit Service 6754ca
    float neighborB1 = neighborB2;
Packit Service 6754ca
Packit Service 6754ca
    for (int i = 0; i < n; ++i)
Packit Service 6754ca
    {
Packit Service 6754ca
	float neighborA0 = neighborA1;
Packit Service 6754ca
	neighborA1 = neighborA2;
Packit Service 6754ca
Packit Service 6754ca
	float neighborB0 = neighborB1;
Packit Service 6754ca
	neighborB1 = neighborB2;
Packit Service 6754ca
Packit Service 6754ca
	if (i < n - 1)
Packit Service 6754ca
	{
Packit Service 6754ca
	    neighborA2 = saturation (rgbaIn[0][i + 1]);
Packit Service 6754ca
	    neighborB2 = saturation (rgbaIn[2][i + 1]);
Packit Service 6754ca
	}
Packit Service 6754ca
Packit Service 6754ca
	//
Packit Service 6754ca
	// A0       A1       A2
Packit Service 6754ca
	//      rgbaOut[i]
Packit Service 6754ca
	// B0       B1       B2
Packit Service 6754ca
	//
Packit Service 6754ca
Packit Service 6754ca
	float sMean = min (1.0f, 0.25f * (neighborA0 + neighborA2 +
Packit Service 6754ca
					  neighborB0 + neighborB2));
Packit Service 6754ca
Packit Service 6754ca
	const Rgba &in  = rgbaIn[1][i];
Packit Service 6754ca
	Rgba &out = rgbaOut[i];
Packit Service 6754ca
Packit Service 6754ca
	float s = saturation (in);
Packit Service 6754ca
Packit Service 6754ca
	if (s > sMean)
Packit Service 6754ca
	{
Packit Service 6754ca
	    float sMax = min (1.0f, 1 - (1 - sMean) * 0.25f);
Packit Service 6754ca
Packit Service 6754ca
	    if (s > sMax)
Packit Service 6754ca
	    {
Packit Service 6754ca
		desaturate (in, sMax / s, yw, out);
Packit Service 6754ca
		continue;
Packit Service 6754ca
	    }
Packit Service 6754ca
	}
Packit Service 6754ca
Packit Service 6754ca
	out = in;
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
} // namespace RgbaYca
Packit Service 6754ca
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT