Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/OpenColorIO/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ set(SOURCES
transforms/builtins/CanonCameras.cpp
transforms/builtins/Displays.cpp
transforms/builtins/PanasonicCameras.cpp
transforms/builtins/ProPhotoRGB.cpp
transforms/builtins/RedCameras.cpp
transforms/builtins/SonyCameras.cpp
transforms/BuiltinTransform.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "transforms/builtins/CanonCameras.h"
#include "transforms/builtins/Displays.h"
#include "transforms/builtins/PanasonicCameras.h"
#include "transforms/builtins/ProPhotoRGB.h"
#include "transforms/builtins/RedCameras.h"
#include "transforms/builtins/SonyCameras.h"
#include "utils/StringUtils.h"
Expand Down Expand Up @@ -117,6 +118,9 @@ void BuiltinTransformRegistryImpl::registerAll() noexcept
CAMERA::RED::RegisterAll(*this);
CAMERA::SONY::RegisterAll(*this);

// ProPhoto RGB / ROMM RGB support.
PROPHOTO::RegisterAll(*this);

// Display support.
DISPLAY::RegisterAll(*this);
}
Expand Down
182 changes: 182 additions & 0 deletions src/OpenColorIO/transforms/builtins/ProPhotoRGB.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.


#include <cmath>

#include <OpenColorIO/OpenColorIO.h>

#include "ops/gamma/GammaOp.h"
#include "ops/matrix/MatrixOp.h"
#include "transforms/builtins/ACES.h"
#include "transforms/builtins/BuiltinTransformRegistry.h"
#include "transforms/builtins/ColorMatrixHelpers.h"
#include "transforms/builtins/OpHelpers.h"
#include "transforms/builtins/ProPhotoRGB.h"


namespace OCIO_NAMESPACE
{

// ProPhoto RGB / ROMM RGB (Reference Output Medium Metric RGB)
// Specified in ANSI/I3A IT10.7666:2003
//
// Primaries and white point.
namespace ROMM_RGB
{

static const Chromaticities red_xy(0.7347, 0.2653);
static const Chromaticities grn_xy(0.1596, 0.8404);
static const Chromaticities blu_xy(0.0366, 0.0001);
static const Chromaticities wht_xy(0.3457, 0.3585); // D50

const Primaries primaries(red_xy, grn_xy, blu_xy, wht_xy);

} // namespace ROMM_RGB


// ROMM RGB uses a piecewise gamma function with gamma 1.8.
//
// Encoded to Linear (decoding):
// if (encoded < 1.0 / 512.0): // breakpoint = 16 * 1.0 / 512.0
// linear = encoded / 16.0
// else:
// linear = encoded ^ 1.8
//
// Linear to Encoded (encoding):
// if (linear < 1.0 / 512.0):
// encoded = linear * 16.0
// else:
// encoded = linear ^ (1/1.8)
//
namespace ROMM_RGB_GAMMA_18
{

static constexpr double gamma = 1.8;
static constexpr double slope = 16.0; // Slope of linear segment.
static constexpr double breakEnc = 1.0 / 32.0; // Encoded breakpoint

void GenerateEncodedToLinearOps(OpRcPtrVec& ops)
{
// Encoded gamma 1.8 to linear curve using LUT for accuracy.
auto GenerateLutValues = [](double in) -> float
{
const double absIn = std::abs(in);
double out = 0.0;

if (absIn < breakEnc)
{
out = absIn / slope;
}
else
{
out = std::pow(absIn, gamma);
}

return float(std::copysign(out, in));
};

CreateHalfLut(ops, GenerateLutValues);
}

} // namespace ROMM_RGB_GAMMA_18


// ProPhoto RGB with sRGB gamma curve.
// This is a common variant used by Adobe and other applications.
// Uses the sRGB transfer function (gamma 2.4, offset 0.055) instead of
// the standard ROMM RGB gamma 1.8 curve.
namespace ROMM_RGB_SRGB_GAMMA
{

void GenerateLinearToEncodedOps(OpRcPtrVec& ops)
{
// sRGB gamma encoding: gamma=2.4, offset=0.055
// This uses the MONCURVE model which is efficient for sRGB-style curves.
const GammaOpData::Params rgbParams = { 2.4, 0.055 };
const GammaOpData::Params alphaParams = { 1.0, 0.0 };
auto gammaData = std::make_shared<GammaOpData>(GammaOpData::MONCURVE_FWD,
rgbParams, rgbParams, rgbParams, alphaParams);
CreateGammaOp(ops, gammaData, TRANSFORM_DIR_FORWARD);
}

void GenerateEncodedToLinearOps(OpRcPtrVec& ops)
{
// sRGB gamma decoding: gamma=2.4, offset=0.055
const GammaOpData::Params rgbParams = { 2.4, 0.055 };
const GammaOpData::Params alphaParams = { 1.0, 0.0 };
auto gammaData = std::make_shared<GammaOpData>(GammaOpData::MONCURVE_REV,
rgbParams, rgbParams, rgbParams, alphaParams);
CreateGammaOp(ops, gammaData, TRANSFORM_DIR_FORWARD);
}

} // namespace ROMM_RGB_SRGB_GAMMA


namespace PROPHOTO
{

void RegisterAll(BuiltinTransformRegistryImpl& registry) noexcept
{
// Linear ProPhoto RGB to ACES2065-1.
{
auto LINEAR_RIMM_to_ACES2065_1_BFD_Functor = [](OpRcPtrVec& ops)
{
// Convert from ROMM RGB (D50) to ACES AP0 (D60).
// Uses Bradford chromatic adaptation.
MatrixOpData::MatrixArrayPtr matrix
= build_conversion_matrix(ROMM_RGB::primaries,
ACES_AP0::primaries,
ADAPTATION_BRADFORD);
CreateMatrixOp(ops, matrix, TRANSFORM_DIR_FORWARD);
};

registry.addBuiltin("LINEAR-RIMM_to_ACES2065-1_BFD",
"Convert ProPhoto RGB (linear) to ACES2065-1",
LINEAR_RIMM_to_ACES2065_1_BFD_Functor);
}

// Encoded ProPhoto RGB (gamma 1.8) to ACES2065-1.
{
auto ROMM_to_CIE_XYZ_D65_BFD_Functor = [](OpRcPtrVec& ops)
{
// 1. Decode gamma 1.8 to linear.
ROMM_RGB_GAMMA_18::GenerateEncodedToLinearOps(ops);

// 2. Convert color space from ROMM RGB (D50) to ACES AP0 (D60).
MatrixOpData::MatrixArrayPtr matrix
= build_conversion_matrix_to_XYZ_D65(ROMM_RGB::primaries,
ADAPTATION_BRADFORD);
CreateMatrixOp(ops, matrix, TRANSFORM_DIR_FORWARD);
};

registry.addBuiltin("ROMM_to_CIE-XYZ-D65_BFD",
"Convert ProPhoto RGB (gamma 1.8 encoded) to ACES2065-1",
ROMM_to_CIE_XYZ_D65_BFD_Functor);
}

// ProPhoto RGB with sRGB gamma to ACES2065-1.
{
auto ROMM_RGB_SRGB_to_ACES2065_1_Functor = [](OpRcPtrVec& ops)
{
// 1. Decode sRGB gamma to linear.
ROMM_RGB_SRGB_GAMMA::GenerateEncodedToLinearOps(ops);

// 2. Convert color space from ROMM RGB (D50) to ACES AP0 (D60).
MatrixOpData::MatrixArrayPtr matrix
= build_conversion_matrix(ROMM_RGB::primaries,
ACES_AP0::primaries,
ADAPTATION_BRADFORD);
CreateMatrixOp(ops, matrix, TRANSFORM_DIR_FORWARD);
};

registry.addBuiltin("PROPHOTO-RGB-SRGB-GAMMA_to_ACES2065-1",
"Convert ProPhoto RGB (sRGB gamma encoded) to ACES2065-1",
ROMM_RGB_SRGB_to_ACES2065_1_Functor);
}

}

} // namespace PROPHOTO

} // namespace OCIO_NAMESPACE
24 changes: 24 additions & 0 deletions src/OpenColorIO/transforms/builtins/ProPhotoRGB.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.


#ifndef INCLUDED_OCIO_PROPHOTO_RGB_H
#define INCLUDED_OCIO_PROPHOTO_RGB_H


namespace OCIO_NAMESPACE
{

class BuiltinTransformRegistryImpl;

namespace PROPHOTO
{

void RegisterAll(BuiltinTransformRegistryImpl& registry) noexcept;

} // namespace PROPHOTO

} // namespace OCIO_NAMESPACE


#endif // INCLUDED_OCIO_PROPHOTO_RGB_H
9 changes: 8 additions & 1 deletion tests/cpu/transforms/BuiltinTransform_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,14 @@ AllValues UnitTestValues
{ "DISPLAY - CIE-XYZ-D65_to_REC.2100-HLG-1000nit",
{ 6.0e-5f,
{ 0.5f, 0.4f, 0.3f, -0.1f, 1.01f, 0.2f },
{ 0.5649694f, 0.4038837f, 0.3751478f, -0.505630434f, 0.738133013f, 0.251128823f } } }
{ 0.5649694f, 0.4038837f, 0.3751478f, -0.505630434f, 0.738133013f, 0.251128823f } } },
{ "ROMM_to_CIE-XYZ-D65_BFD",
{ 1.0e-6f,
{ 0.5f, 0.4f, 0.3f, 0.248054f, 0.216383f, 0.124372f },
{ 0.03f, 0.02f, 0.01f, 0.00160897f, 0.00140735f, 0.000677473f } } },
{ "LINEAR-RIMM_to_ACES2065-1_BFD",
{ 1.0e-6f,
{0.5f, 0.4f, 0.3f}, {0.47351069f, 0.39131449f, 0.29965645f} } }
};

} // anon.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,4 +403,9 @@ OCIO_ADD_TEST(Builtins, version_2_3_validation)
TestStyle("ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - HDR-1000nit-REC2020-D60-in-REC2020-D65_2.0");
TestStyle("ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - HDR-2000nit-REC2020-D60-in-REC2020-D65_2.0");
TestStyle("ACES-OUTPUT - ACES2065-1_to_CIE-XYZ-D65 - HDR-4000nit-REC2020-D60-in-REC2020-D65_2.0");

// ProPhotoRGB / ROMM RGB builtin transforms.
TestStyle("ROMM_to_CIE-XYZ-D65_BFD");
TestStyle("LINEAR-RIMM_to_ACES2065-1_BFD");
//TestStyle("PROPHOTO-RGB-SRGB-GAMMA_to_ACES2065-1");
}
Loading