Refactor: Color Management: Determine gamut and transfer function for views
Ref #144911 Pull Request: https://projects.blender.org/blender/blender/pulls/145025
This commit is contained in:
@@ -2836,7 +2836,7 @@ bool IMB_colormanagement_display_is_wide_gamut(const ColorManagedDisplaySettings
|
||||
return false;
|
||||
}
|
||||
const ocio::View *view = display->get_view_by_name(view_name);
|
||||
return (view) ? view->is_wide_gamut() : false;
|
||||
return (view) ? view->gamut() != ocio::Gamut::Rec709 : false;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -8,6 +8,25 @@
|
||||
|
||||
namespace blender::ocio {
|
||||
|
||||
enum class Gamut {
|
||||
Unknown,
|
||||
Rec709, /* sRGB primaries + D65 white point. */
|
||||
P3D65, /* DCI-P3 primaries + D65 white point. */
|
||||
Rec2020, /* Rec.2020 primaries + D65 white point */
|
||||
};
|
||||
|
||||
enum class TransferFunction {
|
||||
Unknown,
|
||||
sRGB, /* Piecewise sRGB */
|
||||
ExtendedsRGB, /* Piecewise sRGB, unclipped for wide gamut */
|
||||
Gamma18, /* Pure Gamma 1.8 */
|
||||
Gamma22, /* Pure Gamma 2.2 */
|
||||
Gamma24, /* Pure Gamma 2.4 */
|
||||
Gamma26, /* Pure Gamma 2.6 */
|
||||
PQ, /* PQ from Rec.2100 */
|
||||
HLG, /* HLG from Rec.2100 */
|
||||
};
|
||||
|
||||
class View {
|
||||
public:
|
||||
virtual ~View() = default;
|
||||
@@ -30,9 +49,14 @@ class View {
|
||||
virtual bool is_hdr() const = 0;
|
||||
|
||||
/**
|
||||
* Does this view transform output wide gamut colors?
|
||||
* Gamut of the display colorspace.
|
||||
*/
|
||||
virtual bool is_wide_gamut() const = 0;
|
||||
virtual Gamut gamut() const = 0;
|
||||
|
||||
/**
|
||||
* Transfer function of the display colorspace.
|
||||
*/
|
||||
virtual TransferFunction transfer_function() const = 0;
|
||||
};
|
||||
|
||||
} // namespace blender::ocio
|
||||
|
||||
@@ -25,9 +25,14 @@ class FallbackDefaultView : public View {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_wide_gamut() const override
|
||||
Gamut gamut() const override
|
||||
{
|
||||
return false;
|
||||
return Gamut::Rec709;
|
||||
}
|
||||
|
||||
TransferFunction transfer_function() const override
|
||||
{
|
||||
return TransferFunction::sRGB;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -158,6 +158,15 @@ LibOCIOColorSpace::LibOCIOColorSpace(const int index,
|
||||
else if (first_alias == "rec2100_hlg_display") {
|
||||
interop_id_ = "hlg_rec2020_display";
|
||||
}
|
||||
else if (first_alias == "lin_rec709_srgb" || first_alias == "lin_rec709") {
|
||||
interop_id_ = "lin_rec709_scene";
|
||||
}
|
||||
else if (first_alias == "lin_rec2020") {
|
||||
interop_id_ = "lin_rec2020_scene";
|
||||
}
|
||||
else if (first_alias == "lin_p3d65" || first_alias == "lin_displayp3") {
|
||||
interop_id_ = "lin_p3d65_scene";
|
||||
}
|
||||
else if ((first_alias.startswith("lin_") || first_alias.startswith("srgb_") ||
|
||||
first_alias.startswith("g18_") || first_alias.startswith("g22_") ||
|
||||
first_alias.startswith("g24_") || first_alias.startswith("g26_") ||
|
||||
|
||||
@@ -347,6 +347,23 @@ const ColorSpace *LibOCIOConfig::get_sorted_color_space_by_index(const int index
|
||||
return get_color_space_by_index(sorted_color_space_index_[index]);
|
||||
}
|
||||
|
||||
const ColorSpace *LibOCIOConfig::get_color_space_by_interop_id(StringRefNull interop_id) const
|
||||
{
|
||||
for (const LibOCIOColorSpace &color_space : color_spaces_) {
|
||||
if (color_space.interop_id() == interop_id) {
|
||||
return &color_space;
|
||||
}
|
||||
}
|
||||
|
||||
for (const LibOCIOColorSpace &color_space : inactive_color_spaces_) {
|
||||
if (color_space.interop_id() == interop_id) {
|
||||
return &color_space;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
@@ -59,6 +59,7 @@ class LibOCIOConfig : public Config {
|
||||
int get_num_color_spaces() const override;
|
||||
const ColorSpace *get_color_space_by_index(int index) const override;
|
||||
const ColorSpace *get_sorted_color_space_by_index(int index) const override;
|
||||
const ColorSpace *get_color_space_by_interop_id(StringRefNull interop_id) const;
|
||||
|
||||
/* Display API. */
|
||||
const Display *get_default_display() const override;
|
||||
|
||||
@@ -65,11 +65,10 @@ LibOCIODisplay::LibOCIODisplay(const int index, const LibOCIOConfig &config) : c
|
||||
is_hdr_ |= view_is_hdr;
|
||||
}
|
||||
|
||||
/* Detect sRGB and wide gamut through interop ID. These are not entirely reliable,
|
||||
* and are currently only used as optimization. */
|
||||
bool is_wide_gamut = true;
|
||||
bool is_srgb = false;
|
||||
bool is_extended = false;
|
||||
/* Detect gamut and transfer function through interop ID. When unknown, things
|
||||
* should still work correctly but may miss optimizations. */
|
||||
Gamut gamut = Gamut::Unknown;
|
||||
TransferFunction transfer_function = TransferFunction::Unknown;
|
||||
|
||||
StringRefNull display_interop_id;
|
||||
if (ocio_display_colorspace) {
|
||||
@@ -81,14 +80,49 @@ LibOCIODisplay::LibOCIODisplay(const int index, const LibOCIOConfig &config) : c
|
||||
}
|
||||
|
||||
if (!display_interop_id.is_empty()) {
|
||||
is_srgb = display_interop_id == "srgb_rec709_display" ||
|
||||
display_interop_id == "srgb_rec709_scene";
|
||||
is_wide_gamut = !(display_interop_id.endswith("_rec709_display") ||
|
||||
display_interop_id.endswith("_rec709_scene"));
|
||||
is_extended = display_interop_id.startswith("srgbx_");
|
||||
if (display_interop_id.endswith("_rec709_display") ||
|
||||
display_interop_id.endswith("_rec709_scene"))
|
||||
{
|
||||
gamut = Gamut::Rec709;
|
||||
}
|
||||
else if (display_interop_id.endswith("_p3d65_display") ||
|
||||
display_interop_id.endswith("_p3d65_scene"))
|
||||
{
|
||||
gamut = Gamut::P3D65;
|
||||
}
|
||||
else if (display_interop_id.endswith("_rec2020_display") ||
|
||||
display_interop_id.endswith("_rec2020_scene"))
|
||||
{
|
||||
gamut = Gamut::Rec2020;
|
||||
}
|
||||
|
||||
if (display_interop_id.startswith("srgb_")) {
|
||||
transfer_function = TransferFunction::sRGB;
|
||||
}
|
||||
else if (display_interop_id.startswith("srgbx_")) {
|
||||
transfer_function = TransferFunction::ExtendedsRGB;
|
||||
}
|
||||
else if (display_interop_id.startswith("pq_")) {
|
||||
transfer_function = TransferFunction::PQ;
|
||||
}
|
||||
else if (display_interop_id.startswith("hlg_")) {
|
||||
transfer_function = TransferFunction::HLG;
|
||||
}
|
||||
else if (display_interop_id.startswith("g18_")) {
|
||||
transfer_function = TransferFunction::Gamma18;
|
||||
}
|
||||
else if (display_interop_id.startswith("g22_")) {
|
||||
transfer_function = TransferFunction::Gamma22;
|
||||
}
|
||||
else if (display_interop_id.startswith("g24_")) {
|
||||
transfer_function = TransferFunction::Gamma24;
|
||||
}
|
||||
else if (display_interop_id.startswith("g26_")) {
|
||||
transfer_function = TransferFunction::Gamma26;
|
||||
}
|
||||
}
|
||||
|
||||
views_.append_as(view_index, view_name, view_is_hdr, is_wide_gamut, is_srgb, is_extended);
|
||||
views_.append_as(view_index, view_name, view_is_hdr, gamut, transfer_function);
|
||||
}
|
||||
|
||||
/* Detect untonemppaed view transform. */
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "libocio_display_processor.hh"
|
||||
#include "OCIO_view.hh"
|
||||
#include <OpenColorIO/OpenColorTransforms.h>
|
||||
|
||||
#if defined(WITH_OPENCOLORIO)
|
||||
|
||||
@@ -55,7 +57,7 @@ static void display_as_extended_srgb(const LibOCIOConfig &config,
|
||||
/* Clamp to gamut, so that we don't display values outside of it. One exception
|
||||
* is extended sRGB, where we need to preserve them for correct results and assume
|
||||
* the view transform already clamped them. */
|
||||
if (!(view && view->is_extended())) {
|
||||
if (!(view && view->transfer_function() == TransferFunction::ExtendedsRGB)) {
|
||||
auto clamp = OCIO_NAMESPACE::RangeTransform::Create();
|
||||
clamp->setStyle(OCIO_NAMESPACE::RANGE_CLAMP);
|
||||
clamp->setMinInValue(0.0);
|
||||
@@ -66,7 +68,9 @@ static void display_as_extended_srgb(const LibOCIOConfig &config,
|
||||
}
|
||||
|
||||
/* Nothing further to do if already using sRGB. */
|
||||
if (view && view->is_srgb()) {
|
||||
if (view && view->transfer_function() == TransferFunction::sRGB &&
|
||||
view->gamut() == Gamut::Rec709)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,22 +17,16 @@ namespace blender::ocio {
|
||||
class LibOCIOView : public View {
|
||||
StringRefNull name_;
|
||||
bool is_hdr_ = false;
|
||||
bool is_wide_gamut_ = false;
|
||||
bool is_srgb_ = false;
|
||||
bool is_extended_ = false;
|
||||
Gamut gamut_ = Gamut::Unknown;
|
||||
TransferFunction transfer_function_ = TransferFunction::Unknown;
|
||||
|
||||
public:
|
||||
LibOCIOView(const int index,
|
||||
const StringRefNull name,
|
||||
const bool is_hdr,
|
||||
const bool is_wide_gamut,
|
||||
const bool is_srgb,
|
||||
const bool is_extended)
|
||||
: name_(name),
|
||||
is_hdr_(is_hdr),
|
||||
is_wide_gamut_(is_wide_gamut),
|
||||
is_srgb_(is_srgb),
|
||||
is_extended_(is_extended)
|
||||
const Gamut gamut,
|
||||
const TransferFunction transfer_function)
|
||||
: name_(name), is_hdr_(is_hdr), gamut_(gamut), transfer_function_(transfer_function)
|
||||
{
|
||||
this->index = index;
|
||||
}
|
||||
@@ -47,21 +41,14 @@ class LibOCIOView : public View {
|
||||
return is_hdr_;
|
||||
}
|
||||
|
||||
bool is_wide_gamut() const override
|
||||
Gamut gamut() const override
|
||||
{
|
||||
return is_wide_gamut_;
|
||||
return gamut_;
|
||||
}
|
||||
|
||||
/* Display space is exactly Rec.709 + sRGB piecewise transfer function. */
|
||||
bool is_srgb() const
|
||||
TransferFunction transfer_function() const override
|
||||
{
|
||||
return is_srgb_;
|
||||
}
|
||||
|
||||
/* Display space has values outside of 0..1 range. */
|
||||
bool is_extended() const
|
||||
{
|
||||
return is_extended_;
|
||||
return transfer_function_;
|
||||
}
|
||||
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("LibOCIOView");
|
||||
|
||||
Reference in New Issue
Block a user