Skip to content

Commit

Permalink
- WIP Fixed-function for PQ<->Linear function. Doesn't have the GPU i…
Browse files Browse the repository at this point in the history
…mplementation yet and the rest may need tweaks.

Signed-off-by: cuneyt.ozdas <[email protected]>
  • Loading branch information
cozdas committed Jul 20, 2024
1 parent 67a26e4 commit 1754818
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 50 deletions.
3 changes: 2 additions & 1 deletion include/OpenColorIO/OpenColorTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ enum FixedFunctionStyle
FIXED_FUNCTION_XYZ_TO_LUV, ///< CIE XYZ to 1976 CIELUV colour space (D65 white)
FIXED_FUNCTION_ACES_GAMUTMAP_02, ///< ACES 0.2 Gamut clamping algorithm -- NOT IMPLEMENTED YET
FIXED_FUNCTION_ACES_GAMUTMAP_07, ///< ACES 0.7 Gamut clamping algorithm -- NOT IMPLEMENTED YET
FIXED_FUNCTION_ACES_GAMUT_COMP_13 ///< ACES 1.3 Parametric Gamut Compression (expects ACEScg values)
FIXED_FUNCTION_ACES_GAMUT_COMP_13, ///< ACES 1.3 Parametric Gamut Compression (expects ACEScg values)
FIXED_FUNCTION_PQ_TO_LINEAR, ///< SMPTE ST 2084:2014 EOTF linearization equation
};

/// Enumeration of the :cpp:class:`ExposureContrastTransform` transform algorithms.
Expand Down
2 changes: 2 additions & 0 deletions src/OpenColorIO/ParseUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ const char * FixedFunctionStyleToString(FixedFunctionStyle style)
case FIXED_FUNCTION_XYZ_TO_xyY: return "XYZ_TO_xyY";
case FIXED_FUNCTION_XYZ_TO_uvY: return "XYZ_TO_uvY";
case FIXED_FUNCTION_XYZ_TO_LUV: return "XYZ_TO_LUV";
case FIXED_FUNCTION_PQ_TO_LINEAR: return "PQ_TO_LINEAR";
case FIXED_FUNCTION_ACES_GAMUTMAP_02:
case FIXED_FUNCTION_ACES_GAMUTMAP_07:
throw Exception("Unimplemented fixed function types: "
Expand Down Expand Up @@ -391,6 +392,7 @@ FixedFunctionStyle FixedFunctionStyleFromString(const char * style)
else if(str == "xyz_to_xyy") return FIXED_FUNCTION_XYZ_TO_xyY;
else if(str == "xyz_to_uvy") return FIXED_FUNCTION_XYZ_TO_uvY;
else if(str == "xyz_to_luv") return FIXED_FUNCTION_XYZ_TO_LUV;
else if(str == "pq_to_linear") return FIXED_FUNCTION_PQ_TO_LINEAR;

// Default style is meaningless.
std::stringstream ss;
Expand Down
167 changes: 167 additions & 0 deletions src/OpenColorIO/ops/fixedfunction/FixedFunctionOpCPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,22 @@ class Renderer_LUV_TO_XYZ : public OpCPU
void apply(const void * inImg, void * outImg, long numPixels) const override;
};

class Renderer_PQ_TO_LINEAR : public OpCPU {
public:
Renderer_PQ_TO_LINEAR() = delete;
explicit Renderer_PQ_TO_LINEAR(ConstFixedFunctionOpDataRcPtr &data);

void apply(const void *inImg, void *outImg, long numPixels) const override;
};

class Renderer_LINEAR_TO_PQ : public OpCPU {
public:
Renderer_LINEAR_TO_PQ() = delete;
explicit Renderer_LINEAR_TO_PQ(ConstFixedFunctionOpDataRcPtr &data);

void apply(const void *inImg, void *outImg, long numPixels) const override;
};


///////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -1178,7 +1194,150 @@ void Renderer_LUV_TO_XYZ::apply(const void * inImg, void * outImg, long numPixel
}


namespace ST_2084
{
static constexpr float m1 = float(0.25 * 2610. / 4096.);
static constexpr float m2 = float(128. * 2523. / 4096.);
static constexpr float c2 = float(32. * 2413. / 4096.);
static constexpr float c3 = float(32. * 2392. / 4096.);
static constexpr float c1 = c3 - c2 + 1.;
} // ST_2084

Renderer_PQ_TO_LINEAR::Renderer_PQ_TO_LINEAR(ConstFixedFunctionOpDataRcPtr & /*data*/)
: OpCPU()
{
}

void Renderer_PQ_TO_LINEAR::apply(const void *inImg, void *outImg, long numPixels) const
{
// TODO optimize
using namespace ST_2084;
const float *in = (const float *)inImg;
float *out = (float *)outImg;

for (long idx = 0; idx < numPixels; ++idx, out += 4, in += 4)
{
// (0..1) values will be pass through
// output values are scaled by 100 to convert nits/10,000 into nits/100

// R
{
float r = in[0];
if ((r <= 0.0f) || (r >= 1.0f))
{
out[0] = r * 100.0f;
}
else
{
const float x = std::pow(r, 1.f / m2);
out[0] = 100.0f * std::pow(std::max(0.f, x - c1) / (c2 - c3 * x), 1.f / m1);
};
}

// G
{
float g = in[1];
if ((g <= 0.0f) || (g >= 1.0f))
{
out[1] = g * 100.0f;
}
else
{
const float x = std::pow(g, 1.f / m2);
out[1] = 100.0f * std::pow(std::max(0.f, x - c1) / (c2 - c3 * x), 1.f / m1);
};
}

// B
{
float b = in[2];
if ((b <= 0.0f) || (b >= 1.0f))
{
out[2] = b * 100.0f;
}
else
{
const float x = std::pow(b, 1.f / m2);
out[2] = 100.0f * std::pow(std::max(0.f, x - c1) / (c2 - c3 * x), 1.f / m1);
};
}

// A
out[3] = in[3];
}
}

Renderer_LINEAR_TO_PQ::Renderer_LINEAR_TO_PQ(ConstFixedFunctionOpDataRcPtr & /*data*/)
: OpCPU()
{

}

void Renderer_LINEAR_TO_PQ::apply(const void *inImg, void *outImg, long numPixels) const
{
using namespace ST_2084;
const float* in = (const float*)inImg;
float* out = (float*)outImg;

// Input is in nits/100, convert to [0,1], where 1 is 10000 nits.

for (long idx = 0; idx < numPixels; ++idx, out += 4, in += 4)
{
// R
{
float r = 0.01f * in[0];
if (r < 0.0f || r > 1.0f)
{
out[0] = r;
}
else
{
const float L = std::max(0.0f, r);
const float y = std::pow(L, m1);
const float ratpoly = (c1 + c2 * y) / (1.f + c3 * y);
const float N = std::pow(std::max(0.f, ratpoly), m2);
out[0] = N;
}
}

// G
{
float g = 0.01f * in[1];
if (g < 0.0f || g > 1.0f)
{
out[1] = g;
}
else
{
const float L = std::max(0.0f, g);
const float y = std::pow(L, m1);
const float ratpoly = (c1 + c2 * y) / (1.f + c3 * y);
const float N = std::pow(std::max(0.f, ratpoly), m2);
out[1] = N;
}
}

// B
{
float b = 0.01f * in[2];
if (b < 0.0f || b > 1.0f)
{
out[2] = b;
}
else
{
const float L = std::max(0.0f, b);
const float y = std::pow(L, m1);
const float ratpoly = (c1 + c2 * y) / (1.f + c3 * y);
const float N = std::pow(std::max(0.f, ratpoly), m2);
out[2] = N;
}
}

//A
out[3] = in[3];
};
}

///////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -1278,6 +1437,14 @@ ConstOpCPURcPtr GetFixedFunctionCPURenderer(ConstFixedFunctionOpDataRcPtr & func
{
return std::make_shared<Renderer_LUV_TO_XYZ>(func);
}
case FixedFunctionOpData::PQ_TO_LINEAR:
{
return std::make_shared<Renderer_PQ_TO_LINEAR>(func);
}
case FixedFunctionOpData::LINEAR_TO_PQ:
{
return std::make_shared<Renderer_LINEAR_TO_PQ>(func);
}
}

throw Exception("Unsupported FixedFunction style");
Expand Down
35 changes: 35 additions & 0 deletions src/OpenColorIO/ops/fixedfunction/FixedFunctionOpData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ constexpr char XYZ_TO_uvY_STR[] = "XYZ_TO_uvY";
constexpr char uvY_TO_XYZ_STR[] = "uvY_TO_XYZ";
constexpr char XYZ_TO_LUV_STR[] = "XYZ_TO_LUV";
constexpr char LUV_TO_XYZ_STR[] = "LUV_TO_XYZ";
constexpr char PQ_TO_LINEAR_STR[] = "PQ_TO_LINEAR";
constexpr char LINEAR_TO_PQ_STR[] = "LINEAR_TO_PQ";


// NOTE: Converts the enumeration value to its string representation (i.e. CLF reader).
Expand Down Expand Up @@ -94,6 +96,10 @@ const char * FixedFunctionOpData::ConvertStyleToString(Style style, bool detaile
return XYZ_TO_LUV_STR;
case LUV_TO_XYZ:
return LUV_TO_XYZ_STR;
case PQ_TO_LINEAR:
return PQ_TO_LINEAR_STR;
case LINEAR_TO_PQ:
return LINEAR_TO_PQ_STR;
}

std::stringstream ss("Unknown FixedFunction style: ");
Expand Down Expand Up @@ -196,6 +202,14 @@ FixedFunctionOpData::Style FixedFunctionOpData::GetStyle(const char * name)
{
return LUV_TO_XYZ;
}
else if (0 == Platform::Strcasecmp(name, PQ_TO_LINEAR_STR))
{
return PQ_TO_LINEAR;
}
else if (0 == Platform::Strcasecmp(name, LINEAR_TO_PQ_STR))
{
return LINEAR_TO_PQ;
}
}

std::string st("Unknown FixedFunction style: ");
Expand Down Expand Up @@ -270,6 +284,10 @@ FixedFunctionOpData::Style FixedFunctionOpData::ConvertStyle(FixedFunctionStyle
"FIXED_FUNCTION_ACES_GAMUTMAP_02, "
"FIXED_FUNCTION_ACES_GAMUTMAP_07.");
}
case FIXED_FUNCTION_PQ_TO_LINEAR:
{
return FixedFunctionOpData::PQ_TO_LINEAR;
}
}

std::stringstream ss("Unknown FixedFunction transform style: ");
Expand Down Expand Up @@ -326,6 +344,10 @@ FixedFunctionStyle FixedFunctionOpData::ConvertStyle(FixedFunctionOpData::Style
case FixedFunctionOpData::XYZ_TO_LUV:
case FixedFunctionOpData::LUV_TO_XYZ:
return FIXED_FUNCTION_XYZ_TO_LUV;

case FixedFunctionOpData::PQ_TO_LINEAR:
case FixedFunctionOpData::LINEAR_TO_PQ:
return FIXED_FUNCTION_PQ_TO_LINEAR;
}

std::stringstream ss("Unknown FixedFunction style: ");
Expand Down Expand Up @@ -584,6 +606,17 @@ void FixedFunctionOpData::invert() noexcept
setStyle(XYZ_TO_LUV);
break;
}

case PQ_TO_LINEAR:
{
setStyle(LINEAR_TO_PQ);
break;
}
case LINEAR_TO_PQ:
{
setStyle(PQ_TO_LINEAR);
break;
}
}

// Note that any existing metadata could become stale at this point but
Expand Down Expand Up @@ -614,6 +647,7 @@ TransformDirection FixedFunctionOpData::getDirection() const noexcept
case FixedFunctionOpData::XYZ_TO_xyY:
case FixedFunctionOpData::XYZ_TO_uvY:
case FixedFunctionOpData::XYZ_TO_LUV:
case FixedFunctionOpData::PQ_TO_LINEAR:
return TRANSFORM_DIR_FORWARD;

case FixedFunctionOpData::ACES_RED_MOD_03_INV:
Expand All @@ -627,6 +661,7 @@ TransformDirection FixedFunctionOpData::getDirection() const noexcept
case FixedFunctionOpData::xyY_TO_XYZ:
case FixedFunctionOpData::uvY_TO_XYZ:
case FixedFunctionOpData::LUV_TO_XYZ:
case FixedFunctionOpData::LINEAR_TO_PQ:
return TRANSFORM_DIR_INVERSE;
}
return TRANSFORM_DIR_FORWARD;
Expand Down
4 changes: 3 additions & 1 deletion src/OpenColorIO/ops/fixedfunction/FixedFunctionOpData.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ class FixedFunctionOpData : public OpData
XYZ_TO_uvY, // CIE XYZ to 1976 u'v' chromaticity coordinates
uvY_TO_XYZ, // Inverse of above
XYZ_TO_LUV, // CIE XYZ to 1976 CIELUV colour space (D65 white)
LUV_TO_XYZ // Inverse of above
LUV_TO_XYZ, // Inverse of above
PQ_TO_LINEAR, // Perceptual Quantizer curve to linear
LINEAR_TO_PQ, // Inverse of above
};

static const char * ConvertStyleToString(Style style, bool detailed);
Expand Down
8 changes: 8 additions & 0 deletions src/OpenColorIO/ops/fixedfunction/FixedFunctionOpGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,14 @@ void GetFixedFunctionGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
{
Add_LUV_TO_XYZ(shaderCreator, ss);
}
case FixedFunctionOpData::PQ_TO_LINEAR:
{
// TODO: Add function
}
case FixedFunctionOpData::LINEAR_TO_PQ:
{
// TODO: Add function
}
}

ss.dedent();
Expand Down
Loading

0 comments on commit 1754818

Please sign in to comment.